VAULT-27015: Fix Issue with plugin_name not used in vault_database_secret_backend_connection (#2705)

* Fix db getpluginname (#2704)

* Update resource_database_secret_backend_connection.go

Modify getDatabaseAPIDataForEngine to use unifiedSchema and then been able to getPluginName:
- with the prefix (UnifiedSchema = true)
- without the prefix (UnifiedSchema = false)

* modified:   vault/resource_database_secret_backend_connection_test.go

* modified:   vault/resource_database_secret_backend_connection_test.go

* modified:   vault/resource_database_secret_backend_connection_test.go

* modified:   vault/resource_database_secret_backend_connection_test.go

* Update CHANGELOG.md
This commit is contained in:
chpag 2026-01-09 23:30:44 +01:00 committed by GitHub
parent b187d58a04
commit 0cea5fa544
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 165 additions and 3 deletions

View file

@ -20,6 +20,7 @@ IMPROVEMENTS:
BUGS:
* `provider/auth_login_aws`: Fix issue where AWS authentication with IAM role assumption (`aws_role_arn`) was not working correctly due to incorrect credential handling ([#2679](https://github.com/hashicorp/terraform-provider-vault/pull/2679))
* Fix plugin_name attribute not correctly use in vault_database_secret_backend_connection. ([#2705](https://github.com/hashicorp/terraform-provider-vault/pull/2705))
## 5.6.0 (December 19, 2025)

View file

@ -1055,11 +1055,17 @@ func getDBEngineFromResp(engines []*dbEngine, r *api.Secret) (*dbEngine, error)
return nil, fmt.Errorf("no supported database engines found for plugin %q", pluginName)
}
func getDatabaseAPIDataForEngine(engine *dbEngine, idx int, d *schema.ResourceData, meta interface{}) (map[string]interface{}, error) {
func getDatabaseAPIDataForEngine(engine *dbEngine, idx int, d *schema.ResourceData, meta interface{}, unifiedSchema bool) (map[string]interface{}, error) {
prefix := engine.ResourcePrefix(idx)
data := map[string]interface{}{}
pluginName, err := engine.GetPluginName(d, prefix)
var pluginPrefix string
if unifiedSchema {
pluginPrefix = prefix
} else {
pluginPrefix = ""
}
pluginName, err := engine.GetPluginName(d, pluginPrefix)
if err != nil {
return nil, err
}
@ -2057,7 +2063,7 @@ func databaseSecretBackendConnectionCreateOrUpdate(
}
func writeDatabaseSecretConfig(ctx context.Context, d *schema.ResourceData, client *api.Client, engine *dbEngine, idx int, unifiedSchema bool, path string, meta interface{}) error {
data, err := getDatabaseAPIDataForEngine(engine, idx, d, meta)
data, err := getDatabaseAPIDataForEngine(engine, idx, d, meta, unifiedSchema)
if err != nil {
return err
}

View file

@ -689,6 +689,25 @@ func TestAccDatabaseSecretBackendConnection_mysql(t *testing.T) {
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "mysql.0.max_connection_lifetime", "0"),
),
},
},
})
}
func TestAccDatabaseSecretBackendConnection_mysql_rds(t *testing.T) {
MaybeSkipDBTests(t, dbEngineMySQL)
// TODO: make these fatal once we auto provision the required test infrastructure.
values := testutil.SkipTestEnvUnset(t,
"MYSQL_CONNECTION_URL", "MYSQL_CONNECTION_USERNAME", "MYSQL_CONNECTION_PASSWORD")
connURL, username, password := values[0], values[1], values[2]
backend := acctest.RandomWithPrefix("tf-test-db")
name := acctest.RandomWithPrefix("db")
resource.Test(t, resource.TestCase{
ProtoV5ProviderFactories: testAccProtoV5ProviderFactories(context.Background(), t),
PreCheck: func() { testutil.TestAccPreCheck(t) },
CheckDestroy: testAccDatabaseSecretBackendConnectionCheckDestroy,
Steps: []resource.TestStep{
{
Config: testAccDatabaseSecretBackendConnectionConfig_mysql_rds(name, backend, connURL, username, password),
Check: testComposeCheckFuncCommonDatabaseSecretBackend(name, backend, dbEngineMySQLRDS.DefaultPluginName(),
@ -705,6 +724,25 @@ func TestAccDatabaseSecretBackendConnection_mysql(t *testing.T) {
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "mysql_rds.0.max_connection_lifetime", "0"),
),
},
},
})
}
func TestAccDatabaseSecretBackendConnection_mysql_aurora(t *testing.T) {
MaybeSkipDBTests(t, dbEngineMySQL)
// TODO: make these fatal once we auto provision the required test infrastructure.
values := testutil.SkipTestEnvUnset(t,
"MYSQL_CONNECTION_URL", "MYSQL_CONNECTION_USERNAME", "MYSQL_CONNECTION_PASSWORD")
connURL, username, password := values[0], values[1], values[2]
backend := acctest.RandomWithPrefix("tf-test-db")
name := acctest.RandomWithPrefix("db")
resource.Test(t, resource.TestCase{
ProtoV5ProviderFactories: testAccProtoV5ProviderFactories(context.Background(), t),
PreCheck: func() { testutil.TestAccPreCheck(t) },
CheckDestroy: testAccDatabaseSecretBackendConnectionCheckDestroy,
Steps: []resource.TestStep{
{
Config: testAccDatabaseSecretBackendConnectionConfig_mysql_aurora(name, backend, connURL, username, password),
Check: testComposeCheckFuncCommonDatabaseSecretBackend(name, backend, dbEngineMySQLAurora.DefaultPluginName(),
@ -721,6 +759,25 @@ func TestAccDatabaseSecretBackendConnection_mysql(t *testing.T) {
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "mysql_aurora.0.max_connection_lifetime", "0"),
),
},
},
})
}
func TestAccDatabaseSecretBackendConnection_mysql_legacy(t *testing.T) {
MaybeSkipDBTests(t, dbEngineMySQL)
// TODO: make these fatal once we auto provision the required test infrastructure.
values := testutil.SkipTestEnvUnset(t,
"MYSQL_CONNECTION_URL", "MYSQL_CONNECTION_USERNAME", "MYSQL_CONNECTION_PASSWORD")
connURL, username, password := values[0], values[1], values[2]
backend := acctest.RandomWithPrefix("tf-test-db")
name := acctest.RandomWithPrefix("db")
resource.Test(t, resource.TestCase{
ProtoV5ProviderFactories: testAccProtoV5ProviderFactories(context.Background(), t),
PreCheck: func() { testutil.TestAccPreCheck(t) },
CheckDestroy: testAccDatabaseSecretBackendConnectionCheckDestroy,
Steps: []resource.TestStep{
{
Config: testAccDatabaseSecretBackendConnectionConfig_mysql_legacy(name, backend, connURL, username, password),
Check: testComposeCheckFuncCommonDatabaseSecretBackend(name, backend, dbEngineMySQLLegacy.DefaultPluginName(),
@ -951,6 +1008,54 @@ func TestAccDatabaseSecretBackendConnection_mysql_tls(t *testing.T) {
})
}
func TestAccDatabaseSecretBackendConnection_oracle(t *testing.T) {
MaybeSkipDBTests(t, dbEngineOracle)
// ORACLE_PLUGIN_NAME is required as not built-in plugin (already installed or installed during test, cf below)
// if ORACLE_PLUGIN_INSTALL=true
// plugin ORACLE_PLUGIN_NAME will be add to the catalog using vault_plugin resources:
// resource "vault_plugin" "plugin" {
// type = "database"
// name = "$ORACLE_PLUGIN_NAME"
// command = "$ORACLE_PLUGIN_NAME"
// version = "$ORACLE_PLUGIN_VERSION"
// sha256 = "$ORACLE_PLUGIN_SHA"
// }
//
// To work, it requires the oracle binary plugin in Vault plugin directory
//
values := testutil.SkipTestEnvUnset(t, "ORACLE_CONNECTION_URL", "ORACLE_CONNECTION_USERNAME", "ORACLE_CONNECTION_PASSWORD", "ORACLE_PLUGIN_NAME", "ORACLE_PLUGIN_INSTALL")
connURL, username, password, pluginName, pluginInstall := values[0], values[1], values[2], values[3], values[4]
var pluginVersion, pluginSHA string
if pluginInstall == "true" {
values2 := testutil.SkipTestEnvUnset(t, "ORACLE_PLUGIN_VERSION", "ORACLE_PLUGIN_SHA")
pluginVersion, pluginSHA = values2[0], values2[1]
}
backend := acctest.RandomWithPrefix("tf-test-db")
name := acctest.RandomWithPrefix("db")
resource.Test(t, resource.TestCase{
ProtoV5ProviderFactories: testAccProtoV5ProviderFactories(context.Background(), t),
PreCheck: func() { testutil.TestAccPreCheck(t) },
CheckDestroy: testAccDatabaseSecretBackendConnectionCheckDestroy,
Steps: []resource.TestStep{
{
Config: testAccDatabaseSecretBackendConnectionConfig_oracle(name, backend, pluginName, connURL, username, password, "*", pluginInstall, pluginVersion, pluginSHA),
Check: testComposeCheckFuncCommonDatabaseSecretBackend(name, backend, pluginName,
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "allowed_roles.#", "1"),
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "allowed_roles.0", "*"),
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "verify_connection", "true"),
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "oracle.0.connection_url", connURL),
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "oracle.0.username", username),
resource.TestCheckResourceAttr(testDefaultDatabaseSecretBackendResource, "oracle.0.password", password),
),
},
},
})
}
func TestAccDatabaseSecretBackendConnection_postgresql(t *testing.T) {
MaybeSkipDBTests(t, dbEnginePostgres)
@ -2281,6 +2386,56 @@ resource "vault_database_secret_backend_connection" "test" {
`, path, name, connURL, authType, serviceAccountJSON)
}
func testAccDatabaseSecretBackendConnectionConfig_oracle(name, path, pluginName, connURL, username, password, allowedRoles, pluginInstall, pluginVersion, pluginSHA string) string {
config := fmt.Sprintf(`
resource "vault_mount" "db" {
path = "%s"
type = "database"
}
`, path)
if pluginInstall == "true" {
config += fmt.Sprintf(`
resource "vault_plugin" "plugin" {
type = "database"
name = "%s"
command = "%s"
version = "%s"
sha256 = "%s"
}
resource "vault_database_secret_backend_connection" "test" {
backend = vault_mount.db.path
plugin_name = vault_plugin.plugin.name
name = "%s"
allowed_roles = [%q]
oracle {
connection_url = "%s"
username = "%s"
password = "%s"
}
}
`, pluginName, pluginName, pluginVersion, pluginSHA, name, allowedRoles, connURL, username, password)
} else {
config += fmt.Sprintf(`
resource "vault_database_secret_backend_connection" "test" {
backend = vault_mount.db.path
plugin_name = "%s"
name = "%s"
allowed_roles = [%q]
oracle {
connection_url = "%s"
username = "%s"
password = "%s"
}
}`, pluginName, name, allowedRoles, connURL, username, password)
}
return config
}
func testAccDatabaseSecretBackendConnectionConfig_postgresql(name, path, userTempl, username, password, openConn, idleConn, maxConnLifetime string, parsedURL *url.URL) string {
return fmt.Sprintf(`
resource "vault_mount" "db" {