diff --git a/stackit/internal/services/scf/organization/datasource.go b/stackit/internal/services/scf/organization/datasource.go index 6d8b32ade..7cf9f43bc 100644 --- a/stackit/internal/services/scf/organization/datasource.go +++ b/stackit/internal/services/scf/organization/datasource.go @@ -10,7 +10,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-log/tflog" - "github.com/stackitcloud/stackit-sdk-go/services/scf" + scf "github.com/stackitcloud/stackit-sdk-go/services/scf/v1api" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/conversion" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core" @@ -149,7 +149,7 @@ func (s *scfOrganizationDataSource) Read(ctx context.Context, request datasource ctx = tflog.SetField(ctx, "region", region) // Read the current scf organization via orgId - scfOrgResponse, err := s.client.GetOrganization(ctx, projectId, region, orgId).Execute() + scfOrgResponse, err := s.client.DefaultAPI.GetOrganization(ctx, projectId, region, orgId).Execute() if err != nil { utils.LogError( ctx, diff --git a/stackit/internal/services/scf/organization/resource.go b/stackit/internal/services/scf/organization/resource.go index 15c4dc3a1..b80cc43ba 100644 --- a/stackit/internal/services/scf/organization/resource.go +++ b/stackit/internal/services/scf/organization/resource.go @@ -17,8 +17,8 @@ import ( "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/stackitcloud/stackit-sdk-go/core/oapierror" - "github.com/stackitcloud/stackit-sdk-go/services/scf" - "github.com/stackitcloud/stackit-sdk-go/services/scf/wait" + scf "github.com/stackitcloud/stackit-sdk-go/services/scf/v1api" + "github.com/stackitcloud/stackit-sdk-go/services/scf/v1api/wait" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/conversion" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core" @@ -249,7 +249,7 @@ func (s *scfOrganizationResource) Create(ctx context.Context, request resource.C } // Create the new scf organization via the API client. - scfOrgCreateResponse, err := s.client.CreateOrganization(ctx, projectId, region). + scfOrgCreateResponse, err := s.client.DefaultAPI.CreateOrganization(ctx, projectId, region). CreateOrganizationPayload(payload). Execute() if err != nil { @@ -259,11 +259,7 @@ func (s *scfOrganizationResource) Create(ctx context.Context, request resource.C ctx = core.LogResponse(ctx) - if scfOrgCreateResponse.Guid == nil { - core.LogAndAddError(ctx, &response.Diagnostics, "Error creating scf organization", "API response did not include org ID") - return - } - orgId := *scfOrgCreateResponse.Guid + orgId := scfOrgCreateResponse.Guid ctx = utils.SetAndLogStateFields(ctx, &response.Diagnostics, &response.State, map[string]any{ "project_id": projectId, @@ -273,19 +269,19 @@ func (s *scfOrganizationResource) Create(ctx context.Context, request resource.C // Apply the org quota if provided if quotaId != "" { - applyOrgQuota, err := s.client.ApplyOrganizationQuota(ctx, projectId, region, orgId).ApplyOrganizationQuotaPayload( + applyOrgQuota, err := s.client.DefaultAPI.ApplyOrganizationQuota(ctx, projectId, region, orgId).ApplyOrganizationQuotaPayload( scf.ApplyOrganizationQuotaPayload{ - QuotaId: "aId, + QuotaId: quotaId, }).Execute() if err != nil { core.LogAndAddError(ctx, &response.Diagnostics, "Error creating scf organization", fmt.Sprintf("Calling API to apply quota: %v", err)) return } - model.QuotaId = types.StringPointerValue(applyOrgQuota.QuotaId) + model.QuotaId = types.StringValue(applyOrgQuota.QuotaId) } if suspended { - _, err := s.client.UpdateOrganization(ctx, projectId, region, orgId).UpdateOrganizationPayload( + _, err := s.client.DefaultAPI.UpdateOrganization(ctx, projectId, region, orgId).UpdateOrganizationPayload( scf.UpdateOrganizationPayload{ Suspended: &suspended, @@ -297,7 +293,7 @@ func (s *scfOrganizationResource) Create(ctx context.Context, request resource.C } // Load the newly created scf organization - scfOrgResponse, err := s.client.GetOrganization(ctx, projectId, region, orgId).Execute() + scfOrgResponse, err := s.client.DefaultAPI.GetOrganization(ctx, projectId, region, orgId).Execute() if err != nil { core.LogAndAddError(ctx, &response.Diagnostics, "Error creating scf organization", fmt.Sprintf("Calling API to load created org: %v", err)) return @@ -339,7 +335,7 @@ func (s *scfOrganizationResource) Read(ctx context.Context, request resource.Rea ctx = tflog.SetField(ctx, "org_id", orgId) ctx = tflog.SetField(ctx, "region", region) // Read the current scf organization via guid - scfOrgResponse, err := s.client.GetOrganization(ctx, projectId, region, orgId).Execute() + scfOrgResponse, err := s.client.DefaultAPI.GetOrganization(ctx, projectId, region, orgId).Execute() if err != nil { var oapiErr *oapierror.GenericOpenAPIError ok := errors.As(err, &oapiErr) @@ -388,7 +384,7 @@ func (s *scfOrganizationResource) Update(ctx context.Context, request resource.U ctx = tflog.SetField(ctx, "org_id", orgId) ctx = tflog.SetField(ctx, "region", region) - org, err := s.client.GetOrganization(ctx, projectId, region, orgId).Execute() + org, err := s.client.DefaultAPI.GetOrganization(ctx, projectId, region, orgId).Execute() if err != nil { core.LogAndAddError(ctx, &response.Diagnostics, "Error retrieving organization state", fmt.Sprintf("Getting organization state: %v", err)) return @@ -396,7 +392,7 @@ func (s *scfOrganizationResource) Update(ctx context.Context, request resource.U // handle a change of the organization name or the suspended flag if name != org.GetName() || suspended != org.GetSuspended() { - updatedOrg, err := s.client.UpdateOrganization(ctx, projectId, region, orgId).UpdateOrganizationPayload( + updatedOrg, err := s.client.DefaultAPI.UpdateOrganization(ctx, projectId, region, orgId).UpdateOrganizationPayload( scf.UpdateOrganizationPayload{ Name: &name, Suspended: &suspended, @@ -412,9 +408,9 @@ func (s *scfOrganizationResource) Update(ctx context.Context, request resource.U // handle a quota change of the org if quotaId != org.GetQuotaId() { - applyOrgQuota, err := s.client.ApplyOrganizationQuota(ctx, projectId, region, orgId).ApplyOrganizationQuotaPayload( + applyOrgQuota, err := s.client.DefaultAPI.ApplyOrganizationQuota(ctx, projectId, region, orgId).ApplyOrganizationQuotaPayload( scf.ApplyOrganizationQuotaPayload{ - QuotaId: "aId, + QuotaId: quotaId, }).Execute() if err != nil { core.LogAndAddError(ctx, &response.Diagnostics, "Error applying organization quota", fmt.Sprintf("Processing API payload: %v", err)) @@ -460,7 +456,7 @@ func (s *scfOrganizationResource) Delete(ctx context.Context, request resource.D ctx = tflog.SetField(ctx, "region", region) // Call API to delete the existing scf organization. - _, err := s.client.DeleteOrganization(ctx, projectId, region, orgId).Execute() + _, err := s.client.DefaultAPI.DeleteOrganization(ctx, projectId, region, orgId).Execute() if err != nil { core.LogAndAddError(ctx, &response.Diagnostics, "Error deleting scf organization", fmt.Sprintf("Calling API: %v", err)) return @@ -468,7 +464,7 @@ func (s *scfOrganizationResource) Delete(ctx context.Context, request resource.D ctx = core.LogResponse(ctx) - _, err = wait.DeleteOrganizationWaitHandler(ctx, s.client, projectId, model.Region.ValueString(), orgId).WaitWithContext(ctx) + _, err = wait.DeleteOrganizationWaitHandler(ctx, s.client.DefaultAPI, projectId, model.Region.ValueString(), orgId).WaitWithContext(ctx) if err != nil { core.LogAndAddError(ctx, &response.Diagnostics, "Error waiting for scf org deletion", fmt.Sprintf("SCFOrganization deleting waiting: %v", err)) return @@ -511,43 +507,16 @@ func mapFields(response *scf.Organization, model *Model) error { return fmt.Errorf("model input is nil") } - var orgId string - if response.Guid != nil { - orgId = *response.Guid - } else if model.OrgId.ValueString() != "" { - orgId = model.OrgId.ValueString() - } else { - return fmt.Errorf("org id is not present") - } - - var projectId string - if response.ProjectId != nil { - projectId = *response.ProjectId - } else if model.ProjectId.ValueString() != "" { - projectId = model.ProjectId.ValueString() - } else { - return fmt.Errorf("project id is not present") - } - - var region string - if response.Region != nil { - region = *response.Region - } else if model.Region.ValueString() != "" { - region = model.Region.ValueString() - } else { - return fmt.Errorf("region is not present") - } - // Build the ID by combining the project ID and organization id and assign the model's fields. - model.Id = utils.BuildInternalTerraformId(projectId, region, orgId) - model.ProjectId = types.StringValue(projectId) - model.Region = types.StringValue(region) - model.PlatformId = types.StringPointerValue(response.PlatformId) - model.OrgId = types.StringValue(orgId) - model.Name = types.StringPointerValue(response.Name) - model.Status = types.StringPointerValue(response.Status) - model.Suspended = types.BoolPointerValue(response.Suspended) - model.QuotaId = types.StringPointerValue(response.QuotaId) + model.Id = utils.BuildInternalTerraformId(response.ProjectId, response.Region, response.Guid) + model.ProjectId = types.StringValue(response.ProjectId) + model.Region = types.StringValue(response.Region) + model.PlatformId = types.StringValue(response.PlatformId) + model.OrgId = types.StringValue(response.Guid) + model.Name = types.StringValue(response.Name) + model.Status = types.StringValue(response.Status) + model.Suspended = types.BoolValue(response.Suspended) + model.QuotaId = types.StringValue(response.QuotaId) model.CreateAt = types.StringValue(response.CreatedAt.String()) model.UpdatedAt = types.StringValue(response.UpdatedAt.String()) return nil @@ -560,7 +529,7 @@ func toCreatePayload(model *Model) (scf.CreateOrganizationPayload, error) { } payload := scf.CreateOrganizationPayload{ - Name: model.Name.ValueStringPointer(), + Name: model.Name.ValueString(), } if !model.PlatformId.IsNull() && !model.PlatformId.IsUnknown() { payload.PlatformId = model.PlatformId.ValueStringPointer() diff --git a/stackit/internal/services/scf/organization/resource_test.go b/stackit/internal/services/scf/organization/resource_test.go index e4b47b1bd..a4ba2c562 100644 --- a/stackit/internal/services/scf/organization/resource_test.go +++ b/stackit/internal/services/scf/organization/resource_test.go @@ -8,7 +8,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stackitcloud/stackit-sdk-go/services/scf" + scf "github.com/stackitcloud/stackit-sdk-go/services/scf/v1api" ) var ( @@ -34,23 +34,23 @@ func TestMapFields(t *testing.T) { { description: "minimal_input", input: &scf.Organization{ - Guid: new(testOrgId), - Name: new("scf-org-min-instance"), - Region: new(testRegion), - CreatedAt: &createdTime, - UpdatedAt: &createdTime, - ProjectId: new(testProjectId), + Guid: testOrgId, + Name: "scf-org-min-instance", + Region: testRegion, + CreatedAt: createdTime, + UpdatedAt: createdTime, + ProjectId: testProjectId, }, expected: &Model{ Id: types.StringValue(fmt.Sprintf("%s,%s,%s", testProjectId, testRegion, testOrgId)), ProjectId: types.StringValue(testProjectId), Region: types.StringValue(testRegion), Name: types.StringValue("scf-org-min-instance"), - PlatformId: types.StringNull(), + PlatformId: types.StringValue(""), OrgId: types.StringValue(testOrgId), - QuotaId: types.StringNull(), - Status: types.StringNull(), - Suspended: types.BoolNull(), + QuotaId: types.StringValue(""), + Status: types.StringValue(""), + Suspended: types.BoolValue(false), CreateAt: types.StringValue("2025-01-01 00:00:00 +0000 UTC"), UpdatedAt: types.StringValue("2025-01-01 00:00:00 +0000 UTC"), }, @@ -59,16 +59,16 @@ func TestMapFields(t *testing.T) { { description: "max_input", input: &scf.Organization{ - CreatedAt: &createdTime, - Guid: new(testOrgId), - Name: new("scf-full-org"), - PlatformId: new(testPlatformId), - ProjectId: new(testProjectId), - QuotaId: new(testQuotaId), - Region: new(testRegion), - Status: nil, - Suspended: new(true), - UpdatedAt: &createdTime, + CreatedAt: createdTime, + Guid: testOrgId, + Name: "scf-full-org", + PlatformId: testPlatformId, + ProjectId: testProjectId, + QuotaId: testQuotaId, + Region: testRegion, + Status: "", + Suspended: true, + UpdatedAt: createdTime, }, expected: &Model{ Id: types.StringValue(fmt.Sprintf("%s,%s,%s", testProjectId, testRegion, testOrgId)), @@ -80,7 +80,7 @@ func TestMapFields(t *testing.T) { CreateAt: types.StringValue("2025-01-01 00:00:00 +0000 UTC"), UpdatedAt: types.StringValue("2025-01-01 00:00:00 +0000 UTC"), QuotaId: types.StringValue(testQuotaId), - Status: types.StringNull(), + Status: types.StringValue(""), Suspended: types.BoolValue(true), }, isValid: true, @@ -91,20 +91,6 @@ func TestMapFields(t *testing.T) { expected: nil, isValid: false, }, - { - description: "empty_org", - input: &scf.Organization{}, - expected: nil, - isValid: false, - }, - { - description: "missing_id", - input: &scf.Organization{ - Name: new("scf-missing-id"), - }, - expected: nil, - isValid: false, - }, } for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { @@ -143,8 +129,8 @@ func TestToCreatePayload(t *testing.T) { PlatformId: types.StringValue(testPlatformId), }, expected: scf.CreateOrganizationPayload{ - Name: new("example-org"), - PlatformId: new(testPlatformId), + Name: "example-org", + PlatformId: &testPlatformId, }, expectError: false, }, diff --git a/stackit/internal/services/scf/organizationmanager/datasource.go b/stackit/internal/services/scf/organizationmanager/datasource.go index 2f0a19262..0de8b9a73 100644 --- a/stackit/internal/services/scf/organizationmanager/datasource.go +++ b/stackit/internal/services/scf/organizationmanager/datasource.go @@ -11,7 +11,7 @@ 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/scf" + scf "github.com/stackitcloud/stackit-sdk-go/services/scf/v1api" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/conversion" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core" @@ -152,7 +152,7 @@ func (s *scfOrganizationManagerDataSource) Read(ctx context.Context, request dat ctx = tflog.SetField(ctx, "org_id", orgId) ctx = tflog.SetField(ctx, "region", region) // Read the current scf organization manager via orgId - ScfOrgManager, err := s.client.GetOrgManagerExecute(ctx, projectId, region, orgId) + ScfOrgManager, err := s.client.DefaultAPI.GetOrgManager(ctx, projectId, region, orgId).Execute() if err != nil { utils.LogError( ctx, @@ -189,53 +189,17 @@ func mapFieldsDataSource(response *scf.OrgManager, model *DataSourceModel) error if model == nil { return fmt.Errorf("model input is nil") } - - var projectId string - if response.ProjectId != nil { - projectId = *response.ProjectId - } else if model.ProjectId.ValueString() != "" { - projectId = model.ProjectId.ValueString() - } else { - return fmt.Errorf("project id is not present") - } - - var region string - if response.Region != nil { - region = *response.Region - } else if model.Region.ValueString() != "" { - region = model.Region.ValueString() - } else { - return fmt.Errorf("region is not present") - } - - var orgId string - if response.OrgId != nil { - orgId = *response.OrgId - } else if model.OrgId.ValueString() != "" { - orgId = model.OrgId.ValueString() - } else { - return fmt.Errorf("org id is not present") - } - - var userId string - if response.Guid != nil { - userId = *response.Guid - if model.UserId.ValueString() != "" && userId != model.UserId.ValueString() { - return fmt.Errorf("user id mismatch in response and model") - } - } else if model.UserId.ValueString() != "" { - userId = model.UserId.ValueString() - } else { - return fmt.Errorf("user id is not present") + if userId := model.UserId.ValueString(); userId != "" && userId != response.Guid { + return fmt.Errorf("user id mismatch in response and model") } - model.Id = utils.BuildInternalTerraformId(projectId, region, orgId, userId) - model.Region = types.StringValue(region) - model.PlatformId = types.StringPointerValue(response.PlatformId) - model.ProjectId = types.StringValue(projectId) - model.OrgId = types.StringValue(orgId) - model.UserId = types.StringValue(userId) - model.UserName = types.StringPointerValue(response.Username) + model.Id = utils.BuildInternalTerraformId(response.ProjectId, response.Region, response.OrgId, response.Guid) + model.Region = types.StringValue(response.Region) + model.PlatformId = types.StringValue(response.PlatformId) + model.ProjectId = types.StringValue(response.ProjectId) + model.OrgId = types.StringValue(response.OrgId) + model.UserId = types.StringValue(response.Guid) + model.UserName = types.StringValue(response.Username) model.CreateAt = types.StringValue(response.CreatedAt.String()) model.UpdatedAt = types.StringValue(response.UpdatedAt.String()) return nil diff --git a/stackit/internal/services/scf/organizationmanager/datasource_test.go b/stackit/internal/services/scf/organizationmanager/datasource_test.go index fd058bfca..ac6ef1429 100644 --- a/stackit/internal/services/scf/organizationmanager/datasource_test.go +++ b/stackit/internal/services/scf/organizationmanager/datasource_test.go @@ -7,7 +7,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stackitcloud/stackit-sdk-go/services/scf" + scf "github.com/stackitcloud/stackit-sdk-go/services/scf/v1api" ) func TestMapFieldsDataSource(t *testing.T) { @@ -25,12 +25,12 @@ func TestMapFieldsDataSource(t *testing.T) { { description: "minimal_input", input: &scf.OrgManager{ - Guid: new(testUserId), - OrgId: new(testOrgId), - ProjectId: new(testProjectId), - Region: new(testRegion), - CreatedAt: &createdTime, - UpdatedAt: &createdTime, + Guid: testUserId, + OrgId: testOrgId, + ProjectId: testProjectId, + Region: testRegion, + CreatedAt: createdTime, + UpdatedAt: createdTime, }, expected: &DataSourceModel{ Id: types.StringValue(fmt.Sprintf("%s,%s,%s,%s", testProjectId, testRegion, testOrgId, testUserId)), @@ -38,8 +38,8 @@ func TestMapFieldsDataSource(t *testing.T) { OrgId: types.StringValue(testOrgId), ProjectId: types.StringValue(testProjectId), Region: types.StringValue(testRegion), - UserName: types.StringNull(), - PlatformId: types.StringNull(), + UserName: types.StringValue(""), + PlatformId: types.StringValue(""), CreateAt: types.StringValue("2025-01-01 00:00:00 +0000 UTC"), UpdatedAt: types.StringValue("2025-01-01 00:00:00 +0000 UTC"), }, @@ -48,14 +48,14 @@ func TestMapFieldsDataSource(t *testing.T) { { description: "max_input", input: &scf.OrgManager{ - Guid: new(testUserId), - OrgId: new(testOrgId), - ProjectId: new(testProjectId), - PlatformId: new(testPlatformId), - Region: new(testRegion), - CreatedAt: &createdTime, - UpdatedAt: &createdTime, - Username: new("test-user"), + Guid: testUserId, + OrgId: testOrgId, + ProjectId: testProjectId, + PlatformId: testPlatformId, + Region: testRegion, + CreatedAt: createdTime, + UpdatedAt: createdTime, + Username: "test-user", }, expected: &DataSourceModel{ Id: types.StringValue(fmt.Sprintf("%s,%s,%s,%s", testProjectId, testRegion, testOrgId, testUserId)), @@ -76,20 +76,6 @@ func TestMapFieldsDataSource(t *testing.T) { expected: nil, isValid: false, }, - { - description: "empty_org", - input: &scf.OrgManager{}, - expected: nil, - isValid: false, - }, - { - description: "missing_id", - input: &scf.OrgManager{ - Username: new("scf-missing-id"), - }, - expected: nil, - isValid: false, - }, } for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { diff --git a/stackit/internal/services/scf/organizationmanager/resource.go b/stackit/internal/services/scf/organizationmanager/resource.go index ad8e9ae14..51cad3075 100644 --- a/stackit/internal/services/scf/organizationmanager/resource.go +++ b/stackit/internal/services/scf/organizationmanager/resource.go @@ -16,7 +16,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/stackitcloud/stackit-sdk-go/core/oapierror" - "github.com/stackitcloud/stackit-sdk-go/services/scf" + scf "github.com/stackitcloud/stackit-sdk-go/services/scf/v1api" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/conversion" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core" @@ -230,7 +230,7 @@ func (s *scfOrganizationManagerResource) Create(ctx context.Context, request res } // Create the new scf organization manager via the API client. - scfOrgManagerCreateResponse, err := s.client.CreateOrgManagerExecute(ctx, projectId, region, orgId) + scfOrgManagerCreateResponse, err := s.client.DefaultAPI.CreateOrgManager(ctx, projectId, region, orgId).Execute() if err != nil { core.LogAndAddError(ctx, &response.Diagnostics, "Error creating scf organization manager", fmt.Sprintf("Calling API to create org manager: %v", err)) return @@ -238,10 +238,7 @@ func (s *scfOrganizationManagerResource) Create(ctx context.Context, request res ctx = core.LogResponse(ctx) - if scfOrgManagerCreateResponse.Guid == nil { - core.LogAndAddError(ctx, &response.Diagnostics, "Error creating scf organization manager", "API response does not contain user id") - } - userId := *scfOrgManagerCreateResponse.Guid + userId := scfOrgManagerCreateResponse.Guid ctx = utils.SetAndLogStateFields(ctx, &response.Diagnostics, &response.State, map[string]any{ "project_id": projectId, "region": region, @@ -284,7 +281,7 @@ func (s *scfOrganizationManagerResource) Read(ctx context.Context, request resou ctx = tflog.SetField(ctx, "region", region) // Read the current scf organization manager via orgId - scfOrgManager, err := s.client.GetOrgManagerExecute(ctx, projectId, region, orgId) + scfOrgManager, err := s.client.DefaultAPI.GetOrgManager(ctx, projectId, region, orgId).Execute() if err != nil { var oapiErr *oapierror.GenericOpenAPIError ok := errors.As(err, &oapiErr) @@ -335,7 +332,7 @@ func (s *scfOrganizationManagerResource) Delete(ctx context.Context, request res ctx = tflog.SetField(ctx, "region", region) // Call API to delete the existing scf organization manager. - _, err := s.client.DeleteOrgManagerExecute(ctx, projectId, region, orgId) + _, err := s.client.DefaultAPI.DeleteOrgManager(ctx, projectId, region, orgId).Execute() if err != nil { var oapiErr *oapierror.GenericOpenAPIError ok := errors.As(err, &oapiErr) @@ -387,50 +384,14 @@ func mapFieldsCreate(response *scf.OrgManagerResponse, model *Model) error { return fmt.Errorf("model input is nil") } - var projectId string - if response.ProjectId != nil { - projectId = *response.ProjectId - } else if model.ProjectId.ValueString() != "" { - projectId = model.ProjectId.ValueString() - } else { - return fmt.Errorf("project id is not present") - } - - var region string - if response.Region != nil { - region = *response.Region - } else if model.Region.ValueString() != "" { - region = model.Region.ValueString() - } else { - return fmt.Errorf("region is not present") - } - - var orgId string - if response.OrgId != nil { - orgId = *response.OrgId - } else if model.OrgId.ValueString() != "" { - orgId = model.OrgId.ValueString() - } else { - return fmt.Errorf("org id is not present") - } - - var userId string - if response.Guid != nil { - userId = *response.Guid - } else if model.UserId.ValueString() != "" { - userId = model.UserId.ValueString() - } else { - return fmt.Errorf("user id is not present") - } - - model.Id = utils.BuildInternalTerraformId(projectId, region, orgId, userId) - model.Region = types.StringValue(region) - model.PlatformId = types.StringPointerValue(response.PlatformId) - model.ProjectId = types.StringValue(projectId) - model.OrgId = types.StringValue(orgId) - model.UserId = types.StringValue(userId) - model.UserName = types.StringPointerValue(response.Username) - model.Password = types.StringPointerValue(response.Password) + model.Id = utils.BuildInternalTerraformId(response.ProjectId, response.Region, response.OrgId, response.Guid) + model.Region = types.StringValue(response.Region) + model.PlatformId = types.StringValue(response.PlatformId) + model.ProjectId = types.StringValue(response.ProjectId) + model.OrgId = types.StringValue(response.OrgId) + model.UserId = types.StringValue(response.Guid) + model.UserName = types.StringValue(response.Username) + model.Password = types.StringValue(response.Password) model.CreateAt = types.StringValue(response.CreatedAt.String()) model.UpdatedAt = types.StringValue(response.UpdatedAt.String()) return nil @@ -443,53 +404,17 @@ func mapFieldsRead(response *scf.OrgManager, model *Model) error { if model == nil { return fmt.Errorf("model input is nil") } - - var projectId string - if response.ProjectId != nil { - projectId = *response.ProjectId - } else if model.ProjectId.ValueString() != "" { - projectId = model.ProjectId.ValueString() - } else { - return fmt.Errorf("project id is not present") - } - - var region string - if response.Region != nil { - region = *response.Region - } else if model.Region.ValueString() != "" { - region = model.Region.ValueString() - } else { - return fmt.Errorf("region is not present") - } - - var orgId string - if response.OrgId != nil { - orgId = *response.OrgId - } else if model.OrgId.ValueString() != "" { - orgId = model.OrgId.ValueString() - } else { - return fmt.Errorf("org id is not present") - } - - var userId string - if response.Guid != nil { - userId = *response.Guid - if model.UserId.ValueString() != "" && userId != model.UserId.ValueString() { - return fmt.Errorf("user id mismatch in response and model") - } - } else if model.UserId.ValueString() != "" { - userId = model.UserId.ValueString() - } else { - return fmt.Errorf("user id is not present") + if userId := model.UserId.ValueString(); userId != "" && userId != response.Guid { + return fmt.Errorf("user id mismatch in response and model") } - model.Id = utils.BuildInternalTerraformId(projectId, region, orgId, userId) - model.Region = types.StringValue(region) - model.PlatformId = types.StringPointerValue(response.PlatformId) - model.ProjectId = types.StringValue(projectId) - model.OrgId = types.StringValue(orgId) - model.UserId = types.StringValue(userId) - model.UserName = types.StringPointerValue(response.Username) + model.Id = utils.BuildInternalTerraformId(response.ProjectId, response.Region, response.OrgId, response.Guid) + model.Region = types.StringValue(response.Region) + model.PlatformId = types.StringValue(response.PlatformId) + model.ProjectId = types.StringValue(response.ProjectId) + model.OrgId = types.StringValue(response.OrgId) + model.UserId = types.StringValue(response.Guid) + model.UserName = types.StringValue(response.Username) model.CreateAt = types.StringValue(response.CreatedAt.String()) model.UpdatedAt = types.StringValue(response.UpdatedAt.String()) return nil diff --git a/stackit/internal/services/scf/organizationmanager/resource_test.go b/stackit/internal/services/scf/organizationmanager/resource_test.go index 8f9e2d777..74122b515 100644 --- a/stackit/internal/services/scf/organizationmanager/resource_test.go +++ b/stackit/internal/services/scf/organizationmanager/resource_test.go @@ -8,7 +8,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stackitcloud/stackit-sdk-go/services/scf" + scf "github.com/stackitcloud/stackit-sdk-go/services/scf/v1api" ) var ( @@ -34,12 +34,12 @@ func TestMapFields(t *testing.T) { { description: "minimal_input", input: &scf.OrgManager{ - Guid: new(testUserId), - OrgId: new(testOrgId), - ProjectId: new(testProjectId), - Region: new(testRegion), - CreatedAt: &createdTime, - UpdatedAt: &createdTime, + Guid: testUserId, + OrgId: testOrgId, + ProjectId: testProjectId, + Region: testRegion, + CreatedAt: createdTime, + UpdatedAt: createdTime, }, expected: &Model{ Id: types.StringValue(fmt.Sprintf("%s,%s,%s,%s", testProjectId, testRegion, testOrgId, testUserId)), @@ -47,8 +47,8 @@ func TestMapFields(t *testing.T) { OrgId: types.StringValue(testOrgId), ProjectId: types.StringValue(testProjectId), Region: types.StringValue(testRegion), - UserName: types.StringNull(), - PlatformId: types.StringNull(), + UserName: types.StringValue(""), + PlatformId: types.StringValue(""), CreateAt: types.StringValue("2025-01-01 00:00:00 +0000 UTC"), UpdatedAt: types.StringValue("2025-01-01 00:00:00 +0000 UTC"), }, @@ -57,14 +57,14 @@ func TestMapFields(t *testing.T) { { description: "max_input", input: &scf.OrgManager{ - Guid: new(testUserId), - OrgId: new(testOrgId), - ProjectId: new(testProjectId), - PlatformId: new(testPlatformId), - Region: new(testRegion), - CreatedAt: &createdTime, - UpdatedAt: &createdTime, - Username: new("test-user"), + Guid: testUserId, + OrgId: testOrgId, + ProjectId: testProjectId, + PlatformId: testPlatformId, + Region: testRegion, + CreatedAt: createdTime, + UpdatedAt: createdTime, + Username: "test-user", }, expected: &Model{ Id: types.StringValue(fmt.Sprintf("%s,%s,%s,%s", testProjectId, testRegion, testOrgId, testUserId)), @@ -86,20 +86,6 @@ func TestMapFields(t *testing.T) { expected: nil, isValid: false, }, - { - description: "empty_org", - input: &scf.OrgManager{}, - expected: nil, - isValid: false, - }, - { - description: "missing_id", - input: &scf.OrgManager{ - Username: new("scf-missing-id"), - }, - expected: nil, - isValid: false, - }, } for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { @@ -139,12 +125,12 @@ func TestMapFieldsCreate(t *testing.T) { { description: "minimal_input", input: &scf.OrgManagerResponse{ - Guid: new(testUserId), - OrgId: new(testOrgId), - ProjectId: new(testProjectId), - Region: new(testRegion), - CreatedAt: &createdTime, - UpdatedAt: &createdTime, + Guid: testUserId, + OrgId: testOrgId, + ProjectId: testProjectId, + Region: testRegion, + CreatedAt: createdTime, + UpdatedAt: createdTime, }, expected: &Model{ Id: types.StringValue(fmt.Sprintf("%s,%s,%s,%s", testProjectId, testRegion, testOrgId, testUserId)), @@ -152,9 +138,9 @@ func TestMapFieldsCreate(t *testing.T) { OrgId: types.StringValue(testOrgId), ProjectId: types.StringValue(testProjectId), Region: types.StringValue(testRegion), - UserName: types.StringNull(), - PlatformId: types.StringNull(), - Password: types.StringNull(), + UserName: types.StringValue(""), + PlatformId: types.StringValue(""), + Password: types.StringValue(""), CreateAt: types.StringValue("2025-01-01 00:00:00 +0000 UTC"), UpdatedAt: types.StringValue("2025-01-01 00:00:00 +0000 UTC"), }, @@ -163,15 +149,15 @@ func TestMapFieldsCreate(t *testing.T) { { description: "max_input", input: &scf.OrgManagerResponse{ - Guid: new(testUserId), - OrgId: new(testOrgId), - ProjectId: new(testProjectId), - PlatformId: new(testPlatformId), - Region: new(testRegion), - CreatedAt: &createdTime, - UpdatedAt: &createdTime, - Username: new("test-user"), - Password: new("test-password"), + Guid: testUserId, + OrgId: testOrgId, + ProjectId: testProjectId, + PlatformId: testPlatformId, + Region: testRegion, + CreatedAt: createdTime, + UpdatedAt: createdTime, + Username: "test-user", + Password: "test-password", }, expected: &Model{ Id: types.StringValue(fmt.Sprintf("%s,%s,%s,%s", testProjectId, testRegion, testOrgId, testUserId)), @@ -193,20 +179,6 @@ func TestMapFieldsCreate(t *testing.T) { expected: nil, isValid: false, }, - { - description: "empty_org", - input: &scf.OrgManagerResponse{}, - expected: nil, - isValid: false, - }, - { - description: "missing_id", - input: &scf.OrgManagerResponse{ - Username: new("scf-missing-id"), - }, - expected: nil, - isValid: false, - }, } for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { diff --git a/stackit/internal/services/scf/platform/datasource.go b/stackit/internal/services/scf/platform/datasource.go index 5deb1b627..70f533ca2 100644 --- a/stackit/internal/services/scf/platform/datasource.go +++ b/stackit/internal/services/scf/platform/datasource.go @@ -10,7 +10,7 @@ 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/scf" + scf "github.com/stackitcloud/stackit-sdk-go/services/scf/v1api" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/conversion" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core" @@ -147,7 +147,7 @@ func (s *scfPlatformDataSource) Read(ctx context.Context, request datasource.Rea ctx = tflog.SetField(ctx, "region", region) // Read the scf platform - scfPlatformResponse, err := s.client.GetPlatformExecute(ctx, projectId, region, platformId) + scfPlatformResponse, err := s.client.DefaultAPI.GetPlatform(ctx, projectId, region, platformId).Execute() if err != nil { utils.LogError( ctx, @@ -186,38 +186,13 @@ func mapFields(response *scf.Platforms, model *Model) error { return fmt.Errorf("model input is nil") } - var projectId string - if model.ProjectId.ValueString() == "" { - return fmt.Errorf("project id is not present") - } - projectId = model.ProjectId.ValueString() - - var region string - if response.Region != nil { - region = *response.Region - } else if model.Region.ValueString() != "" { - region = model.Region.ValueString() - } else { - return fmt.Errorf("region is not present") - } - - var platformId string - if response.Guid != nil { - platformId = *response.Guid - } else if model.PlatformId.ValueString() != "" { - platformId = model.PlatformId.ValueString() - } else { - return fmt.Errorf("platform id is not present") - } - // Build the ID - model.Id = utils.BuildInternalTerraformId(projectId, region, platformId) - model.PlatformId = types.StringValue(platformId) - model.ProjectId = types.StringValue(projectId) - model.SystemId = types.StringPointerValue(response.SystemId) - model.DisplayName = types.StringPointerValue(response.DisplayName) - model.Region = types.StringValue(region) - model.ApiUrl = types.StringPointerValue(response.ApiUrl) + model.Id = utils.BuildInternalTerraformId(model.ProjectId.ValueString(), response.Region, response.Guid) + model.PlatformId = types.StringValue(response.Guid) + model.SystemId = types.StringValue(response.SystemId) + model.DisplayName = types.StringValue(response.DisplayName) + model.Region = types.StringValue(response.Region) + model.ApiUrl = types.StringValue(response.ApiUrl) model.ConsoleUrl = types.StringPointerValue(response.ConsoleUrl) return nil } diff --git a/stackit/internal/services/scf/platform/datasource_test.go b/stackit/internal/services/scf/platform/datasource_test.go index 8307a46d1..b86c65986 100644 --- a/stackit/internal/services/scf/platform/datasource_test.go +++ b/stackit/internal/services/scf/platform/datasource_test.go @@ -7,7 +7,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stackitcloud/stackit-sdk-go/services/scf" + scf "github.com/stackitcloud/stackit-sdk-go/services/scf/v1api" ) var ( @@ -26,17 +26,17 @@ func TestMapFields(t *testing.T) { { description: "minimal_input", input: &scf.Platforms{ - Guid: new(testPlatformId), - Region: new(testRegion), + Guid: testPlatformId, + Region: testRegion, }, expected: &Model{ Id: types.StringValue(fmt.Sprintf("%s,%s,%s", testProjectId, testRegion, testPlatformId)), PlatformId: types.StringValue(testPlatformId), ProjectId: types.StringValue(testProjectId), Region: types.StringValue(testRegion), - SystemId: types.StringNull(), - DisplayName: types.StringNull(), - ApiUrl: types.StringNull(), + SystemId: types.StringValue(""), + DisplayName: types.StringValue(""), + ApiUrl: types.StringValue(""), ConsoleUrl: types.StringNull(), }, isValid: true, @@ -44,11 +44,11 @@ func TestMapFields(t *testing.T) { { description: "max_input", input: &scf.Platforms{ - Guid: new(testPlatformId), - SystemId: new("eu01.01"), - DisplayName: new("scf-full-org"), - Region: new(testRegion), - ApiUrl: new("https://example.scf.stackit.cloud"), + Guid: testPlatformId, + SystemId: "eu01.01", + DisplayName: "scf-full-org", + Region: testRegion, + ApiUrl: "https://example.scf.stackit.cloud", ConsoleUrl: new("https://example.console.scf.stackit.cloud"), }, expected: &Model{ @@ -69,20 +69,6 @@ func TestMapFields(t *testing.T) { expected: nil, isValid: false, }, - { - description: "empty_org", - input: &scf.Platforms{}, - expected: nil, - isValid: false, - }, - { - description: "missing_id", - input: &scf.Platforms{ - DisplayName: new("scf-missing-id"), - }, - expected: nil, - isValid: false, - }, } for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { diff --git a/stackit/internal/services/scf/scf_acc_test.go b/stackit/internal/services/scf/scf_acc_test.go index b8b54ed7c..45d630ee2 100644 --- a/stackit/internal/services/scf/scf_acc_test.go +++ b/stackit/internal/services/scf/scf_acc_test.go @@ -5,16 +5,16 @@ import ( _ "embed" "fmt" "maps" + "slices" "strings" "testing" - "github.com/stackitcloud/stackit-sdk-go/services/scf" + scf "github.com/stackitcloud/stackit-sdk-go/services/scf/v1api" "github.com/hashicorp/terraform-plugin-testing/config" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" - "github.com/stackitcloud/stackit-sdk-go/core/utils" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/testutil" @@ -254,7 +254,7 @@ func TestAccScfOrgMax(t *testing.T) { resource.TestCheckResourceAttr("data.stackit_scf_platform.scf_platform", "display_name", platformName), resource.TestCheckResourceAttr("data.stackit_scf_platform.scf_platform", "system_id", platformSystemId), resource.TestCheckResourceAttr("data.stackit_scf_platform.scf_platform", "api_url", platformApiUrl), - resource.TestCheckResourceAttr("data.stackit_scf_platform.scf_platform", "console_url", platformConsoleUrl), + resource.TestCheckResourceAttrWith("data.stackit_scf_platform.scf_platform", "console_url", testutil.CheckAttrHasPrefix(platformConsoleUrl)), resource.TestCheckResourceAttrSet("stackit_scf_organization_manager.orgmanager", "id"), resource.TestCheckResourceAttrSet("stackit_scf_organization_manager.orgmanager", "org_id"), resource.TestCheckResourceAttr("stackit_scf_organization_manager.orgmanager", "platform_id", testutil.ConvertConfigVariable(testConfigVarsMax["platform_id"])), @@ -342,7 +342,7 @@ func TestAccScfOrgMax(t *testing.T) { resource.TestCheckResourceAttr("data.stackit_scf_platform.platform", "display_name", platformName), resource.TestCheckResourceAttr("data.stackit_scf_platform.platform", "region", region), resource.TestCheckResourceAttr("data.stackit_scf_platform.platform", "api_url", platformApiUrl), - resource.TestCheckResourceAttr("data.stackit_scf_platform.platform", "console_url", platformConsoleUrl), + resource.TestCheckResourceAttrWith("data.stackit_scf_platform.platform", "console_url", testutil.CheckAttrHasPrefix(platformConsoleUrl)), resource.TestCheckResourceAttrPair( "stackit_scf_organization.org", "region", "data.stackit_scf_organization_manager.orgmanager", "region", @@ -424,20 +424,20 @@ func testAccCheckScfOrganizationDestroy(s *terraform.State) error { orgsToDestroy = append(orgsToDestroy, orgId) } - organizationsList, err := client.ListOrganizations(ctx, testutil.ProjectId, testutil.Region).Execute() + organizationsList, err := client.DefaultAPI.ListOrganizations(ctx, testutil.ProjectId, testutil.Region).Execute() if err != nil { return fmt.Errorf("getting scf organizations: %w", err) } scfOrgs := organizationsList.GetResources() for i := range scfOrgs { - if scfOrgs[i].Guid == nil { + if scfOrgs[i].Guid == "" { continue } - if utils.Contains(orgsToDestroy, *scfOrgs[i].Guid) { - _, err := client.DeleteOrganizationExecute(ctx, testutil.ProjectId, testutil.Region, *scfOrgs[i].Guid) + if slices.Contains(orgsToDestroy, scfOrgs[i].Guid) { + _, err := client.DefaultAPI.DeleteOrganization(ctx, testutil.ProjectId, testutil.Region, scfOrgs[i].Guid).Execute() if err != nil { - return fmt.Errorf("destroying scf organization %s during CheckDestroy: %w", *scfOrgs[i].Guid, err) + return fmt.Errorf("destroying scf organization %s during CheckDestroy: %w", scfOrgs[i].Guid, err) } } } diff --git a/stackit/internal/services/scf/scf_test.go b/stackit/internal/services/scf/scf_test.go index 897f24b8b..5880d4f89 100644 --- a/stackit/internal/services/scf/scf_test.go +++ b/stackit/internal/services/scf/scf_test.go @@ -8,7 +8,7 @@ import ( "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-testing/helper/resource" - "github.com/stackitcloud/stackit-sdk-go/services/scf" + scf "github.com/stackitcloud/stackit-sdk-go/services/scf/v1api" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/testutil" ) @@ -43,7 +43,7 @@ resource "stackit_scf_organization" "org" { testutil.MockResponse{ Description: "create", ToJsonBody: &scf.OrganizationCreateResponse{ - Guid: new(guid), + Guid: guid, }, }, testutil.MockResponse{Description: "create waiter", StatusCode: http.StatusNotFound}, diff --git a/stackit/internal/services/scf/utils/utils.go b/stackit/internal/services/scf/utils/utils.go index 347e109bb..b2b4b65f6 100644 --- a/stackit/internal/services/scf/utils/utils.go +++ b/stackit/internal/services/scf/utils/utils.go @@ -6,7 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/stackitcloud/stackit-sdk-go/core/config" - "github.com/stackitcloud/stackit-sdk-go/services/scf" + scf "github.com/stackitcloud/stackit-sdk-go/services/scf/v1api" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/utils" diff --git a/stackit/internal/services/scf/utils/utils_test.go b/stackit/internal/services/scf/utils/utils_test.go index 1a77a0ae3..363788bcb 100644 --- a/stackit/internal/services/scf/utils/utils_test.go +++ b/stackit/internal/services/scf/utils/utils_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/scf" + scf "github.com/stackitcloud/stackit-sdk-go/services/scf/v1api" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/utils" diff --git a/stackit/internal/testutil/testutil.go b/stackit/internal/testutil/testutil.go index eda56aeb8..5be2e7281 100644 --- a/stackit/internal/testutil/testutil.go +++ b/stackit/internal/testutil/testutil.go @@ -15,6 +15,7 @@ import ( "github.com/hashicorp/terraform-plugin-go/tfprotov6" "github.com/hashicorp/terraform-plugin-testing/config" "github.com/hashicorp/terraform-plugin-testing/echoprovider" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" sdkConf "github.com/stackitcloud/stackit-sdk-go/core/config" "github.com/stackitcloud/terraform-provider-stackit/stackit" @@ -353,3 +354,14 @@ func ConvertConfigVariable(variable config.Variable) string { return input } + +// CheckAttrHasPrefix returns a CheckResourceAttrWithFunc that validates +// whether an attribute value starts with the given prefix. +func CheckAttrHasPrefix(prefix string) resource.CheckResourceAttrWithFunc { + return func(value string) error { + if !strings.HasPrefix(value, prefix) { + return fmt.Errorf("should start with %s", prefix) + } + return nil + } +}