From 1451273760089f01b1a5cd6e3855f62eb6144ba3 Mon Sep 17 00:00:00 2001 From: "Marcel S. Henselin" Date: Mon, 16 Feb 2026 14:39:15 +0100 Subject: [PATCH 1/4] fix: try fix errors --- .../postgresflexalpha/instance/resource.go | 2 +- .../testdata/instance_template.gompl | 2 +- .../sqlserverflexalpha/database/resource.go | 2 +- .../sqlserverflexalpha/instance/resource.go | 2 +- .../sqlserverflexalpha/user/mapper_test.go | 18 ++--- .../sqlserverflexbeta/database/resource.go | 2 +- .../sqlserverflexbeta/instance/resource.go | 9 +-- .../sqlserverflex_acc_test.go | 65 ++++++++++++++++++- .../services/sqlserverflexbeta/user/mapper.go | 19 ++++-- .../sqlserverflexbeta/user/mapper_test.go | 14 ++-- .../sqlserverflexbeta/user/planModifiers.yaml | 4 ++ .../sqlserverflexbeta/user/resource.go | 33 ++++++++++ .../internal/wait/postgresflexalpha/wait.go | 2 +- .../internal/wait/sqlserverflexbeta/wait.go | 6 +- 14 files changed, 140 insertions(+), 40 deletions(-) diff --git a/stackit/internal/services/postgresflexalpha/instance/resource.go b/stackit/internal/services/postgresflexalpha/instance/resource.go index 0b354c64..f6402220 100644 --- a/stackit/internal/services/postgresflexalpha/instance/resource.go +++ b/stackit/internal/services/postgresflexalpha/instance/resource.go @@ -593,7 +593,7 @@ func (r *instanceResource) ImportState( ctx, &resp.Diagnostics, "Error importing instance", fmt.Sprintf( - "Expected import identifier with format: [project_id],[region],[instance_id] Got: %q", + "Expected import identifier with format [project_id],[region],[instance_id] Got: %q", req.ID, ), ) diff --git a/stackit/internal/services/postgresflexalpha/testdata/instance_template.gompl b/stackit/internal/services/postgresflexalpha/testdata/instance_template.gompl index 83444f7c..260f0b57 100644 --- a/stackit/internal/services/postgresflexalpha/testdata/instance_template.gompl +++ b/stackit/internal/services/postgresflexalpha/testdata/instance_template.gompl @@ -48,7 +48,7 @@ resource "stackitprivatepreview_postgresflexalpha_database" "{{ $db.Name }}" { project_id = "{{ $db.ProjectId }}" instance_id = stackitprivatepreview_postgresflexalpha_instance.{{ $tfName }}.instance_id name = "{{ $db.Name }}" - owner = "{{ $db.Owner }}" + owner = stackitprivatepreview_postgresflexalpha_user.{{ $db.Owner }}.name } {{ end }} {{ end }} diff --git a/stackit/internal/services/sqlserverflexalpha/database/resource.go b/stackit/internal/services/sqlserverflexalpha/database/resource.go index e7887330..91761b18 100644 --- a/stackit/internal/services/sqlserverflexalpha/database/resource.go +++ b/stackit/internal/services/sqlserverflexalpha/database/resource.go @@ -548,7 +548,7 @@ func (r *databaseResource) ImportState( ctx, &resp.Diagnostics, "Error importing database", fmt.Sprintf( - "Expected import identifier with format: [project_id],[region],[instance_id],[database_name] Got: %q", + "Expected import identifier with format [project_id],[region],[instance_id],[database_name] Got: %q", req.ID, ), ) diff --git a/stackit/internal/services/sqlserverflexalpha/instance/resource.go b/stackit/internal/services/sqlserverflexalpha/instance/resource.go index 41f9027c..6adf07df 100644 --- a/stackit/internal/services/sqlserverflexalpha/instance/resource.go +++ b/stackit/internal/services/sqlserverflexalpha/instance/resource.go @@ -523,7 +523,7 @@ func (r *instanceResource) ImportState( ctx, &resp.Diagnostics, "Error importing instance", fmt.Sprintf( - "Expected import identifier with format: [project_id],[region],[instance_id] Got: %q", + "Expected import identifier with format [project_id],[region],[instance_id] Got: %q", req.ID, ), ) diff --git a/stackit/internal/services/sqlserverflexalpha/user/mapper_test.go b/stackit/internal/services/sqlserverflexalpha/user/mapper_test.go index f981eb0e..b116b8dd 100644 --- a/stackit/internal/services/sqlserverflexalpha/user/mapper_test.go +++ b/stackit/internal/services/sqlserverflexalpha/user/mapper_test.go @@ -63,9 +63,9 @@ func TestMapDataSourceFields(t *testing.T) { Roles: types.List( types.SetValueMust( types.StringType, []attr.Value{ + types.StringValue(""), types.StringValue("role_1"), types.StringValue("role_2"), - types.StringValue(""), }, ), ), @@ -138,7 +138,7 @@ func TestMapDataSourceFields(t *testing.T) { t.Fatalf("Should not have failed: %v", err) } if tt.isValid { - diff := cmp.Diff(state, &tt.expected) + diff := cmp.Diff(&tt.expected, state) if diff != "" { t.Fatalf("Data does not match: %s", diff) } @@ -183,8 +183,8 @@ func TestMapFieldsCreate(t *testing.T) { &sqlserverflexalpha.CreateUserResponse{ Id: utils.Ptr(int64(2)), Roles: &[]string{ - "role_1", "role_2", + "role_1", "", }, Username: utils.Ptr("username"), @@ -204,9 +204,9 @@ func TestMapFieldsCreate(t *testing.T) { Roles: types.List( types.SetValueMust( types.StringType, []attr.Value{ + types.StringValue(""), types.StringValue("role_1"), types.StringValue("role_2"), - types.StringValue(""), }, ), ), @@ -292,7 +292,7 @@ func TestMapFieldsCreate(t *testing.T) { t.Fatalf("Should not have failed: %v", err) } if tt.isValid { - diff := cmp.Diff(state, &tt.expected) + diff := cmp.Diff(&tt.expected, state) if diff != "" { t.Fatalf("Data does not match: %s", diff) } @@ -332,8 +332,8 @@ func TestMapFields(t *testing.T) { "simple_values", &sqlserverflexalpha.GetUserResponse{ Roles: &[]string{ - "role_1", "role_2", + "role_1", "", }, Username: utils.Ptr("username"), @@ -350,9 +350,9 @@ func TestMapFields(t *testing.T) { Roles: types.List( types.SetValueMust( types.StringType, []attr.Value{ + types.StringValue(""), types.StringValue("role_1"), types.StringValue("role_2"), - types.StringValue(""), }, ), ), @@ -423,7 +423,7 @@ func TestMapFields(t *testing.T) { t.Fatalf("Should not have failed: %v", err) } if tt.isValid { - diff := cmp.Diff(state, &tt.expected) + diff := cmp.Diff(&tt.expected, state) if diff != "" { t.Fatalf("Data does not match: %s", diff) } @@ -516,7 +516,7 @@ func TestToCreatePayload(t *testing.T) { t.Fatalf("Should not have failed: %v", err) } if tt.isValid { - diff := cmp.Diff(output, tt.expected) + diff := cmp.Diff(tt.expected, output) if diff != "" { t.Fatalf("Data does not match: %s", diff) } diff --git a/stackit/internal/services/sqlserverflexbeta/database/resource.go b/stackit/internal/services/sqlserverflexbeta/database/resource.go index 39879cae..8eb93b54 100644 --- a/stackit/internal/services/sqlserverflexbeta/database/resource.go +++ b/stackit/internal/services/sqlserverflexbeta/database/resource.go @@ -548,7 +548,7 @@ func (r *databaseResource) ImportState( ctx, &resp.Diagnostics, "Error importing database", fmt.Sprintf( - "Expected import identifier with format: [project_id],[region],[instance_id],[database_name] Got: %q", + "Expected import identifier with format [project_id],[region],[instance_id],[database_name] Got: %q", req.ID, ), ) diff --git a/stackit/internal/services/sqlserverflexbeta/instance/resource.go b/stackit/internal/services/sqlserverflexbeta/instance/resource.go index c04c1fd3..404f665b 100644 --- a/stackit/internal/services/sqlserverflexbeta/instance/resource.go +++ b/stackit/internal/services/sqlserverflexbeta/instance/resource.go @@ -293,13 +293,6 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r return } - // Read identity data - var identityData InstanceResourceIdentityModel - resp.Diagnostics.Append(req.Identity.Get(ctx, &identityData)...) - if resp.Diagnostics.HasError() { - return - } - ctx = core.InitProviderContext(ctx) projectId := data.ProjectId.ValueString() @@ -523,7 +516,7 @@ func (r *instanceResource) ImportState( ctx, &resp.Diagnostics, "Error importing instance", fmt.Sprintf( - "Expected import identifier with format: [project_id],[region],[instance_id] Got: %q", + "Expected import identifier with format [project_id],[region],[instance_id] Got: %q", req.ID, ), ) diff --git a/stackit/internal/services/sqlserverflexbeta/sqlserverflex_acc_test.go b/stackit/internal/services/sqlserverflexbeta/sqlserverflex_acc_test.go index e3fd5473..0f0b47ea 100644 --- a/stackit/internal/services/sqlserverflexbeta/sqlserverflex_acc_test.go +++ b/stackit/internal/services/sqlserverflexbeta/sqlserverflex_acc_test.go @@ -15,7 +15,7 @@ import ( "github.com/stackitcloud/stackit-sdk-go/core/config" "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/internal/testutils" - sqlserverflexbeta2 "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/pkg_gen/sqlserverflexbeta" sqlserverflexbeta "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta/instance" // The fwresource import alias is so there is no collision @@ -36,7 +36,7 @@ func init() { F: func(region string) error { ctx := context.Background() apiClientConfigOptions := []config.ConfigurationOption{} - apiClient, err := sqlserverflexbeta2.NewAPIClient(apiClientConfigOptions...) + apiClient, err := sqlserverflexbetaResGen.NewAPIClient(apiClientConfigOptions...) if err != nil { log.Fatalln(err) } @@ -228,6 +228,67 @@ func TestAccInstance(t *testing.T) { }) } +func TestAccInstanceReApply(t *testing.T) { + exData := getExample() + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + t.Logf(" ... working on instance %s", exData.TfName) + testInstances = append(testInstances, exData.TfName) + }, + ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Create and verify + { + Config: testutils.StringFromTemplateMust( + "testdata/instance_template.gompl", + exData, + ), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(resName("instance", exData.TfName), "name", exData.Name), + resource.TestCheckResourceAttrSet(resName("instance", exData.TfName), "id"), + // TODO: check all fields + ), + }, + // Create and verify + { + Config: testutils.StringFromTemplateMust( + "testdata/instance_template.gompl", + exData, + ), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(resName("instance", exData.TfName), "name", exData.Name), + resource.TestCheckResourceAttrSet(resName("instance", exData.TfName), "id"), + // TODO: check all fields + ), + }, + { + RefreshState: true, + }, + // Create and verify + { + Config: testutils.StringFromTemplateMust( + "testdata/instance_template.gompl", + exData, + ), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(resName("instance", exData.TfName), "name", exData.Name), + resource.TestCheckResourceAttrSet(resName("instance", exData.TfName), "id"), + // TODO: check all fields + ), + }, + // Import test + { + ResourceName: resName("instance", exData.TfName), + ImportStateKind: resource.ImportBlockWithResourceIdentity, + ImportState: true, + // ImportStateVerify is not supported with plannable import blocks + // ImportStateVerify: true, + }, + }, + }) +} + func TestAccInstanceNoEncryption(t *testing.T) { data := getExample() diff --git a/stackit/internal/services/sqlserverflexbeta/user/mapper.go b/stackit/internal/services/sqlserverflexbeta/user/mapper.go index 3674ac0b..54ba2547 100644 --- a/stackit/internal/services/sqlserverflexbeta/user/mapper.go +++ b/stackit/internal/services/sqlserverflexbeta/user/mapper.go @@ -46,7 +46,9 @@ func mapDataSourceFields(userResp *sqlserverflexbeta.GetUserResponse, model *dat model.Roles = types.List(types.SetNull(types.StringType)) } else { var roles []attr.Value - for _, role := range *user.Roles { + resRoles := *user.Roles + slices.Sort(resRoles) + for _, role := range resRoles { roles = append(roles, types.StringValue(string(role))) } rolesSet, diags := types.SetValue(types.StringType, roles) @@ -183,9 +185,14 @@ func toCreatePayload( return nil, fmt.Errorf("nil model") } - return &sqlserverflexbeta.CreateUserRequestPayload{ - Username: conversion.StringValueToPointer(model.Username), - DefaultDatabase: conversion.StringValueToPointer(model.DefaultDatabase), - Roles: &roles, - }, nil + pl := sqlserverflexbeta.CreateUserRequestPayload{ + Username: conversion.StringValueToPointer(model.Username), + Roles: &roles, + } + slices.Sort(roles) + if !model.DefaultDatabase.IsNull() || !model.DefaultDatabase.IsUnknown() { + pl.DefaultDatabase = conversion.StringValueToPointer(model.DefaultDatabase) + } + + return &pl, nil } diff --git a/stackit/internal/services/sqlserverflexbeta/user/mapper_test.go b/stackit/internal/services/sqlserverflexbeta/user/mapper_test.go index b0e2bb02..c0e09bda 100644 --- a/stackit/internal/services/sqlserverflexbeta/user/mapper_test.go +++ b/stackit/internal/services/sqlserverflexbeta/user/mapper_test.go @@ -63,9 +63,9 @@ func TestMapDataSourceFields(t *testing.T) { Roles: types.List( types.SetValueMust( types.StringType, []attr.Value{ + types.StringValue(""), types.StringValue("role_1"), types.StringValue("role_2"), - types.StringValue(""), }, ), ), @@ -138,7 +138,7 @@ func TestMapDataSourceFields(t *testing.T) { t.Fatalf("Should not have failed: %v", err) } if tt.isValid { - diff := cmp.Diff(state, &tt.expected) + diff := cmp.Diff(&tt.expected, state) if diff != "" { t.Fatalf("Data does not match: %s", diff) } @@ -204,9 +204,9 @@ func TestMapFieldsCreate(t *testing.T) { Roles: types.List( types.SetValueMust( types.StringType, []attr.Value{ + types.StringValue(""), types.StringValue("role_1"), types.StringValue("role_2"), - types.StringValue(""), }, ), ), @@ -292,7 +292,7 @@ func TestMapFieldsCreate(t *testing.T) { t.Fatalf("Should not have failed: %v", err) } if tt.isValid { - diff := cmp.Diff(state, &tt.expected) + diff := cmp.Diff(&tt.expected, state) if diff != "" { t.Fatalf("Data does not match: %s", diff) } @@ -332,8 +332,8 @@ func TestMapFields(t *testing.T) { "simple_values", &sqlserverflexbeta.GetUserResponse{ Roles: &[]string{ - "role_1", "role_2", + "role_1", "", }, Username: utils.Ptr("username"), @@ -350,9 +350,9 @@ func TestMapFields(t *testing.T) { Roles: types.List( types.SetValueMust( types.StringType, []attr.Value{ + types.StringValue(""), types.StringValue("role_1"), types.StringValue("role_2"), - types.StringValue(""), }, ), ), @@ -423,7 +423,7 @@ func TestMapFields(t *testing.T) { t.Fatalf("Should not have failed: %v", err) } if tt.isValid { - diff := cmp.Diff(state, &tt.expected) + diff := cmp.Diff(&tt.expected, state) if diff != "" { t.Fatalf("Data does not match: %s", diff) } diff --git a/stackit/internal/services/sqlserverflexbeta/user/planModifiers.yaml b/stackit/internal/services/sqlserverflexbeta/user/planModifiers.yaml index 8ff346ab..43b029e8 100644 --- a/stackit/internal/services/sqlserverflexbeta/user/planModifiers.yaml +++ b/stackit/internal/services/sqlserverflexbeta/user/planModifiers.yaml @@ -2,6 +2,7 @@ fields: - name: 'id' modifiers: - 'UseStateForUnknown' + - 'RequiresReplace' - name: 'instance_id' validators: @@ -22,6 +23,7 @@ fields: - name: 'region' modifiers: - 'RequiresReplace' + - 'RequiresReplace' - name: 'user_id' modifiers: @@ -31,10 +33,12 @@ fields: - name: 'username' modifiers: - 'UseStateForUnknown' + - 'RequiresReplace' - name: 'roles' modifiers: - 'UseStateForUnknown' + - 'RequiresReplace' - name: 'password' modifiers: diff --git a/stackit/internal/services/sqlserverflexbeta/user/resource.go b/stackit/internal/services/sqlserverflexbeta/user/resource.go index 8f19eb61..9159cf01 100644 --- a/stackit/internal/services/sqlserverflexbeta/user/resource.go +++ b/stackit/internal/services/sqlserverflexbeta/user/resource.go @@ -11,6 +11,7 @@ import ( "strings" "time" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/identityschema" @@ -107,6 +108,38 @@ func (r *userResource) ModifyPlan( return } + // TODO: verify if this is needed - START + var configRoles []string + diags := configModel.Roles.ElementsAs(ctx, &configRoles, false) + resp.Diagnostics.Append(diags...) + if diags.HasError() { + return + } + + var planRoles []string + diags = planModel.Roles.ElementsAs(ctx, &planRoles, false) + resp.Diagnostics.Append(diags...) + if diags.HasError() { + return + } + + slices.Sort(configRoles) + slices.Sort(planRoles) + + if !slices.Equal(configRoles, planRoles) { + var roles []attr.Value + for _, role := range configRoles { + roles = append(roles, types.StringValue(string(role))) + } + rolesSet, diags := types.SetValue(types.StringType, roles) + resp.Diagnostics.Append(diags...) + if diags.HasError() { + return + } + planModel.Roles = types.List(rolesSet) + } + // TODO: verify if this is needed - END + resp.Diagnostics.Append(resp.Plan.Set(ctx, planModel)...) if resp.Diagnostics.HasError() { return diff --git a/stackit/internal/wait/postgresflexalpha/wait.go b/stackit/internal/wait/postgresflexalpha/wait.go index 5c41c4b1..57106cec 100644 --- a/stackit/internal/wait/postgresflexalpha/wait.go +++ b/stackit/internal/wait/postgresflexalpha/wait.go @@ -208,7 +208,7 @@ func PartialUpdateInstanceWaitHandler( case InstanceStateUnknown: return false, nil, nil case InstanceStateFailed: - return true, s, fmt.Errorf("update failed for instance with id %s", instanceId) + return true, s, fmt.Errorf("update got status FAILURE for instance with id %s", instanceId) } }, ) diff --git a/stackit/internal/wait/sqlserverflexbeta/wait.go b/stackit/internal/wait/sqlserverflexbeta/wait.go index d898b47a..41bfa2c1 100644 --- a/stackit/internal/wait/sqlserverflexbeta/wait.go +++ b/stackit/internal/wait/sqlserverflexbeta/wait.go @@ -161,8 +161,10 @@ func CreateInstanceWaitHandler( return false, nil, nil } return true, s, nil - case strings.ToLower(InstanceStateUnknown), strings.ToLower(InstanceStateFailed): - return true, nil, fmt.Errorf("create failed for instance with id %s", instanceId) + case strings.ToLower(InstanceStateUnknown): + return true, nil, fmt.Errorf("create failed for instance %s with status %s", instanceId, InstanceStateUnknown) + case strings.ToLower(InstanceStateFailed): + return true, nil, fmt.Errorf("create failed for instance %s with status %s", instanceId, InstanceStateFailed) case strings.ToLower(InstanceStatePending), strings.ToLower(InstanceStateProcessing): tflog.Info( ctx, "request is being handled", map[string]interface{}{ From 7ee82366d7d6bf6a62d0ad7542e43e4a67b6b59d Mon Sep 17 00:00:00 2001 From: "Marcel S. Henselin" Date: Mon, 16 Feb 2026 13:40:05 +0000 Subject: [PATCH 2/4] fix: try fix errors (#71) ## Description relates to #1234 ## Checklist - [ ] Issue was linked above - [ ] Code format was applied: `make fmt` - [ ] Examples were added / adjusted (see `examples/` directory) - [x] Docs are up-to-date: `make generate-docs` (will be checked by CI) - [ ] Unit tests got implemented or updated - [ ] Acceptance tests got implemented or updated (see e.g. [here](https://github.com/stackitcloud/terraform-provider-stackit/blob/f5f99d170996b208672ae684b6da53420e369563/stackit/internal/services/dns/dns_acc_test.go)) - [x] Unit tests are passing: `make test` (will be checked by CI) - [x] No linter issues: `make lint` (will be checked by CI) Reviewed-on: https://tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pulls/71 Co-authored-by: Marcel S. Henselin Co-committed-by: Marcel S. Henselin --- .../postgresflexalpha/instance/resource.go | 2 +- .../testdata/instance_template.gompl | 2 +- .../sqlserverflexalpha/database/resource.go | 2 +- .../sqlserverflexalpha/instance/resource.go | 2 +- .../sqlserverflexalpha/user/mapper_test.go | 18 ++--- .../sqlserverflexbeta/database/resource.go | 2 +- .../sqlserverflexbeta/instance/resource.go | 9 +-- .../sqlserverflex_acc_test.go | 65 ++++++++++++++++++- .../services/sqlserverflexbeta/user/mapper.go | 19 ++++-- .../sqlserverflexbeta/user/mapper_test.go | 14 ++-- .../sqlserverflexbeta/user/planModifiers.yaml | 4 ++ .../sqlserverflexbeta/user/resource.go | 33 ++++++++++ .../internal/wait/postgresflexalpha/wait.go | 2 +- .../internal/wait/sqlserverflexbeta/wait.go | 6 +- 14 files changed, 140 insertions(+), 40 deletions(-) diff --git a/stackit/internal/services/postgresflexalpha/instance/resource.go b/stackit/internal/services/postgresflexalpha/instance/resource.go index 0b354c64..f6402220 100644 --- a/stackit/internal/services/postgresflexalpha/instance/resource.go +++ b/stackit/internal/services/postgresflexalpha/instance/resource.go @@ -593,7 +593,7 @@ func (r *instanceResource) ImportState( ctx, &resp.Diagnostics, "Error importing instance", fmt.Sprintf( - "Expected import identifier with format: [project_id],[region],[instance_id] Got: %q", + "Expected import identifier with format [project_id],[region],[instance_id] Got: %q", req.ID, ), ) diff --git a/stackit/internal/services/postgresflexalpha/testdata/instance_template.gompl b/stackit/internal/services/postgresflexalpha/testdata/instance_template.gompl index 83444f7c..260f0b57 100644 --- a/stackit/internal/services/postgresflexalpha/testdata/instance_template.gompl +++ b/stackit/internal/services/postgresflexalpha/testdata/instance_template.gompl @@ -48,7 +48,7 @@ resource "stackitprivatepreview_postgresflexalpha_database" "{{ $db.Name }}" { project_id = "{{ $db.ProjectId }}" instance_id = stackitprivatepreview_postgresflexalpha_instance.{{ $tfName }}.instance_id name = "{{ $db.Name }}" - owner = "{{ $db.Owner }}" + owner = stackitprivatepreview_postgresflexalpha_user.{{ $db.Owner }}.name } {{ end }} {{ end }} diff --git a/stackit/internal/services/sqlserverflexalpha/database/resource.go b/stackit/internal/services/sqlserverflexalpha/database/resource.go index e7887330..91761b18 100644 --- a/stackit/internal/services/sqlserverflexalpha/database/resource.go +++ b/stackit/internal/services/sqlserverflexalpha/database/resource.go @@ -548,7 +548,7 @@ func (r *databaseResource) ImportState( ctx, &resp.Diagnostics, "Error importing database", fmt.Sprintf( - "Expected import identifier with format: [project_id],[region],[instance_id],[database_name] Got: %q", + "Expected import identifier with format [project_id],[region],[instance_id],[database_name] Got: %q", req.ID, ), ) diff --git a/stackit/internal/services/sqlserverflexalpha/instance/resource.go b/stackit/internal/services/sqlserverflexalpha/instance/resource.go index 41f9027c..6adf07df 100644 --- a/stackit/internal/services/sqlserverflexalpha/instance/resource.go +++ b/stackit/internal/services/sqlserverflexalpha/instance/resource.go @@ -523,7 +523,7 @@ func (r *instanceResource) ImportState( ctx, &resp.Diagnostics, "Error importing instance", fmt.Sprintf( - "Expected import identifier with format: [project_id],[region],[instance_id] Got: %q", + "Expected import identifier with format [project_id],[region],[instance_id] Got: %q", req.ID, ), ) diff --git a/stackit/internal/services/sqlserverflexalpha/user/mapper_test.go b/stackit/internal/services/sqlserverflexalpha/user/mapper_test.go index f981eb0e..b116b8dd 100644 --- a/stackit/internal/services/sqlserverflexalpha/user/mapper_test.go +++ b/stackit/internal/services/sqlserverflexalpha/user/mapper_test.go @@ -63,9 +63,9 @@ func TestMapDataSourceFields(t *testing.T) { Roles: types.List( types.SetValueMust( types.StringType, []attr.Value{ + types.StringValue(""), types.StringValue("role_1"), types.StringValue("role_2"), - types.StringValue(""), }, ), ), @@ -138,7 +138,7 @@ func TestMapDataSourceFields(t *testing.T) { t.Fatalf("Should not have failed: %v", err) } if tt.isValid { - diff := cmp.Diff(state, &tt.expected) + diff := cmp.Diff(&tt.expected, state) if diff != "" { t.Fatalf("Data does not match: %s", diff) } @@ -183,8 +183,8 @@ func TestMapFieldsCreate(t *testing.T) { &sqlserverflexalpha.CreateUserResponse{ Id: utils.Ptr(int64(2)), Roles: &[]string{ - "role_1", "role_2", + "role_1", "", }, Username: utils.Ptr("username"), @@ -204,9 +204,9 @@ func TestMapFieldsCreate(t *testing.T) { Roles: types.List( types.SetValueMust( types.StringType, []attr.Value{ + types.StringValue(""), types.StringValue("role_1"), types.StringValue("role_2"), - types.StringValue(""), }, ), ), @@ -292,7 +292,7 @@ func TestMapFieldsCreate(t *testing.T) { t.Fatalf("Should not have failed: %v", err) } if tt.isValid { - diff := cmp.Diff(state, &tt.expected) + diff := cmp.Diff(&tt.expected, state) if diff != "" { t.Fatalf("Data does not match: %s", diff) } @@ -332,8 +332,8 @@ func TestMapFields(t *testing.T) { "simple_values", &sqlserverflexalpha.GetUserResponse{ Roles: &[]string{ - "role_1", "role_2", + "role_1", "", }, Username: utils.Ptr("username"), @@ -350,9 +350,9 @@ func TestMapFields(t *testing.T) { Roles: types.List( types.SetValueMust( types.StringType, []attr.Value{ + types.StringValue(""), types.StringValue("role_1"), types.StringValue("role_2"), - types.StringValue(""), }, ), ), @@ -423,7 +423,7 @@ func TestMapFields(t *testing.T) { t.Fatalf("Should not have failed: %v", err) } if tt.isValid { - diff := cmp.Diff(state, &tt.expected) + diff := cmp.Diff(&tt.expected, state) if diff != "" { t.Fatalf("Data does not match: %s", diff) } @@ -516,7 +516,7 @@ func TestToCreatePayload(t *testing.T) { t.Fatalf("Should not have failed: %v", err) } if tt.isValid { - diff := cmp.Diff(output, tt.expected) + diff := cmp.Diff(tt.expected, output) if diff != "" { t.Fatalf("Data does not match: %s", diff) } diff --git a/stackit/internal/services/sqlserverflexbeta/database/resource.go b/stackit/internal/services/sqlserverflexbeta/database/resource.go index 39879cae..8eb93b54 100644 --- a/stackit/internal/services/sqlserverflexbeta/database/resource.go +++ b/stackit/internal/services/sqlserverflexbeta/database/resource.go @@ -548,7 +548,7 @@ func (r *databaseResource) ImportState( ctx, &resp.Diagnostics, "Error importing database", fmt.Sprintf( - "Expected import identifier with format: [project_id],[region],[instance_id],[database_name] Got: %q", + "Expected import identifier with format [project_id],[region],[instance_id],[database_name] Got: %q", req.ID, ), ) diff --git a/stackit/internal/services/sqlserverflexbeta/instance/resource.go b/stackit/internal/services/sqlserverflexbeta/instance/resource.go index c04c1fd3..404f665b 100644 --- a/stackit/internal/services/sqlserverflexbeta/instance/resource.go +++ b/stackit/internal/services/sqlserverflexbeta/instance/resource.go @@ -293,13 +293,6 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r return } - // Read identity data - var identityData InstanceResourceIdentityModel - resp.Diagnostics.Append(req.Identity.Get(ctx, &identityData)...) - if resp.Diagnostics.HasError() { - return - } - ctx = core.InitProviderContext(ctx) projectId := data.ProjectId.ValueString() @@ -523,7 +516,7 @@ func (r *instanceResource) ImportState( ctx, &resp.Diagnostics, "Error importing instance", fmt.Sprintf( - "Expected import identifier with format: [project_id],[region],[instance_id] Got: %q", + "Expected import identifier with format [project_id],[region],[instance_id] Got: %q", req.ID, ), ) diff --git a/stackit/internal/services/sqlserverflexbeta/sqlserverflex_acc_test.go b/stackit/internal/services/sqlserverflexbeta/sqlserverflex_acc_test.go index e3fd5473..0f0b47ea 100644 --- a/stackit/internal/services/sqlserverflexbeta/sqlserverflex_acc_test.go +++ b/stackit/internal/services/sqlserverflexbeta/sqlserverflex_acc_test.go @@ -15,7 +15,7 @@ import ( "github.com/stackitcloud/stackit-sdk-go/core/config" "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/internal/testutils" - sqlserverflexbeta2 "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/pkg_gen/sqlserverflexbeta" sqlserverflexbeta "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta/instance" // The fwresource import alias is so there is no collision @@ -36,7 +36,7 @@ func init() { F: func(region string) error { ctx := context.Background() apiClientConfigOptions := []config.ConfigurationOption{} - apiClient, err := sqlserverflexbeta2.NewAPIClient(apiClientConfigOptions...) + apiClient, err := sqlserverflexbetaResGen.NewAPIClient(apiClientConfigOptions...) if err != nil { log.Fatalln(err) } @@ -228,6 +228,67 @@ func TestAccInstance(t *testing.T) { }) } +func TestAccInstanceReApply(t *testing.T) { + exData := getExample() + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + t.Logf(" ... working on instance %s", exData.TfName) + testInstances = append(testInstances, exData.TfName) + }, + ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Create and verify + { + Config: testutils.StringFromTemplateMust( + "testdata/instance_template.gompl", + exData, + ), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(resName("instance", exData.TfName), "name", exData.Name), + resource.TestCheckResourceAttrSet(resName("instance", exData.TfName), "id"), + // TODO: check all fields + ), + }, + // Create and verify + { + Config: testutils.StringFromTemplateMust( + "testdata/instance_template.gompl", + exData, + ), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(resName("instance", exData.TfName), "name", exData.Name), + resource.TestCheckResourceAttrSet(resName("instance", exData.TfName), "id"), + // TODO: check all fields + ), + }, + { + RefreshState: true, + }, + // Create and verify + { + Config: testutils.StringFromTemplateMust( + "testdata/instance_template.gompl", + exData, + ), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(resName("instance", exData.TfName), "name", exData.Name), + resource.TestCheckResourceAttrSet(resName("instance", exData.TfName), "id"), + // TODO: check all fields + ), + }, + // Import test + { + ResourceName: resName("instance", exData.TfName), + ImportStateKind: resource.ImportBlockWithResourceIdentity, + ImportState: true, + // ImportStateVerify is not supported with plannable import blocks + // ImportStateVerify: true, + }, + }, + }) +} + func TestAccInstanceNoEncryption(t *testing.T) { data := getExample() diff --git a/stackit/internal/services/sqlserverflexbeta/user/mapper.go b/stackit/internal/services/sqlserverflexbeta/user/mapper.go index 3674ac0b..54ba2547 100644 --- a/stackit/internal/services/sqlserverflexbeta/user/mapper.go +++ b/stackit/internal/services/sqlserverflexbeta/user/mapper.go @@ -46,7 +46,9 @@ func mapDataSourceFields(userResp *sqlserverflexbeta.GetUserResponse, model *dat model.Roles = types.List(types.SetNull(types.StringType)) } else { var roles []attr.Value - for _, role := range *user.Roles { + resRoles := *user.Roles + slices.Sort(resRoles) + for _, role := range resRoles { roles = append(roles, types.StringValue(string(role))) } rolesSet, diags := types.SetValue(types.StringType, roles) @@ -183,9 +185,14 @@ func toCreatePayload( return nil, fmt.Errorf("nil model") } - return &sqlserverflexbeta.CreateUserRequestPayload{ - Username: conversion.StringValueToPointer(model.Username), - DefaultDatabase: conversion.StringValueToPointer(model.DefaultDatabase), - Roles: &roles, - }, nil + pl := sqlserverflexbeta.CreateUserRequestPayload{ + Username: conversion.StringValueToPointer(model.Username), + Roles: &roles, + } + slices.Sort(roles) + if !model.DefaultDatabase.IsNull() || !model.DefaultDatabase.IsUnknown() { + pl.DefaultDatabase = conversion.StringValueToPointer(model.DefaultDatabase) + } + + return &pl, nil } diff --git a/stackit/internal/services/sqlserverflexbeta/user/mapper_test.go b/stackit/internal/services/sqlserverflexbeta/user/mapper_test.go index b0e2bb02..c0e09bda 100644 --- a/stackit/internal/services/sqlserverflexbeta/user/mapper_test.go +++ b/stackit/internal/services/sqlserverflexbeta/user/mapper_test.go @@ -63,9 +63,9 @@ func TestMapDataSourceFields(t *testing.T) { Roles: types.List( types.SetValueMust( types.StringType, []attr.Value{ + types.StringValue(""), types.StringValue("role_1"), types.StringValue("role_2"), - types.StringValue(""), }, ), ), @@ -138,7 +138,7 @@ func TestMapDataSourceFields(t *testing.T) { t.Fatalf("Should not have failed: %v", err) } if tt.isValid { - diff := cmp.Diff(state, &tt.expected) + diff := cmp.Diff(&tt.expected, state) if diff != "" { t.Fatalf("Data does not match: %s", diff) } @@ -204,9 +204,9 @@ func TestMapFieldsCreate(t *testing.T) { Roles: types.List( types.SetValueMust( types.StringType, []attr.Value{ + types.StringValue(""), types.StringValue("role_1"), types.StringValue("role_2"), - types.StringValue(""), }, ), ), @@ -292,7 +292,7 @@ func TestMapFieldsCreate(t *testing.T) { t.Fatalf("Should not have failed: %v", err) } if tt.isValid { - diff := cmp.Diff(state, &tt.expected) + diff := cmp.Diff(&tt.expected, state) if diff != "" { t.Fatalf("Data does not match: %s", diff) } @@ -332,8 +332,8 @@ func TestMapFields(t *testing.T) { "simple_values", &sqlserverflexbeta.GetUserResponse{ Roles: &[]string{ - "role_1", "role_2", + "role_1", "", }, Username: utils.Ptr("username"), @@ -350,9 +350,9 @@ func TestMapFields(t *testing.T) { Roles: types.List( types.SetValueMust( types.StringType, []attr.Value{ + types.StringValue(""), types.StringValue("role_1"), types.StringValue("role_2"), - types.StringValue(""), }, ), ), @@ -423,7 +423,7 @@ func TestMapFields(t *testing.T) { t.Fatalf("Should not have failed: %v", err) } if tt.isValid { - diff := cmp.Diff(state, &tt.expected) + diff := cmp.Diff(&tt.expected, state) if diff != "" { t.Fatalf("Data does not match: %s", diff) } diff --git a/stackit/internal/services/sqlserverflexbeta/user/planModifiers.yaml b/stackit/internal/services/sqlserverflexbeta/user/planModifiers.yaml index 8ff346ab..43b029e8 100644 --- a/stackit/internal/services/sqlserverflexbeta/user/planModifiers.yaml +++ b/stackit/internal/services/sqlserverflexbeta/user/planModifiers.yaml @@ -2,6 +2,7 @@ fields: - name: 'id' modifiers: - 'UseStateForUnknown' + - 'RequiresReplace' - name: 'instance_id' validators: @@ -22,6 +23,7 @@ fields: - name: 'region' modifiers: - 'RequiresReplace' + - 'RequiresReplace' - name: 'user_id' modifiers: @@ -31,10 +33,12 @@ fields: - name: 'username' modifiers: - 'UseStateForUnknown' + - 'RequiresReplace' - name: 'roles' modifiers: - 'UseStateForUnknown' + - 'RequiresReplace' - name: 'password' modifiers: diff --git a/stackit/internal/services/sqlserverflexbeta/user/resource.go b/stackit/internal/services/sqlserverflexbeta/user/resource.go index 8f19eb61..9159cf01 100644 --- a/stackit/internal/services/sqlserverflexbeta/user/resource.go +++ b/stackit/internal/services/sqlserverflexbeta/user/resource.go @@ -11,6 +11,7 @@ import ( "strings" "time" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/identityschema" @@ -107,6 +108,38 @@ func (r *userResource) ModifyPlan( return } + // TODO: verify if this is needed - START + var configRoles []string + diags := configModel.Roles.ElementsAs(ctx, &configRoles, false) + resp.Diagnostics.Append(diags...) + if diags.HasError() { + return + } + + var planRoles []string + diags = planModel.Roles.ElementsAs(ctx, &planRoles, false) + resp.Diagnostics.Append(diags...) + if diags.HasError() { + return + } + + slices.Sort(configRoles) + slices.Sort(planRoles) + + if !slices.Equal(configRoles, planRoles) { + var roles []attr.Value + for _, role := range configRoles { + roles = append(roles, types.StringValue(string(role))) + } + rolesSet, diags := types.SetValue(types.StringType, roles) + resp.Diagnostics.Append(diags...) + if diags.HasError() { + return + } + planModel.Roles = types.List(rolesSet) + } + // TODO: verify if this is needed - END + resp.Diagnostics.Append(resp.Plan.Set(ctx, planModel)...) if resp.Diagnostics.HasError() { return diff --git a/stackit/internal/wait/postgresflexalpha/wait.go b/stackit/internal/wait/postgresflexalpha/wait.go index 5c41c4b1..57106cec 100644 --- a/stackit/internal/wait/postgresflexalpha/wait.go +++ b/stackit/internal/wait/postgresflexalpha/wait.go @@ -208,7 +208,7 @@ func PartialUpdateInstanceWaitHandler( case InstanceStateUnknown: return false, nil, nil case InstanceStateFailed: - return true, s, fmt.Errorf("update failed for instance with id %s", instanceId) + return true, s, fmt.Errorf("update got status FAILURE for instance with id %s", instanceId) } }, ) diff --git a/stackit/internal/wait/sqlserverflexbeta/wait.go b/stackit/internal/wait/sqlserverflexbeta/wait.go index d898b47a..41bfa2c1 100644 --- a/stackit/internal/wait/sqlserverflexbeta/wait.go +++ b/stackit/internal/wait/sqlserverflexbeta/wait.go @@ -161,8 +161,10 @@ func CreateInstanceWaitHandler( return false, nil, nil } return true, s, nil - case strings.ToLower(InstanceStateUnknown), strings.ToLower(InstanceStateFailed): - return true, nil, fmt.Errorf("create failed for instance with id %s", instanceId) + case strings.ToLower(InstanceStateUnknown): + return true, nil, fmt.Errorf("create failed for instance %s with status %s", instanceId, InstanceStateUnknown) + case strings.ToLower(InstanceStateFailed): + return true, nil, fmt.Errorf("create failed for instance %s with status %s", instanceId, InstanceStateFailed) case strings.ToLower(InstanceStatePending), strings.ToLower(InstanceStateProcessing): tflog.Info( ctx, "request is being handled", map[string]interface{}{ From f83fe3b30b4e4ce580d3274a42bbb5aef6525319 Mon Sep 17 00:00:00 2001 From: "Marcel S. Henselin" Date: Mon, 16 Feb 2026 17:06:33 +0100 Subject: [PATCH 3/4] fix: try fix errors --- .../postgresflexalpha/database/resource.go | 20 +-- .../postgresflexalpha/user/mapper_test.go | 102 +++++++------- .../sqlserverflexalpha/database/resource.go | 124 ++++-------------- .../sqlserverflexalpha/user/mapper_test.go | 18 ++- .../sqlserverflexbeta/database/mapper.go | 5 +- .../sqlserverflexbeta/database/resource.go | 27 +--- .../sqlserverflex_acc_test.go | 4 +- .../services/sqlserverflexbeta/user/mapper.go | 12 +- .../sqlserverflexbeta/user/resource.go | 51 +++---- stackit/provider.go | 17 +-- 10 files changed, 137 insertions(+), 243 deletions(-) diff --git a/stackit/internal/services/postgresflexalpha/database/resource.go b/stackit/internal/services/postgresflexalpha/database/resource.go index fd3f225c..1cf3f2df 100644 --- a/stackit/internal/services/postgresflexalpha/database/resource.go +++ b/stackit/internal/services/postgresflexalpha/database/resource.go @@ -281,24 +281,12 @@ func (r *databaseResource) Read( return } - // Read identity data - var identityData DatabaseResourceIdentityModel - resp.Diagnostics.Append(req.Identity.Get(ctx, &identityData)...) - if resp.Diagnostics.HasError() { - return - } - ctx = core.InitProviderContext(ctx) - projectId, region, instanceId, databaseId, errExt := r.extractIdentityData(model, identityData) - if errExt != nil { - core.LogAndAddError( - ctx, - &resp.Diagnostics, - extractErrorSummary, - fmt.Sprintf(extractErrorMessage, errExt), - ) - } + projectId := model.ProjectId.ValueString() + instanceId := model.InstanceId.ValueString() + region := model.Region.ValueString() + databaseId := model.DatabaseId.ValueInt64() ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "instance_id", instanceId) diff --git a/stackit/internal/services/postgresflexalpha/user/mapper_test.go b/stackit/internal/services/postgresflexalpha/user/mapper_test.go index 1a8c3f99..5014d4ac 100644 --- a/stackit/internal/services/postgresflexalpha/user/mapper_test.go +++ b/stackit/internal/services/postgresflexalpha/user/mapper_test.go @@ -164,16 +164,16 @@ func TestMapFieldsCreate(t *testing.T) { }, testRegion, 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)), - Password: types.StringNull(), - Region: types.StringValue(testRegion), - Status: types.StringNull(), - ConnectionString: types.StringNull(), + 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)), + Password: types.StringNull(), + Region: types.StringValue(testRegion), + Status: types.StringNull(), + //ConnectionString: types.StringNull(), }, true, }, @@ -186,16 +186,16 @@ func TestMapFieldsCreate(t *testing.T) { }, testRegion, 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.SetNull(types.StringType)), - Password: types.StringNull(), - Region: types.StringValue(testRegion), - Status: types.StringValue("status"), - ConnectionString: types.StringNull(), + Id: types.Int64Value(1), + 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.StringNull(), }, true, }, @@ -208,16 +208,16 @@ func TestMapFieldsCreate(t *testing.T) { }, testRegion, 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)), - Password: types.StringNull(), - Region: types.StringValue(testRegion), - Status: types.StringNull(), - ConnectionString: types.StringNull(), + 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)), + Password: types.StringNull(), + Region: types.StringValue(testRegion), + Status: types.StringNull(), + //ConnectionString: types.StringNull(), }, true, }, @@ -285,15 +285,15 @@ func TestMapFields(t *testing.T) { }, testRegion, 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(), + 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, }, @@ -324,9 +324,9 @@ func TestMapFields(t *testing.T) { }, ), ), - Region: types.StringValue(testRegion), - Status: types.StringNull(), - ConnectionString: types.StringNull(), + Region: types.StringValue(testRegion), + Status: types.StringNull(), + //ConnectionString: types.StringNull(), }, true, }, @@ -338,15 +338,15 @@ func TestMapFields(t *testing.T) { }, testRegion, 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(), + 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, }, diff --git a/stackit/internal/services/sqlserverflexalpha/database/resource.go b/stackit/internal/services/sqlserverflexalpha/database/resource.go index 91761b18..eec284f1 100644 --- a/stackit/internal/services/sqlserverflexalpha/database/resource.go +++ b/stackit/internal/services/sqlserverflexalpha/database/resource.go @@ -186,25 +186,25 @@ func (r *databaseResource) Create(ctx context.Context, req resource.CreateReques payLoad.Name = data.Name.ValueStringPointer() payLoad.Owner = data.Owner.ValueStringPointer() - _, err := wait.WaitForUserWaitHandler( - ctx, - r.client, - projectId, - instanceId, - region, - data.Owner.ValueString(), - ). - SetSleepBeforeWait(10 * time.Second). - WaitWithContext(ctx) - if err != nil { - core.LogAndAddError( - ctx, - &resp.Diagnostics, - createErr, - fmt.Sprintf("Calling API: %v", err), - ) - return - } + //_, err := wait.WaitForUserWaitHandler( + // ctx, + // r.client, + // projectId, + // instanceId, + // region, + // data.Owner.ValueString(), + //). + // SetSleepBeforeWait(10 * time.Second). + // WaitWithContext(ctx) + //if err != nil { + // core.LogAndAddError( + // ctx, + // &resp.Diagnostics, + // createErr, + // fmt.Sprintf("Calling API: %v", err), + // ) + // return + //} createResp, err := r.client.CreateDatabaseRequest(ctx, projectId, region, instanceId). CreateDatabaseRequestPayload(payLoad). @@ -361,15 +361,10 @@ func (r *databaseResource) Read(ctx context.Context, req resource.ReadRequest, r ctx = core.InitProviderContext(ctx) - projectId, region, instanceId, databaseName, errExt := r.extractIdentityData(model, identityData) - if errExt != nil { - core.LogAndAddError( - ctx, - &resp.Diagnostics, - extractErrorSummary, - fmt.Sprintf(extractErrorMessage, errExt), - ) - } + projectId := model.ProjectId.ValueString() + region := model.Region.ValueString() + instanceId := model.InstanceId.ValueString() + databaseName := model.DatabaseName.ValueString() ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "instance_id", instanceId) @@ -445,15 +440,10 @@ func (r *databaseResource) Delete(ctx context.Context, req resource.DeleteReques ctx = core.InitProviderContext(ctx) - projectId, region, instanceId, databaseName, errExt := r.extractIdentityData(model, identityData) - if errExt != nil { - core.LogAndAddError( - ctx, - &resp.Diagnostics, - extractErrorSummary, - fmt.Sprintf(extractErrorMessage, errExt), - ) - } + projectId := model.ProjectId.ValueString() + region := model.Region.ValueString() + instanceId := model.InstanceId.ValueString() + databaseName := model.DatabaseName.ValueString() ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "instance_id", instanceId) @@ -508,23 +498,6 @@ func (r *databaseResource) ModifyPlan( return } - var identityModel DatabaseResourceIdentityModel - identityModel.ProjectID = planModel.ProjectId - identityModel.Region = planModel.Region - - if !planModel.InstanceId.IsNull() && !planModel.InstanceId.IsUnknown() { - identityModel.InstanceID = planModel.InstanceId - } - - if !planModel.Name.IsNull() && !planModel.Name.IsUnknown() { - identityModel.DatabaseName = planModel.Name - } - - resp.Diagnostics.Append(resp.Identity.Set(ctx, identityModel)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.Plan.Set(ctx, planModel)...) if resp.Diagnostics.HasError() { return @@ -594,46 +567,3 @@ func (r *databaseResource) ImportState( tflog.Info(ctx, "sqlserverflexalpha database state imported") } - -// extractIdentityData extracts essential identifiers from the resource model, falling back to the identity model. -func (r *databaseResource) extractIdentityData( - model resourceModel, - identity DatabaseResourceIdentityModel, -) (projectId, region, instanceId, databaseName string, err error) { - if !model.Name.IsNull() && !model.Name.IsUnknown() { - databaseName = model.Name.ValueString() - } else { - if identity.DatabaseName.IsNull() || identity.DatabaseName.IsUnknown() { - return "", "", "", "", fmt.Errorf("database_name not found in config") - } - databaseName = identity.DatabaseName.ValueString() - } - - if !model.ProjectId.IsNull() && !model.ProjectId.IsUnknown() { - projectId = model.ProjectId.ValueString() - } else { - if identity.ProjectID.IsNull() || identity.ProjectID.IsUnknown() { - return "", "", "", "", fmt.Errorf("project_id not found in config") - } - projectId = identity.ProjectID.ValueString() - } - - if !model.Region.IsNull() && !model.Region.IsUnknown() { - region = r.providerData.GetRegionWithOverride(model.Region) - } else { - if identity.Region.IsNull() || identity.Region.IsUnknown() { - return "", "", "", "", fmt.Errorf("region not found in config") - } - region = r.providerData.GetRegionWithOverride(identity.Region) - } - - if !model.InstanceId.IsNull() && !model.InstanceId.IsUnknown() { - instanceId = model.InstanceId.ValueString() - } else { - if identity.InstanceID.IsNull() || identity.InstanceID.IsUnknown() { - return "", "", "", "", fmt.Errorf("instance_id not found in config") - } - instanceId = identity.InstanceID.ValueString() - } - return projectId, region, instanceId, databaseName, nil -} diff --git a/stackit/internal/services/sqlserverflexalpha/user/mapper_test.go b/stackit/internal/services/sqlserverflexalpha/user/mapper_test.go index b116b8dd..4dbe7d03 100644 --- a/stackit/internal/services/sqlserverflexalpha/user/mapper_test.go +++ b/stackit/internal/services/sqlserverflexalpha/user/mapper_test.go @@ -43,9 +43,12 @@ func TestMapDataSourceFields(t *testing.T) { "simple_values", &sqlserverflexalpha.GetUserResponse{ Roles: &[]string{ - "role_1", - "role_2", - "", + "##STACKIT_SQLAgentUser##", + "##STACKIT_DatabaseManager##", + "##STACKIT_LoginManager##", + "##STACKIT_SQLAgentManager##", + "##STACKIT_ProcessManager##", + "##STACKIT_ServerManager##", }, Username: utils.Ptr("username"), Host: utils.Ptr("host"), @@ -63,9 +66,12 @@ func TestMapDataSourceFields(t *testing.T) { Roles: types.List( types.SetValueMust( types.StringType, []attr.Value{ - types.StringValue(""), - types.StringValue("role_1"), - types.StringValue("role_2"), + types.StringValue("##STACKIT_DatabaseManager##"), + types.StringValue("##STACKIT_LoginManager##"), + types.StringValue("##STACKIT_ProcessManager##"), + types.StringValue("##STACKIT_SQLAgentManager##"), + types.StringValue("##STACKIT_SQLAgentUser##"), + types.StringValue("##STACKIT_ServerManager##"), }, ), ), diff --git a/stackit/internal/services/sqlserverflexbeta/database/mapper.go b/stackit/internal/services/sqlserverflexbeta/database/mapper.go index a418dadb..43a4344f 100644 --- a/stackit/internal/services/sqlserverflexbeta/database/mapper.go +++ b/stackit/internal/services/sqlserverflexbeta/database/mapper.go @@ -2,7 +2,6 @@ package sqlserverflexbeta import ( "fmt" - "strings" "github.com/hashicorp/terraform-plugin-framework/types" @@ -34,7 +33,7 @@ func mapFields(source *sqlserverflexbeta.GetDatabaseResponse, model *dataSourceM model.Id = types.Int64Value(databaseId) model.DatabaseName = types.StringValue(source.GetName()) model.Name = types.StringValue(source.GetName()) - model.Owner = types.StringValue(strings.Trim(source.GetOwner(), "\"")) + model.Owner = types.StringValue(source.GetOwner()) model.Region = types.StringValue(region) model.ProjectId = types.StringValue(model.ProjectId.ValueString()) model.InstanceId = types.StringValue(model.InstanceId.ValueString()) @@ -75,7 +74,7 @@ func mapResourceFields(source *sqlserverflexbeta.GetDatabaseResponse, model *res model.Id = types.Int64Value(databaseId) model.DatabaseName = types.StringValue(source.GetName()) model.Name = types.StringValue(source.GetName()) - model.Owner = types.StringValue(strings.Trim(source.GetOwner(), "\"")) + model.Owner = types.StringValue(source.GetOwner()) model.Region = types.StringValue(region) model.ProjectId = types.StringValue(model.ProjectId.ValueString()) model.InstanceId = types.StringValue(model.InstanceId.ValueString()) diff --git a/stackit/internal/services/sqlserverflexbeta/database/resource.go b/stackit/internal/services/sqlserverflexbeta/database/resource.go index 8eb93b54..2f77191e 100644 --- a/stackit/internal/services/sqlserverflexbeta/database/resource.go +++ b/stackit/internal/services/sqlserverflexbeta/database/resource.go @@ -247,7 +247,6 @@ func (r *databaseResource) Create(ctx context.Context, req resource.CreateReques return } - // TODO: is this necessary to wait for the database-> API say 200 ? waitResp, err := wait.CreateDatabaseWaitHandler( ctx, r.client, @@ -310,19 +309,8 @@ func (r *databaseResource) Create(ctx context.Context, req resource.CreateReques return } - database, err := r.client.GetDatabaseRequest(ctx, projectId, region, instanceId, databaseName).Execute() - if err != nil { - core.LogAndAddError( - ctx, - &resp.Diagnostics, - "Error creating database", - fmt.Sprintf("Getting database details after creation: %v", err), - ) - return - } - // Map response body to schema - err = mapResourceFields(database, &data, region) + err = mapResourceFields(waitResp, &data, region) if err != nil { core.LogAndAddError( ctx, @@ -361,15 +349,10 @@ func (r *databaseResource) Read(ctx context.Context, req resource.ReadRequest, r ctx = core.InitProviderContext(ctx) - projectId, region, instanceId, databaseName, errExt := r.extractIdentityData(model, identityData) - if errExt != nil { - core.LogAndAddError( - ctx, - &resp.Diagnostics, - extractErrorSummary, - fmt.Sprintf(extractErrorMessage, errExt), - ) - } + projectId := model.ProjectId.ValueString() + region := model.Region.ValueString() + instanceId := model.InstanceId.ValueString() + databaseName := model.DatabaseName.ValueString() ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "instance_id", instanceId) diff --git a/stackit/internal/services/sqlserverflexbeta/sqlserverflex_acc_test.go b/stackit/internal/services/sqlserverflexbeta/sqlserverflex_acc_test.go index 0f0b47ea..3beb0da8 100644 --- a/stackit/internal/services/sqlserverflexbeta/sqlserverflex_acc_test.go +++ b/stackit/internal/services/sqlserverflexbeta/sqlserverflex_acc_test.go @@ -302,9 +302,9 @@ func TestAccInstanceNoEncryption(t *testing.T) { "##STACKIT_DatabaseManager##", "##STACKIT_LoginManager##", "##STACKIT_ProcessManager##", - "##STACKIT_ServerManager##", "##STACKIT_SQLAgentManager##", "##STACKIT_SQLAgentUser##", + "##STACKIT_ServerManager##", }, }, } @@ -402,7 +402,7 @@ func TestAccInstanceEncryption(t *testing.T) { { Name: userName, ProjectId: os.Getenv("TF_ACC_PROJECT_ID"), - Roles: []string{"##STACKIT_LoginManager##", "##STACKIT_DatabaseManager##"}, + Roles: []string{"##STACKIT_DatabaseManager##", "##STACKIT_LoginManager##"}, }, } data.Databases = []Database{ diff --git a/stackit/internal/services/sqlserverflexbeta/user/mapper.go b/stackit/internal/services/sqlserverflexbeta/user/mapper.go index 54ba2547..ca916d28 100644 --- a/stackit/internal/services/sqlserverflexbeta/user/mapper.go +++ b/stackit/internal/services/sqlserverflexbeta/user/mapper.go @@ -94,8 +94,8 @@ func mapFields(userResp *sqlserverflexbeta.GetUserResponse, model *resourceModel model.Username = types.StringPointerValue(user.Username) // Map roles - if user.Roles != nil { - resRoles := *user.Roles + if userResp.Roles != nil { + resRoles := *userResp.Roles slices.Sort(resRoles) var roles []attr.Value @@ -103,11 +103,11 @@ func mapFields(userResp *sqlserverflexbeta.GetUserResponse, model *resourceModel roles = append(roles, types.StringValue(string(role))) } - rolesSet, diags := types.SetValue(types.StringType, roles) + rolesSet, diags := types.ListValue(types.StringType, roles) if diags.HasError() { return fmt.Errorf("failed to map roles: %w", core.DiagsToError(diags)) } - model.Roles = types.List(rolesSet) + model.Roles = rolesSet } // Ensure roles is not null @@ -153,11 +153,11 @@ func mapFieldsCreate(userResp *sqlserverflexbeta.CreateUserResponse, model *reso for _, role := range resRoles { roles = append(roles, types.StringValue(string(role))) } - rolesSet, diags := types.SetValue(types.StringType, roles) + rolesList, diags := types.ListValue(types.StringType, roles) if diags.HasError() { return fmt.Errorf("failed to map roles: %w", core.DiagsToError(diags)) } - model.Roles = types.List(rolesSet) + model.Roles = rolesList } if model.Roles.IsNull() || model.Roles.IsUnknown() { diff --git a/stackit/internal/services/sqlserverflexbeta/user/resource.go b/stackit/internal/services/sqlserverflexbeta/user/resource.go index 9159cf01..f960c726 100644 --- a/stackit/internal/services/sqlserverflexbeta/user/resource.go +++ b/stackit/internal/services/sqlserverflexbeta/user/resource.go @@ -11,7 +11,6 @@ import ( "strings" "time" - "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/identityschema" @@ -108,37 +107,25 @@ func (r *userResource) ModifyPlan( return } - // TODO: verify if this is needed - START - var configRoles []string - diags := configModel.Roles.ElementsAs(ctx, &configRoles, false) - resp.Diagnostics.Append(diags...) - if diags.HasError() { - return - } - - var planRoles []string - diags = planModel.Roles.ElementsAs(ctx, &planRoles, false) - resp.Diagnostics.Append(diags...) - if diags.HasError() { - return - } - - slices.Sort(configRoles) - slices.Sort(planRoles) - - if !slices.Equal(configRoles, planRoles) { - var roles []attr.Value - for _, role := range configRoles { - roles = append(roles, types.StringValue(string(role))) - } - rolesSet, diags := types.SetValue(types.StringType, roles) - resp.Diagnostics.Append(diags...) - if diags.HasError() { - return - } - planModel.Roles = types.List(rolesSet) - } - // TODO: verify if this is needed - END + //// TODO: verify if this is needed - START + //var planRoles []string + //diags := planModel.Roles.ElementsAs(ctx, &planRoles, false) + //resp.Diagnostics.Append(diags...) + //if diags.HasError() { + // return + //} + //slices.Sort(planRoles) + //var roles []attr.Value + //for _, role := range planRoles { + // roles = append(roles, types.StringValue(string(role))) + //} + //rolesSet, diags := types.ListValue(types.StringType, roles) + //resp.Diagnostics.Append(diags...) + //if diags.HasError() { + // return + //} + //planModel.Roles = rolesSet + //// TODO: verify if this is needed - END resp.Diagnostics.Append(resp.Plan.Set(ctx, planModel)...) if resp.Diagnostics.HasError() { diff --git a/stackit/provider.go b/stackit/provider.go index ab3dd060..bb9ffad0 100644 --- a/stackit/provider.go +++ b/stackit/provider.go @@ -489,17 +489,18 @@ func (p *Provider) Configure(ctx context.Context, req provider.ConfigureRequest, return } - roundTripper := core.NewRetryRoundTripper( - baseRoundTripper, - maxRetries, - initialDelay, - maxDelay, - perTryTimeout, - ) + //roundTripper := core.NewRetryRoundTripper( + // baseRoundTripper, + // maxRetries, + // initialDelay, + // maxDelay, + // perTryTimeout, + //) // Make round tripper and custom endpoints available during DataSource and Resource // type Configure methods. - providerData.RoundTripper = roundTripper + // providerData.RoundTripper = roundTripper + providerData.RoundTripper = baseRoundTripper resp.DataSourceData = providerData resp.ResourceData = providerData From 8c98e1d3bc51181c89c72f922ce6e046b433aaeb Mon Sep 17 00:00:00 2001 From: "Marcel S. Henselin" Date: Mon, 16 Feb 2026 17:06:33 +0100 Subject: [PATCH 4/4] fix: try fix errors --- .../postgresflexalpha/database/resource.go | 20 +-- .../postgresflexalpha/user/mapper_test.go | 102 +++++++------- .../sqlserverflexalpha/database/resource.go | 124 ++++-------------- .../sqlserverflexalpha/user/mapper_test.go | 18 ++- .../sqlserverflexbeta/database/mapper.go | 5 +- .../sqlserverflexbeta/database/resource.go | 27 +--- .../sqlserverflex_acc_test.go | 4 +- .../services/sqlserverflexbeta/user/mapper.go | 12 +- .../sqlserverflexbeta/user/resource.go | 51 +++---- stackit/provider.go | 17 +-- 10 files changed, 137 insertions(+), 243 deletions(-) diff --git a/stackit/internal/services/postgresflexalpha/database/resource.go b/stackit/internal/services/postgresflexalpha/database/resource.go index fd3f225c..1cf3f2df 100644 --- a/stackit/internal/services/postgresflexalpha/database/resource.go +++ b/stackit/internal/services/postgresflexalpha/database/resource.go @@ -281,24 +281,12 @@ func (r *databaseResource) Read( return } - // Read identity data - var identityData DatabaseResourceIdentityModel - resp.Diagnostics.Append(req.Identity.Get(ctx, &identityData)...) - if resp.Diagnostics.HasError() { - return - } - ctx = core.InitProviderContext(ctx) - projectId, region, instanceId, databaseId, errExt := r.extractIdentityData(model, identityData) - if errExt != nil { - core.LogAndAddError( - ctx, - &resp.Diagnostics, - extractErrorSummary, - fmt.Sprintf(extractErrorMessage, errExt), - ) - } + projectId := model.ProjectId.ValueString() + instanceId := model.InstanceId.ValueString() + region := model.Region.ValueString() + databaseId := model.DatabaseId.ValueInt64() ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "instance_id", instanceId) diff --git a/stackit/internal/services/postgresflexalpha/user/mapper_test.go b/stackit/internal/services/postgresflexalpha/user/mapper_test.go index 1a8c3f99..5014d4ac 100644 --- a/stackit/internal/services/postgresflexalpha/user/mapper_test.go +++ b/stackit/internal/services/postgresflexalpha/user/mapper_test.go @@ -164,16 +164,16 @@ func TestMapFieldsCreate(t *testing.T) { }, testRegion, 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)), - Password: types.StringNull(), - Region: types.StringValue(testRegion), - Status: types.StringNull(), - ConnectionString: types.StringNull(), + 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)), + Password: types.StringNull(), + Region: types.StringValue(testRegion), + Status: types.StringNull(), + //ConnectionString: types.StringNull(), }, true, }, @@ -186,16 +186,16 @@ func TestMapFieldsCreate(t *testing.T) { }, testRegion, 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.SetNull(types.StringType)), - Password: types.StringNull(), - Region: types.StringValue(testRegion), - Status: types.StringValue("status"), - ConnectionString: types.StringNull(), + Id: types.Int64Value(1), + 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.StringNull(), }, true, }, @@ -208,16 +208,16 @@ func TestMapFieldsCreate(t *testing.T) { }, testRegion, 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)), - Password: types.StringNull(), - Region: types.StringValue(testRegion), - Status: types.StringNull(), - ConnectionString: types.StringNull(), + 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)), + Password: types.StringNull(), + Region: types.StringValue(testRegion), + Status: types.StringNull(), + //ConnectionString: types.StringNull(), }, true, }, @@ -285,15 +285,15 @@ func TestMapFields(t *testing.T) { }, testRegion, 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(), + 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, }, @@ -324,9 +324,9 @@ func TestMapFields(t *testing.T) { }, ), ), - Region: types.StringValue(testRegion), - Status: types.StringNull(), - ConnectionString: types.StringNull(), + Region: types.StringValue(testRegion), + Status: types.StringNull(), + //ConnectionString: types.StringNull(), }, true, }, @@ -338,15 +338,15 @@ func TestMapFields(t *testing.T) { }, testRegion, 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(), + 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, }, diff --git a/stackit/internal/services/sqlserverflexalpha/database/resource.go b/stackit/internal/services/sqlserverflexalpha/database/resource.go index 91761b18..eec284f1 100644 --- a/stackit/internal/services/sqlserverflexalpha/database/resource.go +++ b/stackit/internal/services/sqlserverflexalpha/database/resource.go @@ -186,25 +186,25 @@ func (r *databaseResource) Create(ctx context.Context, req resource.CreateReques payLoad.Name = data.Name.ValueStringPointer() payLoad.Owner = data.Owner.ValueStringPointer() - _, err := wait.WaitForUserWaitHandler( - ctx, - r.client, - projectId, - instanceId, - region, - data.Owner.ValueString(), - ). - SetSleepBeforeWait(10 * time.Second). - WaitWithContext(ctx) - if err != nil { - core.LogAndAddError( - ctx, - &resp.Diagnostics, - createErr, - fmt.Sprintf("Calling API: %v", err), - ) - return - } + //_, err := wait.WaitForUserWaitHandler( + // ctx, + // r.client, + // projectId, + // instanceId, + // region, + // data.Owner.ValueString(), + //). + // SetSleepBeforeWait(10 * time.Second). + // WaitWithContext(ctx) + //if err != nil { + // core.LogAndAddError( + // ctx, + // &resp.Diagnostics, + // createErr, + // fmt.Sprintf("Calling API: %v", err), + // ) + // return + //} createResp, err := r.client.CreateDatabaseRequest(ctx, projectId, region, instanceId). CreateDatabaseRequestPayload(payLoad). @@ -361,15 +361,10 @@ func (r *databaseResource) Read(ctx context.Context, req resource.ReadRequest, r ctx = core.InitProviderContext(ctx) - projectId, region, instanceId, databaseName, errExt := r.extractIdentityData(model, identityData) - if errExt != nil { - core.LogAndAddError( - ctx, - &resp.Diagnostics, - extractErrorSummary, - fmt.Sprintf(extractErrorMessage, errExt), - ) - } + projectId := model.ProjectId.ValueString() + region := model.Region.ValueString() + instanceId := model.InstanceId.ValueString() + databaseName := model.DatabaseName.ValueString() ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "instance_id", instanceId) @@ -445,15 +440,10 @@ func (r *databaseResource) Delete(ctx context.Context, req resource.DeleteReques ctx = core.InitProviderContext(ctx) - projectId, region, instanceId, databaseName, errExt := r.extractIdentityData(model, identityData) - if errExt != nil { - core.LogAndAddError( - ctx, - &resp.Diagnostics, - extractErrorSummary, - fmt.Sprintf(extractErrorMessage, errExt), - ) - } + projectId := model.ProjectId.ValueString() + region := model.Region.ValueString() + instanceId := model.InstanceId.ValueString() + databaseName := model.DatabaseName.ValueString() ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "instance_id", instanceId) @@ -508,23 +498,6 @@ func (r *databaseResource) ModifyPlan( return } - var identityModel DatabaseResourceIdentityModel - identityModel.ProjectID = planModel.ProjectId - identityModel.Region = planModel.Region - - if !planModel.InstanceId.IsNull() && !planModel.InstanceId.IsUnknown() { - identityModel.InstanceID = planModel.InstanceId - } - - if !planModel.Name.IsNull() && !planModel.Name.IsUnknown() { - identityModel.DatabaseName = planModel.Name - } - - resp.Diagnostics.Append(resp.Identity.Set(ctx, identityModel)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.Plan.Set(ctx, planModel)...) if resp.Diagnostics.HasError() { return @@ -594,46 +567,3 @@ func (r *databaseResource) ImportState( tflog.Info(ctx, "sqlserverflexalpha database state imported") } - -// extractIdentityData extracts essential identifiers from the resource model, falling back to the identity model. -func (r *databaseResource) extractIdentityData( - model resourceModel, - identity DatabaseResourceIdentityModel, -) (projectId, region, instanceId, databaseName string, err error) { - if !model.Name.IsNull() && !model.Name.IsUnknown() { - databaseName = model.Name.ValueString() - } else { - if identity.DatabaseName.IsNull() || identity.DatabaseName.IsUnknown() { - return "", "", "", "", fmt.Errorf("database_name not found in config") - } - databaseName = identity.DatabaseName.ValueString() - } - - if !model.ProjectId.IsNull() && !model.ProjectId.IsUnknown() { - projectId = model.ProjectId.ValueString() - } else { - if identity.ProjectID.IsNull() || identity.ProjectID.IsUnknown() { - return "", "", "", "", fmt.Errorf("project_id not found in config") - } - projectId = identity.ProjectID.ValueString() - } - - if !model.Region.IsNull() && !model.Region.IsUnknown() { - region = r.providerData.GetRegionWithOverride(model.Region) - } else { - if identity.Region.IsNull() || identity.Region.IsUnknown() { - return "", "", "", "", fmt.Errorf("region not found in config") - } - region = r.providerData.GetRegionWithOverride(identity.Region) - } - - if !model.InstanceId.IsNull() && !model.InstanceId.IsUnknown() { - instanceId = model.InstanceId.ValueString() - } else { - if identity.InstanceID.IsNull() || identity.InstanceID.IsUnknown() { - return "", "", "", "", fmt.Errorf("instance_id not found in config") - } - instanceId = identity.InstanceID.ValueString() - } - return projectId, region, instanceId, databaseName, nil -} diff --git a/stackit/internal/services/sqlserverflexalpha/user/mapper_test.go b/stackit/internal/services/sqlserverflexalpha/user/mapper_test.go index b116b8dd..4dbe7d03 100644 --- a/stackit/internal/services/sqlserverflexalpha/user/mapper_test.go +++ b/stackit/internal/services/sqlserverflexalpha/user/mapper_test.go @@ -43,9 +43,12 @@ func TestMapDataSourceFields(t *testing.T) { "simple_values", &sqlserverflexalpha.GetUserResponse{ Roles: &[]string{ - "role_1", - "role_2", - "", + "##STACKIT_SQLAgentUser##", + "##STACKIT_DatabaseManager##", + "##STACKIT_LoginManager##", + "##STACKIT_SQLAgentManager##", + "##STACKIT_ProcessManager##", + "##STACKIT_ServerManager##", }, Username: utils.Ptr("username"), Host: utils.Ptr("host"), @@ -63,9 +66,12 @@ func TestMapDataSourceFields(t *testing.T) { Roles: types.List( types.SetValueMust( types.StringType, []attr.Value{ - types.StringValue(""), - types.StringValue("role_1"), - types.StringValue("role_2"), + types.StringValue("##STACKIT_DatabaseManager##"), + types.StringValue("##STACKIT_LoginManager##"), + types.StringValue("##STACKIT_ProcessManager##"), + types.StringValue("##STACKIT_SQLAgentManager##"), + types.StringValue("##STACKIT_SQLAgentUser##"), + types.StringValue("##STACKIT_ServerManager##"), }, ), ), diff --git a/stackit/internal/services/sqlserverflexbeta/database/mapper.go b/stackit/internal/services/sqlserverflexbeta/database/mapper.go index a418dadb..43a4344f 100644 --- a/stackit/internal/services/sqlserverflexbeta/database/mapper.go +++ b/stackit/internal/services/sqlserverflexbeta/database/mapper.go @@ -2,7 +2,6 @@ package sqlserverflexbeta import ( "fmt" - "strings" "github.com/hashicorp/terraform-plugin-framework/types" @@ -34,7 +33,7 @@ func mapFields(source *sqlserverflexbeta.GetDatabaseResponse, model *dataSourceM model.Id = types.Int64Value(databaseId) model.DatabaseName = types.StringValue(source.GetName()) model.Name = types.StringValue(source.GetName()) - model.Owner = types.StringValue(strings.Trim(source.GetOwner(), "\"")) + model.Owner = types.StringValue(source.GetOwner()) model.Region = types.StringValue(region) model.ProjectId = types.StringValue(model.ProjectId.ValueString()) model.InstanceId = types.StringValue(model.InstanceId.ValueString()) @@ -75,7 +74,7 @@ func mapResourceFields(source *sqlserverflexbeta.GetDatabaseResponse, model *res model.Id = types.Int64Value(databaseId) model.DatabaseName = types.StringValue(source.GetName()) model.Name = types.StringValue(source.GetName()) - model.Owner = types.StringValue(strings.Trim(source.GetOwner(), "\"")) + model.Owner = types.StringValue(source.GetOwner()) model.Region = types.StringValue(region) model.ProjectId = types.StringValue(model.ProjectId.ValueString()) model.InstanceId = types.StringValue(model.InstanceId.ValueString()) diff --git a/stackit/internal/services/sqlserverflexbeta/database/resource.go b/stackit/internal/services/sqlserverflexbeta/database/resource.go index 8eb93b54..2f77191e 100644 --- a/stackit/internal/services/sqlserverflexbeta/database/resource.go +++ b/stackit/internal/services/sqlserverflexbeta/database/resource.go @@ -247,7 +247,6 @@ func (r *databaseResource) Create(ctx context.Context, req resource.CreateReques return } - // TODO: is this necessary to wait for the database-> API say 200 ? waitResp, err := wait.CreateDatabaseWaitHandler( ctx, r.client, @@ -310,19 +309,8 @@ func (r *databaseResource) Create(ctx context.Context, req resource.CreateReques return } - database, err := r.client.GetDatabaseRequest(ctx, projectId, region, instanceId, databaseName).Execute() - if err != nil { - core.LogAndAddError( - ctx, - &resp.Diagnostics, - "Error creating database", - fmt.Sprintf("Getting database details after creation: %v", err), - ) - return - } - // Map response body to schema - err = mapResourceFields(database, &data, region) + err = mapResourceFields(waitResp, &data, region) if err != nil { core.LogAndAddError( ctx, @@ -361,15 +349,10 @@ func (r *databaseResource) Read(ctx context.Context, req resource.ReadRequest, r ctx = core.InitProviderContext(ctx) - projectId, region, instanceId, databaseName, errExt := r.extractIdentityData(model, identityData) - if errExt != nil { - core.LogAndAddError( - ctx, - &resp.Diagnostics, - extractErrorSummary, - fmt.Sprintf(extractErrorMessage, errExt), - ) - } + projectId := model.ProjectId.ValueString() + region := model.Region.ValueString() + instanceId := model.InstanceId.ValueString() + databaseName := model.DatabaseName.ValueString() ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "instance_id", instanceId) diff --git a/stackit/internal/services/sqlserverflexbeta/sqlserverflex_acc_test.go b/stackit/internal/services/sqlserverflexbeta/sqlserverflex_acc_test.go index 0f0b47ea..3beb0da8 100644 --- a/stackit/internal/services/sqlserverflexbeta/sqlserverflex_acc_test.go +++ b/stackit/internal/services/sqlserverflexbeta/sqlserverflex_acc_test.go @@ -302,9 +302,9 @@ func TestAccInstanceNoEncryption(t *testing.T) { "##STACKIT_DatabaseManager##", "##STACKIT_LoginManager##", "##STACKIT_ProcessManager##", - "##STACKIT_ServerManager##", "##STACKIT_SQLAgentManager##", "##STACKIT_SQLAgentUser##", + "##STACKIT_ServerManager##", }, }, } @@ -402,7 +402,7 @@ func TestAccInstanceEncryption(t *testing.T) { { Name: userName, ProjectId: os.Getenv("TF_ACC_PROJECT_ID"), - Roles: []string{"##STACKIT_LoginManager##", "##STACKIT_DatabaseManager##"}, + Roles: []string{"##STACKIT_DatabaseManager##", "##STACKIT_LoginManager##"}, }, } data.Databases = []Database{ diff --git a/stackit/internal/services/sqlserverflexbeta/user/mapper.go b/stackit/internal/services/sqlserverflexbeta/user/mapper.go index 54ba2547..ca916d28 100644 --- a/stackit/internal/services/sqlserverflexbeta/user/mapper.go +++ b/stackit/internal/services/sqlserverflexbeta/user/mapper.go @@ -94,8 +94,8 @@ func mapFields(userResp *sqlserverflexbeta.GetUserResponse, model *resourceModel model.Username = types.StringPointerValue(user.Username) // Map roles - if user.Roles != nil { - resRoles := *user.Roles + if userResp.Roles != nil { + resRoles := *userResp.Roles slices.Sort(resRoles) var roles []attr.Value @@ -103,11 +103,11 @@ func mapFields(userResp *sqlserverflexbeta.GetUserResponse, model *resourceModel roles = append(roles, types.StringValue(string(role))) } - rolesSet, diags := types.SetValue(types.StringType, roles) + rolesSet, diags := types.ListValue(types.StringType, roles) if diags.HasError() { return fmt.Errorf("failed to map roles: %w", core.DiagsToError(diags)) } - model.Roles = types.List(rolesSet) + model.Roles = rolesSet } // Ensure roles is not null @@ -153,11 +153,11 @@ func mapFieldsCreate(userResp *sqlserverflexbeta.CreateUserResponse, model *reso for _, role := range resRoles { roles = append(roles, types.StringValue(string(role))) } - rolesSet, diags := types.SetValue(types.StringType, roles) + rolesList, diags := types.ListValue(types.StringType, roles) if diags.HasError() { return fmt.Errorf("failed to map roles: %w", core.DiagsToError(diags)) } - model.Roles = types.List(rolesSet) + model.Roles = rolesList } if model.Roles.IsNull() || model.Roles.IsUnknown() { diff --git a/stackit/internal/services/sqlserverflexbeta/user/resource.go b/stackit/internal/services/sqlserverflexbeta/user/resource.go index 9159cf01..f960c726 100644 --- a/stackit/internal/services/sqlserverflexbeta/user/resource.go +++ b/stackit/internal/services/sqlserverflexbeta/user/resource.go @@ -11,7 +11,6 @@ import ( "strings" "time" - "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/identityschema" @@ -108,37 +107,25 @@ func (r *userResource) ModifyPlan( return } - // TODO: verify if this is needed - START - var configRoles []string - diags := configModel.Roles.ElementsAs(ctx, &configRoles, false) - resp.Diagnostics.Append(diags...) - if diags.HasError() { - return - } - - var planRoles []string - diags = planModel.Roles.ElementsAs(ctx, &planRoles, false) - resp.Diagnostics.Append(diags...) - if diags.HasError() { - return - } - - slices.Sort(configRoles) - slices.Sort(planRoles) - - if !slices.Equal(configRoles, planRoles) { - var roles []attr.Value - for _, role := range configRoles { - roles = append(roles, types.StringValue(string(role))) - } - rolesSet, diags := types.SetValue(types.StringType, roles) - resp.Diagnostics.Append(diags...) - if diags.HasError() { - return - } - planModel.Roles = types.List(rolesSet) - } - // TODO: verify if this is needed - END + //// TODO: verify if this is needed - START + //var planRoles []string + //diags := planModel.Roles.ElementsAs(ctx, &planRoles, false) + //resp.Diagnostics.Append(diags...) + //if diags.HasError() { + // return + //} + //slices.Sort(planRoles) + //var roles []attr.Value + //for _, role := range planRoles { + // roles = append(roles, types.StringValue(string(role))) + //} + //rolesSet, diags := types.ListValue(types.StringType, roles) + //resp.Diagnostics.Append(diags...) + //if diags.HasError() { + // return + //} + //planModel.Roles = rolesSet + //// TODO: verify if this is needed - END resp.Diagnostics.Append(resp.Plan.Set(ctx, planModel)...) if resp.Diagnostics.HasError() { diff --git a/stackit/provider.go b/stackit/provider.go index ab3dd060..bb9ffad0 100644 --- a/stackit/provider.go +++ b/stackit/provider.go @@ -489,17 +489,18 @@ func (p *Provider) Configure(ctx context.Context, req provider.ConfigureRequest, return } - roundTripper := core.NewRetryRoundTripper( - baseRoundTripper, - maxRetries, - initialDelay, - maxDelay, - perTryTimeout, - ) + //roundTripper := core.NewRetryRoundTripper( + // baseRoundTripper, + // maxRetries, + // initialDelay, + // maxDelay, + // perTryTimeout, + //) // Make round tripper and custom endpoints available during DataSource and Resource // type Configure methods. - providerData.RoundTripper = roundTripper + // providerData.RoundTripper = roundTripper + providerData.RoundTripper = baseRoundTripper resp.DataSourceData = providerData resp.ResourceData = providerData