Skip to content

Commit 6505bde

Browse files
Jeffrey van der Laanmp911de
authored andcommitted
Add support for key prefixes in vault paths.
See gh-488 Original pull request: gh-582.
1 parent d4de4b6 commit 6505bde

File tree

3 files changed

+67
-2
lines changed

3 files changed

+67
-2
lines changed

docs/src/main/asciidoc/config-data.adoc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,19 @@ Optional locations are skipped during application startup if Vault support was d
5050

5151
NOTE: Vault context paths that cannot be found (HTTP Status 404) are skipped regardless of whether the config location is marked optional. <<vault.config.fail-fast>> allows failing on start if a Vault context path cannot be found because of HTTP Status 404.
5252

53+
If you have the same secret names in different paths, you can distinguish them by using a prefix on the path.
54+
55+
.application.yml
56+
====
57+
[source,yaml]
58+
----
59+
spring.config.import: vault://my/prefixed/path?prefix=prefix1, vault://my/other/path?prefix=prefix2
60+
secret: ${prefix1.secret}
61+
other.secret: ${prefix2.secret}
62+
----
63+
64+
====
65+
5366
[[vault.configdata.customization]]
5467
=== Infrastructure Customization
5568

spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultConfigDataLocationResolver.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@
3737
import org.springframework.core.io.support.SpringFactoriesLoader;
3838
import org.springframework.util.ClassUtils;
3939
import org.springframework.util.ReflectionUtils;
40+
import org.springframework.util.StringUtils;
41+
import org.springframework.vault.core.util.PropertyTransformer;
42+
import org.springframework.vault.core.util.PropertyTransformers;
43+
import org.springframework.web.util.UriComponents;
44+
import org.springframework.web.util.UriComponentsBuilder;
4045

4146
/**
4247
* {@link ConfigDataLocationResolver} for Vault resolving {@link VaultConfigLocation}
@@ -113,7 +118,17 @@ public List<VaultConfigLocation> resolveProfileSpecific(ConfigDataLocationResolv
113118
contextPath = contextPath.substring(1);
114119
}
115120

116-
return Collections.singletonList(new VaultConfigLocation(contextPath, location.isOptional()));
121+
UriComponents uriComponents = UriComponentsBuilder.fromUriString(contextPath).build();
122+
String prefix = uriComponents.getQueryParams().getFirst("prefix");
123+
String path = uriComponents.getPath();
124+
if (StringUtils.hasLength(prefix) && StringUtils.hasLength(path)) {
125+
PropertyTransformer keyPrefixPropertyTransformer = PropertyTransformers.propertyNamePrefix(prefix);
126+
SecretBackendMetadata secretBackendMetadata = KeyValueSecretBackendMetadata.create(path, keyPrefixPropertyTransformer);
127+
return Collections.singletonList(new VaultConfigLocation(secretBackendMetadata, location.isOptional()));
128+
}
129+
else {
130+
return Collections.singletonList(new VaultConfigLocation(contextPath, location.isOptional()));
131+
}
117132
}
118133

119134
private static void registerVaultProperties(ConfigDataLocationResolverContext context) {

spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigDataLocationResolverUnitTests.java

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,22 @@
1919
import java.util.Arrays;
2020
import java.util.List;
2121

22+
import java.util.Arrays;
23+
import java.util.Collections;
24+
import java.util.List;
25+
2226
import org.junit.Before;
2327
import org.junit.Test;
24-
2528
import org.springframework.boot.DefaultBootstrapContext;
2629
import org.springframework.boot.context.config.ConfigDataLocation;
2730
import org.springframework.boot.context.config.ConfigDataLocationResolverContext;
2831
import org.springframework.boot.context.config.Profiles;
2932
import org.springframework.boot.context.properties.bind.Binder;
3033

34+
import java.util.Arrays;
35+
import java.util.Collections;
36+
import java.util.List;
37+
3138
import static org.assertj.core.api.Assertions.assertThat;
3239
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
3340
import static org.mockito.Mockito.mock;
@@ -89,6 +96,36 @@ public void shouldDiscoverContextualLocations() {
8996

9097
assertThat(locations).hasSize(1);
9198
assertThat(locations.get(0)).hasToString("VaultConfigLocation [path='my/context/path', optional=false]");
99+
assertThat(locations.get(0).getSecretBackendMetadata().getPropertyTransformer()
100+
.transformProperties(Collections.singletonMap("key", "value"))).containsEntry("key", "value");
101+
}
102+
103+
@Test
104+
public void shouldDiscoverContextualLocationsWithPrefix() {
105+
106+
VaultConfigDataLocationResolver resolver = new VaultConfigDataLocationResolver();
107+
108+
List<VaultConfigLocation> locations = resolver.resolveProfileSpecific(this.contextMock,
109+
ConfigDataLocation.of("vault://my/context/path?prefix=myPrefix"), this.profilesMock);
110+
111+
assertThat(locations).hasSize(1);
112+
assertThat(locations.get(0)).hasToString("VaultConfigLocation [path='my/context/path', optional=false]");
113+
assertThat(locations.get(0).getSecretBackendMetadata().getPropertyTransformer()
114+
.transformProperties(Collections.singletonMap("key", "value"))).containsEntry("myPrefix.key", "value");
115+
}
116+
117+
@Test
118+
public void shouldNotPrefixWhenPrefixIsEmpty() {
119+
120+
VaultConfigDataLocationResolver resolver = new VaultConfigDataLocationResolver();
121+
122+
List<VaultConfigLocation> locations = resolver.resolveProfileSpecific(this.contextMock,
123+
ConfigDataLocation.of("vault://my/context/path?prefix="), this.profilesMock);
124+
125+
assertThat(locations).hasSize(1);
126+
assertThat(locations.get(0)).hasToString("VaultConfigLocation [path='my/context/path', optional=false]");
127+
assertThat(locations.get(0).getSecretBackendMetadata().getPropertyTransformer()
128+
.transformProperties(Collections.singletonMap("key", "value"))).containsEntry("key", "value");
92129
}
93130

94131
}

0 commit comments

Comments
 (0)