diff --git a/stackit/internal/services/sqlserverflexbeta/database/mapper.go b/stackit/internal/services/sqlserverflexbeta/database/mapper.go index 349f7717..7d82039a 100644 --- a/stackit/internal/services/sqlserverflexbeta/database/mapper.go +++ b/stackit/internal/services/sqlserverflexbeta/database/mapper.go @@ -79,7 +79,10 @@ func mapResourceFields(source *sqlserverflexbeta.GetDatabaseResponse, model *res model.ProjectId = types.StringValue(model.ProjectId.ValueString()) model.InstanceId = types.StringValue(model.InstanceId.ValueString()) + model.Compatibility = types.Int64Value(source.GetCompatibilityLevel()) model.CompatibilityLevel = types.Int64Value(source.GetCompatibilityLevel()) + + model.Collation = types.StringValue(source.GetCollationName()) // it does not come back from api model.CollationName = types.StringValue(source.GetCollationName()) return nil diff --git a/stackit/internal/services/sqlserverflexbeta/database/resource.go b/stackit/internal/services/sqlserverflexbeta/database/resource.go index 652575fc..7c191e42 100644 --- a/stackit/internal/services/sqlserverflexbeta/database/resource.go +++ b/stackit/internal/services/sqlserverflexbeta/database/resource.go @@ -174,13 +174,18 @@ func (r *databaseResource) Create(ctx context.Context, req resource.CreateReques databaseName := data.Name.ValueString() ctx = tflog.SetField(ctx, "database_name", databaseName) - payLoad := sqlserverflexbeta.CreateDatabaseRequestPayload{ - Collation: data.Collation.ValueStringPointer(), - Compatibility: data.Compatibility.ValueInt64Pointer(), - Name: data.Name.ValueStringPointer(), - Owner: data.Owner.ValueStringPointer(), + payLoad := sqlserverflexbeta.CreateDatabaseRequestPayload{} + if !data.Collation.IsNull() && !data.Collation.IsUnknown() { + payLoad.Collation = data.Collation.ValueStringPointer() } + if !data.Compatibility.IsNull() && !data.Compatibility.IsUnknown() { + payLoad.Compatibility = data.Compatibility.ValueInt64Pointer() + } + + payLoad.Name = data.Name.ValueStringPointer() + payLoad.Owner = data.Owner.ValueStringPointer() + _, err := wait.WaitForUserWaitHandler( ctx, r.client, diff --git a/stackit/internal/services/sqlserverflexbeta/sqlserverflex_acc_test.go b/stackit/internal/services/sqlserverflexbeta/sqlserverflex_acc_test.go index 9c091cde..e6c776dc 100644 --- a/stackit/internal/services/sqlserverflexbeta/sqlserverflex_acc_test.go +++ b/stackit/internal/services/sqlserverflexbeta/sqlserverflex_acc_test.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" sqlserverflexbeta "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta/instance" "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/internal/testutils" @@ -19,6 +20,8 @@ import ( fwresource "github.com/hashicorp/terraform-plugin-framework/resource" ) +const providerPrefix = "stackitprivatepreview_sqlserverflexbeta" + func TestInstanceResourceSchema(t *testing.T) { t.Parallel() @@ -84,9 +87,15 @@ type User struct { } type Database struct { - Name string - ProjectId string - Owner string + Name string + ProjectId string + Owner string + Collation string + Compatibility string +} + +func resName(res, name string) string { + return fmt.Sprintf("%s_%s.%s", providerPrefix, res, name) } func getExample() resData { @@ -111,10 +120,6 @@ func getExample() resData { func TestAccInstance(t *testing.T) { exData := getExample() - resName := fmt.Sprintf( - "stackitprivatepreview_sqlserverflexbeta_instance.%s", - exData.TfName, - ) updNameData := exData updNameData.Name = "name-updated" @@ -133,8 +138,8 @@ func TestAccInstance(t *testing.T) { exData, ), Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr(resName, "name", exData.Name), - resource.TestCheckResourceAttrSet(resName, "id"), + resource.TestCheckResourceAttr(resName("instance", exData.TfName), "name", exData.Name), + resource.TestCheckResourceAttrSet(resName("instance", exData.TfName), "id"), ), }, // Update name and verify @@ -144,7 +149,7 @@ func TestAccInstance(t *testing.T) { updNameData, ), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resName, "name", updNameData.Name), + resource.TestCheckResourceAttr(resName("instance", exData.TfName), "name", updNameData.Name), ), }, // Update size and verify @@ -155,12 +160,15 @@ func TestAccInstance(t *testing.T) { ), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr( - resName, + resName("instance", exData.TfName), "storage.size", strconv.Itoa(int(updSizeData.Size)), ), ), }, + { + RefreshState: true, + }, //// Import test //{ // ResourceName: "example_resource.test", @@ -171,49 +179,7 @@ func TestAccInstance(t *testing.T) { }) } -func TestAccInstanceWithUsers(t *testing.T) { - data := getExample() - userName := "testUser" - data.Users = []User{ - { - Name: userName, - ProjectId: os.Getenv("TF_ACC_PROJECT_ID"), - Roles: []string{"##STACKIT_LoginManager##", "##STACKIT_DatabaseManager##"}, - }, - } - - resName := fmt.Sprintf( - "stackitprivatepreview_sqlserverflexbeta_instance.%s", - data.TfName, - ) - - resUserName := fmt.Sprintf( - "stackitprivatepreview_sqlserverflexbeta_user.%s", - userName, - ) - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, - Steps: []resource.TestStep{ - // Create and verify - { - Config: testutils.StringFromTemplateMust( - "testdata/instance_template.gompl", - data, - ), - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr(resName, "name", data.Name), - resource.TestCheckResourceAttrSet(resName, "id"), - resource.TestCheckResourceAttr(resUserName, "name", userName), - resource.TestCheckResourceAttrSet(resUserName, "id"), - ), - }, - }, - }) -} - -func TestAccInstanceWithDatabases(t *testing.T) { +func TestAccInstanceNoEncryption(t *testing.T) { data := getExample() t.Logf(" ... working on instance %s", data.TfName) dbName := "testDb" @@ -233,20 +199,104 @@ func TestAccInstanceWithDatabases(t *testing.T) { }, } - resName := fmt.Sprintf( - "stackitprivatepreview_sqlserverflexbeta_instance.%s", - data.TfName, - ) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Create and verify + { + Config: testutils.StringFromTemplateMust( + "testdata/instance_template.gompl", + data, + ), + Check: resource.ComposeAggregateTestCheckFunc( + // check instance values are set + resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "id"), + resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "backup_schedule"), + resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "edition"), + resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "flavor_id"), + resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "instance_id"), + resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "is_deletable"), + resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "name"), + resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "replicas"), + resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "retention_days"), + resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "status"), + resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "version"), - resUserName := fmt.Sprintf( - "stackitprivatepreview_sqlserverflexbeta_user.%s", - userName, - ) + resource.TestCheckNoResourceAttr(resName("instance", data.TfName), "encryption"), - resDbName := fmt.Sprintf( - "stackitprivatepreview_sqlserverflexbeta_database.%s", - dbName, - ) + //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption"), + //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_id"), + //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_version"), + //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_ring_id"), + //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.service_account"), + + //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.access_scope"), + //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.acl"), + + //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.instance_address"), + //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.router_address"), + + //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "storage.class"), + //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "storage.size"), + + // check instance values are correct + resource.TestCheckResourceAttr(resName("instance", data.TfName), "name", data.Name), + + // check user values are set + resource.TestCheckResourceAttrSet(resName("user", userName), "id"), + resource.TestCheckResourceAttrSet(resName("user", userName), "username"), + // resource.TestCheckResourceAttrSet(resName("user", userName), "roles"), + + func(s *terraform.State) error { + return nil + }, + + // check user values are correct + resource.TestCheckResourceAttr(resName("user", userName), "username", userName), + resource.TestCheckResourceAttr(resName("user", userName), "roles.#", "2"), + + // check database values are set + resource.TestCheckResourceAttrSet(resName("database", dbName), "id"), + resource.TestCheckResourceAttrSet(resName("database", dbName), "name"), + resource.TestCheckResourceAttrSet(resName("database", dbName), "owner"), + resource.TestCheckResourceAttrSet(resName("database", dbName), "compatibility"), + resource.TestCheckResourceAttrSet(resName("database", dbName), "collation"), + + // check database values are correct + resource.TestCheckResourceAttr(resName("database", dbName), "name", dbName), + resource.TestCheckResourceAttr(resName("database", dbName), "owner", userName), + ), + }, + }, + }) +} + +func TestAccInstanceEncryption(t *testing.T) { + data := getExample() + t.Logf(" ... working on instance %s", data.TfName) + dbName := "testDb" + userName := "testUser" + data.Users = []User{ + { + Name: userName, + ProjectId: os.Getenv("TF_ACC_PROJECT_ID"), + Roles: []string{"##STACKIT_LoginManager##", "##STACKIT_DatabaseManager##"}, + }, + } + data.Databases = []Database{ + { + Name: dbName, + ProjectId: os.Getenv("TF_ACC_PROJECT_ID"), + Owner: userName, + }, + } + + data.UseEncryption = true + data.KekKeyId = "fe039bcf-8d7b-431a-801d-9e81371a6b7b" + data.KekKeyRingId = "6a2d95ab-3c4c-4963-a2bb-08d17a320e27" + data.KekKeyVersion = 1 + data.KekServiceAccount = "henselinm-u2v3ex1@sa.stackit.cloud" resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -259,15 +309,59 @@ func TestAccInstanceWithDatabases(t *testing.T) { data, ), Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttrSet(resName, "id"), - resource.TestCheckResourceAttr(resName, "name", data.Name), + // check instance values are set + resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "id"), + resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "backup_schedule"), + resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "edition"), + resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "flavor_id"), + resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "instance_id"), + resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "is_deletable"), + resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "name"), + resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "replicas"), + resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "retention_days"), + resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "status"), + resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "version"), - resource.TestCheckResourceAttrSet(resUserName, "id"), - resource.TestCheckResourceAttr(resUserName, "username", userName), + //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption"), + //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_id"), + //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_version"), + //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_ring_id"), + //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.service_account"), - resource.TestCheckResourceAttrSet(resDbName, "id"), - resource.TestCheckResourceAttr(resDbName, "name", dbName), - resource.TestCheckResourceAttr(resDbName, "owner", userName), + //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.access_scope"), + //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.acl"), + + //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.instance_address"), + //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.router_address"), + + //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "storage.class"), + //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "storage.size"), + + // check instance values are correct + resource.TestCheckResourceAttr(resName("instance", data.TfName), "name", data.Name), + + // check user values are set + resource.TestCheckResourceAttrSet(resName("user", userName), "id"), + resource.TestCheckResourceAttrSet(resName("user", userName), "username"), + + func(s *terraform.State) error { + return nil + }, + + // check user values are correct + resource.TestCheckResourceAttr(resName("user", userName), "username", userName), + resource.TestCheckResourceAttr(resName("user", userName), "roles.#", "2"), + + // check database values are set + resource.TestCheckResourceAttrSet(resName("database", dbName), "id"), + resource.TestCheckResourceAttrSet(resName("database", dbName), "name"), + resource.TestCheckResourceAttrSet(resName("database", dbName), "owner"), + resource.TestCheckResourceAttrSet(resName("database", dbName), "compatibility"), + resource.TestCheckResourceAttrSet(resName("database", dbName), "collation"), + + // check database values are correct + resource.TestCheckResourceAttr(resName("database", dbName), "name", dbName), + resource.TestCheckResourceAttr(resName("database", dbName), "owner", userName), ), }, }, diff --git a/stackit/internal/services/sqlserverflexbeta/testdata/instance_template.gompl b/stackit/internal/services/sqlserverflexbeta/testdata/instance_template.gompl index 84ca19c1..e71f3fa0 100644 --- a/stackit/internal/services/sqlserverflexbeta/testdata/instance_template.gompl +++ b/stackit/internal/services/sqlserverflexbeta/testdata/instance_template.gompl @@ -15,8 +15,8 @@ resource "stackitprivatepreview_sqlserverflexbeta_instance" "{{ .TfName }}" { } {{ if .UseEncryption }} encryption = { - kek_key_id = {{ .KekKeyId }} - kek_key_ring_id = {{ .KekKeyRingId }} + kek_key_id = "{{ .KekKeyId }}" + kek_key_ring_id = "{{ .KekKeyRingId }}" kek_key_version = {{ .KekKeyVersion }} service_account = "{{ .KekServiceAccount }}" } @@ -49,8 +49,12 @@ resource "stackitprivatepreview_sqlserverflexbeta_database" "{{ $db.Name }}" { instance_id = stackitprivatepreview_sqlserverflexbeta_instance.{{ $tfName }}.instance_id name = "{{ $db.Name }}" owner = "{{ $db.Owner }}" - collation = "Albanian_BIN" - compatibility = "160" +{{ if $db.Collation }} + collation = "{{ $db.Collation }}" +{{ end }} +{{ if $db.Compatibility }} + compatibility = "{{ $db.Compatibility }}" +{{ end }} } {{ end }} {{ end }}