From 5f08b1a3036c1642d203ffaf42afb96787897ab3 Mon Sep 17 00:00:00 2001 From: Alexander Dahmen Date: Tue, 31 Mar 2026 13:58:07 +0200 Subject: [PATCH] chore(cdn): Switch to new multi API support SDK structure STACKITTPR-554 Signed-off-by: Alexander Dahmen --- .../services/cdn/customdomain/datasource.go | 40 ++-- .../cdn/customdomain/datasource_test.go | 50 ++--- .../services/cdn/customdomain/resource.go | 89 ++++---- .../cdn/customdomain/resource_test.go | 73 +++--- .../services/cdn/distribution/datasource.go | 56 ++--- .../cdn/distribution/datasource_test.go | 92 ++++---- .../services/cdn/distribution/resource.go | 190 ++++++++-------- .../cdn/distribution/resource_test.go | 212 +++++++++--------- stackit/internal/services/cdn/utils/util.go | 6 +- .../internal/services/cdn/utils/util_test.go | 12 +- 10 files changed, 406 insertions(+), 414 deletions(-) diff --git a/stackit/internal/services/cdn/customdomain/datasource.go b/stackit/internal/services/cdn/customdomain/datasource.go index 3f90993fb..38f2b09b3 100644 --- a/stackit/internal/services/cdn/customdomain/datasource.go +++ b/stackit/internal/services/cdn/customdomain/datasource.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + cdnSdk "github.com/stackitcloud/stackit-sdk-go/services/cdn/v1api" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/conversion" cdnUtils "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/cdn/utils" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/utils" @@ -14,7 +15,6 @@ import ( "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" - "github.com/stackitcloud/stackit-sdk-go/services/cdn" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/features" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/validate" @@ -27,11 +27,11 @@ var ( ) var certificateDataSourceTypes = map[string]attr.Type{ - "version": types.Int64Type, + "version": types.Int32Type, } type customDomainDataSource struct { - client *cdn.APIClient + client *cdnSdk.APIClient } func NewCustomDomainDataSource() datasource.DataSource { @@ -106,7 +106,7 @@ func (r *customDomainDataSource) Schema(_ context.Context, _ datasource.SchemaRe Description: certificateSchemaDescriptions["main"], Optional: true, Attributes: map[string]schema.Attribute{ - "version": schema.Int64Attribute{ + "version": schema.Int32Attribute{ Description: certificateSchemaDescriptions["version"], Computed: true, }, @@ -133,7 +133,7 @@ func (r *customDomainDataSource) Read(ctx context.Context, req datasource.ReadRe name := model.Name.ValueString() ctx = tflog.SetField(ctx, "name", name) - customDomainResp, err := r.client.GetCustomDomain(ctx, projectId, distributionId, name).Execute() + customDomainResp, err := r.client.DefaultAPI.GetCustomDomain(ctx, projectId, distributionId, name).Execute() if err != nil { utils.LogError( ctx, @@ -165,7 +165,7 @@ func (r *customDomainDataSource) Read(ctx context.Context, req datasource.ReadRe tflog.Info(ctx, "CDN custom domain read") } -func mapCustomDomainDataSourceFields(customDomainResponse *cdn.GetCustomDomainResponse, model *customDomainDataSourceModel, projectId, distributionId string) error { +func mapCustomDomainDataSourceFields(customDomainResponse *cdnSdk.GetCustomDomainResponse, model *customDomainDataSourceModel, projectId, distributionId string) error { if customDomainResponse == nil { return fmt.Errorf("response input is nil") } @@ -173,15 +173,11 @@ func mapCustomDomainDataSourceFields(customDomainResponse *cdn.GetCustomDomainRe return fmt.Errorf("model input is nil") } - if customDomainResponse.CustomDomain == nil { - return fmt.Errorf("CustomDomain is missing in response") + if customDomainResponse.CustomDomain.Name == "" { + return fmt.Errorf("name is empty in response") } - - if customDomainResponse.CustomDomain.Name == nil { - return fmt.Errorf("name is missing in response") - } - if customDomainResponse.CustomDomain.Status == nil { - return fmt.Errorf("status missing in response") + if customDomainResponse.CustomDomain.Status == "" { + return fmt.Errorf("status is empty in response") } normalizedCert, err := normalizeCertificate(customDomainResponse.Certificate) @@ -194,9 +190,9 @@ func mapCustomDomainDataSourceFields(customDomainResponse *cdn.GetCustomDomainRe model.Certificate = types.ObjectNull(certificateDataSourceTypes) } else { // For custom certificates, we only care about the version. - version := types.Int64Null() + version := types.Int32Null() if normalizedCert.Version != nil { - version = types.Int64Value(*normalizedCert.Version) + version = types.Int32Value(*normalizedCert.Version) } certificateObj, diags := types.ObjectValue(certificateDataSourceTypes, map[string]attr.Value{ @@ -208,16 +204,16 @@ func mapCustomDomainDataSourceFields(customDomainResponse *cdn.GetCustomDomainRe model.Certificate = certificateObj } - model.ID = types.StringValue(fmt.Sprintf("%s,%s,%s", projectId, distributionId, *customDomainResponse.CustomDomain.Name)) - model.Status = types.StringValue(string(*customDomainResponse.CustomDomain.Status)) + model.ID = types.StringValue(fmt.Sprintf("%s,%s,%s", projectId, distributionId, customDomainResponse.CustomDomain.Name)) + model.Status = types.StringValue(string(customDomainResponse.CustomDomain.Status)) customDomainErrors := []attr.Value{} if customDomainResponse.CustomDomain.Errors != nil { - for _, e := range *customDomainResponse.CustomDomain.Errors { - if e.En == nil { + for _, e := range customDomainResponse.CustomDomain.Errors { + if e.En == "" { return fmt.Errorf("error description missing") } - customDomainErrors = append(customDomainErrors, types.StringValue(*e.En)) + customDomainErrors = append(customDomainErrors, types.StringValue(e.En)) } } modelErrors, diags := types.ListValue(types.StringType, customDomainErrors) @@ -229,7 +225,7 @@ func mapCustomDomainDataSourceFields(customDomainResponse *cdn.GetCustomDomainRe // Also map the fields back to the model from the config model.ProjectId = types.StringValue(projectId) model.DistributionId = types.StringValue(distributionId) - model.Name = types.StringValue(*customDomainResponse.CustomDomain.Name) + model.Name = types.StringValue(customDomainResponse.CustomDomain.Name) return nil } diff --git a/stackit/internal/services/cdn/customdomain/datasource_test.go b/stackit/internal/services/cdn/customdomain/datasource_test.go index dc4e60c6e..169fc8908 100644 --- a/stackit/internal/services/cdn/customdomain/datasource_test.go +++ b/stackit/internal/services/cdn/customdomain/datasource_test.go @@ -6,7 +6,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stackitcloud/stackit-sdk-go/services/cdn" + cdnSdk "github.com/stackitcloud/stackit-sdk-go/services/cdn/v1api" ) func TestMapDataSourceFields(t *testing.T) { @@ -14,7 +14,7 @@ func TestMapDataSourceFields(t *testing.T) { // Expected certificate object when a custom certificate is returned certAttributes := map[string]attr.Value{ - "version": types.Int64Value(3), + "version": types.Int32Value(3), } certificateObj, _ := types.ObjectValue(certificateDataSourceTypes, certAttributes) @@ -37,30 +37,30 @@ func TestMapDataSourceFields(t *testing.T) { // API response fixtures for custom and managed certificates customType := "custom" - customVersion := int64(3) - getRespCustom := cdn.GetCustomDomainResponseGetCertificateAttributeType(&cdn.GetCustomDomainResponseCertificate{ - GetCustomDomainCustomCertificate: &cdn.GetCustomDomainCustomCertificate{ - Type: &customType, - Version: &customVersion, + customVersion := int32(3) + getRespCustom := cdnSdk.GetCustomDomainResponseCertificate{ + GetCustomDomainCustomCertificate: &cdnSdk.GetCustomDomainCustomCertificate{ + Type: customType, + Version: customVersion, }, - }) + } managedType := "managed" - getRespManaged := cdn.GetCustomDomainResponseGetCertificateAttributeType(&cdn.GetCustomDomainResponseCertificate{ - GetCustomDomainManagedCertificate: &cdn.GetCustomDomainManagedCertificate{ - Type: &managedType, + getRespManaged := cdnSdk.GetCustomDomainResponseCertificate{ + GetCustomDomainManagedCertificate: &cdnSdk.GetCustomDomainManagedCertificate{ + Type: managedType, }, - }) + } // Helper to create API response fixtures - customDomainFixture := func(mods ...func(*cdn.GetCustomDomainResponse)) *cdn.GetCustomDomainResponse { - distribution := &cdn.CustomDomain{ - Errors: &[]cdn.StatusError{}, - Name: new("https://testdomain.com"), - Status: cdn.DOMAINSTATUS_ACTIVE.Ptr(), + customDomainFixture := func(mods ...func(*cdnSdk.GetCustomDomainResponse)) *cdnSdk.GetCustomDomainResponse { + distribution := &cdnSdk.CustomDomain{ + Errors: []cdnSdk.StatusError{}, + Name: "https://testdomain.com", + Status: cdnSdk.DOMAINSTATUS_ACTIVE, } - customDomainResponse := &cdn.GetCustomDomainResponse{ - CustomDomain: distribution, + customDomainResponse := &cdnSdk.GetCustomDomainResponse{ + CustomDomain: *distribution, Certificate: getRespCustom, } @@ -72,7 +72,7 @@ func TestMapDataSourceFields(t *testing.T) { // Test cases tests := map[string]struct { - Input *cdn.GetCustomDomainResponse + Input *cdnSdk.GetCustomDomainResponse Expected *customDomainDataSourceModel IsValid bool }{ @@ -87,7 +87,7 @@ func TestMapDataSourceFields(t *testing.T) { Expected: expectedModel(func(m *customDomainDataSourceModel) { m.Certificate = types.ObjectNull(certificateDataSourceTypes) }), - Input: customDomainFixture(func(gcdr *cdn.GetCustomDomainResponse) { + Input: customDomainFixture(func(gcdr *cdnSdk.GetCustomDomainResponse) { gcdr.Certificate = getRespManaged }), IsValid: true, @@ -97,8 +97,8 @@ func TestMapDataSourceFields(t *testing.T) { m.Status = types.StringValue("ERROR") m.Certificate = certificateObj }), - Input: customDomainFixture(func(d *cdn.GetCustomDomainResponse) { - d.CustomDomain.Status = cdn.DOMAINSTATUS_ERROR.Ptr() + Input: customDomainFixture(func(d *cdnSdk.GetCustomDomainResponse) { + d.CustomDomain.Status = cdnSdk.DOMAINSTATUS_ERROR }), IsValid: true, }, @@ -109,8 +109,8 @@ func TestMapDataSourceFields(t *testing.T) { }, "sad_path_name_missing": { Expected: expectedModel(), - Input: customDomainFixture(func(d *cdn.GetCustomDomainResponse) { - d.CustomDomain.Name = nil + Input: customDomainFixture(func(d *cdnSdk.GetCustomDomainResponse) { + d.CustomDomain.Name = "" }), IsValid: false, }, diff --git a/stackit/internal/services/cdn/customdomain/resource.go b/stackit/internal/services/cdn/customdomain/resource.go index ed8de254e..d5113fe32 100644 --- a/stackit/internal/services/cdn/customdomain/resource.go +++ b/stackit/internal/services/cdn/customdomain/resource.go @@ -11,6 +11,7 @@ import ( "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/utils" + cdnSdk "github.com/stackitcloud/stackit-sdk-go/services/cdn/v1api" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/conversion" cdnUtils "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/cdn/utils" @@ -25,8 +26,8 @@ import ( "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/stackitcloud/stackit-sdk-go/core/oapierror" - "github.com/stackitcloud/stackit-sdk-go/services/cdn" - "github.com/stackitcloud/stackit-sdk-go/services/cdn/wait" + + "github.com/stackitcloud/stackit-sdk-go/services/cdn/v1api/wait" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/features" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/validate" @@ -46,7 +47,7 @@ var certificateSchemaDescriptions = map[string]string{ } var certificateTypes = map[string]attr.Type{ - "version": types.Int64Type, + "version": types.Int32Type, "certificate": types.StringType, "private_key": types.StringType, } @@ -62,7 +63,7 @@ var customDomainSchemaDescriptions = map[string]string{ type CertificateModel struct { Certificate types.String `tfsdk:"certificate"` PrivateKey types.String `tfsdk:"private_key"` - Version types.Int64 `tfsdk:"version"` + Version types.Int32 `tfsdk:"version"` } type CustomDomainModel struct { @@ -76,7 +77,7 @@ type CustomDomainModel struct { } type customDomainResource struct { - client *cdn.APIClient + client *cdnSdk.APIClient } func NewCustomDomainResource() resource.Resource { @@ -85,7 +86,7 @@ func NewCustomDomainResource() resource.Resource { type Certificate struct { Type string - Version *int64 + Version *int32 } func (r *customDomainResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { @@ -159,7 +160,7 @@ func (r *customDomainResource) Schema(_ context.Context, _ resource.SchemaReques Optional: true, Sensitive: true, }, - "version": schema.Int64Attribute{ + "version": schema.Int32Attribute{ Description: certificateSchemaDescriptions["version"], Computed: true, }, @@ -200,11 +201,11 @@ func (r *customDomainResource) Create(ctx context.Context, req resource.CreateRe return } - payload := cdn.PutCustomDomainPayload{ + payload := cdnSdk.PutCustomDomainPayload{ IntentId: new(uuid.NewString()), Certificate: certificate, } - _, err = r.client.PutCustomDomain(ctx, projectId, distributionId, name).PutCustomDomainPayload(payload).Execute() + _, err = r.client.DefaultAPI.PutCustomDomain(ctx, projectId, distributionId, name).PutCustomDomainPayload(payload).Execute() if err != nil { core.LogAndAddError(ctx, &resp.Diagnostics, "Error creating CDN custom domain", fmt.Sprintf("Calling API: %v", err)) return @@ -221,13 +222,13 @@ func (r *customDomainResource) Create(ctx context.Context, req resource.CreateRe return } - _, err = wait.CreateCDNCustomDomainWaitHandler(ctx, r.client, projectId, distributionId, name).SetTimeout(5 * time.Minute).WaitWithContext(ctx) + _, err = wait.CreateCDNCustomDomainWaitHandler(ctx, r.client.DefaultAPI, projectId, distributionId, name).SetTimeout(5 * time.Minute).WaitWithContext(ctx) if err != nil { core.LogAndAddError(ctx, &resp.Diagnostics, "Error creating CDN custom domain", fmt.Sprintf("Waiting for create: %v", err)) return } - respCustomDomain, err := r.client.GetCustomDomainExecute(ctx, projectId, distributionId, name) + respCustomDomain, err := r.client.DefaultAPI.GetCustomDomain(ctx, projectId, distributionId, name).Execute() if err != nil { core.LogAndAddError(ctx, &resp.Diagnostics, "Error creating CDN custom domain", fmt.Sprintf("Calling API: %v", err)) return @@ -263,7 +264,7 @@ func (r *customDomainResource) Read(ctx context.Context, req resource.ReadReques name := model.Name.ValueString() ctx = tflog.SetField(ctx, "name", name) - customDomainResp, err := r.client.GetCustomDomain(ctx, projectId, distributionId, name).Execute() + customDomainResp, err := r.client.DefaultAPI.GetCustomDomain(ctx, projectId, distributionId, name).Execute() if err != nil { var oapiErr *oapierror.GenericOpenAPIError // n.b. err is caught here if of type *oapierror.GenericOpenAPIError, which the stackit SDK client returns @@ -316,11 +317,11 @@ func (r *customDomainResource) Update(ctx context.Context, req resource.UpdateRe return } - payload := cdn.PutCustomDomainPayload{ + payload := cdnSdk.PutCustomDomainPayload{ IntentId: new(uuid.NewString()), Certificate: certificate, } - _, err = r.client.PutCustomDomain(ctx, projectId, distributionId, name).PutCustomDomainPayload(payload).Execute() + _, err = r.client.DefaultAPI.PutCustomDomain(ctx, projectId, distributionId, name).PutCustomDomainPayload(payload).Execute() if err != nil { core.LogAndAddError(ctx, &resp.Diagnostics, "Error updating CDN custom domain certificate", fmt.Sprintf("Calling API: %v", err)) return @@ -328,13 +329,13 @@ func (r *customDomainResource) Update(ctx context.Context, req resource.UpdateRe ctx = core.LogResponse(ctx) - _, err = wait.CreateCDNCustomDomainWaitHandler(ctx, r.client, projectId, distributionId, name).SetTimeout(5 * time.Minute).WaitWithContext(ctx) + _, err = wait.CreateCDNCustomDomainWaitHandler(ctx, r.client.DefaultAPI, projectId, distributionId, name).SetTimeout(5 * time.Minute).WaitWithContext(ctx) if err != nil { core.LogAndAddError(ctx, &resp.Diagnostics, "Error updating CDN custom domain certificate", fmt.Sprintf("Waiting for update: %v", err)) return } - respCustomDomain, err := r.client.GetCustomDomainExecute(ctx, projectId, distributionId, name) + respCustomDomain, err := r.client.DefaultAPI.GetCustomDomain(ctx, projectId, distributionId, name).Execute() if err != nil { core.LogAndAddError(ctx, &resp.Diagnostics, "Error updating CDN custom domain certificate", fmt.Sprintf("Calling API to read final state: %v", err)) return @@ -369,14 +370,14 @@ func (r *customDomainResource) Delete(ctx context.Context, req resource.DeleteRe name := model.Name.ValueString() ctx = tflog.SetField(ctx, "name", name) - _, err := r.client.DeleteCustomDomain(ctx, projectId, distributionId, name).Execute() + _, err := r.client.DefaultAPI.DeleteCustomDomain(ctx, projectId, distributionId, name).Execute() if err != nil { core.LogAndAddError(ctx, &resp.Diagnostics, "Delete CDN custom domain", fmt.Sprintf("Delete custom domain: %v", err)) } ctx = core.LogResponse(ctx) - _, err = wait.DeleteCDNCustomDomainWaitHandler(ctx, r.client, projectId, distributionId, name).WaitWithContext(ctx) + _, err = wait.DeleteCDNCustomDomainWaitHandler(ctx, r.client.DefaultAPI, projectId, distributionId, name).WaitWithContext(ctx) if err != nil { core.LogAndAddError(ctx, &resp.Diagnostics, "Delete CDN custom domain", fmt.Sprintf("Waiting for deletion: %v", err)) return @@ -398,28 +399,25 @@ func (r *customDomainResource) ImportState(ctx context.Context, req resource.Imp tflog.Info(ctx, "CDN custom domain state imported") } -func normalizeCertificate(certInput cdn.GetCustomDomainResponseGetCertificateAttributeType) (Certificate, error) { - var customCert *cdn.GetCustomDomainCustomCertificate - var managedCert *cdn.GetCustomDomainManagedCertificate +func normalizeCertificate(certInput cdnSdk.GetCustomDomainResponseCertificate) (Certificate, error) { + var customCert *cdnSdk.GetCustomDomainCustomCertificate + var managedCert *cdnSdk.GetCustomDomainManagedCertificate - if certInput == nil { - return Certificate{}, errors.New("input of type GetCustomDomainResponseCertificate is nil") - } customCert = certInput.GetCustomDomainCustomCertificate managedCert = certInput.GetCustomDomainManagedCertificate // Now we process the extracted certificates - if customCert != nil && customCert.Type != nil && customCert.Version != nil { + if customCert != nil && customCert.Type != "" { return Certificate{ - Type: *customCert.Type, - Version: customCert.Version, // Converts from *int64 to int + Type: customCert.Type, + Version: new(customCert.Version), }, nil } - if managedCert != nil && managedCert.Type != nil { + if managedCert != nil && managedCert.Type != "" { // The version will be the zero value for int (0), as requested return Certificate{ - Type: *managedCert.Type, + Type: managedCert.Type, }, nil } @@ -428,11 +426,11 @@ func normalizeCertificate(certInput cdn.GetCustomDomainResponseGetCertificateAtt // toCertificatePayload constructs the certificate part of the payload for the API request. // It defaults to a managed certificate if the certificate block is omitted, otherwise it creates a custom certificate. -func toCertificatePayload(ctx context.Context, model *CustomDomainModel) (*cdn.PutCustomDomainPayloadCertificate, error) { +func toCertificatePayload(ctx context.Context, model *CustomDomainModel) (*cdnSdk.PutCustomDomainPayloadCertificate, error) { // If the certificate block is not specified, default to a managed certificate. if model.Certificate.IsNull() { - managedCert := cdn.NewPutCustomDomainManagedCertificate("managed") - certPayload := cdn.PutCustomDomainManagedCertificateAsPutCustomDomainPayloadCertificate(managedCert) + managedCert := cdnSdk.NewPutCustomDomainManagedCertificate("managed") + certPayload := cdnSdk.PutCustomDomainManagedCertificateAsPutCustomDomainPayloadCertificate(managedCert) return &certPayload, nil } @@ -454,17 +452,17 @@ func toCertificatePayload(ctx context.Context, model *CustomDomainModel) (*cdn.P return nil, errors.New("invalid certificate or private key. Please check if the string of the public certificate and private key in PEM format") } - customCert := cdn.NewPutCustomDomainCustomCertificate( + customCert := cdnSdk.NewPutCustomDomainCustomCertificate( certStr, keyStr, "custom", ) - certPayload := cdn.PutCustomDomainCustomCertificateAsPutCustomDomainPayloadCertificate(customCert) + certPayload := cdnSdk.PutCustomDomainCustomCertificateAsPutCustomDomainPayloadCertificate(customCert) return &certPayload, nil } -func mapCustomDomainResourceFields(customDomainResponse *cdn.GetCustomDomainResponse, model *CustomDomainModel) error { +func mapCustomDomainResourceFields(customDomainResponse *cdnSdk.GetCustomDomainResponse, model *CustomDomainModel) error { if customDomainResponse == nil { return fmt.Errorf("response input is nil") } @@ -472,14 +470,11 @@ func mapCustomDomainResourceFields(customDomainResponse *cdn.GetCustomDomainResp return fmt.Errorf("model input is nil") } - if customDomainResponse.CustomDomain == nil { - return fmt.Errorf("CustomDomain is missing in response") - } - if customDomainResponse.CustomDomain.Name == nil { + if customDomainResponse.CustomDomain.Name == "" { return fmt.Errorf("name is missing in response") } - if customDomainResponse.CustomDomain.Status == nil { + if customDomainResponse.CustomDomain.Status == "" { return fmt.Errorf("status missing in response") } normalizedCert, err := normalizeCertificate(customDomainResponse.Certificate) @@ -496,7 +491,7 @@ func mapCustomDomainResourceFields(customDomainResponse *cdn.GetCustomDomainResp certAttributes := map[string]attr.Value{ "certificate": types.StringNull(), // Default to null "private_key": types.StringNull(), // Default to null - "version": types.Int64Null(), + "version": types.Int32Null(), } // Get existing values from the model's certificate object if it exists @@ -512,7 +507,7 @@ func mapCustomDomainResourceFields(customDomainResponse *cdn.GetCustomDomainResp // Set the computed version from the API response if normalizedCert.Version != nil { - certAttributes["version"] = types.Int64Value(*normalizedCert.Version) + certAttributes["version"] = types.Int32Value(*normalizedCert.Version) } certificateObj, diags := types.ObjectValue(certificateTypes, certAttributes) @@ -522,16 +517,16 @@ func mapCustomDomainResourceFields(customDomainResponse *cdn.GetCustomDomainResp model.Certificate = certificateObj } - model.ID = utils.BuildInternalTerraformId(model.ProjectId.ValueString(), model.DistributionId.ValueString(), *customDomainResponse.CustomDomain.Name) - model.Status = types.StringValue(string(*customDomainResponse.CustomDomain.Status)) + model.ID = utils.BuildInternalTerraformId(model.ProjectId.ValueString(), model.DistributionId.ValueString(), customDomainResponse.CustomDomain.Name) + model.Status = types.StringValue(string(customDomainResponse.CustomDomain.Status)) customDomainErrors := []attr.Value{} if customDomainResponse.CustomDomain.Errors != nil { - for _, e := range *customDomainResponse.CustomDomain.Errors { - if e.En == nil { + for _, e := range customDomainResponse.CustomDomain.Errors { + if e.En == "" { return fmt.Errorf("error description missing") } - customDomainErrors = append(customDomainErrors, types.StringValue(*e.En)) + customDomainErrors = append(customDomainErrors, types.StringValue(e.En)) } } modelErrors, diags := types.ListValue(types.StringType, customDomainErrors) diff --git a/stackit/internal/services/cdn/customdomain/resource_test.go b/stackit/internal/services/cdn/customdomain/resource_test.go index dd10dcee8..4f1bf8f47 100644 --- a/stackit/internal/services/cdn/customdomain/resource_test.go +++ b/stackit/internal/services/cdn/customdomain/resource_test.go @@ -18,13 +18,13 @@ import ( "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-framework/types/basetypes" - "github.com/stackitcloud/stackit-sdk-go/services/cdn" + cdnSdk "github.com/stackitcloud/stackit-sdk-go/services/cdn/v1api" ) func TestMapFields(t *testing.T) { // Redefine certificateTypes locally for testing, matching the updated schema certificateTypes := map[string]attr.Type{ - "version": types.Int64Type, + "version": types.Int32Type, "certificate": types.StringType, "private_key": types.StringType, } @@ -36,7 +36,7 @@ func TestMapFields(t *testing.T) { // Expected object when a custom certificate is returned certAttributes := map[string]attr.Value{ - "version": types.Int64Value(3), + "version": types.Int32Value(3), "certificate": types.StringValue(dummyCert), "private_key": types.StringValue(dummyKey), } @@ -57,30 +57,31 @@ func TestMapFields(t *testing.T) { return model } + // API response fixtures for custom and managed certificates customType := "custom" - customVersion := int64(3) - getRespCustom := cdn.GetCustomDomainResponseGetCertificateAttributeType(&cdn.GetCustomDomainResponseCertificate{ - GetCustomDomainCustomCertificate: &cdn.GetCustomDomainCustomCertificate{ - Type: &customType, - Version: &customVersion, + customVersion := int32(3) + getRespCustom := cdnSdk.GetCustomDomainResponseCertificate{ + GetCustomDomainCustomCertificate: &cdnSdk.GetCustomDomainCustomCertificate{ + Type: customType, + Version: customVersion, }, - }) + } managedType := "managed" - getRespManaged := cdn.GetCustomDomainResponseGetCertificateAttributeType(&cdn.GetCustomDomainResponseCertificate{ - GetCustomDomainManagedCertificate: &cdn.GetCustomDomainManagedCertificate{ - Type: &managedType, + getRespManaged := cdnSdk.GetCustomDomainResponseCertificate{ + GetCustomDomainManagedCertificate: &cdnSdk.GetCustomDomainManagedCertificate{ + Type: managedType, }, - }) + } - customDomainFixture := func(mods ...func(*cdn.GetCustomDomainResponse)) *cdn.GetCustomDomainResponse { - distribution := &cdn.CustomDomain{ - Errors: &[]cdn.StatusError{}, - Name: new("https://testdomain.com"), - Status: cdn.DOMAINSTATUS_ACTIVE.Ptr(), + customDomainFixture := func(mods ...func(*cdnSdk.GetCustomDomainResponse)) *cdnSdk.GetCustomDomainResponse { + distribution := &cdnSdk.CustomDomain{ + Errors: []cdnSdk.StatusError{}, + Name: "https://testdomain.com", + Status: cdnSdk.DOMAINSTATUS_ACTIVE, } - customDomainResponse := &cdn.GetCustomDomainResponse{ - CustomDomain: distribution, + customDomainResponse := &cdnSdk.GetCustomDomainResponse{ + CustomDomain: *distribution, Certificate: getRespCustom, } @@ -91,7 +92,7 @@ func TestMapFields(t *testing.T) { } tests := map[string]struct { - Input *cdn.GetCustomDomainResponse + Input *cdnSdk.GetCustomDomainResponse Certificate any Expected *CustomDomainModel InitialModel *CustomDomainModel @@ -108,7 +109,7 @@ func TestMapFields(t *testing.T) { m.Certificate = basetypes.NewObjectValueMust(certificateTypes, map[string]attr.Value{ "certificate": types.StringValue(dummyCert), "private_key": types.StringValue(dummyKey), - "version": types.Int64Null(), + "version": types.Int32Null(), }) }), }, @@ -116,7 +117,7 @@ func TestMapFields(t *testing.T) { Expected: expectedModel(func(m *CustomDomainModel) { m.Certificate = types.ObjectNull(certificateTypes) }), - Input: customDomainFixture(func(gcdr *cdn.GetCustomDomainResponse) { + Input: customDomainFixture(func(gcdr *cdnSdk.GetCustomDomainResponse) { gcdr.Certificate = getRespManaged }), IsValid: true, @@ -127,15 +128,15 @@ func TestMapFields(t *testing.T) { m.Status = types.StringValue("ERROR") m.Certificate = certificateObj }), - Input: customDomainFixture(func(d *cdn.GetCustomDomainResponse) { - d.CustomDomain.Status = cdn.DOMAINSTATUS_ERROR.Ptr() + Input: customDomainFixture(func(d *cdnSdk.GetCustomDomainResponse) { + d.CustomDomain.Status = cdnSdk.DOMAINSTATUS_ERROR }), IsValid: true, InitialModel: expectedModel(func(m *CustomDomainModel) { m.Certificate = basetypes.NewObjectValueMust(certificateTypes, map[string]attr.Value{ "certificate": types.StringValue(dummyCert), "private_key": types.StringValue(dummyKey), - "version": types.Int64Null(), + "version": types.Int32Null(), }) }), }, @@ -147,8 +148,8 @@ func TestMapFields(t *testing.T) { }, "sad_path_name_missing": { Expected: expectedModel(), - Input: customDomainFixture(func(d *cdn.GetCustomDomainResponse) { - d.CustomDomain.Name = nil + Input: customDomainFixture(func(d *cdnSdk.GetCustomDomainResponse) { + d.CustomDomain.Name = "" }), IsValid: false, InitialModel: &CustomDomainModel{}, @@ -223,7 +224,7 @@ func TestToCertificatePayload(t *testing.T) { tests := map[string]struct { model *CustomDomainModel - expectedPayload *cdn.PutCustomDomainPayloadCertificate + expectedPayload *cdnSdk.PutCustomDomainPayloadCertificate expectErr bool expectedErrMsg string }{ @@ -231,8 +232,8 @@ func TestToCertificatePayload(t *testing.T) { model: &CustomDomainModel{ Certificate: types.ObjectNull(certificateTypes), }, - expectedPayload: &cdn.PutCustomDomainPayloadCertificate{ - PutCustomDomainManagedCertificate: cdn.NewPutCustomDomainManagedCertificate("managed"), + expectedPayload: &cdnSdk.PutCustomDomainPayloadCertificate{ + PutCustomDomainManagedCertificate: cdnSdk.NewPutCustomDomainManagedCertificate("managed"), }, expectErr: false, }, @@ -241,14 +242,14 @@ func TestToCertificatePayload(t *testing.T) { Certificate: basetypes.NewObjectValueMust( certificateTypes, map[string]attr.Value{ - "version": types.Int64Null(), + "version": types.Int32Null(), "certificate": types.StringValue(certPEM), "private_key": types.StringValue(keyPEM), }, ), }, - expectedPayload: &cdn.PutCustomDomainPayloadCertificate{ - PutCustomDomainCustomCertificate: cdn.NewPutCustomDomainCustomCertificate(certBase64, keyBase64, "custom"), + expectedPayload: &cdnSdk.PutCustomDomainPayloadCertificate{ + PutCustomDomainCustomCertificate: cdnSdk.NewPutCustomDomainCustomCertificate(certBase64, keyBase64, "custom"), }, expectErr: false, }, @@ -257,7 +258,7 @@ func TestToCertificatePayload(t *testing.T) { Certificate: basetypes.NewObjectValueMust( certificateTypes, map[string]attr.Value{ - "version": types.Int64Null(), + "version": types.Int32Null(), "certificate": types.StringValue(""), // Empty certificate "private_key": types.StringValue(keyPEM), }, @@ -272,7 +273,7 @@ func TestToCertificatePayload(t *testing.T) { Certificate: basetypes.NewObjectValueMust( certificateTypes, map[string]attr.Value{ - "version": types.Int64Null(), + "version": types.Int32Null(), "certificate": types.StringNull(), "private_key": types.StringNull(), }, diff --git a/stackit/internal/services/cdn/distribution/datasource.go b/stackit/internal/services/cdn/distribution/datasource.go index f352d863b..1613d6d09 100644 --- a/stackit/internal/services/cdn/distribution/datasource.go +++ b/stackit/internal/services/cdn/distribution/datasource.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + cdnSdk "github.com/stackitcloud/stackit-sdk-go/services/cdn/v1api" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/conversion" cdnUtils "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/cdn/utils" @@ -14,7 +15,6 @@ import ( "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" - "github.com/stackitcloud/stackit-sdk-go/services/cdn" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/features" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/utils" @@ -41,7 +41,7 @@ var dataSourceConfigTypes = map[string]attr.Type{ } type distributionDataSource struct { - client *cdn.APIClient + client *cdnSdk.APIClient } // Ensure the implementation satisfies the expected interfaces. @@ -217,7 +217,7 @@ func (r *distributionDataSource) Read(ctx context.Context, req datasource.ReadRe projectId := model.ProjectId.ValueString() distributionId := model.DistributionId.ValueString() - distributionResp, err := r.client.GetDistributionExecute(ctx, projectId, distributionId) + distributionResp, err := r.client.DefaultAPI.GetDistribution(ctx, projectId, distributionId).Execute() if err != nil { utils.LogError( ctx, @@ -234,7 +234,7 @@ func (r *distributionDataSource) Read(ctx context.Context, req datasource.ReadRe ctx = core.LogResponse(ctx) // Use specific Data Source mapping function - err = mapDataSourceFields(ctx, distributionResp.Distribution, &model) + err = mapDataSourceFields(ctx, &distributionResp.Distribution, &model) if err != nil { core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading CDN distribution", fmt.Sprintf("Error processing API response: %v", err)) return @@ -245,7 +245,7 @@ func (r *distributionDataSource) Read(ctx context.Context, req datasource.ReadRe // mapDataSourceFields is a specialized version of mapFields for the Data Source. // It uses dataSourceConfigTypes (excludes bucket access and secrets) and skips state restoration logic. -func mapDataSourceFields(ctx context.Context, distribution *cdn.Distribution, model *Model) error { +func mapDataSourceFields(ctx context.Context, distribution *cdnSdk.Distribution, model *Model) error { if distribution == nil { return fmt.Errorf("response input is nil") } @@ -254,13 +254,13 @@ func mapDataSourceFields(ctx context.Context, distribution *cdn.Distribution, mo } // Basic fields mapping (same as resource) - if distribution.ProjectId == nil || distribution.Id == nil || distribution.CreatedAt == nil || distribution.UpdatedAt == nil || distribution.Status == nil { + if distribution.ProjectId == "" || distribution.Id == "" || distribution.Status == "" { return fmt.Errorf("missing required fields in response") } - model.ID = utils.BuildInternalTerraformId(*distribution.ProjectId, *distribution.Id) - model.DistributionId = types.StringValue(*distribution.Id) - model.ProjectId = types.StringValue(*distribution.ProjectId) + model.ID = utils.BuildInternalTerraformId(distribution.ProjectId, distribution.Id) + model.DistributionId = types.StringValue(distribution.Id) + model.ProjectId = types.StringValue(distribution.ProjectId) model.Status = types.StringValue(string(distribution.GetStatus())) model.CreatedAt = types.StringValue(distribution.CreatedAt.String()) model.UpdatedAt = types.StringValue(distribution.UpdatedAt.String()) @@ -268,8 +268,8 @@ func mapDataSourceFields(ctx context.Context, distribution *cdn.Distribution, mo // Distribution Errors distributionErrors := []attr.Value{} if distribution.Errors != nil { - for _, e := range *distribution.Errors { - distributionErrors = append(distributionErrors, types.StringValue(*e.En)) + for _, e := range distribution.Errors { + distributionErrors = append(distributionErrors, types.StringValue(e.En)) } } modelErrors, diags := types.ListValue(types.StringType, distributionErrors) @@ -280,7 +280,7 @@ func mapDataSourceFields(ctx context.Context, distribution *cdn.Distribution, mo // Regions regions := []attr.Value{} - for _, r := range *distribution.Config.Regions { + for _, r := range distribution.Config.Regions { regions = append(regions, types.StringValue(string(r))) } modelRegions, diags := types.ListValue(types.StringType, regions) @@ -290,8 +290,8 @@ func mapDataSourceFields(ctx context.Context, distribution *cdn.Distribution, mo // Blocked Countries var blockedCountries []attr.Value - if distribution.Config != nil && distribution.Config.BlockedCountries != nil { - for _, c := range *distribution.Config.BlockedCountries { + if distribution.Config.BlockedCountries != nil { + for _, c := range distribution.Config.BlockedCountries { blockedCountries = append(blockedCountries, types.StringValue(string(c))) } } @@ -308,9 +308,9 @@ func mapDataSourceFields(ctx context.Context, distribution *cdn.Distribution, mo // If HTTP Backend is present if distribution.Config.Backend.HttpBackend != nil { // Headers - if origHeaders := distribution.Config.Backend.HttpBackend.OriginRequestHeaders; origHeaders != nil && len(*origHeaders) > 0 { + if origHeaders := distribution.Config.Backend.HttpBackend.OriginRequestHeaders; len(origHeaders) > 0 { headers := map[string]attr.Value{} - for k, v := range *origHeaders { + for k, v := range origHeaders { headers[k] = types.StringValue(v) } mappedHeaders, diags := types.MapValue(types.StringType, headers) @@ -321,9 +321,9 @@ func mapDataSourceFields(ctx context.Context, distribution *cdn.Distribution, mo } // Geofencing - if geofencingAPI := distribution.Config.Backend.HttpBackend.Geofencing; geofencingAPI != nil && len(*geofencingAPI) > 0 { + if geofencingAPI := distribution.Config.Backend.HttpBackend.Geofencing; len(geofencingAPI) > 0 { geofencingMapElems := make(map[string]attr.Value) - for url, countries := range *geofencingAPI { + for url, countries := range geofencingAPI { listVal, diags := types.ListValueFrom(ctx, types.StringType, countries) if diags.HasError() { return core.DiagsToError(diags) @@ -339,7 +339,7 @@ func mapDataSourceFields(ctx context.Context, distribution *cdn.Distribution, mo backendValues = map[string]attr.Value{ "type": types.StringValue("http"), - "origin_url": types.StringValue(*distribution.Config.Backend.HttpBackend.OriginUrl), + "origin_url": types.StringValue(distribution.Config.Backend.HttpBackend.OriginUrl), "origin_request_headers": originRequestHeaders, "geofencing": geofencingVal, "bucket_url": types.StringNull(), @@ -349,8 +349,8 @@ func mapDataSourceFields(ctx context.Context, distribution *cdn.Distribution, mo // For Data Source, we strictly return what API gives us. No secret restoration. backendValues = map[string]attr.Value{ "type": types.StringValue("bucket"), - "bucket_url": types.StringValue(*distribution.Config.Backend.BucketBackend.BucketUrl), - "region": types.StringValue(*distribution.Config.Backend.BucketBackend.Region), + "bucket_url": types.StringValue(distribution.Config.Backend.BucketBackend.BucketUrl), + "region": types.StringValue(distribution.Config.Backend.BucketBackend.Region), "origin_url": types.StringNull(), "origin_request_headers": types.MapNull(types.StringType), "geofencing": types.MapNull(geofencingTypes.ElemType), @@ -369,7 +369,7 @@ func mapDataSourceFields(ctx context.Context, distribution *cdn.Distribution, mo if enabled, ok := o.GetEnabledOk(); ok { var diags diag.Diagnostics optimizerVal, diags = types.ObjectValue(optimizerTypes, map[string]attr.Value{ - "enabled": types.BoolValue(enabled), + "enabled": types.BoolPointerValue(enabled), }) if diags.HasError() { return core.DiagsToError(diags) @@ -392,11 +392,11 @@ func mapDataSourceFields(ctx context.Context, distribution *cdn.Distribution, mo // Domains domains := []attr.Value{} if distribution.Domains != nil { - for _, d := range *distribution.Domains { + for _, d := range distribution.Domains { domainErrors := []attr.Value{} if d.Errors != nil { - for _, e := range *d.Errors { - domainErrors = append(domainErrors, types.StringValue(*e.En)) + for _, e := range d.Errors { + domainErrors = append(domainErrors, types.StringValue(e.En)) } } modelDomainErrors, diags := types.ListValue(types.StringType, domainErrors) @@ -404,9 +404,9 @@ func mapDataSourceFields(ctx context.Context, distribution *cdn.Distribution, mo return core.DiagsToError(diags) } modelDomain, diags := types.ObjectValue(domainTypes, map[string]attr.Value{ - "name": types.StringValue(*d.Name), - "status": types.StringValue(string(*d.Status)), - "type": types.StringValue(string(*d.Type)), + "name": types.StringValue(d.Name), + "status": types.StringValue(string(d.Status)), + "type": types.StringValue(string(d.Type)), "errors": modelDomainErrors, }) if diags.HasError() { diff --git a/stackit/internal/services/cdn/distribution/datasource_test.go b/stackit/internal/services/cdn/distribution/datasource_test.go index 4157297be..977082cb0 100644 --- a/stackit/internal/services/cdn/distribution/datasource_test.go +++ b/stackit/internal/services/cdn/distribution/datasource_test.go @@ -8,7 +8,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stackitcloud/stackit-sdk-go/services/cdn" + cdnSdk "github.com/stackitcloud/stackit-sdk-go/services/cdn/v1api" ) func TestMapDataSourceFields(t *testing.T) { @@ -71,35 +71,35 @@ func TestMapDataSourceFields(t *testing.T) { } return model } - distributionFixture := func(mods ...func(*cdn.Distribution)) *cdn.Distribution { - distribution := &cdn.Distribution{ - Config: &cdn.Config{ - Backend: &cdn.ConfigBackend{ - HttpBackend: &cdn.HttpBackend{ - OriginRequestHeaders: &map[string]string{ + distributionFixture := func(mods ...func(*cdnSdk.Distribution)) *cdnSdk.Distribution { + distribution := &cdnSdk.Distribution{ + Config: cdnSdk.Config{ + Backend: cdnSdk.ConfigBackend{ + HttpBackend: &cdnSdk.HttpBackend{ + OriginRequestHeaders: map[string]string{ "testHeader0": "testHeaderValue0", "testHeader1": "testHeaderValue1", }, - OriginUrl: new("https://www.mycoolapp.com"), - Type: new("http"), + OriginUrl: "https://www.mycoolapp.com", + Type: "http", }, }, - Regions: &[]cdn.Region{"EU", "US"}, - BlockedCountries: &[]string{"XX", "YY", "ZZ"}, + Regions: []cdnSdk.Region{"EU", "US"}, + BlockedCountries: []string{"XX", "YY", "ZZ"}, Optimizer: nil, }, - CreatedAt: &createdAt, - Domains: &[]cdn.Domain{ + CreatedAt: createdAt, + Domains: []cdnSdk.Domain{ { - Name: new("test.stackit-cdn.com"), - Status: cdn.DOMAINSTATUS_ACTIVE.Ptr(), - Type: cdn.DOMAINTYPE_MANAGED.Ptr(), + Name: "test.stackit-cdn.com", + Status: cdnSdk.DOMAINSTATUS_ACTIVE, + Type: "managed", }, }, - Id: new("test-distribution-id"), - ProjectId: new("test-project-id"), - Status: cdn.DISTRIBUTIONSTATUS_ACTIVE.Ptr(), - UpdatedAt: &updatedAt, + Id: "test-distribution-id", + ProjectId: "test-project-id", + Status: string(cdnSdk.DOMAINSTATUS_ACTIVE), + UpdatedAt: updatedAt, } for _, mod := range mods { mod(distribution) @@ -116,7 +116,7 @@ func TestMapDataSourceFields(t *testing.T) { "geofencing": types.MapNull(geofencingTypes.ElemType), }) tests := map[string]struct { - Input *cdn.Distribution + Input *cdnSdk.Distribution Expected *Model IsValid bool }{ @@ -134,20 +134,20 @@ func TestMapDataSourceFields(t *testing.T) { "blocked_countries": blockedCountriesFixture, }) }), - Input: distributionFixture(func(d *cdn.Distribution) { - d.Config.Optimizer = &cdn.Optimizer{ - Enabled: new(true), + Input: distributionFixture(func(d *cdnSdk.Distribution) { + d.Config.Optimizer = &cdnSdk.Optimizer{ + Enabled: true, } }), IsValid: true, }, "happy_path_bucket": { - Input: distributionFixture(func(d *cdn.Distribution) { - d.Config.Backend = &cdn.ConfigBackend{ - BucketBackend: &cdn.BucketBackend{ - Type: new("bucket"), - BucketUrl: new("https://s3.example.com"), - Region: new("eu01"), + Input: distributionFixture(func(d *cdnSdk.Distribution) { + d.Config.Backend = cdnSdk.ConfigBackend{ + BucketBackend: &cdnSdk.BucketBackend{ + Type: "bucket", + BucketUrl: "https://s3.example.com", + Region: "eu01", }, } }), @@ -178,8 +178,8 @@ func TestMapDataSourceFields(t *testing.T) { "blocked_countries": blockedCountriesFixture, }) }), - Input: distributionFixture(func(d *cdn.Distribution) { - d.Config.Backend.HttpBackend.Geofencing = &geofencingInput + Input: distributionFixture(func(d *cdnSdk.Distribution) { + d.Config.Backend.HttpBackend.Geofencing = geofencingInput }), IsValid: true, }, @@ -187,8 +187,8 @@ func TestMapDataSourceFields(t *testing.T) { Expected: expectedModel(func(m *Model) { m.Status = types.StringValue("ERROR") }), - Input: distributionFixture(func(d *cdn.Distribution) { - d.Status = cdn.DISTRIBUTIONSTATUS_ERROR.Ptr() + Input: distributionFixture(func(d *cdnSdk.Distribution) { + d.Status = string(cdnSdk.DOMAINSTATUS_ERROR) }), IsValid: true, }, @@ -209,17 +209,17 @@ func TestMapDataSourceFields(t *testing.T) { domains := types.ListValueMust(types.ObjectType{AttrTypes: domainTypes}, []attr.Value{managedDomain, customDomain}) m.Domains = domains }), - Input: distributionFixture(func(d *cdn.Distribution) { - d.Domains = &[]cdn.Domain{ + Input: distributionFixture(func(d *cdnSdk.Distribution) { + d.Domains = []cdnSdk.Domain{ { - Name: new("test.stackit-cdn.com"), - Status: cdn.DOMAINSTATUS_ACTIVE.Ptr(), - Type: cdn.DOMAINTYPE_MANAGED.Ptr(), + Name: "test.stackit-cdn.com", + Status: cdnSdk.DOMAINSTATUS_ACTIVE, + Type: "managed", }, { - Name: new("mycoolapp.info"), - Status: cdn.DOMAINSTATUS_ACTIVE.Ptr(), - Type: cdn.DOMAINTYPE_CUSTOM.Ptr(), + Name: "mycoolapp.info", + Status: cdnSdk.DOMAINSTATUS_ACTIVE, + Type: "custom", }, } }), @@ -232,15 +232,15 @@ func TestMapDataSourceFields(t *testing.T) { }, "sad_path_project_id_missing": { Expected: expectedModel(), - Input: distributionFixture(func(d *cdn.Distribution) { - d.ProjectId = nil + Input: distributionFixture(func(d *cdnSdk.Distribution) { + d.ProjectId = "" }), IsValid: false, }, "sad_path_distribution_id_missing": { Expected: expectedModel(), - Input: distributionFixture(func(d *cdn.Distribution) { - d.Id = nil + Input: distributionFixture(func(d *cdnSdk.Distribution) { + d.Id = "" }), IsValid: false, }, diff --git a/stackit/internal/services/cdn/distribution/resource.go b/stackit/internal/services/cdn/distribution/resource.go index 17b0ce0ca..34ce3c684 100644 --- a/stackit/internal/services/cdn/distribution/resource.go +++ b/stackit/internal/services/cdn/distribution/resource.go @@ -26,8 +26,8 @@ import ( "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/stackitcloud/stackit-sdk-go/core/oapierror" - "github.com/stackitcloud/stackit-sdk-go/services/cdn" - "github.com/stackitcloud/stackit-sdk-go/services/cdn/wait" + cdnSdk "github.com/stackitcloud/stackit-sdk-go/services/cdn/v1api" + "github.com/stackitcloud/stackit-sdk-go/services/cdn/v1api/wait" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/conversion" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/features" @@ -150,7 +150,7 @@ var domainTypes = map[string]attr.Type{ } type distributionResource struct { - client *cdn.APIClient + client *cdnSdk.APIClient providerData core.ProviderData } @@ -426,7 +426,7 @@ func (r *distributionResource) Create(ctx context.Context, req resource.CreateRe return } - createResp, err := r.client.CreateDistribution(ctx, projectId).CreateDistributionPayload(*payload).Execute() + createResp, err := r.client.DefaultAPI.CreateDistribution(ctx, projectId).CreateDistributionPayload(*payload).Execute() if err != nil { core.LogAndAddError(ctx, &resp.Diagnostics, "Error creating CDN distribution", fmt.Sprintf("Calling API: %v", err)) return @@ -434,7 +434,7 @@ func (r *distributionResource) Create(ctx context.Context, req resource.CreateRe ctx = core.LogResponse(ctx) - if createResp.Distribution.Id == nil { + if createResp.Distribution.Id == "" { core.LogAndAddError(ctx, &resp.Diagnostics, "Error creating CDN distribution", "Got empty cdn distribution id") return } @@ -442,19 +442,19 @@ func (r *distributionResource) Create(ctx context.Context, req resource.CreateRe // Write id attributes to state before polling via the wait handler - just in case anything goes wrong during the wait handler ctx = utils.SetAndLogStateFields(ctx, &resp.Diagnostics, &resp.State, map[string]any{ "project_id": projectId, - "distribution_id": *createResp.Distribution.Id, + "distribution_id": createResp.Distribution.Id, }) if resp.Diagnostics.HasError() { return } - waitResp, err := wait.CreateDistributionPoolWaitHandler(ctx, r.client, projectId, *createResp.Distribution.Id).SetTimeout(5 * time.Minute).WaitWithContext(ctx) + waitResp, err := wait.CreateDistributionPoolWaitHandler(ctx, r.client.DefaultAPI, projectId, createResp.Distribution.Id).SetTimeout(5 * time.Minute).WaitWithContext(ctx) if err != nil { core.LogAndAddError(ctx, &resp.Diagnostics, "Error creating CDN distribution", fmt.Sprintf("Waiting for create: %v", err)) return } - err = mapFields(ctx, waitResp.Distribution, &model) + err = mapFields(ctx, &waitResp.Distribution, &model) if err != nil { core.LogAndAddError(ctx, &resp.Diagnostics, "Error creating CDN distribution", fmt.Sprintf("Processing API payload: %v", err)) return @@ -483,7 +483,7 @@ func (r *distributionResource) Read(ctx context.Context, req resource.ReadReques ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "distribution_id", distributionId) - cdnResp, err := r.client.GetDistribution(ctx, projectId, distributionId).Execute() + cdnResp, err := r.client.DefaultAPI.GetDistribution(ctx, projectId, distributionId).Execute() if err != nil { var oapiErr *oapierror.GenericOpenAPIError // n.b. err is caught here if of type *oapierror.GenericOpenAPIError, which the stackit SDK client returns @@ -499,7 +499,7 @@ func (r *distributionResource) Read(ctx context.Context, req resource.ReadReques ctx = core.LogResponse(ctx) - err = mapFields(ctx, cdnResp.Distribution, &model) + err = mapFields(ctx, &cdnResp.Distribution, &model) if err != nil { core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading CDN ditribution", fmt.Sprintf("Processing API payload: %v", err)) return @@ -538,9 +538,9 @@ func (r *distributionResource) Update(ctx context.Context, req resource.UpdateRe return } - regions := []cdn.Region{} + regions := []cdnSdk.Region{} for _, r := range *configModel.Regions { - regionEnum, err := cdn.NewRegionFromValue(r) + regionEnum, err := cdnSdk.NewRegionFromValue(r) if err != nil { core.LogAndAddError(ctx, &resp.Diagnostics, "Update CDN distribution", fmt.Sprintf("Map regions: %v", err)) return @@ -568,7 +568,7 @@ func (r *distributionResource) Update(ctx context.Context, req resource.UpdateRe blockedCountries = &tempBlockedCountries } - configPatchBackend := &cdn.ConfigPatchBackend{} + configPatchBackend := &cdnSdk.ConfigPatchBackend{} switch configModel.Backend.Type { case "http": @@ -589,30 +589,30 @@ func (r *distributionResource) Update(ctx context.Context, req resource.UpdateRe geofencingPatch = gf } - configPatchBackend.HttpBackendPatch = &cdn.HttpBackendPatch{ + configPatchBackend.HttpBackendPatch = &cdnSdk.HttpBackendPatch{ OriginRequestHeaders: configModel.Backend.OriginRequestHeaders, OriginUrl: configModel.Backend.OriginURL, - Type: new("http"), + Type: "http", Geofencing: &geofencingPatch, } case "bucket": - configPatchBackend.BucketBackendPatch = &cdn.BucketBackendPatch{ - Type: new("bucket"), + configPatchBackend.BucketBackendPatch = &cdnSdk.BucketBackendPatch{ + Type: "bucket", BucketUrl: configModel.Backend.BucketURL, Region: configModel.Backend.Region, } if configModel.Backend.Credentials != nil { - configPatchBackend.BucketBackendPatch.Credentials = &cdn.BucketCredentials{ - AccessKeyId: configModel.Backend.Credentials.AccessKey, - SecretAccessKey: configModel.Backend.Credentials.SecretKey, + configPatchBackend.BucketBackendPatch.Credentials = &cdnSdk.BucketCredentials{ + AccessKeyId: *configModel.Backend.Credentials.AccessKey, + SecretAccessKey: *configModel.Backend.Credentials.SecretKey, } } } - configPatch := &cdn.ConfigPatch{ + configPatch := &cdnSdk.ConfigPatch{ Backend: configPatchBackend, - Regions: ®ions, - BlockedCountries: blockedCountries, + Regions: regions, + BlockedCountries: *blockedCountries, } if !utils.IsUndefined(configModel.Optimizer) { @@ -624,14 +624,14 @@ func (r *distributionResource) Update(ctx context.Context, req resource.UpdateRe return } - optimizer := cdn.NewOptimizerPatch() + optimizer := cdnSdk.NewOptimizerPatch() if !utils.IsUndefined(optimizerModel.Enabled) { optimizer.SetEnabled(optimizerModel.Enabled.ValueBool()) } configPatch.Optimizer = optimizer } - _, err := r.client.PatchDistribution(ctx, projectId, distributionId).PatchDistributionPayload(cdn.PatchDistributionPayload{ + _, err := r.client.DefaultAPI.PatchDistribution(ctx, projectId, distributionId).PatchDistributionPayload(cdnSdk.PatchDistributionPayload{ Config: configPatch, IntentId: new(uuid.NewString()), }).Execute() @@ -642,13 +642,13 @@ func (r *distributionResource) Update(ctx context.Context, req resource.UpdateRe ctx = core.LogResponse(ctx) - waitResp, err := wait.UpdateDistributionWaitHandler(ctx, r.client, projectId, distributionId).WaitWithContext(ctx) + waitResp, err := wait.UpdateDistributionWaitHandler(ctx, r.client.DefaultAPI, projectId, distributionId).WaitWithContext(ctx) if err != nil { core.LogAndAddError(ctx, &resp.Diagnostics, "Update CDN distribution", fmt.Sprintf("Waiting for update: %v", err)) return } - err = mapFields(ctx, waitResp.Distribution, &model) + err = mapFields(ctx, &waitResp.Distribution, &model) if err != nil { core.LogAndAddError(ctx, &resp.Diagnostics, "Update CDN distribution", fmt.Sprintf("Processing API payload: %v", err)) return @@ -677,14 +677,14 @@ func (r *distributionResource) Delete(ctx context.Context, req resource.DeleteRe ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "distribution_id", distributionId) - _, err := r.client.DeleteDistribution(ctx, projectId, distributionId).Execute() + _, err := r.client.DefaultAPI.DeleteDistribution(ctx, projectId, distributionId).Execute() if err != nil { core.LogAndAddError(ctx, &resp.Diagnostics, "Delete CDN distribution", fmt.Sprintf("Delete distribution: %v", err)) } ctx = core.LogResponse(ctx) - _, err = wait.DeleteDistributionWaitHandler(ctx, r.client, projectId, distributionId).WaitWithContext(ctx) + _, err = wait.DeleteDistributionWaitHandler(ctx, r.client.DefaultAPI, projectId, distributionId).WaitWithContext(ctx) if err != nil { core.LogAndAddError(ctx, &resp.Diagnostics, "Delete CDN distribution", fmt.Sprintf("Waiting for deletion: %v", err)) return @@ -705,7 +705,7 @@ func (r *distributionResource) ImportState(ctx context.Context, req resource.Imp tflog.Info(ctx, "CDN distribution state imported") } -func mapFields(ctx context.Context, distribution *cdn.Distribution, model *Model) error { +func mapFields(ctx context.Context, distribution *cdnSdk.Distribution, model *Model) error { if distribution == nil { return fmt.Errorf("response input is nil") } @@ -713,29 +713,21 @@ func mapFields(ctx context.Context, distribution *cdn.Distribution, model *Model return fmt.Errorf("model input is nil") } - if distribution.ProjectId == nil { + if distribution.ProjectId == "" { return fmt.Errorf("'Project ID' not present") } - if distribution.Id == nil { + if distribution.Id == "" { return fmt.Errorf("CDN distribution ID not present") } - if distribution.CreatedAt == nil { - return fmt.Errorf("'CreatedAt' missing in response") - } - - if distribution.UpdatedAt == nil { - return fmt.Errorf("'UpdatedAt' missing in response") - } - - if distribution.Status == nil { + if distribution.Status == "" { return fmt.Errorf("'Status' missing in response") } - model.ID = utils.BuildInternalTerraformId(*distribution.ProjectId, *distribution.Id) - model.DistributionId = types.StringValue(*distribution.Id) - model.ProjectId = types.StringValue(*distribution.ProjectId) + model.ID = utils.BuildInternalTerraformId(distribution.ProjectId, distribution.Id) + model.DistributionId = types.StringValue(distribution.Id) + model.ProjectId = types.StringValue(distribution.ProjectId) model.Status = types.StringValue(string(distribution.GetStatus())) model.CreatedAt = types.StringValue(distribution.CreatedAt.String()) model.UpdatedAt = types.StringValue(distribution.UpdatedAt.String()) @@ -743,8 +735,8 @@ func mapFields(ctx context.Context, distribution *cdn.Distribution, model *Model // distributionErrors distributionErrors := []attr.Value{} if distribution.Errors != nil { - for _, e := range *distribution.Errors { - distributionErrors = append(distributionErrors, types.StringValue(*e.En)) + for _, e := range distribution.Errors { + distributionErrors = append(distributionErrors, types.StringValue(e.En)) } } modelErrors, diags := types.ListValue(types.StringType, distributionErrors) @@ -755,7 +747,7 @@ func mapFields(ctx context.Context, distribution *cdn.Distribution, model *Model // regions regions := []attr.Value{} - for _, r := range *distribution.Config.Regions { + for _, r := range distribution.Config.Regions { regions = append(regions, types.StringValue(string(r))) } modelRegions, diags := types.ListValue(types.StringType, regions) @@ -777,8 +769,8 @@ func mapFields(ctx context.Context, distribution *cdn.Distribution, model *Model // blockedCountries var blockedCountries []attr.Value - if distribution.Config != nil && distribution.Config.BlockedCountries != nil { - for _, c := range *distribution.Config.BlockedCountries { + if distribution.Config.BlockedCountries != nil { + for _, c := range distribution.Config.BlockedCountries { blockedCountries = append(blockedCountries, types.StringValue(string(c))) } } @@ -791,9 +783,9 @@ func mapFields(ctx context.Context, distribution *cdn.Distribution, model *Model // originRequestHeaders originRequestHeaders := types.MapNull(types.StringType) if distribution.Config.Backend.HttpBackend != nil { - if origHeaders := distribution.Config.Backend.HttpBackend.OriginRequestHeaders; origHeaders != nil && len(*origHeaders) > 0 { + if origHeaders := distribution.Config.Backend.HttpBackend.OriginRequestHeaders; len(origHeaders) > 0 { headers := map[string]attr.Value{} - for k, v := range *origHeaders { + for k, v := range origHeaders { headers[k] = types.StringValue(v) } mappedHeaders, diags := types.MapValue(types.StringType, headers) @@ -812,8 +804,8 @@ func mapFields(ctx context.Context, distribution *cdn.Distribution, model *Model reconciledGeofencingData := make(map[string][]string) if distribution.Config.Backend.HttpBackend != nil { - if geofencingAPI := distribution.Config.Backend.HttpBackend.Geofencing; geofencingAPI != nil && len(*geofencingAPI) > 0 { - newGeofencingMap := *geofencingAPI + if geofencingAPI := distribution.Config.Backend.HttpBackend.Geofencing; len(geofencingAPI) > 0 { + newGeofencingMap := geofencingAPI for url, newCountries := range newGeofencingMap { oldCountriesPtrs := oldGeofencingMap[url] @@ -849,7 +841,7 @@ func mapFields(ctx context.Context, distribution *cdn.Distribution, model *Model if distribution.Config.Backend.HttpBackend != nil { backendValues = map[string]attr.Value{ "type": types.StringValue("http"), - "origin_url": types.StringValue(*distribution.Config.Backend.HttpBackend.OriginUrl), + "origin_url": types.StringValue(distribution.Config.Backend.HttpBackend.OriginUrl), "origin_request_headers": originRequestHeaders, "geofencing": geofencingVal, // bucket fields must be null when using HTTP @@ -878,8 +870,8 @@ func mapFields(ctx context.Context, distribution *cdn.Distribution, model *Model backendValues = map[string]attr.Value{ "type": types.StringValue("bucket"), - "bucket_url": types.StringValue(*distribution.Config.Backend.BucketBackend.BucketUrl), - "region": types.StringValue(*distribution.Config.Backend.BucketBackend.Region), + "bucket_url": types.StringValue(distribution.Config.Backend.BucketBackend.BucketUrl), + "region": types.StringValue(distribution.Config.Backend.BucketBackend.Region), "credentials": credentialsObj, // HTTP field must be null when using Bucket "origin_url": types.StringNull(), @@ -900,7 +892,7 @@ func mapFields(ctx context.Context, distribution *cdn.Distribution, model *Model if ok { var diags diag.Diagnostics optimizerVal, diags = types.ObjectValue(optimizerTypes, map[string]attr.Value{ - "enabled": types.BoolValue(optimizerEnabled), + "enabled": types.BoolPointerValue(optimizerEnabled), }) if diags.HasError() { return core.DiagsToError(diags) @@ -920,27 +912,27 @@ func mapFields(ctx context.Context, distribution *cdn.Distribution, model *Model domains := []attr.Value{} if distribution.Domains != nil { - for _, d := range *distribution.Domains { + for _, d := range distribution.Domains { domainErrors := []attr.Value{} if d.Errors != nil { - for _, e := range *d.Errors { - if e.En == nil { + for _, e := range d.Errors { + if e.En == "" { return fmt.Errorf("error description missing") } - domainErrors = append(domainErrors, types.StringValue(*e.En)) + domainErrors = append(domainErrors, types.StringValue(e.En)) } } modelDomainErrors, diags := types.ListValue(types.StringType, domainErrors) if diags.HasError() { return core.DiagsToError(diags) } - if d.Name == nil || d.Status == nil || d.Type == nil { + if d.Name == "" || d.Status == "" || d.Type == "" { return fmt.Errorf("domain entry incomplete") } modelDomain, diags := types.ObjectValue(domainTypes, map[string]attr.Value{ - "name": types.StringValue(*d.Name), - "status": types.StringValue(string(*d.Status)), - "type": types.StringValue(string(*d.Type)), + "name": types.StringValue(d.Name), + "status": types.StringValue(string(d.Status)), + "type": types.StringValue(string(d.Type)), "errors": modelDomainErrors, }) if diags.HasError() { @@ -959,7 +951,7 @@ func mapFields(ctx context.Context, distribution *cdn.Distribution, model *Model return nil } -func toCreatePayload(ctx context.Context, model *Model) (*cdn.CreateDistributionPayload, error) { +func toCreatePayload(ctx context.Context, model *Model) (*cdnSdk.CreateDistributionPayload, error) { if model == nil { return nil, fmt.Errorf("missing model") } @@ -967,18 +959,18 @@ func toCreatePayload(ctx context.Context, model *Model) (*cdn.CreateDistribution if err != nil { return nil, err } - var optimizer *cdn.Optimizer + var optimizer *cdnSdk.Optimizer if cfg.Optimizer != nil { - optimizer = cdn.NewOptimizer(cfg.Optimizer.GetEnabled()) + optimizer = cdnSdk.NewOptimizer(cfg.Optimizer.GetEnabled()) } - var backend *cdn.CreateDistributionPayloadBackend + var backend *cdnSdk.CreateDistributionPayloadBackend if cfg.Backend.HttpBackend != nil { - backend = &cdn.CreateDistributionPayloadBackend{ - HttpBackendCreate: &cdn.HttpBackendCreate{ + backend = &cdnSdk.CreateDistributionPayloadBackend{ + HttpBackendCreate: &cdnSdk.HttpBackendCreate{ OriginUrl: cfg.Backend.HttpBackend.OriginUrl, - OriginRequestHeaders: cfg.Backend.HttpBackend.OriginRequestHeaders, - Geofencing: cfg.Backend.HttpBackend.Geofencing, - Type: new("http"), + OriginRequestHeaders: &cfg.Backend.HttpBackend.OriginRequestHeaders, + Geofencing: &cfg.Backend.HttpBackend.Geofencing, + Type: "http", }, } } else if cfg.Backend.BucketBackend != nil { @@ -997,23 +989,23 @@ func toCreatePayload(ctx context.Context, model *Model) (*cdn.CreateDistribution accessKey = rawConfig.Backend.Credentials.AccessKey secretKey = rawConfig.Backend.Credentials.SecretKey } - backend = &cdn.CreateDistributionPayloadBackend{ - BucketBackendCreate: &cdn.BucketBackendCreate{ - Type: new("bucket"), + backend = &cdnSdk.CreateDistributionPayloadBackend{ + BucketBackendCreate: &cdnSdk.BucketBackendCreate{ + Type: "bucket", BucketUrl: cfg.Backend.BucketBackend.BucketUrl, Region: cfg.Backend.BucketBackend.Region, - Credentials: &cdn.BucketCredentials{ - AccessKeyId: accessKey, - SecretAccessKey: secretKey, + Credentials: cdnSdk.BucketCredentials{ + AccessKeyId: *accessKey, + SecretAccessKey: *secretKey, }, }, } } - payload := &cdn.CreateDistributionPayload{ + payload := &cdnSdk.CreateDistributionPayload{ IntentId: new(uuid.NewString()), Regions: cfg.Regions, - Backend: backend, + Backend: *backend, BlockedCountries: cfg.BlockedCountries, Optimizer: optimizer, } @@ -1021,7 +1013,7 @@ func toCreatePayload(ctx context.Context, model *Model) (*cdn.CreateDistribution return payload, nil } -func convertConfig(ctx context.Context, model *Model) (*cdn.Config, error) { +func convertConfig(ctx context.Context, model *Model) (*cdnSdk.Config, error) { if model == nil { return nil, errors.New("model cannot be nil") } @@ -1038,9 +1030,9 @@ func convertConfig(ctx context.Context, model *Model) (*cdn.Config, error) { } // regions - regions := []cdn.Region{} + regions := []cdnSdk.Region{} for _, r := range *configModel.Regions { - regionEnum, err := cdn.NewRegionFromValue(r) + regionEnum, err := cdnSdk.NewRegionFromValue(r) if err != nil { return nil, err } @@ -1078,10 +1070,10 @@ func convertConfig(ctx context.Context, model *Model) (*cdn.Config, error) { } } - cdnConfig := &cdn.Config{ - Backend: &cdn.ConfigBackend{}, - Regions: ®ions, - BlockedCountries: &blockedCountries, + cdnConfig := &cdnSdk.Config{ + Backend: cdnSdk.ConfigBackend{}, + Regions: regions, + BlockedCountries: blockedCountries, } switch configModel.Backend.Type { @@ -1090,17 +1082,17 @@ func convertConfig(ctx context.Context, model *Model) (*cdn.Config, error) { if configModel.Backend.OriginRequestHeaders != nil { maps.Copy(originRequestHeaders, *configModel.Backend.OriginRequestHeaders) } - cdnConfig.Backend.HttpBackend = &cdn.HttpBackend{ - OriginRequestHeaders: &originRequestHeaders, - OriginUrl: configModel.Backend.OriginURL, - Type: new("http"), - Geofencing: &geofencing, + cdnConfig.Backend.HttpBackend = &cdnSdk.HttpBackend{ + OriginRequestHeaders: originRequestHeaders, + OriginUrl: *configModel.Backend.OriginURL, + Type: "http", + Geofencing: geofencing, } case "bucket": - cdnConfig.Backend.BucketBackend = &cdn.BucketBackend{ - Type: new("bucket"), - BucketUrl: configModel.Backend.BucketURL, - Region: configModel.Backend.Region, + cdnConfig.Backend.BucketBackend = &cdnSdk.BucketBackend{ + Type: "bucket", + BucketUrl: *configModel.Backend.BucketURL, + Region: *configModel.Backend.Region, } } @@ -1112,7 +1104,7 @@ func convertConfig(ctx context.Context, model *Model) (*cdn.Config, error) { } if !utils.IsUndefined(optimizerModel.Enabled) { - cdnConfig.Optimizer = cdn.NewOptimizer(optimizerModel.Enabled.ValueBool()) + cdnConfig.Optimizer = cdnSdk.NewOptimizer(optimizerModel.Enabled.ValueBool()) } } diff --git a/stackit/internal/services/cdn/distribution/resource_test.go b/stackit/internal/services/cdn/distribution/resource_test.go index cc736f7c5..39c528349 100644 --- a/stackit/internal/services/cdn/distribution/resource_test.go +++ b/stackit/internal/services/cdn/distribution/resource_test.go @@ -6,9 +6,10 @@ import ( "time" "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stackitcloud/stackit-sdk-go/services/cdn" + cdnSdk "github.com/stackitcloud/stackit-sdk-go/services/cdn/v1api" ) func TestToCreatePayload(t *testing.T) { @@ -59,20 +60,20 @@ func TestToCreatePayload(t *testing.T) { } tests := map[string]struct { Input *Model - Expected *cdn.CreateDistributionPayload + Expected *cdnSdk.CreateDistributionPayload IsValid bool }{ "happy_path": { Input: modelFixture(), - Expected: &cdn.CreateDistributionPayload{ - Regions: &[]cdn.Region{"EU", "US"}, - BlockedCountries: &[]string{"XX", "YY", "ZZ"}, - Backend: &cdn.CreateDistributionPayloadBackend{ - HttpBackendCreate: &cdn.HttpBackendCreate{ + Expected: &cdnSdk.CreateDistributionPayload{ + Regions: []cdnSdk.Region{"EU", "US"}, + BlockedCountries: []string{"XX", "YY", "ZZ"}, + Backend: cdnSdk.CreateDistributionPayloadBackend{ + HttpBackendCreate: &cdnSdk.HttpBackendCreate{ Geofencing: &map[string][]string{"https://de.mycoolapp.com": {"DE", "FR"}}, OriginRequestHeaders: &map[string]string{"testHeader0": "testHeaderValue0", "testHeader1": "testHeaderValue1"}, - OriginUrl: new("https://www.mycoolapp.com"), - Type: new("http"), + OriginUrl: "https://www.mycoolapp.com", + Type: "http", }, }, }, @@ -87,16 +88,16 @@ func TestToCreatePayload(t *testing.T) { "blocked_countries": blockedCountriesFixture, }) }), - Expected: &cdn.CreateDistributionPayload{ - Regions: &[]cdn.Region{"EU", "US"}, - Optimizer: cdn.NewOptimizer(true), - BlockedCountries: &[]string{"XX", "YY", "ZZ"}, - Backend: &cdn.CreateDistributionPayloadBackend{ - HttpBackendCreate: &cdn.HttpBackendCreate{ + Expected: &cdnSdk.CreateDistributionPayload{ + Regions: []cdnSdk.Region{"EU", "US"}, + Optimizer: cdnSdk.NewOptimizer(true), + BlockedCountries: []string{"XX", "YY", "ZZ"}, + Backend: cdnSdk.CreateDistributionPayloadBackend{ + HttpBackendCreate: &cdnSdk.HttpBackendCreate{ Geofencing: &map[string][]string{"https://de.mycoolapp.com": {"DE", "FR"}}, OriginRequestHeaders: &map[string]string{"testHeader0": "testHeaderValue0", "testHeader1": "testHeaderValue1"}, - OriginUrl: new("https://www.mycoolapp.com"), - Type: new("http"), + OriginUrl: "https://www.mycoolapp.com", + Type: "http", }, }, }, @@ -124,20 +125,20 @@ func TestToCreatePayload(t *testing.T) { "optimizer": types.ObjectNull(optimizerTypes), }) }), - Expected: &cdn.CreateDistributionPayload{ - Backend: &cdn.CreateDistributionPayloadBackend{ - BucketBackendCreate: &cdn.BucketBackendCreate{ - Type: new("bucket"), - BucketUrl: new("https://s3.example.com"), - Region: new("eu01"), - Credentials: &cdn.BucketCredentials{ - AccessKeyId: new("my-access"), - SecretAccessKey: new("my-secret"), + Expected: &cdnSdk.CreateDistributionPayload{ + Backend: cdnSdk.CreateDistributionPayloadBackend{ + BucketBackendCreate: &cdnSdk.BucketBackendCreate{ + Type: "bucket", + BucketUrl: "https://s3.example.com", + Region: "eu01", + Credentials: cdnSdk.BucketCredentials{ + AccessKeyId: "my-access", + SecretAccessKey: "my-secret", }, }, }, - Regions: &[]cdn.Region{"EU", "US"}, - BlockedCountries: &[]string{"XX", "YY", "ZZ"}, + Regions: []cdnSdk.Region{"EU", "US"}, + BlockedCountries: []string{"XX", "YY", "ZZ"}, }, IsValid: true, }, @@ -222,27 +223,27 @@ func TestConvertConfig(t *testing.T) { } tests := map[string]struct { Input *Model - Expected *cdn.Config + Expected *cdnSdk.Config IsValid bool }{ "happy_path": { Input: modelFixture(), - Expected: &cdn.Config{ - Backend: &cdn.ConfigBackend{ - HttpBackend: &cdn.HttpBackend{ - OriginRequestHeaders: &map[string]string{ + Expected: &cdnSdk.Config{ + Backend: cdnSdk.ConfigBackend{ + HttpBackend: &cdnSdk.HttpBackend{ + OriginRequestHeaders: map[string]string{ "testHeader0": "testHeaderValue0", "testHeader1": "testHeaderValue1", }, - OriginUrl: new("https://www.mycoolapp.com"), - Type: new("http"), - Geofencing: &map[string][]string{ + OriginUrl: "https://www.mycoolapp.com", + Type: "http", + Geofencing: map[string][]string{ "https://de.mycoolapp.com": {"DE", "FR"}, }, }, }, - Regions: &[]cdn.Region{"EU", "US"}, - BlockedCountries: &[]string{"XX", "YY", "ZZ"}, + Regions: []cdnSdk.Region{"EU", "US"}, + BlockedCountries: []string{"XX", "YY", "ZZ"}, }, IsValid: true, }, @@ -255,23 +256,23 @@ func TestConvertConfig(t *testing.T) { "blocked_countries": blockedCountriesFixture, }) }), - Expected: &cdn.Config{ - Backend: &cdn.ConfigBackend{ - HttpBackend: &cdn.HttpBackend{ - OriginRequestHeaders: &map[string]string{ + Expected: &cdnSdk.Config{ + Backend: cdnSdk.ConfigBackend{ + HttpBackend: &cdnSdk.HttpBackend{ + OriginRequestHeaders: map[string]string{ "testHeader0": "testHeaderValue0", "testHeader1": "testHeaderValue1", }, - OriginUrl: new("https://www.mycoolapp.com"), - Type: new("http"), - Geofencing: &map[string][]string{ + OriginUrl: "https://www.mycoolapp.com", + Type: "http", + Geofencing: map[string][]string{ "https://de.mycoolapp.com": {"DE", "FR"}, }, }, }, - Regions: &[]cdn.Region{"EU", "US"}, - Optimizer: cdn.NewOptimizer(true), - BlockedCountries: &[]string{"XX", "YY", "ZZ"}, + Regions: []cdnSdk.Region{"EU", "US"}, + Optimizer: cdnSdk.NewOptimizer(true), + BlockedCountries: []string{"XX", "YY", "ZZ"}, }, IsValid: true, }, @@ -297,18 +298,18 @@ func TestConvertConfig(t *testing.T) { "optimizer": types.ObjectNull(optimizerTypes), }) }), - Expected: &cdn.Config{ - Backend: &cdn.ConfigBackend{ - BucketBackend: &cdn.BucketBackend{ - Type: new("bucket"), - BucketUrl: new("https://s3.example.com"), - Region: new("eu01"), + Expected: &cdnSdk.Config{ + Backend: cdnSdk.ConfigBackend{ + BucketBackend: &cdnSdk.BucketBackend{ + Type: "bucket", + BucketUrl: "https://s3.example.com", + Region: "eu01", // Note: config does not return credentials }, }, - Regions: &[]cdn.Region{"EU", "US"}, - BlockedCountries: &[]string{"XX", "YY", "ZZ"}, + Regions: []cdnSdk.Region{"EU", "US"}, + BlockedCountries: []string{"XX", "YY", "ZZ"}, }, IsValid: true, }, @@ -335,7 +336,14 @@ func TestConvertConfig(t *testing.T) { t.Fatalf("Should have failed") } if tc.IsValid { - diff := cmp.Diff(res, tc.Expected) + diff := cmp.Diff(res, tc.Expected, + // The struct contains now a NullableString and NullableInt64. + // Previously those were pointers which could be compared but the value of those + // are unexported and therefore cmp cannot compare them. + cmpopts.IgnoreUnexported( + cdnSdk.NullableString{}, + cdnSdk.NullableInt64{}, + )) if diff != "" { t.Fatalf("Create Payload not as expected: %s", diff) } @@ -405,35 +413,35 @@ func TestMapFields(t *testing.T) { } return model } - distributionFixture := func(mods ...func(*cdn.Distribution)) *cdn.Distribution { - distribution := &cdn.Distribution{ - Config: &cdn.Config{ - Backend: &cdn.ConfigBackend{ - HttpBackend: &cdn.HttpBackend{ - OriginRequestHeaders: &map[string]string{ + distributionFixture := func(mods ...func(*cdnSdk.Distribution)) *cdnSdk.Distribution { + distribution := &cdnSdk.Distribution{ + Config: cdnSdk.Config{ + Backend: cdnSdk.ConfigBackend{ + HttpBackend: &cdnSdk.HttpBackend{ + OriginRequestHeaders: map[string]string{ "testHeader0": "testHeaderValue0", "testHeader1": "testHeaderValue1", }, - OriginUrl: new("https://www.mycoolapp.com"), - Type: new("http"), + OriginUrl: "https://www.mycoolapp.com", + Type: "http", }, }, - Regions: &[]cdn.Region{"EU", "US"}, - BlockedCountries: &[]string{"XX", "YY", "ZZ"}, + Regions: []cdnSdk.Region{"EU", "US"}, + BlockedCountries: []string{"XX", "YY", "ZZ"}, Optimizer: nil, }, - CreatedAt: &createdAt, - Domains: &[]cdn.Domain{ + CreatedAt: createdAt, + Domains: []cdnSdk.Domain{ { - Name: new("test.stackit-cdn.com"), - Status: cdn.DOMAINSTATUS_ACTIVE.Ptr(), - Type: cdn.DOMAINTYPE_MANAGED.Ptr(), + Name: "test.stackit-cdn.com", + Status: cdnSdk.DOMAINSTATUS_ACTIVE, + Type: "managed", }, }, - Id: new("test-distribution-id"), - ProjectId: new("test-project-id"), - Status: cdn.DISTRIBUTIONSTATUS_ACTIVE.Ptr(), - UpdatedAt: &updatedAt, + Id: "test-distribution-id", + ProjectId: "test-project-id", + Status: "ACTIVE", + UpdatedAt: updatedAt, } for _, mod := range mods { mod(distribution) @@ -461,7 +469,7 @@ func TestMapFields(t *testing.T) { "optimizer": types.ObjectNull(optimizerTypes), }) tests := map[string]struct { - Input *cdn.Distribution + Input *cdnSdk.Distribution Expected *Model InitialState *Model IsValid bool @@ -480,9 +488,9 @@ func TestMapFields(t *testing.T) { "blocked_countries": blockedCountriesFixture, }) }), - Input: distributionFixture(func(d *cdn.Distribution) { - d.Config.Optimizer = &cdn.Optimizer{ - Enabled: new(true), + Input: distributionFixture(func(d *cdnSdk.Distribution) { + d.Config.Optimizer = &cdnSdk.Optimizer{ + Enabled: true, } }), IsValid: true, @@ -505,8 +513,8 @@ func TestMapFields(t *testing.T) { "blocked_countries": blockedCountriesFixture, }) }), - Input: distributionFixture(func(d *cdn.Distribution) { - d.Config.Backend.HttpBackend.Geofencing = &geofencingInput + Input: distributionFixture(func(d *cdnSdk.Distribution) { + d.Config.Backend.HttpBackend.Geofencing = geofencingInput }), IsValid: true, }, @@ -514,8 +522,8 @@ func TestMapFields(t *testing.T) { Expected: expectedModel(func(m *Model) { m.Status = types.StringValue("ERROR") }), - Input: distributionFixture(func(d *cdn.Distribution) { - d.Status = cdn.DISTRIBUTIONSTATUS_ERROR.Ptr() + Input: distributionFixture(func(d *cdnSdk.Distribution) { + d.Status = "ERROR" }), IsValid: true, }, @@ -536,29 +544,29 @@ func TestMapFields(t *testing.T) { domains := types.ListValueMust(types.ObjectType{AttrTypes: domainTypes}, []attr.Value{managedDomain, customDomain}) m.Domains = domains }), - Input: distributionFixture(func(d *cdn.Distribution) { - d.Domains = &[]cdn.Domain{ + Input: distributionFixture(func(d *cdnSdk.Distribution) { + d.Domains = []cdnSdk.Domain{ { - Name: new("test.stackit-cdn.com"), - Status: cdn.DOMAINSTATUS_ACTIVE.Ptr(), - Type: cdn.DOMAINTYPE_MANAGED.Ptr(), + Name: "test.stackit-cdn.com", + Status: cdnSdk.DOMAINSTATUS_ACTIVE, + Type: "managed", }, { - Name: new("mycoolapp.info"), - Status: cdn.DOMAINSTATUS_ACTIVE.Ptr(), - Type: cdn.DOMAINTYPE_CUSTOM.Ptr(), + Name: "mycoolapp.info", + Status: cdnSdk.DOMAINSTATUS_ACTIVE, + Type: "custom", }, } }), IsValid: true, }, "happy_path_bucket_restore_creds": { - Input: distributionFixture(func(d *cdn.Distribution) { - d.Config.Backend = &cdn.ConfigBackend{ - BucketBackend: &cdn.BucketBackend{ - Type: new("bucket"), - BucketUrl: new("https://s3.example.com"), - Region: new("eu01"), + Input: distributionFixture(func(d *cdnSdk.Distribution) { + d.Config.Backend = cdnSdk.ConfigBackend{ + BucketBackend: &cdnSdk.BucketBackend{ + Type: "bucket", + BucketUrl: "https://s3.example.com", + Region: "eu01", }, } }), @@ -577,15 +585,15 @@ func TestMapFields(t *testing.T) { }, "sad_path_project_id_missing": { Expected: expectedModel(), - Input: distributionFixture(func(d *cdn.Distribution) { - d.ProjectId = nil + Input: distributionFixture(func(d *cdnSdk.Distribution) { + d.ProjectId = "" }), IsValid: false, }, "sad_path_distribution_id_missing": { Expected: expectedModel(), - Input: distributionFixture(func(d *cdn.Distribution) { - d.Id = nil + Input: distributionFixture(func(d *cdnSdk.Distribution) { + d.Id = "" }), IsValid: false, }, diff --git a/stackit/internal/services/cdn/utils/util.go b/stackit/internal/services/cdn/utils/util.go index e03f68d6f..b62d4ff76 100644 --- a/stackit/internal/services/cdn/utils/util.go +++ b/stackit/internal/services/cdn/utils/util.go @@ -6,12 +6,12 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/stackitcloud/stackit-sdk-go/core/config" - "github.com/stackitcloud/stackit-sdk-go/services/cdn" + cdnSdk "github.com/stackitcloud/stackit-sdk-go/services/cdn/v1api" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/utils" ) -func ConfigureClient(ctx context.Context, providerData *core.ProviderData, diags *diag.Diagnostics) *cdn.APIClient { +func ConfigureClient(ctx context.Context, providerData *core.ProviderData, diags *diag.Diagnostics) *cdnSdk.APIClient { apiClientConfigOptions := []config.ConfigurationOption{ config.WithCustomAuth(providerData.RoundTripper), utils.UserAgentConfigOption(providerData.Version), @@ -19,7 +19,7 @@ func ConfigureClient(ctx context.Context, providerData *core.ProviderData, diags if providerData.CdnCustomEndpoint != "" { apiClientConfigOptions = append(apiClientConfigOptions, config.WithEndpoint(providerData.CdnCustomEndpoint)) } - apiClient, err := cdn.NewAPIClient(apiClientConfigOptions...) + apiClient, err := cdnSdk.NewAPIClient(apiClientConfigOptions...) if err != nil { core.LogAndAddError(ctx, diags, "Error configuring API client", fmt.Sprintf("Configuring client: %v. This is an error related to the provider configuration, not to the resource configuration", err)) return nil diff --git a/stackit/internal/services/cdn/utils/util_test.go b/stackit/internal/services/cdn/utils/util_test.go index 576d02476..0d5282be8 100644 --- a/stackit/internal/services/cdn/utils/util_test.go +++ b/stackit/internal/services/cdn/utils/util_test.go @@ -9,7 +9,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" sdkClients "github.com/stackitcloud/stackit-sdk-go/core/clients" "github.com/stackitcloud/stackit-sdk-go/core/config" - "github.com/stackitcloud/stackit-sdk-go/services/cdn" + cdnSdk "github.com/stackitcloud/stackit-sdk-go/services/cdn/v1api" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/utils" ) @@ -34,7 +34,7 @@ func TestConfigureClient(t *testing.T) { name string args args wantErr bool - expected *cdn.APIClient + expected *cdnSdk.APIClient }{ { name: "default endpoint", @@ -43,8 +43,8 @@ func TestConfigureClient(t *testing.T) { Version: testVersion, }, }, - expected: func() *cdn.APIClient { - apiClient, err := cdn.NewAPIClient( + expected: func() *cdnSdk.APIClient { + apiClient, err := cdnSdk.NewAPIClient( utils.UserAgentConfigOption(testVersion), ) if err != nil { @@ -62,8 +62,8 @@ func TestConfigureClient(t *testing.T) { CdnCustomEndpoint: testCustomEndpoint, }, }, - expected: func() *cdn.APIClient { - apiClient, err := cdn.NewAPIClient( + expected: func() *cdnSdk.APIClient { + apiClient, err := cdnSdk.NewAPIClient( utils.UserAgentConfigOption(testVersion), config.WithEndpoint(testCustomEndpoint), )