From db6f70090d57e32ae9613846bcfe4cceeb826043 Mon Sep 17 00:00:00 2001 From: JM Faircloth Date: Fri, 3 Jan 2025 16:24:41 -0600 Subject: [PATCH] add static role support for role-level field --- ...urce_database_secret_backend_connection.go | 6 +- ...rce_database_secret_backend_static_role.go | 8 +- ...atabase_secret_backend_static_role_test.go | 80 +++++++++++++++++++ 3 files changed, 90 insertions(+), 4 deletions(-) diff --git a/vault/resource_database_secret_backend_connection.go b/vault/resource_database_secret_backend_connection.go index 32a370424..8f5deb9de 100644 --- a/vault/resource_database_secret_backend_connection.go +++ b/vault/resource_database_secret_backend_connection.go @@ -1863,8 +1863,10 @@ func writeDatabaseSecretConfig(d *schema.ResourceData, client *api.Client, } } - if v, ok := d.Get(prefix + consts.FieldSkipStaticRoleImportRotation).(bool); ok { - data[consts.FieldSkipStaticRoleImportRotation] = v + if provider.IsAPISupported(meta, provider.VaultVersion118) && provider.IsEnterpriseSupported(meta) { + if v, ok := d.Get(prefix + consts.FieldSkipStaticRoleImportRotation).(bool); ok { + data[consts.FieldSkipStaticRoleImportRotation] = v + } } log.Printf("[DEBUG] Writing connection config to %q", path) diff --git a/vault/resource_database_secret_backend_static_role.go b/vault/resource_database_secret_backend_static_role.go index b627351e1..937acf4e7 100644 --- a/vault/resource_database_secret_backend_static_role.go +++ b/vault/resource_database_secret_backend_static_role.go @@ -6,12 +6,13 @@ package vault import ( "context" "fmt" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-provider-vault/internal/consts" "log" "regexp" "strings" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-provider-vault/internal/consts" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-vault/internal/provider" @@ -142,6 +143,9 @@ func databaseSecretBackendStaticRoleWrite(ctx context.Context, d *schema.Resourc if v, ok := d.GetOk(consts.FieldSelfManagedPassword); ok && v != "" { data[consts.FieldSelfManagedPassword] = v } + if v, ok := d.Get(consts.FieldSkipImportRotation).(bool); ok { + data[consts.FieldSkipImportRotation] = v + } } log.Printf("[DEBUG] Creating static role %q on database backend %q", name, backend) diff --git a/vault/resource_database_secret_backend_static_role_test.go b/vault/resource_database_secret_backend_static_role_test.go index 96df17f7b..f5db5f976 100644 --- a/vault/resource_database_secret_backend_static_role_test.go +++ b/vault/resource_database_secret_backend_static_role_test.go @@ -203,6 +203,58 @@ CREATE ROLE "{{name}}" WITH }) } +// TestAccDatabaseSecretBackendStaticRole_SkipImportRotation tests the skip +// auto import Rotation configuration. +// To run locally you will need to set the following env vars: +// - POSTGRES_URL_TEST +// - POSTGRES_URL_ROOTLESS +func TestAccDatabaseSecretBackendStaticRole_SkipImportRotation(t *testing.T) { + connURLTestRoot := testutil.SkipTestEnvUnset(t, "POSTGRES_URL_TEST")[0] + connURL := testutil.SkipTestEnvUnset(t, "POSTGRES_URL_ROOTLESS")[0] + + backend := acctest.RandomWithPrefix("tf-test-db") + username := acctest.RandomWithPrefix("user") + dbName := acctest.RandomWithPrefix("db") + name := acctest.RandomWithPrefix("staticrole") + resourceName := "vault_database_secret_backend_static_role.test" + + testRoleStaticCreate := ` +CREATE ROLE "{{name}}" WITH + LOGIN + PASSWORD '{{password}}'; +` + + // create static database user + testutil.CreateTestPGUser(t, connURLTestRoot, username, "testpassword", testRoleStaticCreate) + + resource.Test(t, resource.TestCase{ + ProviderFactories: providerFactories, + PreCheck: func() { + testutil.TestEntPreCheck(t) + SkipIfAPIVersionLT(t, testProvider.Meta(), provider.VaultVersion118) + }, + CheckDestroy: testAccDatabaseSecretBackendStaticRoleCheckDestroy, + Steps: []resource.TestStep{ + { + Config: testAccDatabaseSecretBackendStaticRoleConfig_skipImportRotation(name, username, dbName, backend, connURL, "testpassword"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, "backend", backend), + resource.TestCheckResourceAttr(resourceName, "username", username), + resource.TestCheckResourceAttr(resourceName, "db_name", dbName), + resource.TestCheckResourceAttr(resourceName, "rotation_period", "3600"), + resource.TestCheckResourceAttr(resourceName, "skip_import_rotation", "true"), + ), + }, + { + ResourceName: "vault_database_secret_backend_static_role.test", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testAccDatabaseSecretBackendStaticRoleCheckDestroy(s *terraform.State) error { for _, rs := range s.RootModule().Resources { if rs.Type != "vault_database_secret_backend_static_role" { @@ -371,6 +423,34 @@ resource "vault_database_secret_backend_static_role" "test" { `, path, db, connURL, name, username) } +func testAccDatabaseSecretBackendStaticRoleConfig_skipImportRotation(name, username, db, path, connURL, smPassword string) string { + return fmt.Sprintf(` +resource "vault_mount" "db" { + path = "%s" + type = "database" +} + +resource "vault_database_secret_backend_connection" "test" { + backend = vault_mount.db.path + name = "%s" + allowed_roles = ["*"] + + postgresql { + connection_url = "%s" + } +} + +resource "vault_database_secret_backend_static_role" "test" { + backend = vault_mount.db.path + db_name = vault_database_secret_backend_connection.test.name + name = "%s" + username = "%s" + skip_import_rotation = true + rotation_period = 3600 +} +`, path, db, connURL, name, username) +} + func testAccDatabaseSecretBackendStaticRoleConfig_rootlessConfig(name, username, db, path, connURL, smPassword string) string { return fmt.Sprintf(` resource "vault_mount" "db" {