Alpha (#4)
* chore: initial push to be able to work together * chore: add missing wait folder * chore: add missing folders * chore: cleanup alpha branch * feat: mssql alpha instance (#2) * fix: remove unused attribute types and functions from backup models * fix: update API client references to use sqlserverflexalpha package * fix: update package references to use sqlserverflexalpha and modify user data source model * fix: add sqlserverflexalpha user data source to provider * fix: add sqlserverflexalpha user resource and update related functionality * chore: add stackit_sqlserverflexalpha_user resource and instance_id variable * fix: refactor sqlserverflexalpha user resource and enhance schema with status and default_database --------- Co-authored-by: Andre Harms <andre.harms@stackit.cloud> Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud> * feat: add sqlserver instance * chore: fixing tests * chore: update docs --------- Co-authored-by: Marcel S. Henselin <marcel.henselin@stackit.cloud> Co-authored-by: Andre Harms <andre.harms@stackit.cloud>
This commit is contained in:
parent
45073a716b
commit
2733834fc9
351 changed files with 62744 additions and 3 deletions
168
stackit/internal/core/core.go
Normal file
168
stackit/internal/core/core.go
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
// Copyright (c) STACKIT
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
"github.com/stackitcloud/stackit-sdk-go/core/runtime"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
)
|
||||
|
||||
type ResourceType string
|
||||
|
||||
const (
|
||||
Resource ResourceType = "resource"
|
||||
Datasource ResourceType = "datasource"
|
||||
EphemeralResource ResourceType = "ephemeral-resource"
|
||||
|
||||
// Separator used for concatenation of TF-internal resource ID
|
||||
Separator = ","
|
||||
|
||||
ResourceRegionFallbackDocstring = "Uses the `default_region` specified in the provider configuration as a fallback in case no `region` is defined on resource level."
|
||||
DatasourceRegionFallbackDocstring = "Uses the `default_region` specified in the provider configuration as a fallback in case no `region` is defined on datasource level."
|
||||
)
|
||||
|
||||
type EphemeralProviderData struct {
|
||||
ProviderData
|
||||
|
||||
PrivateKey string
|
||||
PrivateKeyPath string
|
||||
ServiceAccountKey string
|
||||
ServiceAccountKeyPath string
|
||||
TokenCustomEndpoint string
|
||||
}
|
||||
|
||||
type ProviderData struct {
|
||||
RoundTripper http.RoundTripper
|
||||
ServiceAccountEmail string // Deprecated: ServiceAccountEmail is not required and will be removed after 12th June 2025.
|
||||
// Deprecated: Use DefaultRegion instead
|
||||
Region string
|
||||
DefaultRegion string
|
||||
AuthorizationCustomEndpoint string
|
||||
CdnCustomEndpoint string
|
||||
DnsCustomEndpoint string
|
||||
GitCustomEndpoint string
|
||||
IaaSCustomEndpoint string
|
||||
KMSCustomEndpoint string
|
||||
LoadBalancerCustomEndpoint string
|
||||
LogMeCustomEndpoint string
|
||||
MariaDBCustomEndpoint string
|
||||
MongoDBFlexCustomEndpoint string
|
||||
ModelServingCustomEndpoint string
|
||||
ObjectStorageCustomEndpoint string
|
||||
ObservabilityCustomEndpoint string
|
||||
OpenSearchCustomEndpoint string
|
||||
PostgresFlexCustomEndpoint string
|
||||
RabbitMQCustomEndpoint string
|
||||
RedisCustomEndpoint string
|
||||
ResourceManagerCustomEndpoint string
|
||||
ScfCustomEndpoint string
|
||||
SecretsManagerCustomEndpoint string
|
||||
SQLServerFlexCustomEndpoint string
|
||||
ServerBackupCustomEndpoint string
|
||||
ServerUpdateCustomEndpoint string
|
||||
SKECustomEndpoint string
|
||||
ServiceEnablementCustomEndpoint string
|
||||
ServiceAccountCustomEndpoint string
|
||||
EnableBetaResources bool
|
||||
Experiments []string
|
||||
|
||||
Version string // version of the STACKIT Terraform provider
|
||||
}
|
||||
|
||||
// GetRegion returns the effective region for the provider, falling back to the deprecated _region_ attribute
|
||||
func (pd *ProviderData) GetRegion() string {
|
||||
if pd.DefaultRegion != "" {
|
||||
return pd.DefaultRegion
|
||||
} else if pd.Region != "" {
|
||||
return pd.Region
|
||||
}
|
||||
// final fallback
|
||||
return "eu01"
|
||||
}
|
||||
|
||||
func (pd *ProviderData) GetRegionWithOverride(overrideRegion types.String) string {
|
||||
if overrideRegion.IsUnknown() || overrideRegion.IsNull() {
|
||||
return pd.GetRegion()
|
||||
}
|
||||
return overrideRegion.ValueString()
|
||||
}
|
||||
|
||||
// DiagsToError Converts TF diagnostics' errors into an error with a human-readable description.
|
||||
// If there are no errors, the output is nil
|
||||
func DiagsToError(diags diag.Diagnostics) error {
|
||||
if !diags.HasError() {
|
||||
return nil
|
||||
}
|
||||
|
||||
diagsError := diags.Errors()
|
||||
diagsStrings := make([]string, 0)
|
||||
for _, diagnostic := range diagsError {
|
||||
diagsStrings = append(diagsStrings, fmt.Sprintf(
|
||||
"(%s) %s",
|
||||
diagnostic.Summary(),
|
||||
diagnostic.Detail(),
|
||||
))
|
||||
}
|
||||
return fmt.Errorf("%s", strings.Join(diagsStrings, ";"))
|
||||
}
|
||||
|
||||
// LogAndAddError Logs the error and adds it to the diags
|
||||
func LogAndAddError(ctx context.Context, diags *diag.Diagnostics, summary, detail string) {
|
||||
if traceId := runtime.GetTraceId(ctx); traceId != "" {
|
||||
detail = fmt.Sprintf("%s\nTrace ID: %q", detail, traceId)
|
||||
}
|
||||
|
||||
tflog.Error(ctx, fmt.Sprintf("%s | %s", summary, detail))
|
||||
diags.AddError(summary, detail)
|
||||
}
|
||||
|
||||
// LogAndAddWarning Logs the warning and adds it to the diags
|
||||
func LogAndAddWarning(ctx context.Context, diags *diag.Diagnostics, summary, detail string) {
|
||||
if traceId := runtime.GetTraceId(ctx); traceId != "" {
|
||||
detail = fmt.Sprintf("%s\nTrace ID: %q", detail, traceId)
|
||||
}
|
||||
|
||||
tflog.Warn(ctx, fmt.Sprintf("%s | %s", summary, detail))
|
||||
diags.AddWarning(summary, detail)
|
||||
}
|
||||
|
||||
func LogAndAddWarningBeta(ctx context.Context, diags *diag.Diagnostics, name string, resourceType ResourceType) {
|
||||
warnTitle := fmt.Sprintf("The %s %q is in beta", resourceType, name)
|
||||
warnContent := fmt.Sprintf("The %s %q is in beta and may be subject to breaking changes in the future. Use with caution.", resourceType, name)
|
||||
tflog.Warn(ctx, fmt.Sprintf("%s | %s", warnTitle, warnContent))
|
||||
diags.AddWarning(warnTitle, warnContent)
|
||||
}
|
||||
|
||||
func LogAndAddErrorBeta(ctx context.Context, diags *diag.Diagnostics, name string, resourceType ResourceType) {
|
||||
errTitle := fmt.Sprintf("The %s %q is in beta and beta is not enabled", resourceType, name)
|
||||
errContent := fmt.Sprintf(`The %s %q is in beta and the beta functionality is currently not enabled. To enable it, set the environment variable STACKIT_TF_ENABLE_BETA_RESOURCES to "true" or set the "enable_beta_resources" provider field to true.`, resourceType, name)
|
||||
tflog.Error(ctx, fmt.Sprintf("%s | %s", errTitle, errContent))
|
||||
diags.AddError(errTitle, errContent)
|
||||
}
|
||||
|
||||
// InitProviderContext extends the context to capture the http response
|
||||
func InitProviderContext(ctx context.Context) context.Context {
|
||||
// Capture http response to get trace-id
|
||||
var httpResp *http.Response
|
||||
return runtime.WithCaptureHTTPResponse(ctx, &httpResp)
|
||||
}
|
||||
|
||||
// LogResponse logs the trace-id of the last request
|
||||
func LogResponse(ctx context.Context) context.Context {
|
||||
// Logs the trace-id of the request
|
||||
traceId := runtime.GetTraceId(ctx)
|
||||
ctx = tflog.SetField(ctx, "x-trace-id", traceId)
|
||||
|
||||
tflog.Info(ctx, "response data", map[string]interface{}{
|
||||
"x-trace-id": traceId,
|
||||
})
|
||||
return ctx
|
||||
}
|
||||
102
stackit/internal/core/core_test.go
Normal file
102
stackit/internal/core/core_test.go
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
// Copyright (c) STACKIT
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
)
|
||||
|
||||
func TestProviderData_GetRegionWithOverride(t *testing.T) {
|
||||
type args struct {
|
||||
overrideRegion types.String
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
providerData *ProviderData
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "override region is null string",
|
||||
providerData: &ProviderData{
|
||||
DefaultRegion: "eu02",
|
||||
},
|
||||
args: args{
|
||||
types.StringNull(),
|
||||
},
|
||||
want: "eu02",
|
||||
},
|
||||
{
|
||||
name: "override region is unknown string",
|
||||
providerData: &ProviderData{
|
||||
DefaultRegion: "eu02",
|
||||
},
|
||||
args: args{
|
||||
types.StringUnknown(),
|
||||
},
|
||||
want: "eu02",
|
||||
},
|
||||
{
|
||||
name: "override region is set",
|
||||
providerData: &ProviderData{
|
||||
DefaultRegion: "eu02",
|
||||
},
|
||||
args: args{
|
||||
types.StringValue("eu01"),
|
||||
},
|
||||
want: "eu01",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := tt.providerData.GetRegionWithOverride(tt.args.overrideRegion); got != tt.want {
|
||||
t.Errorf("GetRegionWithOverride() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestProviderData_GetRegion(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
providerData *ProviderData
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "default region is set",
|
||||
providerData: &ProviderData{
|
||||
DefaultRegion: "eu02",
|
||||
},
|
||||
want: "eu02",
|
||||
},
|
||||
{
|
||||
name: "(legacy) region is set",
|
||||
providerData: &ProviderData{
|
||||
Region: "eu02",
|
||||
},
|
||||
want: "eu02",
|
||||
},
|
||||
{
|
||||
name: "default region wins over (legacy) region",
|
||||
providerData: &ProviderData{
|
||||
DefaultRegion: "eu02",
|
||||
Region: "eu01",
|
||||
},
|
||||
want: "eu02",
|
||||
},
|
||||
{
|
||||
name: "final fallback - neither region (legacy) nor default region is set",
|
||||
providerData: &ProviderData{},
|
||||
want: "eu01",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := tt.providerData.GetRegion(); got != tt.want {
|
||||
t.Errorf("GetRegion() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue