diff --git a/stackit/internal/services/postgresflexalpha/database/datasource.go b/stackit/internal/services/postgresflexalpha/database/datasource.go index e836bcde..4a89be17 100644 --- a/stackit/internal/services/postgresflexalpha/database/datasource.go +++ b/stackit/internal/services/postgresflexalpha/database/datasource.go @@ -19,12 +19,6 @@ import ( "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/postgresflexalpha" ) -// DataSourceModel maps the data source schema data. -type DataSourceModel struct { - postgresflexalpha2.DatabaseModel - TerraformID types.String `tfsdk:"id"` -} - // Ensure the implementation satisfies the expected interfaces. var ( _ datasource.DataSource = &databaseDataSource{} @@ -35,6 +29,12 @@ func NewDatabaseDataSource() datasource.DataSource { return &databaseDataSource{} } +// dataSourceModel maps the data source schema data. +type dataSourceModel struct { + postgresflexalpha2.DatabaseModel + TerraformID types.String `tfsdk:"id"` +} + // databaseDataSource is the data source implementation. type databaseDataSource struct { client *postgresflexalpha.APIClient @@ -89,7 +89,7 @@ func (r *databaseDataSource) Read( req datasource.ReadRequest, resp *datasource.ReadResponse, ) { // nolint:gocritic // function signature required by Terraform - var model DataSourceModel + var model dataSourceModel diags := req.Config.Get(ctx, &model) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { @@ -141,7 +141,7 @@ func (r *databaseDataSource) Read( // getDatabaseByNameOrID retrieves a single database by ensuring either a unique ID or name is provided. func (r *databaseDataSource) getDatabaseByNameOrID( ctx context.Context, - model *DataSourceModel, + model *dataSourceModel, projectId, region, instanceId string, diags *diag.Diagnostics, ) (*postgresflexalpha.ListDatabase, error) { diff --git a/stackit/internal/services/postgresflexalpha/database/mapper.go b/stackit/internal/services/postgresflexalpha/database/mapper.go index 61707ade..5785f4b7 100644 --- a/stackit/internal/services/postgresflexalpha/database/mapper.go +++ b/stackit/internal/services/postgresflexalpha/database/mapper.go @@ -9,10 +9,10 @@ import ( "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils" ) -// mapFields maps fields from a ListDatabase API response to a ResourceModel for the data source. +// mapFields maps fields from a ListDatabase API response to a resourceModel for the data source. func mapFields( source *postgresflexalpha.ListDatabase, - model *DataSourceModel, + model *dataSourceModel, region string, ) error { if source == nil { @@ -51,8 +51,8 @@ func mapFields( return nil } -// mapResourceFields maps fields from a ListDatabase API response to a ResourceModel for the resource. -func mapResourceFields(source *postgresflexalpha.ListDatabase, model *ResourceModel) error { +// mapResourceFields maps fields from a ListDatabase API response to a resourceModel for the resource. +func mapResourceFields(source *postgresflexalpha.ListDatabase, model *resourceModel) error { if source == nil { return fmt.Errorf("response is nil") } @@ -80,7 +80,7 @@ func mapResourceFields(source *postgresflexalpha.ListDatabase, model *ResourceMo } // toCreatePayload converts the resource model to an API create payload. -func toCreatePayload(model *ResourceModel) (*postgresflexalpha.CreateDatabaseRequestPayload, error) { +func toCreatePayload(model *resourceModel) (*postgresflexalpha.CreateDatabaseRequestPayload, error) { if model == nil { return nil, fmt.Errorf("nil model") } diff --git a/stackit/internal/services/postgresflexalpha/database/mapper_test.go b/stackit/internal/services/postgresflexalpha/database/mapper_test.go index 57024a5d..a2f18c12 100644 --- a/stackit/internal/services/postgresflexalpha/database/mapper_test.go +++ b/stackit/internal/services/postgresflexalpha/database/mapper_test.go @@ -13,11 +13,11 @@ import ( func TestMapFields(t *testing.T) { type given struct { source *postgresflexalpha.ListDatabase - model *DataSourceModel + model *dataSourceModel region string } type expected struct { - model *DataSourceModel + model *dataSourceModel err bool } @@ -34,11 +34,11 @@ func TestMapFields(t *testing.T) { Name: utils.Ptr("my-db"), Owner: utils.Ptr("\"my-owner\""), }, - model: &DataSourceModel{}, + model: &dataSourceModel{}, region: "eu01", }, expected: expected{ - model: &DataSourceModel{ + model: &dataSourceModel{ DatabaseModel: datasource.DatabaseModel{ Id: types.Int64Value(1), Name: types.StringValue("my-db"), @@ -59,7 +59,7 @@ func TestMapFields(t *testing.T) { Id: utils.Ptr(int64(1)), Name: utils.Ptr("my-db"), }, - model: &DataSourceModel{ + model: &dataSourceModel{ DatabaseModel: datasource.DatabaseModel{ Id: types.Int64Value(1), ProjectId: types.StringValue("my-project"), @@ -69,7 +69,7 @@ func TestMapFields(t *testing.T) { region: "eu01", }, expected: expected{ - model: &DataSourceModel{ + model: &dataSourceModel{ DatabaseModel: datasource.DatabaseModel{ Id: types.Int64Value(1), Name: types.StringValue("my-db"), @@ -86,7 +86,7 @@ func TestMapFields(t *testing.T) { name: "should fail on nil source", given: given{ source: nil, - model: &DataSourceModel{}, + model: &dataSourceModel{}, }, expected: expected{err: true}, }, @@ -94,7 +94,7 @@ func TestMapFields(t *testing.T) { name: "should fail on nil source ID", given: given{ source: &postgresflexalpha.ListDatabase{Id: nil}, - model: &DataSourceModel{}, + model: &dataSourceModel{}, }, expected: expected{err: true}, }, @@ -128,10 +128,10 @@ func TestMapFields(t *testing.T) { func TestMapResourceFields(t *testing.T) { type given struct { source *postgresflexalpha.ListDatabase - model *ResourceModel + model *resourceModel } type expected struct { - model *ResourceModel + model *resourceModel err bool } @@ -148,10 +148,10 @@ func TestMapResourceFields(t *testing.T) { Name: utils.Ptr("my-db"), Owner: utils.Ptr("\"my-owner\""), }, - model: &ResourceModel{}, + model: &resourceModel{}, }, expected: expected{ - model: &ResourceModel{ + model: &resourceModel{ Id: types.Int64Value(1), Name: types.StringValue("my-db"), Owner: types.StringValue("my-owner"), @@ -163,7 +163,7 @@ func TestMapResourceFields(t *testing.T) { name: "should fail on nil source", given: given{ source: nil, - model: &ResourceModel{}, + model: &resourceModel{}, }, expected: expected{err: true}, }, @@ -188,7 +188,7 @@ func TestMapResourceFields(t *testing.T) { func TestToCreatePayload(t *testing.T) { type given struct { - model *ResourceModel + model *resourceModel } type expected struct { payload *postgresflexalpha.CreateDatabaseRequestPayload @@ -203,7 +203,7 @@ func TestToCreatePayload(t *testing.T) { { name: "should convert model to payload", given: given{ - model: &ResourceModel{ + model: &resourceModel{ Name: types.StringValue("my-db"), Owner: types.StringValue("my-owner"), }, diff --git a/stackit/internal/services/postgresflexalpha/database/resource.go b/stackit/internal/services/postgresflexalpha/database/resource.go index 3392f39e..59bde925 100644 --- a/stackit/internal/services/postgresflexalpha/database/resource.go +++ b/stackit/internal/services/postgresflexalpha/database/resource.go @@ -41,8 +41,13 @@ var ( extractErrorMessage = "Extracting identity data: %v" ) -// ResourceModel describes the resource data model. -type ResourceModel = postgresflexalpha2.DatabaseModel +// NewDatabaseResource is a helper function to simplify the provider implementation. +func NewDatabaseResource() resource.Resource { + return &databaseResource{} +} + +// resourceModel describes the resource data model. +type resourceModel = postgresflexalpha2.DatabaseModel // DatabaseResourceIdentityModel describes the resource's identity attributes. type DatabaseResourceIdentityModel struct { @@ -52,11 +57,6 @@ type DatabaseResourceIdentityModel struct { DatabaseID types.Int64 `tfsdk:"database_id"` } -// NewDatabaseResource is a helper function to simplify the provider implementation. -func NewDatabaseResource() resource.Resource { - return &databaseResource{} -} - // databaseResource is the resource implementation. type databaseResource struct { client *postgresflexalpha.APIClient @@ -69,7 +69,7 @@ func (r *databaseResource) ModifyPlan( req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse, ) { // nolint:gocritic // function signature required by Terraform - var configModel ResourceModel + var configModel resourceModel // skip initial empty configuration to avoid follow-up errors if req.Config.Raw.IsNull() { return @@ -79,7 +79,7 @@ func (r *databaseResource) ModifyPlan( return } - var planModel ResourceModel + var planModel resourceModel resp.Diagnostics.Append(req.Plan.Get(ctx, &planModel)...) if resp.Diagnostics.HasError() { return @@ -199,7 +199,7 @@ func (r *databaseResource) Create( req resource.CreateRequest, resp *resource.CreateResponse, ) { // nolint:gocritic // function signature required by Terraform - var model ResourceModel + var model resourceModel diags := req.Plan.Get(ctx, &model) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { @@ -309,7 +309,7 @@ func (r *databaseResource) Read( req resource.ReadRequest, resp *resource.ReadResponse, ) { // nolint:gocritic // function signature required by Terraform - var model ResourceModel + var model resourceModel diags := req.State.Get(ctx, &model) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { @@ -380,7 +380,7 @@ func (r *databaseResource) Update( req resource.UpdateRequest, resp *resource.UpdateResponse, ) { - var model ResourceModel + var model resourceModel diags := req.Plan.Get(ctx, &model) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { @@ -418,7 +418,7 @@ func (r *databaseResource) Update( ctx = tflog.SetField(ctx, "database_id", databaseId) // Retrieve values from state - var stateModel ResourceModel + var stateModel resourceModel diags = req.State.Get(ctx, &stateModel) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { @@ -483,7 +483,7 @@ func (r *databaseResource) Delete( req resource.DeleteRequest, resp *resource.DeleteResponse, ) { // nolint:gocritic // function signature required by Terraform - var model ResourceModel + var model resourceModel diags := req.State.Get(ctx, &model) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { @@ -591,7 +591,7 @@ func (r *databaseResource) ImportState( // extractIdentityData extracts essential identifiers from the resource model, falling back to the identity model. func (r *databaseResource) extractIdentityData( - model ResourceModel, + model resourceModel, identity DatabaseResourceIdentityModel, ) (projectId, region, instanceId string, databaseId int64, err error) { if !model.DatabaseId.IsNull() && !model.DatabaseId.IsUnknown() { diff --git a/stackit/internal/services/postgresflexalpha/flavor/functions_test.go b/stackit/internal/services/postgresflexalpha/flavor/functions_test.go index db8fa3bf..90590716 100644 --- a/stackit/internal/services/postgresflexalpha/flavor/functions_test.go +++ b/stackit/internal/services/postgresflexalpha/flavor/functions_test.go @@ -12,8 +12,8 @@ type mockRequest struct { executeFunc func() (*postgresflex.GetFlavorsResponse, error) } -func (m *mockRequest) Page(_ int64) postgresflex.ApiGetFlavorsRequestRequest { return m } -func (m *mockRequest) Size(_ int64) postgresflex.ApiGetFlavorsRequestRequest { return m } +func (m *mockRequest) Page(_ int32) postgresflex.ApiGetFlavorsRequestRequest { return m } +func (m *mockRequest) Size(_ int32) postgresflex.ApiGetFlavorsRequestRequest { return m } func (m *mockRequest) Sort(_ postgresflex.FlavorSort) postgresflex.ApiGetFlavorsRequestRequest { return m } diff --git a/stackit/internal/services/postgresflexalpha/flavors/datasource.go b/stackit/internal/services/postgresflexalpha/flavors/datasource.go index 26be805b..44483018 100644 --- a/stackit/internal/services/postgresflexalpha/flavors/datasource.go +++ b/stackit/internal/services/postgresflexalpha/flavors/datasource.go @@ -21,12 +21,19 @@ func NewFlavorsDataSource() datasource.DataSource { return &flavorsDataSource{} } +// dataSourceModel maps the data source schema data. +type dataSourceModel = postgresflexalphaGen.FlavorsModel + type flavorsDataSource struct { client *postgresflexalpha.APIClient providerData core.ProviderData } -func (d *flavorsDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { +func (d *flavorsDataSource) Metadata( + _ context.Context, + req datasource.MetadataRequest, + resp *datasource.MetadataResponse, +) { resp.TypeName = req.ProviderTypeName + "_postgresflexalpha_flavors" } @@ -35,7 +42,11 @@ func (d *flavorsDataSource) Schema(ctx context.Context, _ datasource.SchemaReque } // Configure adds the provider configured client to the data source. -func (d *flavorsDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { +func (d *flavorsDataSource) Configure( + ctx context.Context, + req datasource.ConfigureRequest, + resp *datasource.ConfigureResponse, +) { var ok bool d.providerData, ok = conversion.ParseProviderData(ctx, req.ProviderData, &resp.Diagnostics) if !ok { @@ -51,7 +62,7 @@ func (d *flavorsDataSource) Configure(ctx context.Context, req datasource.Config } func (d *flavorsDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { - var data postgresflexalphaGen.FlavorsModel + var data dataSourceModel // Read Terraform configuration data into the model resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) diff --git a/stackit/internal/services/postgresflexalpha/instance/datasource.go b/stackit/internal/services/postgresflexalpha/instance/datasource.go index de0c5c74..95f7904b 100644 --- a/stackit/internal/services/postgresflexalpha/instance/datasource.go +++ b/stackit/internal/services/postgresflexalpha/instance/datasource.go @@ -5,6 +5,7 @@ import ( "fmt" "net/http" + "github.com/hashicorp/terraform-plugin-framework/types" "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/postgresflexalpha" "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion" postgresflexalpha2 "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/instance/datasources_gen" @@ -26,6 +27,12 @@ func NewInstanceDataSource() datasource.DataSource { return &instanceDataSource{} } +// dataSourceModel maps the data source schema data. +type dataSourceModel struct { + postgresflexalpha2.InstanceModel + TerraformID types.String `tfsdk:"id"` +} + // instanceDataSource is the data source implementation. type instanceDataSource struct { client *postgresflexalpha.APIClient @@ -33,12 +40,20 @@ type instanceDataSource struct { } // Metadata returns the data source type name. -func (r *instanceDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { +func (r *instanceDataSource) Metadata( + _ context.Context, + req datasource.MetadataRequest, + resp *datasource.MetadataResponse, +) { resp.TypeName = req.ProviderTypeName + "_postgresflexalpha_instance" } // Configure adds the provider configured client to the data source. -func (r *instanceDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { +func (r *instanceDataSource) Configure( + ctx context.Context, + req datasource.ConfigureRequest, + resp *datasource.ConfigureResponse, +) { var ok bool r.providerData, ok = conversion.ParseProviderData(ctx, req.ProviderData, &resp.Diagnostics) if !ok { @@ -59,8 +74,12 @@ func (r *instanceDataSource) Schema(ctx context.Context, _ datasource.SchemaRequ } // Read refreshes the Terraform state with the latest data. -func (r *instanceDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { // nolint:gocritic // function signature required by Terraform - var model postgresflexalpha2.InstanceModel +func (r *instanceDataSource) Read( + ctx context.Context, + req datasource.ReadRequest, + resp *datasource.ReadResponse, +) { // nolint:gocritic // function signature required by Terraform + var model dataSourceModel diags := req.Config.Get(ctx, &model) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { diff --git a/stackit/internal/services/postgresflexalpha/instance/functions.go b/stackit/internal/services/postgresflexalpha/instance/functions.go index dc29abe4..862f88ff 100644 --- a/stackit/internal/services/postgresflexalpha/instance/functions.go +++ b/stackit/internal/services/postgresflexalpha/instance/functions.go @@ -14,26 +14,32 @@ import ( "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils" ) -func mapGetInstanceResponseToModel(ctx context.Context, m *postgresflexalpharesource.InstanceModel, resp *postgresflex.GetInstanceResponse) error { - tflog.Debug(ctx, ">>>> MSH DEBUG <<<<", map[string]interface{}{ - "id": m.Id.ValueString(), - "instance_id": m.InstanceId.ValueString(), - "backup_schedule": m.BackupSchedule.ValueString(), - "flavor_id": m.FlavorId.ValueString(), - "encryption.kek_key_id": m.Encryption.KekKeyId.ValueString(), - "encryption.kek_key_ring_id": m.Encryption.KekKeyRingId.ValueString(), - "encryption.kek_key_version": m.Encryption.KekKeyVersion.ValueString(), - "encryption.service_account": m.Encryption.ServiceAccount.ValueString(), - "is_deletable": m.IsDeletable.ValueBool(), - "name": m.Name.ValueString(), - "status": m.Status.ValueString(), - "retention_days": m.RetentionDays.ValueInt64(), - "replicas": m.Replicas.ValueInt64(), - "network.instance_address": m.Network.InstanceAddress.ValueString(), - "network.router_address": m.Network.RouterAddress.ValueString(), - "version": m.Version.ValueString(), - "network.acl": m.Network.Acl.String(), - }) +func mapGetInstanceResponseToModel( + ctx context.Context, + m *postgresflexalpharesource.InstanceModel, + resp *postgresflex.GetInstanceResponse, +) error { + tflog.Debug( + ctx, ">>>> MSH DEBUG <<<<", map[string]interface{}{ + "id": m.Id.ValueString(), + "instance_id": m.InstanceId.ValueString(), + "backup_schedule": m.BackupSchedule.ValueString(), + "flavor_id": m.FlavorId.ValueString(), + "encryption.kek_key_id": m.Encryption.KekKeyId.ValueString(), + "encryption.kek_key_ring_id": m.Encryption.KekKeyRingId.ValueString(), + "encryption.kek_key_version": m.Encryption.KekKeyVersion.ValueString(), + "encryption.service_account": m.Encryption.ServiceAccount.ValueString(), + "is_deletable": m.IsDeletable.ValueBool(), + "name": m.Name.ValueString(), + "status": m.Status.ValueString(), + "retention_days": m.RetentionDays.ValueInt64(), + "replicas": m.Replicas.ValueInt64(), + "network.instance_address": m.Network.InstanceAddress.ValueString(), + "network.router_address": m.Network.RouterAddress.ValueString(), + "version": m.Version.ValueString(), + "network.acl": m.Network.Acl.String(), + }, + ) m.BackupSchedule = types.StringValue(resp.GetBackupSchedule()) m.Encryption = postgresflexalpharesource.NewEncryptionValueNull() @@ -61,7 +67,11 @@ func mapGetInstanceResponseToModel(ctx context.Context, m *postgresflexalphareso m.FlavorId = types.StringValue(resp.GetFlavorId()) if m.Id.IsNull() || m.Id.IsUnknown() { - m.Id = utils.BuildInternalTerraformId(m.ProjectId.ValueString(), m.Region.ValueString(), m.InstanceId.ValueString()) + m.Id = utils.BuildInternalTerraformId( + m.ProjectId.ValueString(), + m.Region.ValueString(), + m.InstanceId.ValueString(), + ) } m.InstanceId = types.StringPointerValue(resp.Id) @@ -121,7 +131,11 @@ func mapGetInstanceResponseToModel(ctx context.Context, m *postgresflexalphareso return nil } -func mapGetDataInstanceResponseToModel(ctx context.Context, m *postgresflexalphadatasource.InstanceModel, resp *postgresflex.GetInstanceResponse) error { +func mapGetDataInstanceResponseToModel( + ctx context.Context, + m *dataSourceModel, + resp *postgresflex.GetInstanceResponse, +) error { m.BackupSchedule = types.StringValue(resp.GetBackupSchedule()) handleEncryption(m, resp) m.ConnectionInfo.Host = types.StringValue(resp.ConnectionInfo.GetHost()) @@ -155,7 +169,7 @@ func mapGetDataInstanceResponseToModel(ctx context.Context, m *postgresflexalpha return nil } -func handleNetwork(ctx context.Context, m *postgresflexalphadatasource.InstanceModel, resp *postgresflex.GetInstanceResponse) error { +func handleNetwork(ctx context.Context, m *dataSourceModel, resp *postgresflex.GetInstanceResponse) error { netAcl, diags := types.ListValueFrom(ctx, types.StringType, resp.Network.GetAcl()) if diags.HasError() { return fmt.Errorf("failed converting network acl from response") @@ -187,7 +201,7 @@ func handleNetwork(ctx context.Context, m *postgresflexalphadatasource.InstanceM return nil } -func handleEncryption(m *postgresflexalphadatasource.InstanceModel, resp *postgresflex.GetInstanceResponse) { +func handleEncryption(m *dataSourceModel, resp *postgresflex.GetInstanceResponse) { keyId := "" if keyIdVal, ok := resp.Encryption.GetKekKeyIdOk(); ok { keyId = keyIdVal diff --git a/stackit/internal/services/postgresflexalpha/instance/resource.go b/stackit/internal/services/postgresflexalpha/instance/resource.go index f061f8bf..d3680c47 100644 --- a/stackit/internal/services/postgresflexalpha/instance/resource.go +++ b/stackit/internal/services/postgresflexalpha/instance/resource.go @@ -23,8 +23,6 @@ import ( wait "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/wait/postgresflexalpha" ) -const packageName = "postgresflexalpha" - // Ensure the implementation satisfies the expected interfaces. var ( _ resource.Resource = &instanceResource{} @@ -40,11 +38,8 @@ func NewInstanceResource() resource.Resource { return &instanceResource{} } -// instanceResource is the resource implementation. -type instanceResource struct { - client *postgresflex.APIClient - providerData core.ProviderData -} +// resourceModel describes the resource data model. +type resourceModel = postgresflexalpha.InstanceModel type InstanceResourceIdentityModel struct { ProjectID types.String `tfsdk:"project_id"` @@ -52,8 +47,18 @@ type InstanceResourceIdentityModel struct { InstanceID types.String `tfsdk:"instance_id"` } -func (r *instanceResource) ValidateConfig(ctx context.Context, req resource.ValidateConfigRequest, resp *resource.ValidateConfigResponse) { - var data postgresflexalpha.InstanceModel +// instanceResource is the resource implementation. +type instanceResource struct { + client *postgresflex.APIClient + providerData core.ProviderData +} + +func (r *instanceResource) ValidateConfig( + ctx context.Context, + req resource.ValidateConfigRequest, + resp *resource.ValidateConfigResponse, +) { + var data resourceModel resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) if resp.Diagnostics.HasError() { @@ -72,7 +77,11 @@ func (r *instanceResource) ValidateConfig(ctx context.Context, req resource.Vali // ModifyPlan implements resource.ResourceWithModifyPlan. // Use the modifier to set the effective region in the current plan. -func (r *instanceResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { // nolint:gocritic // function signature required by Terraform +func (r *instanceResource) ModifyPlan( + ctx context.Context, + req resource.ModifyPlanRequest, + resp *resource.ModifyPlanResponse, +) { // nolint:gocritic // function signature required by Terraform var configModel postgresflexalpha.InstanceModel // skip initial empty configuration to avoid follow-up errors if req.Config.Raw.IsNull() { @@ -149,7 +158,11 @@ func (r *instanceResource) Schema(ctx context.Context, _ resource.SchemaRequest, resp.Schema = schema } -func (r *instanceResource) IdentitySchema(_ context.Context, _ resource.IdentitySchemaRequest, resp *resource.IdentitySchemaResponse) { +func (r *instanceResource) IdentitySchema( + _ context.Context, + _ resource.IdentitySchemaRequest, + resp *resource.IdentitySchemaResponse, +) { resp.IdentitySchema = identityschema.Schema{ Attributes: map[string]identityschema.Attribute{ "project_id": identityschema.StringAttribute{ @@ -171,7 +184,7 @@ func (r *instanceResource) Create( req resource.CreateRequest, resp *resource.CreateResponse, ) { // nolint:gocritic // function signature required by Terraform - var model postgresflexalpha.InstanceModel + var model resourceModel diags := req.Plan.Get(ctx, &model) resp.Diagnostics.Append(diags...) @@ -201,7 +214,11 @@ func (r *instanceResource) Create( payload := modelToCreateInstancePayload(netAcl, model, replVal) // Create new instance - createResp, err := r.client.CreateInstanceRequest(ctx, projectId, region).CreateInstanceRequestPayload(payload).Execute() + createResp, err := r.client.CreateInstanceRequest( + ctx, + projectId, + region, + ).CreateInstanceRequestPayload(payload).Execute() if err != nil { core.LogAndAddError(ctx, &resp.Diagnostics, "error creating instance", fmt.Sprintf("Calling API: %v", err)) return @@ -227,13 +244,23 @@ func (r *instanceResource) Create( waitResp, err := wait.CreateInstanceWaitHandler(ctx, r.client, projectId, region, instanceId).WaitWithContext(ctx) if err != nil { - core.LogAndAddError(ctx, &resp.Diagnostics, "Error creating instance", fmt.Sprintf("Wait handler error: %v", err)) + core.LogAndAddError( + ctx, + &resp.Diagnostics, + "Error creating instance", + fmt.Sprintf("Wait handler error: %v", err), + ) return } err = mapGetInstanceResponseToModel(ctx, &model, waitResp) if err != nil { - core.LogAndAddError(ctx, &resp.Diagnostics, "Error creating instance", fmt.Sprintf("Error creating model: %v", err)) + core.LogAndAddError( + ctx, + &resp.Diagnostics, + "Error creating instance", + fmt.Sprintf("Error creating model: %v", err), + ) return } @@ -246,7 +273,11 @@ func (r *instanceResource) Create( tflog.Info(ctx, "Postgres Flex instance created") } -func modelToCreateInstancePayload(netAcl []string, model postgresflexalpha.InstanceModel, replVal int32) postgresflex.CreateInstanceRequestPayload { +func modelToCreateInstancePayload( + netAcl []string, + model postgresflexalpha.InstanceModel, + replVal int32, +) postgresflex.CreateInstanceRequestPayload { var enc *postgresflex.InstanceEncryption if !model.Encryption.IsNull() && !model.Encryption.IsUnknown() { enc = &postgresflex.InstanceEncryption{ @@ -279,10 +310,14 @@ func modelToCreateInstancePayload(netAcl []string, model postgresflexalpha.Insta } // Read refreshes the Terraform state with the latest data. -func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { // nolint:gocritic // function signature required by Terraform +func (r *instanceResource) Read( + ctx context.Context, + req resource.ReadRequest, + resp *resource.ReadResponse, +) { // nolint:gocritic // function signature required by Terraform functionErrorSummary := "read instance failed" - var model postgresflexalpha.InstanceModel + var model resourceModel diags := req.State.Get(ctx, &model) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { @@ -371,7 +406,12 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r err = mapGetInstanceResponseToModel(ctx, &model, instanceResp) if err != nil { - core.LogAndAddError(ctx, &resp.Diagnostics, functionErrorSummary, fmt.Sprintf("Processing API payload: %v", err)) + core.LogAndAddError( + ctx, + &resp.Diagnostics, + functionErrorSummary, + fmt.Sprintf("Processing API payload: %v", err), + ) return } @@ -396,8 +436,12 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r } // Update updates the resource and sets the updated Terraform state on success. -func (r *instanceResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { // nolint:gocritic // function signature required by Terraform - var model postgresflexalpha.InstanceModel +func (r *instanceResource) Update( + ctx context.Context, + req resource.UpdateRequest, + resp *resource.UpdateResponse, +) { // nolint:gocritic // function signature required by Terraform + var model resourceModel diags := req.Plan.Get(ctx, &model) resp.Diagnostics.Append(diags...) @@ -475,15 +519,31 @@ func (r *instanceResource) Update(ctx context.Context, req resource.UpdateReques ctx = core.LogResponse(ctx) - waitResp, err := wait.PartialUpdateInstanceWaitHandler(ctx, r.client, projectId, region, instanceId).WaitWithContext(ctx) + waitResp, err := wait.PartialUpdateInstanceWaitHandler( + ctx, + r.client, + projectId, + region, + instanceId, + ).WaitWithContext(ctx) if err != nil { - core.LogAndAddError(ctx, &resp.Diagnostics, "Error updating instance", fmt.Sprintf("Instance update waiting: %v", err)) + core.LogAndAddError( + ctx, + &resp.Diagnostics, + "Error updating instance", + fmt.Sprintf("Instance update waiting: %v", err), + ) return } err = mapGetInstanceResponseToModel(ctx, &model, waitResp) if err != nil { - core.LogAndAddError(ctx, &resp.Diagnostics, "Error updating instance", fmt.Sprintf("Processing API payload: %v", err)) + core.LogAndAddError( + ctx, + &resp.Diagnostics, + "Error updating instance", + fmt.Sprintf("Processing API payload: %v", err), + ) return } @@ -496,8 +556,12 @@ func (r *instanceResource) Update(ctx context.Context, req resource.UpdateReques } // Delete deletes the resource and removes the Terraform state on success. -func (r *instanceResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { // nolint:gocritic // function signature required by Terraform - var model postgresflexalpha.InstanceModel +func (r *instanceResource) Delete( + ctx context.Context, + req resource.DeleteRequest, + resp *resource.DeleteResponse, +) { // nolint:gocritic // function signature required by Terraform + var model resourceModel diags := req.State.Get(ctx, &model) resp.Diagnostics.Append(diags...) @@ -538,16 +602,24 @@ func (r *instanceResource) Delete(ctx context.Context, req resource.DeleteReques // ImportState imports a resource into the Terraform state on success. // The expected format of the resource import identifier is: project_id,region,instance_id -func (r *instanceResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { +func (r *instanceResource) ImportState( + ctx context.Context, + req resource.ImportStateRequest, + resp *resource.ImportStateResponse, +) { ctx = core.InitProviderContext(ctx) if req.ID != "" { idParts := strings.Split(req.ID, core.Separator) if len(idParts) != 3 || idParts[0] == "" || idParts[1] == "" || idParts[2] == "" { - core.LogAndAddError(ctx, &resp.Diagnostics, + core.LogAndAddError( + ctx, &resp.Diagnostics, "Error importing instance", - fmt.Sprintf("Expected import identifier with format: [project_id],[region],[instance_id] Got: %q", req.ID), + fmt.Sprintf( + "Expected import identifier with format: [project_id],[region],[instance_id] Got: %q", + req.ID, + ), ) return } @@ -573,10 +645,23 @@ func (r *instanceResource) ImportState(ctx context.Context, req resource.ImportS identityData.Region.ValueString(), identityData.InstanceID.ValueString(), ), - )...) - resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("project_id"), identityData.ProjectID.ValueString())...) + )..., + ) + resp.Diagnostics.Append( + resp.State.SetAttribute( + ctx, + path.Root("project_id"), + identityData.ProjectID.ValueString(), + )..., + ) resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("region"), identityData.Region.ValueString())...) - resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("instance_id"), identityData.InstanceID.ValueString())...) + resp.Diagnostics.Append( + resp.State.SetAttribute( + ctx, + path.Root("instance_id"), + identityData.InstanceID.ValueString(), + )..., + ) tflog.Info(ctx, "Postgres Flex instance state imported") } diff --git a/stackit/internal/services/postgresflexalpha/user/datasource.go b/stackit/internal/services/postgresflexalpha/user/datasource.go index ac5c30bf..b0cf9d3b 100644 --- a/stackit/internal/services/postgresflexalpha/user/datasource.go +++ b/stackit/internal/services/postgresflexalpha/user/datasource.go @@ -25,17 +25,17 @@ var ( _ datasource.DataSource = &userDataSource{} ) -// DataSourceModel maps the data source schema data. -type DataSourceModel struct { - postgresflexalpha.UserModel - TerraformID types.String `tfsdk:"id"` -} - // NewUserDataSource is a helper function to simplify the provider implementation. func NewUserDataSource() datasource.DataSource { return &userDataSource{} } +// dataSourceModel maps the data source schema data. +type dataSourceModel struct { + postgresflexalpha.UserModel + TerraformID types.String `tfsdk:"id"` +} + // userDataSource is the data source implementation. type userDataSource struct { client *postgresflex.APIClient @@ -90,7 +90,7 @@ func (r *userDataSource) Read( req datasource.ReadRequest, resp *datasource.ReadResponse, ) { // nolint:gocritic // function signature required by Terraform - var model DataSourceModel + var model dataSourceModel diags := req.Config.Get(ctx, &model) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { diff --git a/stackit/internal/services/postgresflexalpha/user/mapper.go b/stackit/internal/services/postgresflexalpha/user/mapper.go index 3eb38d34..2445cb16 100644 --- a/stackit/internal/services/postgresflexalpha/user/mapper.go +++ b/stackit/internal/services/postgresflexalpha/user/mapper.go @@ -13,7 +13,7 @@ import ( ) // mapDataSourceFields maps API response to data source model, preserving existing ID. -func mapDataSourceFields(userResp *postgresflex.GetUserResponse, model *DataSourceModel, region string) error { +func mapDataSourceFields(userResp *postgresflex.GetUserResponse, model *dataSourceModel, region string) error { if userResp == nil { return fmt.Errorf("response is nil") } @@ -68,7 +68,7 @@ func toPayloadRoles(roles *[]string) *[]postgresflex.UserRole { } // toUpdatePayload creates an API update payload from the resource model. -func toUpdatePayload(model *ResourceModel, roles *[]string) ( +func toUpdatePayload(model *resourceModel, roles *[]string) ( *postgresflex.UpdateUserRequestPayload, error, ) { @@ -86,7 +86,7 @@ func toUpdatePayload(model *ResourceModel, roles *[]string) ( } // toCreatePayload creates an API create payload from the resource model. -func toCreatePayload(model *ResourceModel, roles *[]string) (*postgresflex.CreateUserRequestPayload, error) { +func toCreatePayload(model *resourceModel, roles *[]string) (*postgresflex.CreateUserRequestPayload, error) { if model == nil { return nil, fmt.Errorf("nil model") } @@ -101,7 +101,7 @@ func toCreatePayload(model *ResourceModel, roles *[]string) (*postgresflex.Creat } // mapResourceFields maps API response to the resource model, preserving existing ID. -func mapResourceFields(userResp *postgresflex.GetUserResponse, model *ResourceModel, region string) error { +func mapResourceFields(userResp *postgresflex.GetUserResponse, model *resourceModel, region string) error { if userResp == nil { return fmt.Errorf("response is nil") } @@ -118,9 +118,7 @@ func mapResourceFields(userResp *postgresflex.GetUserResponse, model *ResourceMo } else { return fmt.Errorf("user id not present") } - model.TerraformID = utils.BuildInternalTerraformId( - model.ProjectId.ValueString(), region, model.InstanceId.ValueString(), strconv.FormatInt(userId, 10), - ) + model.Id = types.Int64Value(userId) model.UserId = types.Int64Value(userId) model.Name = types.StringPointerValue(user.Name) diff --git a/stackit/internal/services/postgresflexalpha/user/mapper_test.go b/stackit/internal/services/postgresflexalpha/user/mapper_test.go index a48c62ee..6eeff9f0 100644 --- a/stackit/internal/services/postgresflexalpha/user/mapper_test.go +++ b/stackit/internal/services/postgresflexalpha/user/mapper_test.go @@ -9,7 +9,6 @@ import ( "github.com/stackitcloud/stackit-sdk-go/core/utils" postgresflex "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/postgresflexalpha" data "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/user/datasources_gen" - resource "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/user/resources_gen" ) func TestMapDataSourceFields(t *testing.T) { @@ -18,14 +17,14 @@ func TestMapDataSourceFields(t *testing.T) { description string input *postgresflex.GetUserResponse region string - expected DataSourceModel + expected dataSourceModel isValid bool }{ { "default_values", &postgresflex.GetUserResponse{}, testRegion, - DataSourceModel{ + dataSourceModel{ UserModel: data.UserModel{ Id: types.Int64Value(1), UserId: types.Int64Value(1), @@ -51,7 +50,7 @@ func TestMapDataSourceFields(t *testing.T) { Name: utils.Ptr("username"), }, testRegion, - DataSourceModel{ + dataSourceModel{ UserModel: data.UserModel{ Id: types.Int64Value(1), @@ -84,7 +83,7 @@ func TestMapDataSourceFields(t *testing.T) { Status: utils.Ptr("status"), }, testRegion, - DataSourceModel{ + dataSourceModel{ UserModel: data.UserModel{ Id: types.Int64Value(1), UserId: types.Int64Value(1), @@ -103,28 +102,28 @@ func TestMapDataSourceFields(t *testing.T) { "nil_response", nil, testRegion, - DataSourceModel{}, + dataSourceModel{}, false, }, { "nil_response_2", &postgresflex.GetUserResponse{}, testRegion, - DataSourceModel{}, + dataSourceModel{}, false, }, { "no_resource_id", &postgresflex.GetUserResponse{}, testRegion, - DataSourceModel{}, + dataSourceModel{}, false, }, } for _, tt := range tests { t.Run( tt.description, func(t *testing.T) { - state := &DataSourceModel{ + state := &dataSourceModel{ UserModel: data.UserModel{ ProjectId: tt.expected.ProjectId, InstanceId: tt.expected.InstanceId, @@ -155,7 +154,7 @@ func TestMapFieldsCreate(t *testing.T) { description string input *postgresflex.GetUserResponse region string - expected ResourceModel + expected resourceModel isValid bool }{ { @@ -164,19 +163,16 @@ func TestMapFieldsCreate(t *testing.T) { Id: utils.Ptr(int64(1)), }, testRegion, - ResourceModel{ - UserModel: resource.UserModel{ - UserId: types.Int64Value(1), - InstanceId: types.StringValue("iid"), - ProjectId: types.StringValue("pid"), - Name: types.StringNull(), - Roles: types.List(types.SetNull(types.StringType)), - Password: types.StringNull(), - Region: types.StringValue(testRegion), - Status: types.StringNull(), - ConnectionString: types.StringNull(), - }, - TerraformID: types.StringValue("pid,region,iid,1"), + resourceModel{ + UserId: types.Int64Value(1), + InstanceId: types.StringValue("iid"), + ProjectId: types.StringValue("pid"), + Name: types.StringNull(), + Roles: types.List(types.SetNull(types.StringType)), + Password: types.StringNull(), + Region: types.StringValue(testRegion), + Status: types.StringNull(), + ConnectionString: types.StringNull(), }, true, }, @@ -188,19 +184,16 @@ func TestMapFieldsCreate(t *testing.T) { Status: utils.Ptr("status"), }, testRegion, - ResourceModel{ - UserModel: resource.UserModel{ - UserId: types.Int64Value(1), - InstanceId: types.StringValue("iid"), - ProjectId: types.StringValue("pid"), - Name: types.StringValue("username"), - Roles: types.List(types.SetNull(types.StringType)), - Password: types.StringNull(), - Region: types.StringValue(testRegion), - Status: types.StringValue("status"), - ConnectionString: types.StringValue("connection_string"), - }, - TerraformID: types.StringValue("pid,region,iid,1"), + resourceModel{ + UserId: types.Int64Value(1), + InstanceId: types.StringValue("iid"), + ProjectId: types.StringValue("pid"), + Name: types.StringValue("username"), + Roles: types.List(types.SetNull(types.StringType)), + Password: types.StringNull(), + Region: types.StringValue(testRegion), + Status: types.StringValue("status"), + ConnectionString: types.StringValue("connection_string"), }, true, }, @@ -212,19 +205,16 @@ func TestMapFieldsCreate(t *testing.T) { Status: nil, }, testRegion, - ResourceModel{ - UserModel: resource.UserModel{ - UserId: types.Int64Value(1), - InstanceId: types.StringValue("iid"), - ProjectId: types.StringValue("pid"), - Name: types.StringNull(), - Roles: types.List(types.SetNull(types.StringType)), - Password: types.StringNull(), - Region: types.StringValue(testRegion), - Status: types.StringNull(), - ConnectionString: types.StringNull(), - }, - TerraformID: types.StringValue("pid,region,iid,1"), + resourceModel{ + UserId: types.Int64Value(1), + InstanceId: types.StringValue("iid"), + ProjectId: types.StringValue("pid"), + Name: types.StringNull(), + Roles: types.List(types.SetNull(types.StringType)), + Password: types.StringNull(), + Region: types.StringValue(testRegion), + Status: types.StringNull(), + ConnectionString: types.StringNull(), }, true, }, @@ -232,32 +222,30 @@ func TestMapFieldsCreate(t *testing.T) { "nil_response", nil, testRegion, - ResourceModel{}, + resourceModel{}, false, }, { "nil_response_2", &postgresflex.GetUserResponse{}, testRegion, - ResourceModel{}, + resourceModel{}, false, }, { "no_resource_id", &postgresflex.GetUserResponse{}, testRegion, - ResourceModel{}, + resourceModel{}, false, }, } for _, tt := range tests { t.Run( tt.description, func(t *testing.T) { - state := &ResourceModel{ - UserModel: resource.UserModel{ - ProjectId: tt.expected.ProjectId, - InstanceId: tt.expected.InstanceId, - }, + state := &resourceModel{ + ProjectId: tt.expected.ProjectId, + InstanceId: tt.expected.InstanceId, } err := mapResourceFields(tt.input, state, tt.region) @@ -284,7 +272,7 @@ func TestMapFields(t *testing.T) { description string input *postgresflex.GetUserResponse region string - expected ResourceModel + expected resourceModel isValid bool }{ { @@ -293,19 +281,16 @@ func TestMapFields(t *testing.T) { Id: utils.Ptr(int64(1)), }, testRegion, - ResourceModel{ - UserModel: resource.UserModel{ - Id: types.Int64Value(1), - UserId: types.Int64Value(int64(1)), - InstanceId: types.StringValue("iid"), - ProjectId: types.StringValue("pid"), - Name: types.StringNull(), - Roles: types.List(types.SetNull(types.StringType)), - Region: types.StringValue(testRegion), - Status: types.StringNull(), - ConnectionString: types.StringNull(), - }, - TerraformID: types.StringValue("pid,region,iid,1"), + resourceModel{ + Id: types.Int64Value(1), + UserId: types.Int64Value(int64(1)), + InstanceId: types.StringValue("iid"), + ProjectId: types.StringValue("pid"), + Name: types.StringNull(), + Roles: types.List(types.SetNull(types.StringType)), + Region: types.StringValue(testRegion), + Status: types.StringNull(), + ConnectionString: types.StringNull(), }, true, }, @@ -321,27 +306,24 @@ func TestMapFields(t *testing.T) { Name: utils.Ptr("username"), }, testRegion, - ResourceModel{ - UserModel: resource.UserModel{ - Id: types.Int64Value(1), - UserId: types.Int64Value(1), - InstanceId: types.StringValue("iid"), - ProjectId: types.StringValue("pid"), - Name: types.StringValue("username"), - Roles: types.List( - types.SetValueMust( - types.StringType, []attr.Value{ - types.StringValue("role_1"), - types.StringValue("role_2"), - types.StringValue(""), - }, - ), + resourceModel{ + Id: types.Int64Value(1), + UserId: types.Int64Value(1), + InstanceId: types.StringValue("iid"), + ProjectId: types.StringValue("pid"), + Name: types.StringValue("username"), + Roles: types.List( + types.SetValueMust( + types.StringType, []attr.Value{ + types.StringValue("role_1"), + types.StringValue("role_2"), + types.StringValue(""), + }, ), - Region: types.StringValue(testRegion), - Status: types.StringNull(), - ConnectionString: types.StringNull(), - }, - TerraformID: types.StringValue("pid,region,iid,1"), + ), + Region: types.StringValue(testRegion), + Status: types.StringNull(), + ConnectionString: types.StringNull(), }, true, }, @@ -352,19 +334,16 @@ func TestMapFields(t *testing.T) { Name: nil, }, testRegion, - ResourceModel{ - UserModel: resource.UserModel{ - Id: types.Int64Value(1), - UserId: types.Int64Value(1), - InstanceId: types.StringValue("iid"), - ProjectId: types.StringValue("pid"), - Name: types.StringNull(), - Roles: types.List(types.SetNull(types.StringType)), - Region: types.StringValue(testRegion), - Status: types.StringNull(), - ConnectionString: types.StringNull(), - }, - TerraformID: types.StringValue("pid,region,iid,1"), + resourceModel{ + Id: types.Int64Value(1), + UserId: types.Int64Value(1), + InstanceId: types.StringValue("iid"), + ProjectId: types.StringValue("pid"), + Name: types.StringNull(), + Roles: types.List(types.SetNull(types.StringType)), + Region: types.StringValue(testRegion), + Status: types.StringNull(), + ConnectionString: types.StringNull(), }, true, }, @@ -372,32 +351,30 @@ func TestMapFields(t *testing.T) { "nil_response", nil, testRegion, - ResourceModel{}, + resourceModel{}, false, }, { "nil_response_2", &postgresflex.GetUserResponse{}, testRegion, - ResourceModel{}, + resourceModel{}, false, }, { "no_resource_id", &postgresflex.GetUserResponse{}, testRegion, - ResourceModel{}, + resourceModel{}, false, }, } for _, tt := range tests { t.Run( tt.description, func(t *testing.T) { - state := &ResourceModel{ - UserModel: resource.UserModel{ - ProjectId: tt.expected.ProjectId, - InstanceId: tt.expected.InstanceId, - }, + state := &resourceModel{ + ProjectId: tt.expected.ProjectId, + InstanceId: tt.expected.InstanceId, } err := mapResourceFields(tt.input, state, tt.region) if !tt.isValid && err == nil { @@ -420,14 +397,14 @@ func TestMapFields(t *testing.T) { func TestToCreatePayload(t *testing.T) { tests := []struct { description string - input *ResourceModel + input *resourceModel inputRoles *[]string expected *postgresflex.CreateUserRequestPayload isValid bool }{ { "default_values", - &ResourceModel{}, + &resourceModel{}, &[]string{}, &postgresflex.CreateUserRequestPayload{ Name: nil, @@ -437,10 +414,8 @@ func TestToCreatePayload(t *testing.T) { }, { "simple_values", - &ResourceModel{ - UserModel: resource.UserModel{ - Name: types.StringValue("username"), - }, + &resourceModel{ + Name: types.StringValue("username"), }, &[]string{ "role_1", @@ -457,10 +432,8 @@ func TestToCreatePayload(t *testing.T) { }, { "null_fields_and_int_conversions", - &ResourceModel{ - UserModel: resource.UserModel{ - Name: types.StringNull(), - }, + &resourceModel{ + Name: types.StringNull(), }, &[]string{ "", @@ -482,7 +455,7 @@ func TestToCreatePayload(t *testing.T) { }, { "nil_roles", - &ResourceModel{}, + &resourceModel{}, nil, nil, false, @@ -512,14 +485,14 @@ func TestToCreatePayload(t *testing.T) { func TestToUpdatePayload(t *testing.T) { tests := []struct { description string - input *ResourceModel + input *resourceModel inputRoles *[]string expected *postgresflex.UpdateUserRequestPayload isValid bool }{ { "default_values", - &ResourceModel{}, + &resourceModel{}, &[]string{}, &postgresflex.UpdateUserRequestPayload{ Roles: &[]postgresflex.UserRole{}, @@ -528,10 +501,8 @@ func TestToUpdatePayload(t *testing.T) { }, { "default_values", - &ResourceModel{ - UserModel: resource.UserModel{ - Name: types.StringValue("username"), - }, + &resourceModel{ + Name: types.StringValue("username"), }, &[]string{ "role_1", @@ -548,10 +519,8 @@ func TestToUpdatePayload(t *testing.T) { }, { "null_fields_and_int_conversions", - &ResourceModel{ - UserModel: resource.UserModel{ - Name: types.StringNull(), - }, + &resourceModel{ + Name: types.StringNull(), }, &[]string{ "", @@ -572,7 +541,7 @@ func TestToUpdatePayload(t *testing.T) { }, { "nil_roles", - &ResourceModel{}, + &resourceModel{}, nil, nil, false, diff --git a/stackit/internal/services/postgresflexalpha/user/resource.go b/stackit/internal/services/postgresflexalpha/user/resource.go index e459f130..c1a11495 100644 --- a/stackit/internal/services/postgresflexalpha/user/resource.go +++ b/stackit/internal/services/postgresflexalpha/user/resource.go @@ -41,12 +41,14 @@ var ( extractErrorMessage = "Extracting identity data: %v" ) -// ResourceModel represents the Terraform resource state for a PostgreSQL Flex user. -type ResourceModel struct { - postgresflexalpha.UserModel - TerraformID types.String `tfsdk:"id"` +// NewUserResource is a helper function to simplify the provider implementation. +func NewUserResource() resource.Resource { + return &userResource{} } +// resourceModel represents the Terraform resource state for a PostgreSQL Flex user. +type resourceModel = postgresflexalpha.UserModel + // UserResourceIdentityModel describes the resource's identity attributes. type UserResourceIdentityModel struct { ProjectID types.String `tfsdk:"project_id"` @@ -55,11 +57,6 @@ type UserResourceIdentityModel struct { UserID types.Int64 `tfsdk:"database_id"` } -// NewUserResource is a helper function to simplify the provider implementation. -func NewUserResource() resource.Resource { - return &userResource{} -} - // userResource implements the resource handling for a PostgreSQL Flex user. type userResource struct { client *postgresflex.APIClient @@ -73,7 +70,7 @@ func (r *userResource) ModifyPlan( req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse, ) { // nolint:gocritic // function signature required by Terraform - var configModel ResourceModel + var configModel resourceModel // skip initial empty configuration to avoid follow-up errors if req.Config.Raw.IsNull() { return @@ -83,7 +80,7 @@ func (r *userResource) ModifyPlan( return } - var planModel ResourceModel + var planModel resourceModel resp.Diagnostics.Append(req.Plan.Get(ctx, &planModel)...) if resp.Diagnostics.HasError() { return @@ -153,7 +150,7 @@ func (r *userResource) Create( req resource.CreateRequest, resp *resource.CreateResponse, ) { // nolint:gocritic // function signature required by Terraform - var model ResourceModel + var model resourceModel diags := req.Plan.Get(ctx, &model) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { @@ -252,7 +249,7 @@ func (r *userResource) Read( req resource.ReadRequest, resp *resource.ReadResponse, ) { // nolint:gocritic // function signature required by Terraform - var model ResourceModel + var model resourceModel diags := req.State.Get(ctx, &model) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { @@ -312,7 +309,7 @@ func (r *userResource) Update( req resource.UpdateRequest, resp *resource.UpdateResponse, ) { // nolint:gocritic // function signature required by Terraform - var model ResourceModel + var model resourceModel diags := req.Plan.Get(ctx, &model) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { @@ -342,7 +339,7 @@ func (r *userResource) Update( ctx = core.InitProviderContext(ctx) // Retrieve values from state - var stateModel ResourceModel + var stateModel resourceModel diags = req.State.Get(ctx, &stateModel) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { @@ -414,7 +411,7 @@ func (r *userResource) Delete( req resource.DeleteRequest, resp *resource.DeleteResponse, ) { // nolint:gocritic // function signature required by Terraform - var model ResourceModel + var model resourceModel diags := req.State.Get(ctx, &model) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { @@ -559,7 +556,7 @@ func (r *userResource) ImportState( tflog.Info(ctx, "postgresflexalpha user state imported") } -func mapFields(userResp *postgresflex.GetUserResponse, model *ResourceModel, region string) error { +func mapFields(userResp *postgresflex.GetUserResponse, model *resourceModel, region string) error { if userResp == nil { return fmt.Errorf("response is nil") } @@ -576,9 +573,7 @@ func mapFields(userResp *postgresflex.GetUserResponse, model *ResourceModel, reg } else { return fmt.Errorf("user id not present") } - model.TerraformID = utils.BuildInternalTerraformId( - model.ProjectId.ValueString(), region, model.InstanceId.ValueString(), strconv.FormatInt(userId, 10), - ) + model.UserId = types.Int64Value(userId) model.Name = types.StringPointerValue(user.Name) @@ -602,7 +597,7 @@ func mapFields(userResp *postgresflex.GetUserResponse, model *ResourceModel, reg // getUserResource refreshes the resource state by calling the API and mapping the response to the model. // Returns true if the resource state was successfully refreshed, false if the resource does not exist. -func (r *userResource) getUserResource(ctx context.Context, model *ResourceModel, arg *clientArg) (bool, error) { +func (r *userResource) getUserResource(ctx context.Context, model *resourceModel, arg *clientArg) (bool, error) { if arg.userId > math.MaxInt32 { return false, errors.New("error in type conversion: int value too large (userId)") @@ -638,7 +633,7 @@ type clientArg struct { // extractIdentityData extracts essential identifiers from the resource model, falling back to the identity model. func (r *userResource) extractIdentityData( - model ResourceModel, + model resourceModel, identity UserResourceIdentityModel, ) (*clientArg, error) { diff --git a/stackit/internal/services/sqlserverflexalpha/database/datasource.go b/stackit/internal/services/sqlserverflexalpha/database/datasource.go index cd796159..3c201b5a 100644 --- a/stackit/internal/services/sqlserverflexalpha/database/datasource.go +++ b/stackit/internal/services/sqlserverflexalpha/database/datasource.go @@ -4,6 +4,8 @@ import ( "context" "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexalpha" "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion" @@ -12,6 +14,12 @@ import ( sqlserverflexUtils "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/utils" ) +// dataSourceModel maps the data source schema data. +type dataSourceModel struct { + sqlserverflexalphaGen.DatabaseModel + TerraformID types.String `tfsdk:"id"` +} + var _ datasource.DataSource = (*databaseDataSource)(nil) func NewDatabaseDataSource() datasource.DataSource { @@ -23,16 +31,31 @@ type databaseDataSource struct { providerData core.ProviderData } -func (d *databaseDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { +func (d *databaseDataSource) Metadata( + _ context.Context, + req datasource.MetadataRequest, + resp *datasource.MetadataResponse, +) { resp.TypeName = req.ProviderTypeName + "_sqlserverflexalpha_database" } func (d *databaseDataSource) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { - resp.Schema = sqlserverflexalphaGen.DatabaseDataSourceSchema(ctx) + s := sqlserverflexalphaGen.DatabaseDataSourceSchema(ctx) + s.Attributes["id"] = schema.StringAttribute{ + Description: "Terraform's internal resource ID. It is structured as \\\"`project_id`,`region`,`instance_id`," + + "`database_id`\\\".\",", + Computed: true, + } + + resp.Schema = s } // Configure adds the provider configured client to the data source. -func (d *databaseDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { +func (d *databaseDataSource) Configure( + ctx context.Context, + req datasource.ConfigureRequest, + resp *datasource.ConfigureResponse, +) { var ok bool d.providerData, ok = conversion.ParseProviderData(ctx, req.ProviderData, &resp.Diagnostics) if !ok { @@ -48,7 +71,7 @@ func (d *databaseDataSource) Configure(ctx context.Context, req datasource.Confi } func (d *databaseDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { - var data sqlserverflexalphaGen.DatabaseModel + var data dataSourceModel // Read Terraform configuration data into the model resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) diff --git a/stackit/internal/services/sqlserverflexalpha/database/resource.go b/stackit/internal/services/sqlserverflexalpha/database/resource.go index 52866a9c..3a41c205 100644 --- a/stackit/internal/services/sqlserverflexalpha/database/resource.go +++ b/stackit/internal/services/sqlserverflexalpha/database/resource.go @@ -25,6 +25,9 @@ var ( _ resource.ResourceWithModifyPlan = &databaseResource{} ) +// resourceModel describes the resource data model. +type resourceModel = sqlserverflexalphaGen.DatabaseModel + func NewDatabaseResource() resource.Resource { return &databaseResource{} } @@ -59,7 +62,10 @@ func (r *databaseResource) Configure( utils.UserAgentConfigOption(r.providerData.Version), } if r.providerData.PostgresFlexCustomEndpoint != "" { - apiClientConfigOptions = append(apiClientConfigOptions, config.WithEndpoint(r.providerData.PostgresFlexCustomEndpoint)) + apiClientConfigOptions = append( + apiClientConfigOptions, + config.WithEndpoint(r.providerData.PostgresFlexCustomEndpoint), + ) } else { apiClientConfigOptions = append(apiClientConfigOptions, config.WithRegion(r.providerData.GetRegion())) } @@ -67,7 +73,10 @@ func (r *databaseResource) Configure( if err != nil { resp.Diagnostics.AddError( "Error configuring API client", - fmt.Sprintf("Configuring client: %v. This is an error related to the provider configuration, not to the resource configuration", err), + fmt.Sprintf( + "Configuring client: %v. This is an error related to the provider configuration, not to the resource configuration", + err, + ), ) return } @@ -97,7 +106,7 @@ func (r *databaseResource) Create(ctx context.Context, req resource.CreateReques } func (r *databaseResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var data sqlserverflexalphaGen.DatabaseModel + var data resourceModel // Read Terraform prior state data into the model resp.Diagnostics.Append(req.State.Get(ctx, &data)...) @@ -115,7 +124,7 @@ func (r *databaseResource) Read(ctx context.Context, req resource.ReadRequest, r } func (r *databaseResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var data sqlserverflexalphaGen.DatabaseModel + var data resourceModel // Read Terraform plan data into the model resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) diff --git a/stackit/internal/services/sqlserverflexalpha/flavor/datasource.go b/stackit/internal/services/sqlserverflexalpha/flavor/datasource.go index 1deb2beb..a48e7572 100644 --- a/stackit/internal/services/sqlserverflexalpha/flavor/datasource.go +++ b/stackit/internal/services/sqlserverflexalpha/flavor/datasource.go @@ -26,6 +26,11 @@ var ( _ datasource.DataSourceWithConfigure = &flavorDataSource{} ) +// NewFlavorDataSource is a helper function to simplify the provider implementation. +func NewFlavorDataSource() datasource.DataSource { + return &flavorDataSource{} +} + type FlavorModel struct { ProjectId types.String `tfsdk:"project_id"` Region types.String `tfsdk:"region"` @@ -41,11 +46,6 @@ type FlavorModel struct { StorageClasses types.List `tfsdk:"storage_classes"` } -// NewFlavorDataSource is a helper function to simplify the provider implementation. -func NewFlavorDataSource() datasource.DataSource { - return &flavorDataSource{} -} - // flavorDataSource is the data source implementation. type flavorDataSource struct { client *sqlserverflexalpha.APIClient @@ -53,12 +53,20 @@ type flavorDataSource struct { } // Metadata returns the data source type name. -func (r *flavorDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { +func (r *flavorDataSource) Metadata( + _ context.Context, + req datasource.MetadataRequest, + resp *datasource.MetadataResponse, +) { resp.TypeName = req.ProviderTypeName + "_sqlserverflexalpha_flavor" } // Configure adds the provider configured client to the data source. -func (r *flavorDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { +func (r *flavorDataSource) Configure( + ctx context.Context, + req datasource.ConfigureRequest, + resp *datasource.ConfigureResponse, +) { var ok bool r.providerData, ok = conversion.ParseProviderData(ctx, req.ProviderData, &resp.Diagnostics) if !ok { @@ -212,11 +220,13 @@ func (r *flavorDataSource) Read(ctx context.Context, req datasource.ReadRequest, model.MinGb = types.Int64Value(*f.MinGB) if f.StorageClasses == nil { - model.StorageClasses = types.ListNull(sqlserverflexalphaGen.StorageClassesType{ - ObjectType: basetypes.ObjectType{ - AttrTypes: sqlserverflexalphaGen.StorageClassesValue{}.AttributeTypes(ctx), + model.StorageClasses = types.ListNull( + sqlserverflexalphaGen.StorageClassesType{ + ObjectType: basetypes.ObjectType{ + AttrTypes: sqlserverflexalphaGen.StorageClassesValue{}.AttributeTypes(ctx), + }, }, - }) + ) } else { var scList []attr.Value for _, sc := range *f.StorageClasses { diff --git a/stackit/internal/services/sqlserverflexalpha/flavors/datasource.go b/stackit/internal/services/sqlserverflexalpha/flavors/datasource.go index 27609fc5..c1d4de36 100644 --- a/stackit/internal/services/sqlserverflexalpha/flavors/datasource.go +++ b/stackit/internal/services/sqlserverflexalpha/flavors/datasource.go @@ -13,8 +13,12 @@ import ( sqlserverflexalphaGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/flavors/datasources_gen" ) +// dataSourceModel maps the data source schema data. +type dataSourceModel = sqlserverflexalphaGen.FlavorsModel + var _ datasource.DataSource = (*flavorsDataSource)(nil) +// TODO: Use NewFlavorsDataSource when datasource is implemented func NewFlavorsDataSource() datasource.DataSource { return &flavorsDataSource{} } @@ -24,7 +28,11 @@ type flavorsDataSource struct { providerData core.ProviderData } -func (d *flavorsDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { +func (d *flavorsDataSource) Metadata( + _ context.Context, + req datasource.MetadataRequest, + resp *datasource.MetadataResponse, +) { resp.TypeName = req.ProviderTypeName + "_sqlserverflexalpha_flavors" } @@ -33,7 +41,11 @@ func (d *flavorsDataSource) Schema(ctx context.Context, _ datasource.SchemaReque } // Configure adds the provider configured client to the data source. -func (d *flavorsDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { +func (d *flavorsDataSource) Configure( + ctx context.Context, + req datasource.ConfigureRequest, + resp *datasource.ConfigureResponse, +) { var ok bool d.providerData, ok = conversion.ParseProviderData(ctx, req.ProviderData, &resp.Diagnostics) if !ok { @@ -49,7 +61,7 @@ func (d *flavorsDataSource) Configure(ctx context.Context, req datasource.Config } func (d *flavorsDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { - var data sqlserverflexalphaGen.FlavorsModel + var data dataSourceModel // Read Terraform configuration data into the model resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) diff --git a/stackit/internal/services/sqlserverflexalpha/instance/datasource.go b/stackit/internal/services/sqlserverflexalpha/instance/datasource.go index 3f8f787e..0d58140c 100644 --- a/stackit/internal/services/sqlserverflexalpha/instance/datasource.go +++ b/stackit/internal/services/sqlserverflexalpha/instance/datasource.go @@ -7,6 +7,8 @@ import ( "fmt" "net/http" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion" sqlserverflexalpha "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/instance/datasources_gen" sqlserverflexalpha2 "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/instance/resources_gen" @@ -20,6 +22,12 @@ import ( "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils" ) +// dataSourceModel maps the data source schema data. +type dataSourceModel struct { + sqlserverflexalpha2.InstanceModel + TerraformID types.String `tfsdk:"id"` +} + // Ensure the implementation satisfies the expected interfaces. var ( _ datasource.DataSource = &instanceDataSource{} @@ -37,12 +45,20 @@ type instanceDataSource struct { } // Metadata returns the data source type name. -func (r *instanceDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { +func (r *instanceDataSource) Metadata( + _ context.Context, + req datasource.MetadataRequest, + resp *datasource.MetadataResponse, +) { resp.TypeName = req.ProviderTypeName + "_sqlserverflexalpha_instance" } // Configure adds the provider configured client to the data source. -func (r *instanceDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { +func (r *instanceDataSource) Configure( + ctx context.Context, + req datasource.ConfigureRequest, + resp *datasource.ConfigureResponse, +) { var ok bool r.providerData, ok = conversion.ParseProviderData(ctx, req.ProviderData, &resp.Diagnostics) if !ok { @@ -59,167 +75,22 @@ func (r *instanceDataSource) Configure(ctx context.Context, req datasource.Confi // Schema defines the schema for the data source. func (r *instanceDataSource) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { - //descriptions := map[string]string{ - // "main": "SQLServer Flex ALPHA instance resource schema. Must have a `region` specified in the provider configuration.", - // "id": "Terraform's internal resource ID. It is structured as \"`project_id`,`region`,`instance_id`\".", - // "instance_id": "ID of the SQLServer Flex instance.", - // "project_id": "STACKIT project ID to which the instance is associated.", - // "name": "Instance name.", - // "access_scope": "The access scope of the instance. (e.g. SNA)", - // "acl": "The Access Control List (ACL) for the SQLServer Flex instance.", - // "backup_schedule": `The backup schedule. Should follow the cron scheduling system format (e.g. "0 0 * * *")`, - // "region": "The resource region. If not defined, the provider region is used.", - // "encryption": "The encryption block.", - // "network": "The network block.", - // "keyring_id": "STACKIT KMS - KeyRing ID of the encryption key to use.", - // "key_id": "STACKIT KMS - Key ID of the encryption key to use.", - // "key_version": "STACKIT KMS - Key version to use in the encryption key.", - // "service:account": "STACKIT KMS - service account to use in the encryption key.", - // "instance_address": "The returned instance IP address of the SQLServer Flex instance.", - // "router_address": "The returned router IP address of the SQLServer Flex instance.", - //} + s := sqlserverflexalpha.InstanceDataSourceSchema(ctx) + s.Attributes["id"] = schema.StringAttribute{ + Description: "Terraform's internal resource ID. It is structured as \\\"`project_id`,`region`,`instance_id`\\\".", + Computed: true, + } - resp.Schema = sqlserverflexalpha.InstanceDataSourceSchema(ctx) - - //resp.Schema = schema.Schema{ - // Description: descriptions["main"], - // Attributes: map[string]schema.Attribute{ - // "id": schema.StringAttribute{ - // Description: descriptions["id"], - // Computed: true, - // }, - // "instance_id": schema.StringAttribute{ - // Description: descriptions["instance_id"], - // Required: true, - // Validators: []validator.String{ - // validate.UUID(), - // validate.NoSeparator(), - // }, - // }, - // "project_id": schema.StringAttribute{ - // Description: descriptions["project_id"], - // Required: true, - // Validators: []validator.String{ - // validate.UUID(), - // validate.NoSeparator(), - // }, - // }, - // "name": schema.StringAttribute{ - // Description: descriptions["name"], - // Computed: true, - // }, - // "backup_schedule": schema.StringAttribute{ - // Description: descriptions["backup_schedule"], - // Computed: true, - // }, - // "is_deletable": schema.BoolAttribute{ - // Description: descriptions["is_deletable"], - // Computed: true, - // }, - // "flavor": schema.SingleNestedAttribute{ - // Computed: true, - // Attributes: map[string]schema.Attribute{ - // "id": schema.StringAttribute{ - // Computed: true, - // }, - // "description": schema.StringAttribute{ - // Computed: true, - // }, - // "cpu": schema.Int64Attribute{ - // Computed: true, - // }, - // "ram": schema.Int64Attribute{ - // Computed: true, - // }, - // "node_type": schema.StringAttribute{ - // Computed: true, - // }, - // }, - // }, - // "replicas": schema.Int64Attribute{ - // Computed: true, - // }, - // "storage": schema.SingleNestedAttribute{ - // Computed: true, - // Attributes: map[string]schema.Attribute{ - // "class": schema.StringAttribute{ - // Computed: true, - // }, - // "size": schema.Int64Attribute{ - // Computed: true, - // }, - // }, - // }, - // "version": schema.StringAttribute{ - // Computed: true, - // }, - // "status": schema.StringAttribute{ - // Computed: true, - // }, - // "edition": schema.StringAttribute{ - // Computed: true, - // }, - // "retention_days": schema.Int64Attribute{ - // Computed: true, - // }, - // "region": schema.StringAttribute{ - // // the region cannot be found, so it has to be passed - // Optional: true, - // Description: descriptions["region"], - // }, - // "encryption": schema.SingleNestedAttribute{ - // Computed: true, - // Attributes: map[string]schema.Attribute{ - // "key_id": schema.StringAttribute{ - // Description: descriptions["key_id"], - // Computed: true, - // }, - // "key_version": schema.StringAttribute{ - // Description: descriptions["key_version"], - // Computed: true, - // }, - // "keyring_id": schema.StringAttribute{ - // Description: descriptions["keyring_id"], - // Computed: true, - // }, - // "service_account": schema.StringAttribute{ - // Description: descriptions["service_account"], - // Computed: true, - // }, - // }, - // Description: descriptions["encryption"], - // }, - // "network": schema.SingleNestedAttribute{ - // Computed: true, - // Attributes: map[string]schema.Attribute{ - // "access_scope": schema.StringAttribute{ - // Description: descriptions["access_scope"], - // Computed: true, - // }, - // "instance_address": schema.StringAttribute{ - // Description: descriptions["instance_address"], - // Computed: true, - // }, - // "router_address": schema.StringAttribute{ - // Description: descriptions["router_address"], - // Computed: true, - // }, - // "acl": schema.ListAttribute{ - // Description: descriptions["acl"], - // ElementType: types.StringType, - // Computed: true, - // }, - // }, - // Description: descriptions["network"], - // }, - // }, - //} + resp.Schema = s } // Read refreshes the Terraform state with the latest data. -func (r *instanceDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { // nolint:gocritic // function signature required by Terraform - //var model sqlserverflexalpha2.InstanceModel - var model sqlserverflexalpha2.InstanceModel +func (r *instanceDataSource) Read( + ctx context.Context, + req datasource.ReadRequest, + resp *datasource.ReadResponse, +) { // nolint:gocritic // function signature required by Terraform + var model dataSourceModel diags := req.Config.Get(ctx, &model) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { @@ -279,10 +150,15 @@ func (r *instanceDataSource) Read(ctx context.Context, req datasource.ReadReques // } //} - err = mapResponseToModel(ctx, instanceResp, &model, resp.Diagnostics) + err = mapFields(ctx, instanceResp, &model, resp.Diagnostics) //err = mapFields(ctx, instanceResp, &model, storage, encryption, network, region) if err != nil { - core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading instance", fmt.Sprintf("Processing API payload: %v", err)) + core.LogAndAddError( + ctx, + &resp.Diagnostics, + "Error reading instance", + fmt.Sprintf("Processing API payload: %v", err), + ) return } // Set refreshed state diff --git a/stackit/internal/services/sqlserverflexalpha/instance/functions.go b/stackit/internal/services/sqlserverflexalpha/instance/functions.go index 783d95e1..77effc6c 100644 --- a/stackit/internal/services/sqlserverflexalpha/instance/functions.go +++ b/stackit/internal/services/sqlserverflexalpha/instance/functions.go @@ -14,26 +14,21 @@ import ( sqlserverflexResGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/instance/resources_gen" ) -func mapResponseToModel( +// instanceModel is a type constraint for models that can be mapped from a GetInstanceResponse. +type instanceModel interface { + *dataSourceModel | *resourceModel +} + +func mapFields[T instanceModel]( ctx context.Context, resp *sqlserverflex.GetInstanceResponse, - m *sqlserverflexResGen.InstanceModel, + m T, tfDiags diag.Diagnostics, ) error { - m.BackupSchedule = types.StringValue(resp.GetBackupSchedule()) - m.Edition = types.StringValue(string(resp.GetEdition())) - m.Encryption = handleEncryption(m, resp) - m.FlavorId = types.StringValue(resp.GetFlavorId()) - m.Id = types.StringValue(resp.GetId()) - m.InstanceId = types.StringValue(resp.GetId()) - m.IsDeletable = types.BoolValue(resp.GetIsDeletable()) - m.Name = types.StringValue(resp.GetName()) netAcl, diags := types.ListValueFrom(ctx, types.StringType, resp.Network.GetAcl()) tfDiags.Append(diags...) if diags.HasError() { - return fmt.Errorf( - "error converting network acl response value", - ) + return fmt.Errorf("error converting network acl response value") } net, diags := sqlserverflexResGen.NewNetworkValue( sqlserverflexResGen.NetworkValue{}.AttributeTypes(ctx), @@ -46,22 +41,8 @@ func mapResponseToModel( ) tfDiags.Append(diags...) if diags.HasError() { - return fmt.Errorf( - "error converting network response value", - "access_scope", - types.StringValue(string(resp.Network.GetAccessScope())), - "acl", - netAcl, - "instance_address", - types.StringValue(resp.Network.GetInstanceAddress()), - "router_address", - types.StringValue(resp.Network.GetRouterAddress()), - ) + return fmt.Errorf("error converting network response value") } - m.Network = net - m.Replicas = types.Int64Value(int64(resp.GetReplicas())) - m.RetentionDays = types.Int64Value(resp.GetRetentionDays()) - m.Status = types.StringValue(string(resp.GetStatus())) stor, diags := sqlserverflexResGen.NewStorageValue( sqlserverflexResGen.StorageValue{}.AttributeTypes(ctx), @@ -74,14 +55,47 @@ func mapResponseToModel( if diags.HasError() { return fmt.Errorf("error converting storage response value") } - m.Storage = stor - m.Version = types.StringValue(string(resp.GetVersion())) + // The interface conversion is safe due to the type constraint. + model := any(m) + + if rm, ok := model.(*resourceModel); ok { + rm.BackupSchedule = types.StringValue(resp.GetBackupSchedule()) + rm.Edition = types.StringValue(string(resp.GetEdition())) + rm.Encryption = handleEncryption(rm.Encryption, resp) + rm.FlavorId = types.StringValue(resp.GetFlavorId()) + rm.Id = types.StringValue(resp.GetId()) + rm.InstanceId = types.StringValue(resp.GetId()) + rm.IsDeletable = types.BoolValue(resp.GetIsDeletable()) + rm.Name = types.StringValue(resp.GetName()) + rm.Network = net + rm.Replicas = types.Int64Value(int64(resp.GetReplicas())) + rm.RetentionDays = types.Int64Value(resp.GetRetentionDays()) + rm.Status = types.StringValue(string(resp.GetStatus())) + rm.Storage = stor + rm.Version = types.StringValue(string(resp.GetVersion())) + } else if dm, ok := model.(*dataSourceModel); ok { + dm.BackupSchedule = types.StringValue(resp.GetBackupSchedule()) + dm.Edition = types.StringValue(string(resp.GetEdition())) + dm.Encryption = handleEncryption(dm.Encryption, resp) + dm.FlavorId = types.StringValue(resp.GetFlavorId()) + dm.Id = types.StringValue(resp.GetId()) + dm.InstanceId = types.StringValue(resp.GetId()) + dm.IsDeletable = types.BoolValue(resp.GetIsDeletable()) + dm.Name = types.StringValue(resp.GetName()) + dm.Network = net + dm.Replicas = types.Int64Value(int64(resp.GetReplicas())) + dm.RetentionDays = types.Int64Value(resp.GetRetentionDays()) + dm.Status = types.StringValue(string(resp.GetStatus())) + dm.Storage = stor + dm.Version = types.StringValue(string(resp.GetVersion())) + } + return nil } func handleEncryption( - m *sqlserverflexResGen.InstanceModel, + encryptionValue sqlserverflexResGen.EncryptionValue, resp *sqlserverflex.GetInstanceResponse, ) sqlserverflexResGen.EncryptionValue { if !resp.HasEncryption() || @@ -91,10 +105,10 @@ func handleEncryption( resp.Encryption.KekKeyVersion == nil || resp.Encryption.ServiceAccount == nil { - if m.Encryption.IsNull() || m.Encryption.IsUnknown() { + if encryptionValue.IsNull() || encryptionValue.IsUnknown() { return sqlserverflexResGen.NewEncryptionValueNull() } - return m.Encryption + return encryptionValue } enc := sqlserverflexResGen.NewEncryptionValueNull() diff --git a/stackit/internal/services/sqlserverflexalpha/instance/resource.go b/stackit/internal/services/sqlserverflexalpha/instance/resource.go index 9257c8df..2e58a355 100644 --- a/stackit/internal/services/sqlserverflexalpha/instance/resource.go +++ b/stackit/internal/services/sqlserverflexalpha/instance/resource.go @@ -37,23 +37,26 @@ var ( _ resource.ResourceWithIdentity = &instanceResource{} ) +// NewInstanceResource is a helper function to simplify the provider implementation. +func NewInstanceResource() resource.Resource { + return &instanceResource{} +} + //nolint:unused // TODO: remove if not needed later var validNodeTypes []string = []string{ "Single", "Replica", } +// resourceModel describes the resource data model. +type resourceModel = sqlserverflexalpha2.InstanceModel + type InstanceResourceIdentityModel struct { ProjectID types.String `tfsdk:"project_id"` Region types.String `tfsdk:"region"` InstanceID types.String `tfsdk:"instance_id"` } -// NewInstanceResource is a helper function to simplify the provider implementation. -func NewInstanceResource() resource.Resource { - return &instanceResource{} -} - // instanceResource is the resource implementation. type instanceResource struct { client *sqlserverflexalpha.APIClient @@ -140,27 +143,6 @@ var modifiersFileByte []byte // Schema defines the schema for the resource. func (r *instanceResource) Schema(ctx context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) { - //descriptions := map[string]string{ - // "main": "SQLServer Flex ALPHA instance resource schema. Must have a `region` specified in the provider configuration.", - // "id": "Terraform's internal resource ID. It is structured as \"`project_id`,`region`,`instance_id`\".", - // "instance_id": "ID of the SQLServer Flex instance.", - // "project_id": "STACKIT project ID to which the instance is associated.", - // "name": "Instance name.", - // "access_scope": "The access scope of the instance. (SNA | PUBLIC)", - // "flavor_id": "The flavor ID of the instance.", - // "acl": "The Access Control List (ACL) for the SQLServer Flex instance.", - // "backup_schedule": `The backup schedule. Should follow the cron scheduling system format (e.g. "0 0 * * *")`, - // "region": "The resource region. If not defined, the provider region is used.", - // "encryption": "The encryption block.", - // "replicas": "The number of replicas of the SQLServer Flex instance.", - // "network": "The network block.", - // "keyring_id": "STACKIT KMS - KeyRing ID of the encryption key to use.", - // "key_id": "STACKIT KMS - Key ID of the encryption key to use.", - // "key_version": "STACKIT KMS - Key version to use in the encryption key.", - // "service:account": "STACKIT KMS - service account to use in the encryption key.", - // "instance_address": "The returned instance IP address of the SQLServer Flex instance.", - // "router_address": "The returned router IP address of the SQLServer Flex instance.", - //} schema := sqlserverflexalpha2.InstanceResourceSchema(ctx) @@ -176,234 +158,13 @@ func (r *instanceResource) Schema(ctx context.Context, _ resource.SchemaRequest, return } resp.Schema = schema - - //resp.Schema = schema.Schema{ - // Description: descriptions["main"], - // Attributes: map[string]schema.Attribute{ - // "id": schema.StringAttribute{ - // Description: descriptions["id"], - // Computed: true, - // PlanModifiers: []planmodifier.String{ - // stringplanmodifier.UseStateForUnknown(), - // }, - // }, - // "instance_id": schema.StringAttribute{ - // Description: descriptions["instance_id"], - // Computed: true, - // PlanModifiers: []planmodifier.String{ - // stringplanmodifier.UseStateForUnknown(), - // }, - // Validators: []validator.String{ - // validate.UUID(), - // validate.NoSeparator(), - // }, - // }, - // "project_id": schema.StringAttribute{ - // Description: descriptions["project_id"], - // Required: true, - // PlanModifiers: []planmodifier.String{ - // stringplanmodifier.RequiresReplace(), - // }, - // Validators: []validator.String{ - // validate.UUID(), - // validate.NoSeparator(), - // }, - // }, - // "name": schema.StringAttribute{ - // Description: descriptions["name"], - // Required: true, - // Validators: []validator.String{ - // stringvalidator.LengthAtLeast(1), - // stringvalidator.RegexMatches( - // regexp.MustCompile("^[a-z]([-a-z0-9]*[a-z0-9])?$"), - // "must start with a letter, must have lower case letters, numbers or hyphens, and no hyphen at the end", - // ), - // }, - // }, - // "backup_schedule": schema.StringAttribute{ - // Description: descriptions["backup_schedule"], - // Optional: true, - // Computed: true, - // PlanModifiers: []planmodifier.String{ - // stringplanmodifier.UseStateForUnknown(), - // }, - // }, - // "is_deletable": schema.BoolAttribute{ - // Description: descriptions["is_deletable"], - // Optional: true, - // Computed: true, - // PlanModifiers: []planmodifier.Bool{ - // boolplanmodifier.UseStateForUnknown(), - // }, - // }, - // "flavor_id": schema.StringAttribute{ - // PlanModifiers: []planmodifier.String{ - // stringplanmodifier.RequiresReplace(), - // stringplanmodifier.UseStateForUnknown(), - // }, - // Required: true, - // }, - // "replicas": schema.Int64Attribute{ - // Computed: true, - // PlanModifiers: []planmodifier.Int64{ - // int64planmodifier.UseStateForUnknown(), - // }, - // }, - // "storage": schema.SingleNestedAttribute{ - // Optional: true, - // Computed: true, - // PlanModifiers: []planmodifier.Object{ - // objectplanmodifier.UseStateForUnknown(), - // }, - // Attributes: map[string]schema.Attribute{ - // "class": schema.StringAttribute{ - // Optional: true, - // Computed: true, - // PlanModifiers: []planmodifier.String{ - // stringplanmodifier.RequiresReplace(), - // stringplanmodifier.UseStateForUnknown(), - // }, - // }, - // "size": schema.Int64Attribute{ - // Optional: true, - // Computed: true, - // PlanModifiers: []planmodifier.Int64{ - // int64planmodifier.UseStateForUnknown(), - // }, - // }, - // }, - // }, - // "version": schema.StringAttribute{ - // Optional: true, - // Computed: true, - // PlanModifiers: []planmodifier.String{ - // stringplanmodifier.RequiresReplace(), - // stringplanmodifier.UseStateForUnknown(), - // }, - // }, - // "edition": schema.StringAttribute{ - // Computed: true, - // PlanModifiers: []planmodifier.String{ - // stringplanmodifier.RequiresReplace(), - // stringplanmodifier.UseStateForUnknown(), - // }, - // }, - // "retention_days": schema.Int64Attribute{ - // Optional: true, - // Computed: true, - // PlanModifiers: []planmodifier.Int64{ - // int64planmodifier.UseStateForUnknown(), - // }, - // }, - // "region": schema.StringAttribute{ - // Optional: true, - // // must be computed to allow for storing the override value from the provider - // Computed: true, - // Description: descriptions["region"], - // PlanModifiers: []planmodifier.String{ - // stringplanmodifier.RequiresReplace(), - // }, - // }, - // "status": schema.StringAttribute{ - // Optional: true, - // // must be computed to allow for storing the override value from the provider - // Computed: true, - // Description: descriptions["status"], - // }, - // "encryption": schema.SingleNestedAttribute{ - // Optional: true, - // PlanModifiers: []planmodifier.Object{ - // objectplanmodifier.RequiresReplace(), - // objectplanmodifier.UseStateForUnknown(), - // }, - // Attributes: map[string]schema.Attribute{ - // "key_id": schema.StringAttribute{ - // Description: descriptions["key_id"], - // Required: true, - // PlanModifiers: []planmodifier.String{ - // stringplanmodifier.RequiresReplace(), - // }, - // Validators: []validator.String{ - // validate.NoSeparator(), - // }, - // }, - // "key_version": schema.StringAttribute{ - // Description: descriptions["key_version"], - // Required: true, - // PlanModifiers: []planmodifier.String{ - // stringplanmodifier.RequiresReplace(), - // }, - // Validators: []validator.String{ - // validate.NoSeparator(), - // }, - // }, - // "keyring_id": schema.StringAttribute{ - // Description: descriptions["keyring_id"], - // Required: true, - // PlanModifiers: []planmodifier.String{ - // stringplanmodifier.RequiresReplace(), - // }, - // Validators: []validator.String{ - // validate.NoSeparator(), - // }, - // }, - // "service_account": schema.StringAttribute{ - // Description: descriptions["service_account"], - // Required: true, - // PlanModifiers: []planmodifier.String{ - // stringplanmodifier.RequiresReplace(), - // }, - // Validators: []validator.String{ - // validate.NoSeparator(), - // }, - // }, - // }, - // Description: descriptions["encryption"], - // }, - // "network": schema.SingleNestedAttribute{ - // Required: true, - // Attributes: map[string]schema.Attribute{ - // "access_scope": schema.StringAttribute{ - // Description: descriptions["access_scope"], - // Required: true, - // PlanModifiers: []planmodifier.String{ - // stringplanmodifier.RequiresReplace(), - // stringplanmodifier.UseStateForUnknown(), - // }, - // Validators: []validator.String{ - // validate.NoSeparator(), - // }, - // }, - // "acl": schema.ListAttribute{ - // Description: descriptions["acl"], - // ElementType: types.StringType, - // Required: true, - // PlanModifiers: []planmodifier.List{ - // listplanmodifier.UseStateForUnknown(), - // }, - // }, - // "instance_address": schema.StringAttribute{ - // Description: descriptions["instance_address"], - // Computed: true, - // PlanModifiers: []planmodifier.String{ - // stringplanmodifier.UseStateForUnknown(), - // }, - // }, - // "router_address": schema.StringAttribute{ - // Description: descriptions["router_address"], - // Computed: true, - // PlanModifiers: []planmodifier.String{ - // stringplanmodifier.UseStateForUnknown(), - // }, - // }, - // }, - // Description: descriptions["network"], - // }, - // }, - //} } -func (r *instanceResource) IdentitySchema(_ context.Context, _ resource.IdentitySchemaRequest, resp *resource.IdentitySchemaResponse) { +func (r *instanceResource) IdentitySchema( + _ context.Context, + _ resource.IdentitySchemaRequest, + resp *resource.IdentitySchemaResponse, +) { resp.IdentitySchema = identityschema.Schema{ Attributes: map[string]identityschema.Attribute{ "project_id": identityschema.StringAttribute{ @@ -425,7 +186,7 @@ func (r *instanceResource) Create( req resource.CreateRequest, resp *resource.CreateResponse, ) { // nolint:gocritic // function signature required by Terraform - var model sqlserverflexalpha2.InstanceModel + var model resourceModel diags := req.Plan.Get(ctx, &model) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { @@ -528,7 +289,7 @@ func (r *instanceResource) Create( // Map response body to schema // err = mapFields(ctx, waitResp, &model, storage, encryption, network, region) - err = mapResponseToModel(ctx, waitResp, &model, resp.Diagnostics) + err = mapFields(ctx, waitResp, &model, resp.Diagnostics) if err != nil { core.LogAndAddError( ctx, @@ -554,7 +315,7 @@ func (r *instanceResource) Read( req resource.ReadRequest, resp *resource.ReadResponse, ) { // nolint:gocritic // function signature required by Terraform - var model sqlserverflexalpha2.InstanceModel + var model resourceModel diags := req.State.Get(ctx, &model) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { @@ -592,7 +353,7 @@ func (r *instanceResource) Read( ctx = core.LogResponse(ctx) // Map response body to schema - err = mapResponseToModel(ctx, instanceResp, &model, resp.Diagnostics) + err = mapFields(ctx, instanceResp, &model, resp.Diagnostics) if err != nil { core.LogAndAddError( ctx, @@ -629,7 +390,7 @@ func (r *instanceResource) Update( resp *resource.UpdateResponse, ) { // nolint:gocritic // function signature required by Terraform // Retrieve values from plan - var model sqlserverflexalpha2.InstanceModel + var model resourceModel diags := req.Plan.Get(ctx, &model) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { @@ -683,7 +444,7 @@ func (r *instanceResource) Update( } // Map response body to schema - err = mapResponseToModel(ctx, waitResp, &model, resp.Diagnostics) + err = mapFields(ctx, waitResp, &model, resp.Diagnostics) // err = mapFields(ctx, waitResp, &model, storage, encryption, network, region) if err != nil { core.LogAndAddError( @@ -709,7 +470,7 @@ func (r *instanceResource) Delete( resp *resource.DeleteResponse, ) { // nolint:gocritic // function signature required by Terraform // Retrieve values from state - var model sqlserverflexalpha2.InstanceModel + var model resourceModel diags := req.State.Get(ctx, &model) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { diff --git a/stackit/internal/services/sqlserverflexalpha/user/datasource.go b/stackit/internal/services/sqlserverflexalpha/user/datasource.go index 9b083db0..282a713c 100644 --- a/stackit/internal/services/sqlserverflexalpha/user/datasource.go +++ b/stackit/internal/services/sqlserverflexalpha/user/datasource.go @@ -28,7 +28,12 @@ var ( _ datasource.DataSource = &userDataSource{} ) -type DataSourceModel struct { +// NewUserDataSource is a helper function to simplify the provider implementation. +func NewUserDataSource() datasource.DataSource { + return &userDataSource{} +} + +type dataSourceModel struct { Id types.String `tfsdk:"id"` // needed by TF UserId types.Int64 `tfsdk:"user_id"` InstanceId types.String `tfsdk:"instance_id"` @@ -42,11 +47,6 @@ type DataSourceModel struct { DefaultDatabase types.String `tfsdk:"default_database"` } -// NewUserDataSource is a helper function to simplify the provider implementation. -func NewUserDataSource() datasource.DataSource { - return &userDataSource{} -} - // userDataSource is the data source implementation. type userDataSource struct { client *sqlserverflexalpha.APIClient @@ -164,7 +164,7 @@ func (r *userDataSource) Read( req datasource.ReadRequest, resp *datasource.ReadResponse, ) { // nolint:gocritic // function signature required by Terraform - var model DataSourceModel + var model dataSourceModel diags := req.Config.Get(ctx, &model) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { @@ -226,7 +226,7 @@ func (r *userDataSource) Read( tflog.Info(ctx, "SQLServer Flex instance read") } -func mapDataSourceFields(userResp *sqlserverflexalpha.GetUserResponse, model *DataSourceModel, region string) error { +func mapDataSourceFields(userResp *sqlserverflexalpha.GetUserResponse, model *dataSourceModel, region string) error { if userResp == nil { return fmt.Errorf("response is nil") } diff --git a/stackit/internal/services/sqlserverflexalpha/user/datasource_test.go b/stackit/internal/services/sqlserverflexalpha/user/datasource_test.go index b98c2e53..bd1fa093 100644 --- a/stackit/internal/services/sqlserverflexalpha/user/datasource_test.go +++ b/stackit/internal/services/sqlserverflexalpha/user/datasource_test.go @@ -16,14 +16,14 @@ func TestMapDataSourceFields(t *testing.T) { description string input *sqlserverflexalpha.GetUserResponse region string - expected DataSourceModel + expected dataSourceModel isValid bool }{ { "default_values", &sqlserverflexalpha.GetUserResponse{}, testRegion, - DataSourceModel{ + dataSourceModel{ Id: types.StringValue("pid,region,iid,1"), UserId: types.Int64Value(1), InstanceId: types.StringValue("iid"), @@ -54,7 +54,7 @@ func TestMapDataSourceFields(t *testing.T) { DefaultDatabase: utils.Ptr("default_db"), }, testRegion, - DataSourceModel{ + dataSourceModel{ Id: types.StringValue("pid,region,iid,1"), UserId: types.Int64Value(1), InstanceId: types.StringValue("iid"), @@ -85,7 +85,7 @@ func TestMapDataSourceFields(t *testing.T) { Port: utils.Ptr(int64(2123456789)), }, testRegion, - DataSourceModel{ + dataSourceModel{ Id: types.StringValue("pid,region,iid,1"), UserId: types.Int64Value(1), InstanceId: types.StringValue("iid"), @@ -102,28 +102,28 @@ func TestMapDataSourceFields(t *testing.T) { "nil_response", nil, testRegion, - DataSourceModel{}, + dataSourceModel{}, false, }, { "nil_response_2", &sqlserverflexalpha.GetUserResponse{}, testRegion, - DataSourceModel{}, + dataSourceModel{}, false, }, { "no_resource_id", &sqlserverflexalpha.GetUserResponse{}, testRegion, - DataSourceModel{}, + dataSourceModel{}, false, }, } for _, tt := range tests { t.Run( tt.description, func(t *testing.T) { - state := &DataSourceModel{ + state := &dataSourceModel{ ProjectId: tt.expected.ProjectId, InstanceId: tt.expected.InstanceId, UserId: tt.expected.UserId, diff --git a/stackit/internal/services/sqlserverflexalpha/user/resource.go b/stackit/internal/services/sqlserverflexalpha/user/resource.go index c5cea986..9a95ab10 100644 --- a/stackit/internal/services/sqlserverflexalpha/user/resource.go +++ b/stackit/internal/services/sqlserverflexalpha/user/resource.go @@ -5,11 +5,11 @@ import ( "errors" "fmt" "net/http" - "strconv" "strings" "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64planmodifier" "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexalpha" + sqlserverflexalphagen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/user/resources_gen" sqlserverflexalphaUtils "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/utils" sqlserverflexalphaWait "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/wait/sqlserverflexalpha" @@ -39,26 +39,14 @@ var ( _ resource.ResourceWithModifyPlan = &userResource{} ) -type Model struct { - Id types.String `tfsdk:"id"` // needed by TF - UserId types.Int64 `tfsdk:"user_id"` - InstanceId types.String `tfsdk:"instance_id"` - ProjectId types.String `tfsdk:"project_id"` - Username types.String `tfsdk:"username"` - Roles types.Set `tfsdk:"roles"` - Password types.String `tfsdk:"password"` - Host types.String `tfsdk:"host"` - Port types.Int64 `tfsdk:"port"` - Region types.String `tfsdk:"region"` - Status types.String `tfsdk:"status"` - DefaultDatabase types.String `tfsdk:"default_database"` -} - // NewUserResource is a helper function to simplify the provider implementation. func NewUserResource() resource.Resource { return &userResource{} } +// resourceModel describes the resource data model. +type resourceModel = sqlserverflexalphagen.UserModel + // userResource is the resource implementation. type userResource struct { client *sqlserverflexalpha.APIClient @@ -93,7 +81,7 @@ func (r *userResource) ModifyPlan( req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse, ) { // nolint:gocritic // function signature required by Terraform - var configModel Model + var configModel resourceModel // skip initial empty configuration to avoid follow-up errors if req.Config.Raw.IsNull() { return @@ -103,7 +91,7 @@ func (r *userResource) ModifyPlan( return } - var planModel Model + var planModel resourceModel resp.Diagnostics.Append(req.Plan.Get(ctx, &planModel)...) if resp.Diagnostics.HasError() { return @@ -229,7 +217,7 @@ func (r *userResource) Create( req resource.CreateRequest, resp *resource.CreateResponse, ) { // nolint:gocritic // function signature required by Terraform - var model Model + var model resourceModel diags := req.Plan.Get(ctx, &model) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { @@ -313,7 +301,7 @@ func (r *userResource) Read( req resource.ReadRequest, resp *resource.ReadResponse, ) { // nolint:gocritic // function signature required by Terraform - var model Model + var model resourceModel diags := req.State.Get(ctx, &model) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { @@ -387,7 +375,7 @@ func (r *userResource) Delete( resp *resource.DeleteResponse, ) { // nolint:gocritic // function signature required by Terraform // Retrieve values from plan - var model Model + var model resourceModel diags := req.State.Get(ctx, &model) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { @@ -455,7 +443,7 @@ func (r *userResource) ImportState( tflog.Info(ctx, "SQLServer Flex user state imported") } -func mapFieldsCreate(userResp *sqlserverflexalpha.CreateUserResponse, model *Model, region string) error { +func mapFieldsCreate(userResp *sqlserverflexalpha.CreateUserResponse, model *resourceModel, region string) error { if userResp == nil { return fmt.Errorf("response is nil") } @@ -468,12 +456,6 @@ func mapFieldsCreate(userResp *sqlserverflexalpha.CreateUserResponse, model *Mod return fmt.Errorf("user id not present") } userId := *user.Id - model.Id = utils.BuildInternalTerraformId( - model.ProjectId.ValueString(), - region, - model.InstanceId.ValueString(), - strconv.FormatInt(userId, 10), - ) model.UserId = types.Int64Value(userId) model.Username = types.StringPointerValue(user.Username) @@ -491,11 +473,11 @@ func mapFieldsCreate(userResp *sqlserverflexalpha.CreateUserResponse, model *Mod if diags.HasError() { return fmt.Errorf("failed to map roles: %w", core.DiagsToError(diags)) } - model.Roles = rolesSet + model.Roles = types.List(rolesSet) } if model.Roles.IsNull() || model.Roles.IsUnknown() { - model.Roles = types.SetNull(types.StringType) + model.Roles = types.List(types.SetNull(types.StringType)) } model.Host = types.StringPointerValue(user.Host) @@ -507,7 +489,7 @@ func mapFieldsCreate(userResp *sqlserverflexalpha.CreateUserResponse, model *Mod return nil } -func mapFields(userResp *sqlserverflexalpha.GetUserResponse, model *Model, region string) error { +func mapFields(userResp *sqlserverflexalpha.GetUserResponse, model *resourceModel, region string) error { if userResp == nil { return fmt.Errorf("response is nil") } @@ -524,12 +506,7 @@ func mapFields(userResp *sqlserverflexalpha.GetUserResponse, model *Model, regio } else { return fmt.Errorf("user id not present") } - model.Id = utils.BuildInternalTerraformId( - model.ProjectId.ValueString(), - region, - model.InstanceId.ValueString(), - strconv.FormatInt(userId, 10), - ) + model.UserId = types.Int64Value(userId) model.Username = types.StringPointerValue(user.Username) @@ -542,11 +519,11 @@ func mapFields(userResp *sqlserverflexalpha.GetUserResponse, model *Model, regio if diags.HasError() { return fmt.Errorf("failed to map roles: %w", core.DiagsToError(diags)) } - model.Roles = rolesSet + model.Roles = types.List(rolesSet) } if model.Roles.IsNull() || model.Roles.IsUnknown() { - model.Roles = types.SetNull(types.StringType) + model.Roles = types.List(types.SetNull(types.StringType)) } model.Host = types.StringPointerValue(user.Host) @@ -556,7 +533,7 @@ func mapFields(userResp *sqlserverflexalpha.GetUserResponse, model *Model, regio } func toCreatePayload( - model *Model, + model *resourceModel, roles []sqlserverflexalpha.UserRole, ) (*sqlserverflexalpha.CreateUserRequestPayload, error) { if model == nil { diff --git a/stackit/internal/services/sqlserverflexalpha/user/resource_test.go b/stackit/internal/services/sqlserverflexalpha/user/resource_test.go index ad6bbf5a..e7ddddb1 100644 --- a/stackit/internal/services/sqlserverflexalpha/user/resource_test.go +++ b/stackit/internal/services/sqlserverflexalpha/user/resource_test.go @@ -16,7 +16,7 @@ func TestMapFieldsCreate(t *testing.T) { description string input *sqlserverflexalpha.CreateUserResponse region string - expected Model + expected resourceModel isValid bool }{ { @@ -26,13 +26,13 @@ func TestMapFieldsCreate(t *testing.T) { Password: utils.Ptr(""), }, testRegion, - Model{ - Id: types.StringValue("pid,region,iid,1"), + resourceModel{ + Id: types.Int64Value(1), UserId: types.Int64Value(1), InstanceId: types.StringValue("iid"), ProjectId: types.StringValue("pid"), Username: types.StringNull(), - Roles: types.SetNull(types.StringType), + Roles: types.List(types.SetNull(types.StringType)), Password: types.StringValue(""), Host: types.StringNull(), Port: types.Int64Null(), @@ -57,18 +57,20 @@ func TestMapFieldsCreate(t *testing.T) { DefaultDatabase: utils.Ptr("default_db"), }, testRegion, - Model{ - Id: types.StringValue("pid,region,iid,2"), + resourceModel{ + Id: types.Int64Value(2), UserId: types.Int64Value(2), InstanceId: types.StringValue("iid"), ProjectId: types.StringValue("pid"), Username: types.StringValue("username"), - Roles: types.SetValueMust( - types.StringType, []attr.Value{ - types.StringValue("role_1"), - types.StringValue("role_2"), - types.StringValue(""), - }, + Roles: types.List( + types.SetValueMust( + types.StringType, []attr.Value{ + types.StringValue("role_1"), + types.StringValue("role_2"), + types.StringValue(""), + }, + ), ), Password: types.StringValue("password"), Host: types.StringValue("host"), @@ -90,13 +92,13 @@ func TestMapFieldsCreate(t *testing.T) { Port: utils.Ptr(int64(2123456789)), }, testRegion, - Model{ - Id: types.StringValue("pid,region,iid,3"), + resourceModel{ + Id: types.Int64Value(3), UserId: types.Int64Value(3), InstanceId: types.StringValue("iid"), ProjectId: types.StringValue("pid"), Username: types.StringNull(), - Roles: types.SetValueMust(types.StringType, []attr.Value{}), + Roles: types.List(types.SetValueMust(types.StringType, []attr.Value{})), Password: types.StringValue(""), Host: types.StringNull(), Port: types.Int64Value(2123456789), @@ -110,21 +112,21 @@ func TestMapFieldsCreate(t *testing.T) { "nil_response", nil, testRegion, - Model{}, + resourceModel{}, false, }, { "nil_response_2", &sqlserverflexalpha.CreateUserResponse{}, testRegion, - Model{}, + resourceModel{}, false, }, { "no_resource_id", &sqlserverflexalpha.CreateUserResponse{}, testRegion, - Model{}, + resourceModel{}, false, }, { @@ -133,14 +135,14 @@ func TestMapFieldsCreate(t *testing.T) { Id: utils.Ptr(int64(1)), }, testRegion, - Model{}, + resourceModel{}, false, }, } for _, tt := range tests { t.Run( tt.description, func(t *testing.T) { - state := &Model{ + state := &resourceModel{ ProjectId: tt.expected.ProjectId, InstanceId: tt.expected.InstanceId, } @@ -168,20 +170,20 @@ func TestMapFields(t *testing.T) { description string input *sqlserverflexalpha.GetUserResponse region string - expected Model + expected resourceModel isValid bool }{ { "default_values", &sqlserverflexalpha.GetUserResponse{}, testRegion, - Model{ - Id: types.StringValue("pid,region,iid,1"), + resourceModel{ + Id: types.Int64Value(1), UserId: types.Int64Value(1), InstanceId: types.StringValue("iid"), ProjectId: types.StringValue("pid"), Username: types.StringNull(), - Roles: types.SetNull(types.StringType), + Roles: types.List(types.SetNull(types.StringType)), Host: types.StringNull(), Port: types.Int64Null(), Region: types.StringValue(testRegion), @@ -201,18 +203,20 @@ func TestMapFields(t *testing.T) { Port: utils.Ptr(int64(1234)), }, testRegion, - Model{ - Id: types.StringValue("pid,region,iid,2"), + resourceModel{ + Id: types.Int64Value(2), UserId: types.Int64Value(2), InstanceId: types.StringValue("iid"), ProjectId: types.StringValue("pid"), Username: types.StringValue("username"), - Roles: types.SetValueMust( - types.StringType, []attr.Value{ - types.StringValue("role_1"), - types.StringValue("role_2"), - types.StringValue(""), - }, + Roles: types.List( + types.SetValueMust( + types.StringType, []attr.Value{ + types.StringValue("role_1"), + types.StringValue("role_2"), + types.StringValue(""), + }, + ), ), Host: types.StringValue("host"), Port: types.Int64Value(1234), @@ -230,13 +234,13 @@ func TestMapFields(t *testing.T) { Port: utils.Ptr(int64(2123456789)), }, testRegion, - Model{ - Id: types.StringValue("pid,region,iid,1"), + resourceModel{ + Id: types.Int64Value(1), UserId: types.Int64Value(1), InstanceId: types.StringValue("iid"), ProjectId: types.StringValue("pid"), Username: types.StringNull(), - Roles: types.SetValueMust(types.StringType, []attr.Value{}), + Roles: types.List(types.SetValueMust(types.StringType, []attr.Value{})), Host: types.StringNull(), Port: types.Int64Value(2123456789), Region: types.StringValue(testRegion), @@ -247,28 +251,28 @@ func TestMapFields(t *testing.T) { "nil_response", nil, testRegion, - Model{}, + resourceModel{}, false, }, { "nil_response_2", &sqlserverflexalpha.GetUserResponse{}, testRegion, - Model{}, + resourceModel{}, false, }, { "no_resource_id", &sqlserverflexalpha.GetUserResponse{}, testRegion, - Model{}, + resourceModel{}, false, }, } for _, tt := range tests { t.Run( tt.description, func(t *testing.T) { - state := &Model{ + state := &resourceModel{ ProjectId: tt.expected.ProjectId, InstanceId: tt.expected.InstanceId, UserId: tt.expected.UserId, @@ -294,14 +298,14 @@ func TestMapFields(t *testing.T) { func TestToCreatePayload(t *testing.T) { tests := []struct { description string - input *Model + input *resourceModel inputRoles []sqlserverflexalpha.UserRole expected *sqlserverflexalpha.CreateUserRequestPayload isValid bool }{ { "default_values", - &Model{}, + &resourceModel{}, []sqlserverflexalpha.UserRole{}, &sqlserverflexalpha.CreateUserRequestPayload{ Roles: &[]sqlserverflexalpha.UserRole{}, @@ -311,7 +315,7 @@ func TestToCreatePayload(t *testing.T) { }, { "default_values", - &Model{ + &resourceModel{ Username: types.StringValue("username"), }, []sqlserverflexalpha.UserRole{ @@ -329,7 +333,7 @@ func TestToCreatePayload(t *testing.T) { }, { "null_fields_and_int_conversions", - &Model{ + &resourceModel{ Username: types.StringNull(), }, []sqlserverflexalpha.UserRole{ @@ -352,7 +356,7 @@ func TestToCreatePayload(t *testing.T) { }, { "nil_roles", - &Model{ + &resourceModel{ Username: types.StringValue("username"), }, []sqlserverflexalpha.UserRole{}, diff --git a/stackit/internal/services/sqlserverflexbeta/database/datasource.go b/stackit/internal/services/sqlserverflexbeta/database/datasource.go index bb6c3038..063fe6d9 100644 --- a/stackit/internal/services/sqlserverflexbeta/database/datasource.go +++ b/stackit/internal/services/sqlserverflexbeta/database/datasource.go @@ -26,17 +26,21 @@ func NewDatabaseDataSource() datasource.DataSource { return &databaseDataSource{} } +type dataSourceModel struct { + sqlserverflexbetaGen.DatabaseModel + TfId types.String `tfsdk:"id"` +} + type databaseDataSource struct { client *sqlserverflexbetaPkg.APIClient providerData core.ProviderData } -type dsModel struct { - sqlserverflexbetaGen.DatabaseModel - TfId types.String `tfsdk:"id"` -} - -func (d *databaseDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { +func (d *databaseDataSource) Metadata( + _ context.Context, + req datasource.MetadataRequest, + resp *datasource.MetadataResponse, +) { resp.TypeName = req.ProviderTypeName + "_sqlserverflexbeta_database" } @@ -92,7 +96,7 @@ func (d *databaseDataSource) Configure( } func (d *databaseDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { - var data dsModel + var data dataSourceModel readErr := "Read DB error" // Read Terraform configuration data into the model diff --git a/stackit/internal/services/sqlserverflexbeta/database/resource.go b/stackit/internal/services/sqlserverflexbeta/database/resource.go index 5ae1d6c4..3e622e59 100644 --- a/stackit/internal/services/sqlserverflexbeta/database/resource.go +++ b/stackit/internal/services/sqlserverflexbeta/database/resource.go @@ -35,6 +35,9 @@ func NewDatabaseResource() resource.Resource { return &databaseResource{} } +// resourceModel describes the resource data model. +type resourceModel = sqlserverflexbetaResGen.DatabaseModel + type databaseResource struct { client *sqlserverflexbeta.APIClient providerData core.ProviderData @@ -47,7 +50,11 @@ type DatabaseResourceIdentityModel struct { DatabaseName types.String `tfsdk:"database_name"` } -func (r *databaseResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { +func (r *databaseResource) Metadata( + ctx context.Context, + req resource.MetadataRequest, + resp *resource.MetadataResponse, +) { resp.TypeName = req.ProviderTypeName + "_sqlserverflexbeta_database" } @@ -55,7 +62,11 @@ func (r *databaseResource) Schema(ctx context.Context, req resource.SchemaReques resp.Schema = sqlserverflexbetaResGen.DatabaseResourceSchema(ctx) } -func (r *databaseResource) IdentitySchema(_ context.Context, _ resource.IdentitySchemaRequest, resp *resource.IdentitySchemaResponse) { +func (r *databaseResource) IdentitySchema( + _ context.Context, + _ resource.IdentitySchemaRequest, + resp *resource.IdentitySchemaResponse, +) { resp.IdentitySchema = identityschema.Schema{ Attributes: map[string]identityschema.Attribute{ "project_id": identityschema.StringAttribute{ @@ -91,7 +102,10 @@ func (r *databaseResource) Configure( utils.UserAgentConfigOption(r.providerData.Version), } if r.providerData.SQLServerFlexCustomEndpoint != "" { - apiClientConfigOptions = append(apiClientConfigOptions, config.WithEndpoint(r.providerData.SQLServerFlexCustomEndpoint)) + apiClientConfigOptions = append( + apiClientConfigOptions, + config.WithEndpoint(r.providerData.SQLServerFlexCustomEndpoint), + ) } else { apiClientConfigOptions = append(apiClientConfigOptions, config.WithRegion(r.providerData.GetRegion())) } @@ -111,7 +125,7 @@ func (r *databaseResource) Configure( } func (r *databaseResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data sqlserverflexbetaResGen.DatabaseModel + var data resourceModel createErr := "DB create error" // Read Terraform plan data into the model @@ -243,7 +257,7 @@ func (r *databaseResource) Create(ctx context.Context, req resource.CreateReques } func (r *databaseResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var data sqlserverflexbetaResGen.DatabaseModel + var data resourceModel readErr := "[Database Read]" // Read Terraform prior state data into the model @@ -298,7 +312,7 @@ func (r *databaseResource) Read(ctx context.Context, req resource.ReadRequest, r } func (r *databaseResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var data sqlserverflexbetaResGen.DatabaseModel + var data resourceModel // Read Terraform prior state data into the model resp.Diagnostics.Append(req.State.Get(ctx, &data)...) @@ -329,7 +343,7 @@ func (r *databaseResource) Update(ctx context.Context, req resource.UpdateReques } func (r *databaseResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var data sqlserverflexbetaResGen.DatabaseModel + var data resourceModel // Read Terraform prior state data into the model resp.Diagnostics.Append(req.State.Get(ctx, &data)...) @@ -422,9 +436,13 @@ func (r *databaseResource) ImportState( idParts := strings.Split(req.ID, core.Separator) if len(idParts) != 4 || idParts[0] == "" || idParts[1] == "" || idParts[2] == "" || idParts[3] == "" { - core.LogAndAddError(ctx, &resp.Diagnostics, + core.LogAndAddError( + ctx, &resp.Diagnostics, "Error importing database", - fmt.Sprintf("Expected import identifier with format: [project_id],[region],[instance_id],[database_name] Got: %q", req.ID), + fmt.Sprintf( + "Expected import identifier with format: [project_id],[region],[instance_id],[database_name] Got: %q", + req.ID, + ), ) return } @@ -455,10 +473,28 @@ func (r *databaseResource) ImportState( return } - resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("project_id"), identityData.ProjectID.ValueString())...) + resp.Diagnostics.Append( + resp.State.SetAttribute( + ctx, + path.Root("project_id"), + identityData.ProjectID.ValueString(), + )..., + ) resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("region"), identityData.Region.ValueString())...) - resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("instance_id"), identityData.InstanceID.ValueString())...) - resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("database_name"), identityData.DatabaseName.ValueString())...) + resp.Diagnostics.Append( + resp.State.SetAttribute( + ctx, + path.Root("instance_id"), + identityData.InstanceID.ValueString(), + )..., + ) + resp.Diagnostics.Append( + resp.State.SetAttribute( + ctx, + path.Root("database_name"), + identityData.DatabaseName.ValueString(), + )..., + ) resp.Diagnostics.Append(resp.Identity.Set(ctx, &identityData)...) if resp.Diagnostics.HasError() { diff --git a/stackit/internal/services/sqlserverflexbeta/flavors/datasource.go b/stackit/internal/services/sqlserverflexbeta/flavors/datasource.go index 9492387d..b401e4ff 100644 --- a/stackit/internal/services/sqlserverflexbeta/flavors/datasource.go +++ b/stackit/internal/services/sqlserverflexbeta/flavors/datasource.go @@ -14,9 +14,9 @@ import ( "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core" "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils" - sqlserverflexbetaPkg "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexbeta" + sqlserverflexbetaPkg "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexbeta" - sqlserverflexbetaGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta/flavors/datasources_gen" + sqlserverflexbetaGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta/flavors/datasources_gen" ) var _ datasource.DataSource = (*flavorsDataSource)(nil) @@ -27,27 +27,31 @@ func NewFlavorsDataSource() datasource.DataSource { return &flavorsDataSource{} } -type dsModel struct { +type dataSourceModel struct { sqlserverflexbetaGen.FlavorsModel - TfId types.String `tfsdk:"id"` + TerraformId types.String `tfsdk:"id"` } -type flavorsDataSource struct{ +type flavorsDataSource struct { client *sqlserverflexbetaPkg.APIClient providerData core.ProviderData } -func (d *flavorsDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { +func (d *flavorsDataSource) Metadata( + _ context.Context, + req datasource.MetadataRequest, + resp *datasource.MetadataResponse, +) { resp.TypeName = req.ProviderTypeName + "_sqlserverflexbeta_flavors" } func (d *flavorsDataSource) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { resp.Schema = sqlserverflexbetaGen.FlavorsDataSourceSchema(ctx) - resp.Schema.Attributes["id"] = schema.StringAttribute{ - Computed: true, - Description: "The terraform internal identifier.", - MarkdownDescription: "The terraform internal identifier.", - } + resp.Schema.Attributes["id"] = schema.StringAttribute{ + Computed: true, + Description: "The terraform internal identifier.", + MarkdownDescription: "The terraform internal identifier.", + } } // Configure adds the provider configured client to the data source. @@ -66,10 +70,10 @@ func (d *flavorsDataSource) Configure( config.WithCustomAuth(d.providerData.RoundTripper), utils.UserAgentConfigOption(d.providerData.Version), } - if d.providerData.SqlserverflexbetaCustomEndpoint != "" { + if d.providerData.SQLServerFlexCustomEndpoint != "" { apiClientConfigOptions = append( apiClientConfigOptions, - config.WithEndpoint(d.providerData.SqlserverflexbetaCustomEndpoint), + config.WithEndpoint(d.providerData.SQLServerFlexCustomEndpoint), ) } else { apiClientConfigOptions = append( @@ -93,7 +97,7 @@ func (d *flavorsDataSource) Configure( } func (d *flavorsDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { - var data dsModel + var data dataSourceModel // Read Terraform configuration data into the model resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) @@ -106,7 +110,8 @@ func (d *flavorsDataSource) Read(ctx context.Context, req datasource.ReadRequest projectId := data.ProjectId.ValueString() region := d.providerData.GetRegionWithOverride(data.Region) - flavorsId := data.FlavorsId.ValueString() + // TODO: implement right identifier for flavors + flavorsId := data.FlavorsModel.Flavors ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "region", region) @@ -114,8 +119,8 @@ func (d *flavorsDataSource) Read(ctx context.Context, req datasource.ReadRequest // TODO: implement needed fields ctx = tflog.SetField(ctx, "flavors_id", flavorsId) - // TODO: refactor to correct implementation - flavorsResp, err := d.client.GetFlavorsRequest(ctx, projectId, region, flavorsId).Execute() + // TODO: refactor to correct implementation + _, err := d.client.GetFlavorsRequest(ctx, projectId, region).Execute() if err != nil { utils.LogError( ctx, @@ -133,17 +138,17 @@ func (d *flavorsDataSource) Read(ctx context.Context, req datasource.ReadRequest ctx = core.LogResponse(ctx) - - data.TfId = utils.BuildInternalTerraformId(projectId, region, ..) + // TODO: refactor to correct implementation of internal tf id + data.TerraformId = utils.BuildInternalTerraformId(projectId, region) // TODO: fill remaining fields - // data.Flavors = types.Sometype(apiResponse.GetFlavors()) - // data.Page = types.Sometype(apiResponse.GetPage()) - // data.Pagination = types.Sometype(apiResponse.GetPagination()) - // data.ProjectId = types.Sometype(apiResponse.GetProjectId()) - // data.Region = types.Sometype(apiResponse.GetRegion()) - // data.Size = types.Sometype(apiResponse.GetSize()) - // data.Sort = types.Sometype(apiResponse.GetSort())// Save data into Terraform state + // data.Flavors = types.Sometype(apiResponse.GetFlavors()) + // data.Page = types.Sometype(apiResponse.GetPage()) + // data.Pagination = types.Sometype(apiResponse.GetPagination()) + // data.ProjectId = types.Sometype(apiResponse.GetProjectId()) + // data.Region = types.Sometype(apiResponse.GetRegion()) + // data.Size = types.Sometype(apiResponse.GetSize()) + // data.Sort = types.Sometype(apiResponse.GetSort())// Save data into Terraform state resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) tflog.Info(ctx, fmt.Sprintf("%s read successful", errorPrefix)) diff --git a/stackit/internal/services/sqlserverflexbeta/instance/datasource.go b/stackit/internal/services/sqlserverflexbeta/instance/datasource.go index 842a4cfd..85834b26 100644 --- a/stackit/internal/services/sqlserverflexbeta/instance/datasource.go +++ b/stackit/internal/services/sqlserverflexbeta/instance/datasource.go @@ -6,6 +6,7 @@ import ( "net/http" "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/stackitcloud/stackit-sdk-go/core/config" "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion" @@ -25,12 +26,22 @@ func NewInstanceDataSource() datasource.DataSource { return &instanceDataSource{} } +// dataSourceModel maps the data source schema data. +type dataSourceModel struct { + sqlserverflexbetaGen.InstanceModel + TerraformID types.String `tfsdk:"id"` +} + type instanceDataSource struct { client *sqlserverflexbetaPkg.APIClient providerData core.ProviderData } -func (d *instanceDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { +func (d *instanceDataSource) Metadata( + _ context.Context, + req datasource.MetadataRequest, + resp *datasource.MetadataResponse, +) { resp.TypeName = req.ProviderTypeName + "_sqlserverflexbeta_instance" } @@ -81,7 +92,7 @@ func (d *instanceDataSource) Configure( } func (d *instanceDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { - var data sqlserverflexbetaGen.InstanceModel + var data dataSourceModel // Read Terraform configuration data into the model resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) diff --git a/stackit/internal/services/sqlserverflexbeta/instance/functions.go b/stackit/internal/services/sqlserverflexbeta/instance/functions.go index e9e1db57..25f3af0c 100644 --- a/stackit/internal/services/sqlserverflexbeta/instance/functions.go +++ b/stackit/internal/services/sqlserverflexbeta/instance/functions.go @@ -84,7 +84,7 @@ func mapResponseToModel( func mapDataResponseToModel( ctx context.Context, resp *sqlserverflexbeta.GetInstanceResponse, - m *sqlserverflexbetaDataGen.InstanceModel, + m *dataSourceModel, tfDiags diag.Diagnostics, ) error { m.BackupSchedule = types.StringValue(resp.GetBackupSchedule()) @@ -181,7 +181,7 @@ func handleEncryption( } func handleDSEncryption( - m *sqlserverflexbetaDataGen.InstanceModel, + m *dataSourceModel, resp *sqlserverflexbeta.GetInstanceResponse, ) sqlserverflexbetaDataGen.EncryptionValue { if !resp.HasEncryption() || diff --git a/stackit/internal/services/sqlserverflexbeta/instance/resource.go b/stackit/internal/services/sqlserverflexbeta/instance/resource.go index 5d0b47d8..0e9c0012 100644 --- a/stackit/internal/services/sqlserverflexbeta/instance/resource.go +++ b/stackit/internal/services/sqlserverflexbeta/instance/resource.go @@ -43,13 +43,20 @@ type instanceResource struct { providerData core.ProviderData } +// resourceModel describes the resource data model. +type resourceModel = sqlserverflexbetaResGen.InstanceModel + type InstanceResourceIdentityModel struct { ProjectID types.String `tfsdk:"project_id"` Region types.String `tfsdk:"region"` InstanceID types.String `tfsdk:"instance_id"` } -func (r *instanceResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { +func (r *instanceResource) Metadata( + ctx context.Context, + req resource.MetadataRequest, + resp *resource.MetadataResponse, +) { resp.TypeName = req.ProviderTypeName + "_sqlserverflexbeta_instance" } @@ -57,7 +64,11 @@ func (r *instanceResource) Schema(ctx context.Context, req resource.SchemaReques resp.Schema = sqlserverflexbetaResGen.InstanceResourceSchema(ctx) } -func (r *instanceResource) IdentitySchema(_ context.Context, _ resource.IdentitySchemaRequest, resp *resource.IdentitySchemaResponse) { +func (r *instanceResource) IdentitySchema( + _ context.Context, + _ resource.IdentitySchemaRequest, + resp *resource.IdentitySchemaResponse, +) { resp.IdentitySchema = identityschema.Schema{ Attributes: map[string]identityschema.Attribute{ "project_id": identityschema.StringAttribute{ @@ -90,7 +101,10 @@ func (r *instanceResource) Configure( utils.UserAgentConfigOption(r.providerData.Version), } if r.providerData.SQLServerFlexCustomEndpoint != "" { - apiClientConfigOptions = append(apiClientConfigOptions, config.WithEndpoint(r.providerData.SQLServerFlexCustomEndpoint)) + apiClientConfigOptions = append( + apiClientConfigOptions, + config.WithEndpoint(r.providerData.SQLServerFlexCustomEndpoint), + ) } else { apiClientConfigOptions = append(apiClientConfigOptions, config.WithRegion(r.providerData.GetRegion())) } @@ -121,7 +135,7 @@ func (r *instanceResource) ModifyPlan( if req.Config.Raw.IsNull() { return } - var configModel sqlserverflexbetaResGen.InstanceModel + var configModel resourceModel resp.Diagnostics.Append(req.Config.Get(ctx, &configModel)...) if resp.Diagnostics.HasError() { return @@ -151,7 +165,7 @@ func (r *instanceResource) ModifyPlan( var modifiersFileByte []byte func (r *instanceResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data sqlserverflexbetaResGen.InstanceModel + var data resourceModel crateErr := "[SQL Server Flex BETA - Create] error" // Read Terraform plan data into the model @@ -257,7 +271,7 @@ func (r *instanceResource) Create(ctx context.Context, req resource.CreateReques } func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var data sqlserverflexbetaResGen.InstanceModel + var data resourceModel // Read Terraform prior state data into the model resp.Diagnostics.Append(req.State.Get(ctx, &data)...) @@ -324,7 +338,7 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r } func (r *instanceResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var data sqlserverflexbetaResGen.InstanceModel + var data resourceModel updateInstanceError := "Error updating instance" resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) @@ -411,7 +425,7 @@ func (r *instanceResource) Update(ctx context.Context, req resource.UpdateReques } func (r *instanceResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var data sqlserverflexbetaResGen.InstanceModel + var data resourceModel // Read Terraform prior state data into the model resp.Diagnostics.Append(req.State.Get(ctx, &data)...) @@ -484,9 +498,13 @@ func (r *instanceResource) ImportState( idParts := strings.Split(req.ID, core.Separator) if len(idParts) != 3 || idParts[0] == "" || idParts[1] == "" || idParts[2] == "" { - core.LogAndAddError(ctx, &resp.Diagnostics, + core.LogAndAddError( + ctx, &resp.Diagnostics, "Error importing instance", - fmt.Sprintf("Expected import identifier with format: [project_id],[region],[instance_id] Got: %q", req.ID), + fmt.Sprintf( + "Expected import identifier with format: [project_id],[region],[instance_id] Got: %q", + req.ID, + ), ) return } @@ -512,10 +530,23 @@ func (r *instanceResource) ImportState( identityData.Region.ValueString(), identityData.InstanceID.ValueString(), ), - )...) - resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("project_id"), identityData.ProjectID.ValueString())...) + )..., + ) + resp.Diagnostics.Append( + resp.State.SetAttribute( + ctx, + path.Root("project_id"), + identityData.ProjectID.ValueString(), + )..., + ) resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("region"), identityData.Region.ValueString())...) - resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("instance_id"), identityData.InstanceID.ValueString())...) + resp.Diagnostics.Append( + resp.State.SetAttribute( + ctx, + path.Root("instance_id"), + identityData.InstanceID.ValueString(), + )..., + ) tflog.Info(ctx, "Sqlserverflexbeta instance state imported") } diff --git a/stackit/internal/services/sqlserverflexbeta/user/datasource.go b/stackit/internal/services/sqlserverflexbeta/user/datasource.go index df1a8033..e6491a0f 100644 --- a/stackit/internal/services/sqlserverflexbeta/user/datasource.go +++ b/stackit/internal/services/sqlserverflexbeta/user/datasource.go @@ -6,6 +6,7 @@ import ( "net/http" "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core" "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils" @@ -25,12 +26,30 @@ func NewUserDataSource() datasource.DataSource { return &userDataSource{} } +type dataSourceModel struct { + DefaultDatabase types.String `tfsdk:"default_database"` + Host types.String `tfsdk:"host"` + Id types.Int64 `tfsdk:"id"` + InstanceId types.String `tfsdk:"instance_id"` + Port types.Int64 `tfsdk:"port"` + ProjectId types.String `tfsdk:"project_id"` + Region types.String `tfsdk:"region"` + Roles types.List `tfsdk:"roles"` + Status types.String `tfsdk:"status"` + UserId types.Int64 `tfsdk:"user_id"` + Username types.String `tfsdk:"username"` +} + type userDataSource struct { client *sqlserverflexbetaPkg.APIClient providerData core.ProviderData } -func (d *userDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { +func (d *userDataSource) Metadata( + _ context.Context, + req datasource.MetadataRequest, + resp *datasource.MetadataResponse, +) { resp.TypeName = req.ProviderTypeName + "_sqlserverflexbeta_user" } @@ -59,7 +78,7 @@ func (d *userDataSource) Configure( } func (d *userDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { - var data sqlserverflexbetaGen.UserModel + var data dataSourceModel // Read Terraform configuration data into the model resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) @@ -72,13 +91,15 @@ func (d *userDataSource) Read(ctx context.Context, req datasource.ReadRequest, r projectId := data.ProjectId.ValueString() region := d.providerData.GetRegionWithOverride(data.Region) - userId := data.UserId.ValueString() + instanceId := data.InstanceId.ValueString() + userId := data.UserId.ValueInt64() ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "region", region) + ctx = tflog.SetField(ctx, "instance_id", instanceId) ctx = tflog.SetField(ctx, "user_id", userId) - userResp, err := d.client.GetUserRequest(ctx, projectId, region, userId).Execute() + userResp, err := d.client.GetUserRequest(ctx, projectId, region, instanceId, userId).Execute() if err != nil { utils.LogError( ctx, diff --git a/stackit/internal/services/sqlserverflexbeta/user/functions.go b/stackit/internal/services/sqlserverflexbeta/user/functions.go index b565f761..83ce641f 100644 --- a/stackit/internal/services/sqlserverflexbeta/user/functions.go +++ b/stackit/internal/services/sqlserverflexbeta/user/functions.go @@ -3,13 +3,9 @@ package sqlserverflexbeta import ( "context" "fmt" - "math" - "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" - "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/types" - "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion" sqlserverflexbeta "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexbeta" sqlserverflexbetaResGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta/instance/resources_gen" @@ -18,11 +14,39 @@ import ( func mapResponseToModel( ctx context.Context, resp *sqlserverflexbeta.GetUserResponse, - m *sqlserverflexbetaResGen.UserModel, + m *dataSourceModel, tfDiags diag.Diagnostics, ) error { + if resp == nil { + return fmt.Errorf("response is nil") + } + + m.Id = types.Int64Value(resp.GetId()) + m.UserId = types.Int64Value(resp.GetId()) + m.Username = types.StringValue(resp.GetUsername()) + m.Port = types.Int64Value(resp.GetPort()) + m.Host = types.StringValue(resp.GetHost()) + m.DefaultDatabase = types.StringValue(resp.GetDefaultDatabase()) + m.Status = types.StringValue(resp.GetStatus()) + + if resp.Roles != nil { + roles, diags := types.ListValueFrom(ctx, types.StringType, *resp.Roles) + tfDiags.Append(diags...) + if tfDiags.HasError() { + return fmt.Errorf("failed to map roles") + } + m.Roles = roles + } else { + m.Roles = types.ListNull(types.StringType) + } + + if resp.Status != nil { + m.Status = types.StringValue(*resp.Status) + } else { + m.Status = types.StringNull() + } + // TODO: complete and refactor - m.Id = types.StringValue(resp.GetId()) /* sampleList, diags := types.ListValueFrom(ctx, types.StringType, resp.GetList()) @@ -51,48 +75,63 @@ func mapResponseToModel( return nil } +// TODO: handle encryption field mapping when API supports it func handleEncryption( - m *sqlserverflexbetaResGen.UserModel, + m *dataSourceModel, resp *sqlserverflexbeta.GetUserResponse, ) sqlserverflexbetaResGen.EncryptionValue { - if !resp.HasEncryption() || - resp.Encryption == nil || - resp.Encryption.KekKeyId == nil || - resp.Encryption.KekKeyRingId == nil || - resp.Encryption.KekKeyVersion == nil || - resp.Encryption.ServiceAccount == nil { + /* + if !resp.HasEncryption() || - if m.Encryption.IsNull() || m.Encryption.IsUnknown() { - return sqlserverflexbetaResGen.NewEncryptionValueNull() + resp.Encryption == nil || + resp.Encryption.KekKeyId == nil || + resp.Encryption.KekKeyRingId == nil || + resp.Encryption.KekKeyVersion == nil || + resp.Encryption.ServiceAccount == nil { + + if m.Encryption.IsNull() || m.Encryption.IsUnknown() { + return sqlserverflexbetaResGen.NewEncryptionValueNull() + } + return m.Encryption } - return m.Encryption - } - enc := sqlserverflexbetaResGen.NewEncryptionValueNull() - if kVal, ok := resp.Encryption.GetKekKeyIdOk(); ok { - enc.KekKeyId = types.StringValue(kVal) - } - if kkVal, ok := resp.Encryption.GetKekKeyRingIdOk(); ok { - enc.KekKeyRingId = types.StringValue(kkVal) - } - if kkvVal, ok := resp.Encryption.GetKekKeyVersionOk(); ok { - enc.KekKeyVersion = types.StringValue(kkvVal) - } - if sa, ok := resp.Encryption.GetServiceAccountOk(); ok { - enc.ServiceAccount = types.StringValue(sa) - } - return enc + enc := sqlserverflexbetaResGen.NewEncryptionValueNull() + if kVal, ok := resp.Encryption.GetKekKeyIdOk(); ok { + enc.KekKeyId = types.StringValue(kVal) + } + if kkVal, ok := resp.Encryption.GetKekKeyRingIdOk(); ok { + enc.KekKeyRingId = types.StringValue(kkVal) + } + if kkvVal, ok := resp.Encryption.GetKekKeyVersionOk(); ok { + enc.KekKeyVersion = types.StringValue(kkvVal) + } + if sa, ok := resp.Encryption.GetServiceAccountOk(); ok { + enc.ServiceAccount = types.StringValue(sa) + } + return enc + */ + return sqlserverflexbetaResGen.NewEncryptionValueNull() } func toCreatePayload( ctx context.Context, - model *sqlserverflexbetaResGen.UserModel, + model *dataSourceModel, ) (*sqlserverflexbeta.CreateUserRequestPayload, error) { if model == nil { return nil, fmt.Errorf("nil model") } + var roles []sqlserverflexbeta.UserRole + if !model.Roles.IsNull() && !model.Roles.IsUnknown() { + diags := model.Roles.ElementsAs(ctx, &roles, false) + if diags.HasError() { + return nil, fmt.Errorf("failed to convert roles: %v", diags) + } + } + return &sqlserverflexbeta.CreateUserRequestPayload{ - // TODO: fill fields + DefaultDatabase: model.DefaultDatabase.ValueStringPointer(), + Username: model.Username.ValueStringPointer(), + Roles: &roles, }, nil } diff --git a/stackit/internal/services/sqlserverflexbeta/user/resource.go b/stackit/internal/services/sqlserverflexbeta/user/resource.go index e2692e13..f8e1e747 100644 --- a/stackit/internal/services/sqlserverflexbeta/user/resource.go +++ b/stackit/internal/services/sqlserverflexbeta/user/resource.go @@ -33,6 +33,9 @@ func NewUserResource() resource.Resource { return &userResource{} } +// resourceModel describes the resource data model. +type resourceModel = sqlserverflexbetaResGen.UserModel + type userResource struct { client *sqlserverflexbeta.APIClient providerData core.ProviderData @@ -53,7 +56,11 @@ func (r *userResource) Schema(ctx context.Context, req resource.SchemaRequest, r resp.Schema = sqlserverflexbetaResGen.UserResourceSchema(ctx) } -func (r *instanceResource) IdentitySchema(_ context.Context, _ resource.IdentitySchemaRequest, resp *resource.IdentitySchemaResponse) { +func (r *userResource) IdentitySchema( + _ context.Context, + _ resource.IdentitySchemaRequest, + resp *resource.IdentitySchemaResponse, +) { resp.IdentitySchema = identityschema.Schema{ Attributes: map[string]identityschema.Attribute{ "project_id": identityschema.StringAttribute{ @@ -85,8 +92,11 @@ func (r *userResource) Configure( config.WithCustomAuth(r.providerData.RoundTripper), utils.UserAgentConfigOption(r.providerData.Version), } - if r.providerData.SqlserverflexbetaCustomEndpoint != "" { - apiClientConfigOptions = append(apiClientConfigOptions, config.WithEndpoint(r.providerData.sqlserverflexbetaCustomEndpoint)) + if r.providerData.SQLServerFlexCustomEndpoint != "" { + apiClientConfigOptions = append( + apiClientConfigOptions, + config.WithEndpoint(r.providerData.SQLServerFlexCustomEndpoint), + ) } else { apiClientConfigOptions = append(apiClientConfigOptions, config.WithRegion(r.providerData.GetRegion())) } @@ -106,7 +116,7 @@ func (r *userResource) Configure( } func (r *userResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var data sqlserverflexbetaResGen.UserModel + var data resourceModel // Read Terraform plan data into the model resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) @@ -159,14 +169,14 @@ func (r *userResource) Create(ctx context.Context, req resource.CreateRequest, r */ // Example data value setting - data.UserId = types.StringValue("id-from-response") + //data.UserId = types.StringValue("id-from-response") // TODO: Set data returned by API in identity identity := UserResourceIdentityModel{ ProjectID: types.StringValue(projectId), Region: types.StringValue(region), // TODO: add missing values - UserID: types.StringValue(UserId), + // UserID: types.StringValue(UserId), } resp.Diagnostics.Append(resp.Identity.Set(ctx, identity)...) if resp.Diagnostics.HasError() { @@ -228,7 +238,7 @@ func (r *userResource) Create(ctx context.Context, req resource.CreateRequest, r } func (r *userResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var data sqlserverflexbetaResGen.UserModel + var data resourceModel // Read Terraform prior state data into the model resp.Diagnostics.Append(req.State.Get(ctx, &data)...) @@ -270,7 +280,7 @@ func (r *userResource) Read(ctx context.Context, req resource.ReadRequest, resp } func (r *userResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var data sqlserverflexbetaResGen.UserModel + var data resourceModel // Read Terraform prior state data into the model resp.Diagnostics.Append(req.State.Get(ctx, &data)...) @@ -301,7 +311,7 @@ func (r *userResource) Update(ctx context.Context, req resource.UpdateRequest, r } func (r *userResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var data sqlserverflexbetaResGen.UserModel + var data resourceModel // Read Terraform prior state data into the model resp.Diagnostics.Append(req.State.Get(ctx, &data)...) @@ -335,7 +345,7 @@ func (r *userResource) ModifyPlan( req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse, ) { // nolint:gocritic // function signature required by Terraform - var configModel sqlserverflexbetaResGen.UserModel + var configModel resourceModel // skip initial empty configuration to avoid follow-up errors if req.Config.Raw.IsNull() { return @@ -345,7 +355,7 @@ func (r *userResource) ModifyPlan( return } - var planModel sqlserverflexbetaResGen.UserModel + var planModel resourceModel resp.Diagnostics.Append(req.Plan.Get(ctx, &planModel)...) if resp.Diagnostics.HasError() { return diff --git a/stackit/internal/wait/sqlserverflexbeta/wait_test.go b/stackit/internal/wait/sqlserverflexbeta/wait_test.go index e1ccc9c5..35b66cf6 100644 --- a/stackit/internal/wait/sqlserverflexbeta/wait_test.go +++ b/stackit/internal/wait/sqlserverflexbeta/wait_test.go @@ -20,7 +20,30 @@ type apiClientInstanceMocked struct { instanceGetFails bool } -func (a *apiClientInstanceMocked) GetInstanceRequestExecute(_ context.Context, _, _, _ string) (*sqlserverflex.GetInstanceResponse, error) { +func (a *apiClientInstanceMocked) GetDatabaseRequestExecute( + _ context.Context, + projectId string, + region string, + instanceId string, + databaseName string, +) (*sqlserverflex.GetDatabaseResponse, error) { + return nil, nil +} + +func (a *apiClientInstanceMocked) GetUserRequestExecute( + ctx context.Context, + projectId string, + region string, + instanceId string, + userId int64, +) (*sqlserverflex.GetUserResponse, error) { + return nil, nil +} + +func (a *apiClientInstanceMocked) GetInstanceRequestExecute( + _ context.Context, + _, _, _ string, +) (*sqlserverflex.GetInstanceResponse, error) { if a.instanceGetFails { return nil, &oapierror.GenericOpenAPIError{ StatusCode: 500, @@ -111,26 +134,28 @@ func TestCreateInstanceWaitHandler(t *testing.T) { }, } for _, tt := range tests { - t.Run(tt.desc, func(t *testing.T) { - instanceId := "foo-bar" + t.Run( + tt.desc, func(t *testing.T) { + instanceId := "foo-bar" - apiClient := &apiClientInstanceMocked{ - instanceId: instanceId, - instanceState: tt.instanceState, - instanceGetFails: tt.instanceGetFails, - } + apiClient := &apiClientInstanceMocked{ + instanceId: instanceId, + instanceState: tt.instanceState, + instanceGetFails: tt.instanceGetFails, + } - handler := CreateInstanceWaitHandler(context.Background(), apiClient, "", instanceId, "") + handler := CreateInstanceWaitHandler(context.Background(), apiClient, "", instanceId, "") - gotRes, err := handler.SetTimeout(10 * time.Millisecond).SetSleepBeforeWait(1 * time.Millisecond).WaitWithContext(context.Background()) - if (err != nil) != tt.wantErr { - t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr) - } + gotRes, err := handler.SetTimeout(10 * time.Millisecond).SetSleepBeforeWait(1 * time.Millisecond).WaitWithContext(context.Background()) + if (err != nil) != tt.wantErr { + t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr) + } - if !cmp.Equal(gotRes, tt.wantRes) { - t.Fatalf("handler gotRes = %v, want %v", gotRes, tt.wantRes) - } - }) + if !cmp.Equal(gotRes, tt.wantRes) { + t.Fatalf("handler gotRes = %v, want %v", gotRes, tt.wantRes) + } + }, + ) } } @@ -179,34 +204,36 @@ func TestUpdateInstanceWaitHandler(t *testing.T) { }, } for _, tt := range tests { - t.Run(tt.desc, func(t *testing.T) { - instanceId := "foo-bar" + t.Run( + tt.desc, func(t *testing.T) { + instanceId := "foo-bar" - apiClient := &apiClientInstanceMocked{ - instanceId: instanceId, - instanceState: tt.instanceState, - instanceGetFails: tt.instanceGetFails, - } - - var wantRes *sqlserverflex.GetInstanceResponse - if tt.wantResp { - wantRes = &sqlserverflex.GetInstanceResponse{ - Id: &instanceId, - Status: sqlserverflex.GetInstanceResponseGetStatusAttributeType(utils.Ptr(tt.instanceState)), + apiClient := &apiClientInstanceMocked{ + instanceId: instanceId, + instanceState: tt.instanceState, + instanceGetFails: tt.instanceGetFails, } - } - handler := UpdateInstanceWaitHandler(context.Background(), apiClient, "", instanceId, "") + var wantRes *sqlserverflex.GetInstanceResponse + if tt.wantResp { + wantRes = &sqlserverflex.GetInstanceResponse{ + Id: &instanceId, + Status: sqlserverflex.GetInstanceResponseGetStatusAttributeType(utils.Ptr(tt.instanceState)), + } + } - gotRes, err := handler.SetTimeout(10 * time.Millisecond).SetSleepBeforeWait(1 * time.Millisecond).WaitWithContext(context.Background()) + handler := UpdateInstanceWaitHandler(context.Background(), apiClient, "", instanceId, "") - if (err != nil) != tt.wantErr { - t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr) - } - if !cmp.Equal(gotRes, wantRes) { - t.Fatalf("handler gotRes = %v, want %v", gotRes, wantRes) - } - }) + gotRes, err := handler.SetTimeout(10 * time.Millisecond).SetSleepBeforeWait(1 * time.Millisecond).WaitWithContext(context.Background()) + + if (err != nil) != tt.wantErr { + t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr) + } + if !cmp.Equal(gotRes, wantRes) { + t.Fatalf("handler gotRes = %v, want %v", gotRes, wantRes) + } + }, + ) } } @@ -236,23 +263,25 @@ func TestDeleteInstanceWaitHandler(t *testing.T) { }, } for _, tt := range tests { - t.Run(tt.desc, func(t *testing.T) { - instanceId := "foo-bar" + t.Run( + tt.desc, func(t *testing.T) { + instanceId := "foo-bar" - apiClient := &apiClientInstanceMocked{ - instanceGetFails: tt.instanceGetFails, - instanceIsDeleted: tt.instanceState == InstanceStateSuccess, - instanceId: instanceId, - instanceState: tt.instanceState, - } + apiClient := &apiClientInstanceMocked{ + instanceGetFails: tt.instanceGetFails, + instanceIsDeleted: tt.instanceState == InstanceStateSuccess, + instanceId: instanceId, + instanceState: tt.instanceState, + } - handler := DeleteInstanceWaitHandler(context.Background(), apiClient, "", instanceId, "") + handler := DeleteInstanceWaitHandler(context.Background(), apiClient, "", instanceId, "") - _, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(context.Background()) + _, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(context.Background()) - if (err != nil) != tt.wantErr { - t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr) - } - }) + if (err != nil) != tt.wantErr { + t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr) + } + }, + ) } }