package postgresflexalpha_test import ( "context" _ "embed" "fmt" "log" "math" "os" "strconv" "strings" "testing" "time" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/stackitcloud/stackit-sdk-go/core/config" "github.com/stackitcloud/stackit-sdk-go/core/utils" "github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v3alpha1api" "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core" postgresflexalphaInstance "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/instance" "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/wait/postgresflexalpha" "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/internal/testutils" // The fwresource import alias is so there is no collision // with the more typical acceptance testing import: // "github.com/hashicorp/terraform-plugin-testing/helper/resource" fwresource "github.com/hashicorp/terraform-plugin-framework/resource" ) const pfx = "stackitprivatepreview_postgresflexalpha" func TestInstanceResourceSchema(t *testing.T) { // t.Parallel() ctx := context.Background() schemaRequest := fwresource.SchemaRequest{} schemaResponse := &fwresource.SchemaResponse{} // Instantiate the resource.Resource and call its Schema method postgresflexalphaInstance.NewInstanceResource().Schema(ctx, schemaRequest, schemaResponse) if schemaResponse.Diagnostics.HasError() { t.Fatalf("Schema method diagnostics: %+v", schemaResponse.Diagnostics) } // Validate the schema diagnostics := schemaResponse.Schema.ValidateImplementation(ctx) if diagnostics.HasError() { t.Fatalf("Schema validation diagnostics: %+v", diagnostics) } } var ( //go:embed testdata/resource-no-enc.tf resourceConfigNoEnc string //nolint:unused // needs implementation //go:embed testdata/resource-enc.tf resourceConfigEnc string //nolint:unused // needs implementation ) func TestMain(m *testing.M) { testutils.Setup() code := m.Run() // shutdown() os.Exit(code) } func testAccPreCheck(t *testing.T) { if _, ok := os.LookupEnv("TF_ACC_PROJECT_ID"); !ok { t.Fatalf("could not find env var TF_ACC_PROJECT_ID") } } type resData struct { ServiceAccountFilePath string ProjectID string Region string Name string TfName string FlavorID string BackupSchedule string UseEncryption bool KekKeyID string KekKeyRingID string KekKeyVersion uint8 KekServiceAccount string PerformanceClass string Replicas uint32 Size uint32 ACLString string AccessScope string RetentionDays uint32 Version string Users []User Databases []Database } type User struct { Name string ProjectID string Roles []string } type Database struct { Name string ProjectID string Owner string } func getExample() resData { name := acctest.RandomWithPrefix("tf-acc") return resData{ Region: os.Getenv("TF_ACC_REGION"), ServiceAccountFilePath: os.Getenv("TF_ACC_SERVICE_ACCOUNT_FILE"), ProjectID: os.Getenv("TF_ACC_PROJECT_ID"), Name: name, TfName: name, FlavorID: "2.4", BackupSchedule: "0 0 * * *", UseEncryption: false, RetentionDays: 33, Replicas: 1, PerformanceClass: "premium-perf2-stackit", Size: 10, ACLString: "0.0.0.0/0", AccessScope: "PUBLIC", Version: "17", } } func TestAccInstance(t *testing.T) { exData := getExample() updNameData := exData updNameData.Name = "name-updated" updSizeData := exData updSizeData.Size = 25 updBackupSched := updSizeData // api should complain about more than one daily backup updBackupSched.BackupSchedule = "30 3 * * *" /* { "backupSchedule": "6 6 * * *", "flavorId": "1.2", "name": "postgres-instance", "network": { "acl": [ "198.51.100.0/24" ] }, "replicas": 1, "retentionDays": 35, "storage": { "size": 10 }, "version": "string" } */ testItemID := testutils.ResStr(pfx, "instance", exData.TfName) resource.ParallelTest( t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) t.Logf(" ... working on instance %s", exData.TfName) }, CheckDestroy: testAccCheckPostgresFlexDestroy, ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, Steps: []resource.TestStep{ // Create and verify { //PreConfig: func() { // // //}, Config: testutils.StringFromTemplateMust( "testdata/instance_template.gompl", exData, ), Check: resource.ComposeAggregateTestCheckFunc( // check params acl count resource.TestCheckResourceAttr(testItemID, "acl.#", "1"), // check params are set resource.TestCheckResourceAttrSet(testItemID, "backup_schedule"), //// connection_info should contain 1 sub entry // resource.TestCheckResourceAttr(testItemID, "connection_info.%", "1"), // //// connection_info.write should contain 2 sub entries // resource.TestCheckResourceAttr(testItemID, "connection_info.write", "2"), // // resource.TestCheckResourceAttrSet(testItemID, "connection_info.write.host"), // resource.TestCheckResourceAttrSet(testItemID, "connection_info.write.port"), resource.TestCheckResourceAttrSet(testItemID, "flavor_id"), resource.TestCheckResourceAttrSet(testItemID, "id"), resource.TestCheckResourceAttrSet(testItemID, "instance_id"), resource.TestCheckResourceAttrSet(testItemID, "is_deletable"), resource.TestCheckResourceAttrSet(testItemID, "name"), // network should contain 4 sub entries resource.TestCheckResourceAttr(testItemID, "network.%", "4"), resource.TestCheckResourceAttrSet(testItemID, "network.access_scope"), // on unencrypted instances we expect this to be empty resource.TestCheckResourceAttr(testItemID, "network.instance_address", ""), resource.TestCheckResourceAttr(testItemID, "network.router_address", ""), // only one acl entry should be set resource.TestCheckResourceAttr(testItemID, "network.acl.#", "1"), resource.TestCheckResourceAttrSet(testItemID, "replicas"), resource.TestCheckResourceAttrSet(testItemID, "retention_days"), resource.TestCheckResourceAttrSet(testItemID, "status"), // storage should contain 2 sub entries resource.TestCheckResourceAttr(testItemID, "storage.%", "2"), resource.TestCheckResourceAttrSet(testItemID, "storage.performance_class"), resource.TestCheckResourceAttrSet(testItemID, "storage.size"), resource.TestCheckResourceAttrSet(testItemID, "version"), // check absent attr resource.TestCheckNoResourceAttr(testItemID, "encryption"), resource.TestCheckNoResourceAttr(testItemID, "encryption.kek_key_id"), resource.TestCheckNoResourceAttr(testItemID, "encryption.kek_key_ring_id"), resource.TestCheckNoResourceAttr(testItemID, "encryption.kek_key_version"), resource.TestCheckNoResourceAttr(testItemID, "encryption.service_account"), // check param values resource.TestCheckResourceAttr(testItemID, "name", exData.Name), ), }, // Update name and verify { Config: testutils.StringFromTemplateMust( "testdata/instance_template.gompl", updNameData, ), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr( testutils.ResStr(pfx, "instance", exData.TfName), "name", updNameData.Name, ), ), }, // Update size and verify { Config: testutils.StringFromTemplateMust( "testdata/instance_template.gompl", updSizeData, ), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr( testutils.ResStr(pfx, "instance", exData.TfName), "storage.size", strconv.Itoa(int(updSizeData.Size)), ), ), }, // Update backup schedule { Config: testutils.StringFromTemplateMust( "testdata/instance_template.gompl", updBackupSched, ), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr( testutils.ResStr(pfx, "instance", exData.TfName), "backup_schedule", updBackupSched.BackupSchedule, ), ), }, //// Import test //{ // ResourceName: "example_resource.test", // ImportState: true, // ImportStateVerify: true, // }, }, }, ) } func TestAccInstanceWithUsers(t *testing.T) { data := getExample() userName := "testUser" data.Users = []User{ { Name: userName, ProjectID: os.Getenv("TF_ACC_PROJECT_ID"), Roles: []string{"login"}, }, } resource.ParallelTest( t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) t.Logf(" ... working on instance %s", data.TfName) }, CheckDestroy: testAccCheckPostgresFlexDestroy, ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, Steps: []resource.TestStep{ // Create and verify { Config: testutils.StringFromTemplateMust( "testdata/instance_template.gompl", data, ), Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr( testutils.ResStr(pfx, "instance", data.TfName), "name", data.Name, ), resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "instance", data.TfName), "id"), resource.TestCheckResourceAttr(testutils.ResStr(pfx, "user", userName), "name", userName), resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "user", userName), "id"), ), }, }, }, ) } func TestAccInstanceWithDatabases(t *testing.T) { data := getExample() dbName := "testdb" userName := "testUser" data.Users = []User{ { Name: userName, ProjectID: os.Getenv("TF_ACC_PROJECT_ID"), Roles: []string{"login"}, }, } data.Databases = []Database{ { Name: dbName, ProjectID: os.Getenv("TF_ACC_PROJECT_ID"), Owner: userName, }, } resource.ParallelTest( t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) t.Logf(" ... working on instance %s", data.TfName) }, CheckDestroy: testAccCheckPostgresFlexDestroy, ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, Steps: []resource.TestStep{ // Create and verify { Config: testutils.StringFromTemplateMust( "testdata/instance_template.gompl", data, ), Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr( testutils.ResStr(pfx, "instance", data.TfName), "name", data.Name, ), resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "instance", data.TfName), "id"), resource.TestCheckResourceAttr(testutils.ResStr(pfx, "user", userName), "name", userName), resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "user", userName), "id"), resource.TestCheckResourceAttr(testutils.ResStr(pfx, "database", dbName), "name", dbName), resource.TestCheckResourceAttr(testutils.ResStr(pfx, "database", dbName), "owner", userName), resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "database", dbName), "id"), ), }, }, }, ) } func TestAccEncryptedInstanceWithDatabases(t *testing.T) { encKekKeyID, ok := os.LookupEnv("TF_ACC_KEK_KEY_ID") if !ok || encKekKeyID == "" { t.Skip("env var TF_ACC_KEK_KEY_ID needed for encryption test") } encKekKeyRingID, ok := os.LookupEnv("TF_ACC_KEK_KEY_RING_ID") if !ok || encKekKeyRingID == "" { t.Skip("env var TF_ACC_KEK_KEY_RING_ID needed for encryption test") } encKekKeyVersion, ok := os.LookupEnv("TF_ACC_KEK_KEY_VERSION") if !ok || encKekKeyVersion == "" { t.Skip("env var TF_ACC_KEK_KEY_VERSION needed for encryption test") } encSvcAcc, ok := os.LookupEnv("TF_ACC_KEK_SERVICE_ACCOUNT") if !ok || encSvcAcc == "" { t.Skip("env var TF_ACC_KEK_SERVICE_ACCOUNT needed for encryption test") } data := getExample() data.UseEncryption = true data.KekKeyID = encKekKeyID data.KekKeyRingID = encKekKeyRingID data.KekServiceAccount = encSvcAcc encKekKeyVersionInt, err := strconv.Atoi(encKekKeyVersion) if err != nil { t.Errorf("error converting string to int") } if encKekKeyVersionInt > math.MaxUint8 { t.Errorf("value too large to convert to uint8") } data.KekKeyVersion = uint8(encKekKeyVersionInt) //nolint:gosec // handled above dbName := "testdb" userName := "testUser" data.Users = []User{ { Name: userName, ProjectID: os.Getenv("TF_ACC_PROJECT_ID"), Roles: []string{"login"}, }, } data.Databases = []Database{ { Name: dbName, ProjectID: os.Getenv("TF_ACC_PROJECT_ID"), Owner: userName, }, } resource.ParallelTest( t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) t.Logf(" ... working on instance %s", data.TfName) }, CheckDestroy: testAccCheckPostgresFlexDestroy, ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, Steps: []resource.TestStep{ // Create and verify { Config: testutils.StringFromTemplateMust( "testdata/instance_template.gompl", data, ), Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr( testutils.ResStr(pfx, "instance", data.TfName), "name", data.Name, ), resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "instance", data.TfName), "id"), resource.TestCheckResourceAttr(testutils.ResStr(pfx, "user", userName), "name", userName), resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "user", userName), "id"), resource.TestCheckResourceAttr(testutils.ResStr(pfx, "database", dbName), "name", dbName), resource.TestCheckResourceAttr(testutils.ResStr(pfx, "database", dbName), "owner", userName), resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "database", dbName), "id"), ), }, }, }, ) } // func setupMockServer() *httptest.Server { // mux := http.NewServeMux() // // mux.HandleFunc("/api/resources", func(w http.ResponseWriter, r *http.Request) { // switch r.Method { // case http.MethodPost: // w.WriteHeader(http.StatusCreated) // err := json.NewEncoder(w).Encode(map[string]string{ // "id": "mock-id-123", // "name": "test-resource", // }) // if err != nil { // log.Fatalln(err) // } // case http.MethodGet: // w.WriteHeader(http.StatusOK) // err := json.NewEncoder(w).Encode([]map[string]string{}) // if err != nil { // log.Fatalln(err) // } // } // }) // // return httptest.NewServer(mux) //} // // func TestUnitResourceCreate(t *testing.T) { // server := setupMockServer() // defer server.Close() // // // Configure provider to use mock server URL // err := os.Setenv("API_ENDPOINT", server.URL) // if err != nil { // log.Fatalln(err) // } // // // Run unit tests against mock //} // func TestNewInstanceResource(t *testing.T) { // exData := resData{ // Region: "eu01", // ServiceAccountFilePath: sa_file, // ProjectID: project_id, // Name: "testRes", // } // resource.ParallelTest(t, resource.TestCase{ // ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, // Steps: []resource.TestStep{ // { // Config: testAccResourceEncryptionExampleConfig(exData), // Check: resource.ComposeAggregateTestCheckFunc( // resource.TestCheckResourceAttr("example_resource.test", "name", exData.Name), // resource.TestCheckResourceAttrSet("example_resource.test", "id"), // ), // }, // }, // }) // // //tests := []struct { // // name string // // want resource.Resource // //}{ // // { // // name: "create empty instance resource", // // want: &instanceResource{}, // // }, // //} // //for _, tt := range tests { // // t.Run(tt.name, func(t *testing.T) { // // if got := NewInstanceResource(); !reflect.DeepEqual(got, tt.want) { // // t.Errorf("NewInstanceResource() = %v, want %v", got, tt.want) // // } // // }) // //} //} //// Instance resource data // var instanceResource = map[string]string{ // "project_id": testutils.ProjectId, // "region": "eu01", // "name": fmt.Sprintf("tf-acc-%s", acctest.RandStringFromCharSet(7, acctest.CharSetAlphaNum)), // "acl": "192.168.0.0/16", // "backup_schedule": "00 16 * * *", // "backup_schedule_updated": "00 12 * * *", // "retention_days": "33", // "flavor_cpu": "2", // "flavor_ram": "4", // "flavor_description": "Small, Compute optimized", // "replicas": "1", // "storage_class": "premium-perf12-stackit", // "storage_size": "5", // "version": "14", // "flavor_id": "2.4", // "kek_key_id": "UUID1", // "kek_key_ring_id": "UUID2", // "kek_key_version": "1", // "service_account": "service@account.com", // "access_scope": "SNA", //} // //// User resource data // var userResource = map[string]string{ // "username": fmt.Sprintf("tfaccuser%s", acctest.RandStringFromCharSet(4, acctest.CharSetAlpha)), // "role": "createdb", // "project_id": testutils.ProjectId, //} // //// Database resource data // var databaseResource = map[string]string{ // "name": fmt.Sprintf("tfaccdb%s", acctest.RandStringFromCharSet(4, acctest.CharSetAlphaNum)), // "project_id": testutils.ProjectId, //} // // func configResources(backupSchedule string, _ *string) string { // return fmt.Sprintf( // ` // %s // // // resource "stackitprivatepreview_postgresflexalpha_instance" "instance" { // project_id = "%s" // region = "%s" // name = "%s" // backup_schedule = "%s" // retention_days = %s // flavor_id = %s // replicas = %s // storage = { // performance_class = "%s" // size = %s // } // encryption = { // kek_key_id = "%s" // kek_key_ring_id = "%s" // kek_key_version = "%s" // service_account = "%s" // } // network = { // acl = ["%s"] // access_scope = "%s" // } // version = %s // } // // resource "stackitprivatepreview_postgresflexalpha_user" "user" { // project_id = "%s" // instance_id = stackitprivatepreview_postgresflexalpha_instance.instance.instance_id // username = "%s" // roles = ["%s"] // } // // resource "stackitprivatepreview_postgresflexalpha_database" "database" { // project_id = "%s" // instance_id = stackitprivatepreview_postgresflexalpha_instance.instance.instance_id // name = "%s" // owner = stackitprivatepreview_postgresflexalpha_user.user.username // } // `, // testutils.PostgresFlexProviderConfig( // utils.GetEnvOrDefault("TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_FILE", "~/service-account.json"), // ), // instanceResource["project_id"], // instanceResource["region"], // instanceResource["name"], // backupSchedule, // instanceResource["retention_days"], // instanceResource["flavor_id"], // instanceResource["replicas"], // instanceResource["storage_class"], // instanceResource["storage_size"], // instanceResource["kek_key_id"], // instanceResource["kek_key_ring_id"], // instanceResource["kek_key_version"], // instanceResource["service_account"], // instanceResource["acl"], // instanceResource["access_scope"], // instanceResource["version"], // // userResource["project_id"], // userResource["username"], // userResource["role"], // // databaseResource["project_id"], // databaseResource["name"], // ) //} // // func TestAccPostgresFlexFlexResource(t *testing.T) { // resource.ParallelTest( // t, resource.TestCase{ // ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, // CheckDestroy: testAccCheckPostgresFlexDestroy, // Steps: []resource.TestStep{ // // Creation // { // // testdata/ // // ConfigDirectory: config.TestNameDirectory(), // // // testdata// // // ConfigDirectory: config.TestStepDirectory(), // Config: configResources(instanceResource["backup_schedule"], &testutils.Region), // Check: resource.ComposeAggregateTestCheckFunc( // // Instance // resource.TestCheckResourceAttr( // "stackitprivatepreview_postgresflexalpha_instance.instance", // "project_id", // instanceResource["project_id"], // ), // resource.TestCheckResourceAttrSet( // "stackitprivatepreview_postgresflexalpha_instance.instance", // "instance_id", // ), // resource.TestCheckResourceAttr( // "stackitprivatepreview_postgresflexalpha_instance.instance", // "name", // instanceResource["name"], // ), // resource.TestCheckResourceAttr( // "stackitprivatepreview_postgresflexalpha_instance.instance", // "acl.#", // "1", // ), // resource.TestCheckResourceAttr( // "stackitprivatepreview_postgresflexalpha_instance.instance", // "acl.0", // instanceResource["acl"], // ), // resource.TestCheckResourceAttrSet( // "stackitprivatepreview_postgresflexalpha_instance.instance", // "flavor.id", // ), // resource.TestCheckResourceAttrSet( // "stackitprivatepreview_postgresflexalpha_instance.instance", // "flavor.description", // ), // resource.TestCheckResourceAttr( // "stackitprivatepreview_postgresflexalpha_instance.instance", // "backup_schedule", // instanceResource["backup_schedule"], // ), // resource.TestCheckResourceAttr( // "stackitprivatepreview_postgresflexalpha_instance.instance", // "flavor.cpu", // instanceResource["flavor_cpu"], // ), // resource.TestCheckResourceAttr( // "stackitprivatepreview_postgresflexalpha_instance.instance", // "flavor.ram", // instanceResource["flavor_ram"], // ), // resource.TestCheckResourceAttr( // "stackitprivatepreview_postgresflexalpha_instance.instance", // "replicas", // instanceResource["replicas"], // ), // resource.TestCheckResourceAttr( // "stackitprivatepreview_postgresflexalpha_instance.instance", // "storage.class", // instanceResource["storage_class"], // ), // resource.TestCheckResourceAttr( // "stackitprivatepreview_postgresflexalpha_instance.instance", // "storage.size", // instanceResource["storage_size"], // ), // resource.TestCheckResourceAttr( // "stackitprivatepreview_postgresflexalpha_instance.instance", // "version", // instanceResource["version"], // ), // resource.TestCheckResourceAttr( // "stackitprivatepreview_postgresflexalpha_instance.instance", // "region", // testutils.Region, // ), // // // User // resource.TestCheckResourceAttrPair( // "stackitprivatepreview_postgresflexalpha_user.user", "project_id", // "stackitprivatepreview_postgresflexalpha_instance.instance", "project_id", // ), // resource.TestCheckResourceAttrPair( // "stackitprivatepreview_postgresflexalpha_user.user", "instance_id", // "stackitprivatepreview_postgresflexalpha_instance.instance", "instance_id", // ), // resource.TestCheckResourceAttrSet("stackitprivatepreview_postgresflexalpha_user.user", "user_id"), // resource.TestCheckResourceAttrSet("stackitprivatepreview_postgresflexalpha_user.user", "password"), // // // Database // resource.TestCheckResourceAttrPair( // "stackitprivatepreview_postgresflexalpha_database.database", "project_id", // "stackitprivatepreview_postgresflexalpha_instance.instance", "project_id", // ), // resource.TestCheckResourceAttrPair( // "stackitprivatepreview_postgresflexalpha_database.database", "instance_id", // "stackitprivatepreview_postgresflexalpha_instance.instance", "instance_id", // ), // resource.TestCheckResourceAttr( // "stackitprivatepreview_postgresflexalpha_database.database", // "name", // databaseResource["name"], // ), // resource.TestCheckResourceAttrPair( // "stackitprivatepreview_postgresflexalpha_database.database", "owner", // "stackitprivatepreview_postgresflexalpha_user.user", "username", // ), // ), // }, // // data source // { // Config: fmt.Sprintf( // ` // %s // // data "stackitprivatepreview_postgresflexalpha_instance" "instance" { // project_id = stackitprivatepreview_postgresflexalpha_instance.instance.project_id // instance_id = stackitprivatepreview_postgresflexalpha_instance.instance.instance_id // } // // data "stackitprivatepreview_postgresflexalpha_user" "user" { // project_id = stackitprivatepreview_postgresflexalpha_instance.instance.project_id // instance_id = stackitprivatepreview_postgresflexalpha_instance.instance.instance_id // user_id = stackitprivatepreview_postgresflexalpha_user.user.user_id // } // // data "stackitprivatepreview_postgresflexalpha_database" "database" { // project_id = stackitprivatepreview_postgresflexalpha_instance.instance.project_id // instance_id = stackitprivatepreview_postgresflexalpha_instance.instance.instance_id // database_id = stackitprivatepreview_postgresflexalpha_database.database.database_id // } // `, // configResources(instanceResource["backup_schedule"], nil), // ), // Check: resource.ComposeAggregateTestCheckFunc( // // Instance data // resource.TestCheckResourceAttr( // "data.stackitprivatepreview_postgresflexalpha_instance.instance", // "project_id", // instanceResource["project_id"], // ), // resource.TestCheckResourceAttr( // "data.stackitprivatepreview_postgresflexalpha_instance.instance", // "name", // instanceResource["name"], // ), // resource.TestCheckResourceAttrPair( // "data.stackitprivatepreview_postgresflexalpha_instance.instance", "project_id", // "stackitprivatepreview_postgresflexalpha_instance.instance", "project_id", // ), // resource.TestCheckResourceAttrPair( // "data.stackitprivatepreview_postgresflexalpha_instance.instance", "instance_id", // "stackitprivatepreview_postgresflexalpha_instance.instance", "instance_id", // ), // resource.TestCheckResourceAttrPair( // "data.stackitprivatepreview_postgresflexalpha_user.user", "instance_id", // "stackitprivatepreview_postgresflexalpha_user.user", "instance_id", // ), // // resource.TestCheckResourceAttr( // "data.stackitprivatepreview_postgresflexalpha_instance.instance", // "acl.#", // "1", // ), // resource.TestCheckResourceAttr( // "data.stackitprivatepreview_postgresflexalpha_instance.instance", // "acl.0", // instanceResource["acl"], // ), // resource.TestCheckResourceAttr( // "data.stackitprivatepreview_postgresflexalpha_instance.instance", // "backup_schedule", // instanceResource["backup_schedule"], // ), // resource.TestCheckResourceAttr( // "data.stackitprivatepreview_postgresflexalpha_instance.instance", // "flavor.id", // instanceResource["flavor_id"], // ), // resource.TestCheckResourceAttr( // "data.stackitprivatepreview_postgresflexalpha_instance.instance", // "flavor.description", // instanceResource["flavor_description"], // ), // resource.TestCheckResourceAttr( // "data.stackitprivatepreview_postgresflexalpha_instance.instance", // "flavor.cpu", // instanceResource["flavor_cpu"], // ), // resource.TestCheckResourceAttr( // "data.stackitprivatepreview_postgresflexalpha_instance.instance", // "flavor.ram", // instanceResource["flavor_ram"], // ), // resource.TestCheckResourceAttr( // "data.stackitprivatepreview_postgresflexalpha_instance.instance", // "replicas", // instanceResource["replicas"], // ), // // // User data // resource.TestCheckResourceAttr( // "data.stackitprivatepreview_postgresflexalpha_user.user", // "project_id", // userResource["project_id"], // ), // resource.TestCheckResourceAttrSet( // "data.stackitprivatepreview_postgresflexalpha_user.user", // "user_id", // ), // resource.TestCheckResourceAttr( // "data.stackitprivatepreview_postgresflexalpha_user.user", // "username", // userResource["username"], // ), // resource.TestCheckResourceAttr( // "data.stackitprivatepreview_postgresflexalpha_user.user", // "roles.#", // "1", // ), // resource.TestCheckResourceAttr( // "data.stackitprivatepreview_postgresflexalpha_user.user", // "roles.0", // userResource["role"], // ), // resource.TestCheckResourceAttrSet( // "data.stackitprivatepreview_postgresflexalpha_user.user", // "host", // ), // resource.TestCheckResourceAttrSet( // "data.stackitprivatepreview_postgresflexalpha_user.user", // "port", // ), // // // Database data // resource.TestCheckResourceAttr( // "data.stackitprivatepreview_postgresflexalpha_database.database", // "project_id", // instanceResource["project_id"], // ), // resource.TestCheckResourceAttr( // "data.stackitprivatepreview_postgresflexalpha_database.database", // "name", // databaseResource["name"], // ), // resource.TestCheckResourceAttrPair( // "data.stackitprivatepreview_postgresflexalpha_database.database", // "instance_id", // "stackitprivatepreview_postgresflexalpha_instance.instance", // "instance_id", // ), // resource.TestCheckResourceAttrPair( // "data.stackitprivatepreview_postgresflexalpha_database.database", // "owner", // "data.stackitprivatepreview_postgresflexalpha_user.user", // "username", // ), // ), // }, // // Import // { // ResourceName: "stackitprivatepreview_postgresflexalpha_instance.instance", // ImportStateIdFunc: func(s *terraform.State) (string, error) { // r, ok := s.RootModule().Resources["stackitprivatepreview_postgresflexalpha_instance.instance"] // if !ok { // return "", fmt.Errorf("couldn't find resource stackitprivatepreview_postgresflexalpha_instance.instance") // } // instanceId, ok := r.Primary.Attributes["instance_id"] // if !ok { // return "", fmt.Errorf("couldn't find attribute instance_id") // } // // return fmt.Sprintf("%s,%s,%s", testutils.ProjectId, testutils.Region, instanceId), nil // }, // ImportState: true, // ImportStateVerify: true, // ImportStateVerifyIgnore: []string{"password"}, // }, // { // ResourceName: "stackitprivatepreview_postgresflexalpha_user.user", // ImportStateIdFunc: func(s *terraform.State) (string, error) { // r, ok := s.RootModule().Resources["stackitprivatepreview_postgresflexalpha_user.user"] // if !ok { // return "", fmt.Errorf("couldn't find resource stackitprivatepreview_postgresflexalpha_user.user") // } // instanceId, ok := r.Primary.Attributes["instance_id"] // if !ok { // return "", fmt.Errorf("couldn't find attribute instance_id") // } // userId, ok := r.Primary.Attributes["user_id"] // if !ok { // return "", fmt.Errorf("couldn't find attribute user_id") // } // // return fmt.Sprintf("%s,%s,%s,%s", testutils.ProjectId, testutils.Region, instanceId, userId), nil // }, // ImportState: true, // ImportStateVerify: true, // ImportStateVerifyIgnore: []string{"password", "uri"}, // }, // { // ResourceName: "stackitprivatepreview_postgresflexalpha_database.database", // ImportStateIdFunc: func(s *terraform.State) (string, error) { // r, ok := s.RootModule().Resources["stackitprivatepreview_postgresflexalpha_database.database"] // if !ok { // return "", fmt.Errorf("couldn't find resource stackitprivatepreview_postgresflexalpha_database.database") // } // instanceId, ok := r.Primary.Attributes["instance_id"] // if !ok { // return "", fmt.Errorf("couldn't find attribute instance_id") // } // databaseId, ok := r.Primary.Attributes["database_id"] // if !ok { // return "", fmt.Errorf("couldn't find attribute database_id") // } // // return fmt.Sprintf( // "%s,%s,%s,%s", // testutils.ProjectId, // testutils.Region, // instanceId, // databaseId, // ), nil // }, // ImportState: true, // ImportStateVerify: true, // }, // // Update // { // Config: configResources(instanceResource["backup_schedule_updated"], nil), // Check: resource.ComposeAggregateTestCheckFunc( // // Instance data // resource.TestCheckResourceAttr( // "stackitprivatepreview_postgresflexalpha_instance.instance", // "project_id", // instanceResource["project_id"], // ), // resource.TestCheckResourceAttrSet( // "stackitprivatepreview_postgresflexalpha_instance.instance", // "instance_id", // ), // resource.TestCheckResourceAttr( // "stackitprivatepreview_postgresflexalpha_instance.instance", // "name", // instanceResource["name"], // ), // resource.TestCheckResourceAttr( // "stackitprivatepreview_postgresflexalpha_instance.instance", // "acl.#", // "1", // ), // resource.TestCheckResourceAttr( // "stackitprivatepreview_postgresflexalpha_instance.instance", // "acl.0", // instanceResource["acl"], // ), // resource.TestCheckResourceAttr( // "stackitprivatepreview_postgresflexalpha_instance.instance", // "backup_schedule", // instanceResource["backup_schedule_updated"], // ), // resource.TestCheckResourceAttrSet( // "stackitprivatepreview_postgresflexalpha_instance.instance", // "flavor.id", // ), // resource.TestCheckResourceAttrSet( // "stackitprivatepreview_postgresflexalpha_instance.instance", // "flavor.description", // ), // resource.TestCheckResourceAttr( // "stackitprivatepreview_postgresflexalpha_instance.instance", // "flavor.cpu", // instanceResource["flavor_cpu"], // ), // resource.TestCheckResourceAttr( // "stackitprivatepreview_postgresflexalpha_instance.instance", // "flavor.ram", // instanceResource["flavor_ram"], // ), // resource.TestCheckResourceAttr( // "stackitprivatepreview_postgresflexalpha_instance.instance", // "replicas", // instanceResource["replicas"], // ), // resource.TestCheckResourceAttr( // "stackitprivatepreview_postgresflexalpha_instance.instance", // "storage.class", // instanceResource["storage_class"], // ), // resource.TestCheckResourceAttr( // "stackitprivatepreview_postgresflexalpha_instance.instance", // "storage.size", // instanceResource["storage_size"], // ), // resource.TestCheckResourceAttr( // "stackitprivatepreview_postgresflexalpha_instance.instance", // "version", // instanceResource["version"], // ), // ), // }, // // Deletion is done by the framework implicitly // }, // }, // ) //} // // func testAccCheckPostgresFlexDestroy(s *terraform.State) error { // ctx := context.Background() // var client *postgresflex.APIClient // var err error // if testutils.PostgresFlexCustomEndpoint == "" { // client, err = postgresflex.NewAPIClient() // } else { // client, err = postgresflex.NewAPIClient( // config.WithEndpoint(testutils.PostgresFlexCustomEndpoint), // ) // } // if err != nil { // return fmt.Errorf("creating client: %w", err) // } // // instancesToDestroy := []string{} // for _, rs := range s.RootModule().Resources { // if rs.Type != "stackitprivatepreview_postgresflexalpha_instance" { // continue // } // // instance terraform ID: = "[project_id],[region],[instance_id]" // instanceId := strings.Split(rs.Primary.ID, core.Separator)[2] // instancesToDestroy = append(instancesToDestroy, instanceId) // } // // instancesResp, err := client.ListInstancesRequest(ctx, testutils.ProjectId, testutils.Region).Execute() // if err != nil { // return fmt.Errorf("getting instancesResp: %w", err) // } // // items := *instancesResp.Instances // for i := range items { // if items[i].Id == nil { // continue // } // if utils.Contains(instancesToDestroy, *items[i].Id) { // // TODO @mhenselin - does force still exist? // err := client.DeleteInstanceRequestExecute(ctx, testutils.ProjectId, testutils.Region, *items[i].Id) // if err != nil { // return fmt.Errorf("deleting instance %s during CheckDestroy: %w", *items[i].Id, err) // } // } // } // return nil //} func testAccCheckPostgresFlexDestroy(s *terraform.State) error { testutils.Setup() pID, ok := os.LookupEnv("TF_ACC_PROJECT_ID") if !ok { log.Fatalln("unable to read TF_ACC_PROJECT_ID") } ctx := context.Background() var client *v3alpha1api.APIClient var err error var region, projectID string region = testutils.Region if region == "" { region = "eu01" } projectID = pID if projectID == "" { return fmt.Errorf("projectID could not be determined in destroy function") } apiClientConfigOptions := []config.ConfigurationOption{ config.WithServiceAccountKeyPath(os.Getenv("TF_ACC_SERVICE_ACCOUNT_FILE")), config.WithRegion(region), } if testutils.PostgresFlexCustomEndpoint != "" { apiClientConfigOptions = append( apiClientConfigOptions, config.WithEndpoint(testutils.PostgresFlexCustomEndpoint), ) } client, err = v3alpha1api.NewAPIClient(apiClientConfigOptions...) if err != nil { log.Fatalln(err) } instancesToDestroy := []string{} for _, rs := range s.RootModule().Resources { if rs.Type != "stackitprivatepreview_postgresflexalpha_instance" && rs.Type != "stackitprivatepreview_postgresflexbeta_instance" { continue } // instance terraform ID: = "[project_id],[region],[instance_id]" instanceID := strings.Split(rs.Primary.ID, core.Separator)[2] instancesToDestroy = append(instancesToDestroy, instanceID) } instancesResp, err := client.DefaultAPI.ListInstancesRequest(ctx, projectID, region). Size(100). Execute() if err != nil { return fmt.Errorf("getting instancesResp: %w", err) } items := instancesResp.GetInstances() for i := range items { if items[i].Id == "" { continue } if utils.Contains(instancesToDestroy, items[i].Id) { err := client.DefaultAPI.DeleteInstanceRequest(ctx, testutils.ProjectId, region, items[i].Id).Execute() if err != nil { return fmt.Errorf("deleting instance %s during CheckDestroy: %w", items[i].Id, err) } err = postgresflexalpha.DeleteInstanceWaitHandler( ctx, client.DefaultAPI, testutils.ProjectId, testutils.Region, items[i].Id, 15*time.Minute, 10*time.Second, ) if err != nil { return fmt.Errorf("deleting instance %s during CheckDestroy: waiting for deletion %w", items[i].Id, err) } } } return nil }