From 4a97fc89ea2af3f7e124606afe4a8ba4193c8178 Mon Sep 17 00:00:00 2001 From: Goutam Adwant Date: Sat, 27 Jun 2026 10:34:48 -0700 Subject: [PATCH] GH-920 Handle duplicate database roles Use distinct database secret backend metadata names when the same Vault database role is mapped to different target username and password properties. Fixes gh-920 Signed-off-by: Goutam Adwant --- ...tConfigDatabaseBootstrapConfiguration.java | 3 +- ...tabaseBootstrapConfigurationUnitTests.java | 41 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/VaultConfigDatabaseBootstrapConfiguration.java b/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/VaultConfigDatabaseBootstrapConfiguration.java index 2e61b978..8e7169ab 100644 --- a/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/VaultConfigDatabaseBootstrapConfiguration.java +++ b/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/VaultConfigDatabaseBootstrapConfiguration.java @@ -85,7 +85,8 @@ static SecretBackendMetadata forDatabase(final DatabaseSecretProperties properti @Override public String getName() { - return String.format("%s with Role %s", properties.getBackend(), properties.getRole()); + return String.format("%s with Role %s using %s/%s", properties.getBackend(), properties.getRole(), + properties.getUsernameProperty(), properties.getPasswordProperty()); } @Override diff --git a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigDatabaseBootstrapConfigurationUnitTests.java b/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigDatabaseBootstrapConfigurationUnitTests.java index 1017f8e5..33d30959 100644 --- a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigDatabaseBootstrapConfigurationUnitTests.java +++ b/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigDatabaseBootstrapConfigurationUnitTests.java @@ -16,9 +16,13 @@ package org.springframework.cloud.vault.config.databases; +import java.util.Map; + import org.junit.jupiter.api.Test; import org.springframework.cloud.vault.config.SecretBackendMetadata; +import org.springframework.core.env.CompositePropertySource; +import org.springframework.core.env.MapPropertySource; import static org.assertj.core.api.Assertions.assertThat; @@ -44,4 +48,41 @@ public void shouldConsiderCredentialPath() { assertThat(metadata.getPath()).isEqualTo("database/static-creds/my-role"); } + @Test + public void shouldContributePropertiesForSameRoleWithDifferentTargetProperties() { + + VaultConfigDatabaseBootstrapConfiguration.DatabaseSecretBackendMetadataFactory factory = new VaultConfigDatabaseBootstrapConfiguration() + .databaseSecretBackendMetadataFactory(); + + VaultDatabaseProperties primary = databaseProperties("db1-dbuser", "spring.datasource.username", + "spring.datasource.password"); + VaultDatabaseProperties secondary = databaseProperties("db1-dbuser", "spring.secondary-datasource.username", + "spring.secondary-datasource.password"); + + SecretBackendMetadata primaryMetadata = factory.createMetadata(primary); + SecretBackendMetadata secondaryMetadata = factory.createMetadata(secondary); + Map secret = Map.of("username", "vault-user", "password", "vault-password"); + + CompositePropertySource propertySource = new CompositePropertySource("vault"); + propertySource.addPropertySource(new MapPropertySource(primaryMetadata.getName(), + primaryMetadata.getPropertyTransformer().transformProperties(secret))); + propertySource.addPropertySource(new MapPropertySource(secondaryMetadata.getName(), + secondaryMetadata.getPropertyTransformer().transformProperties(secret))); + + assertThat(propertySource.getProperty("spring.datasource.username")).isEqualTo("vault-user"); + assertThat(propertySource.getProperty("spring.datasource.password")).isEqualTo("vault-password"); + assertThat(propertySource.getProperty("spring.secondary-datasource.username")).isEqualTo("vault-user"); + assertThat(propertySource.getProperty("spring.secondary-datasource.password")).isEqualTo("vault-password"); + } + + private static VaultDatabaseProperties databaseProperties(String role, String usernameProperty, + String passwordProperty) { + + VaultDatabaseProperties properties = new VaultDatabaseProperties(); + properties.setRole(role); + properties.setUsernameProperty(usernameProperty); + properties.setPasswordProperty(passwordProperty); + return properties; + } + }