Polishing.
Add author tags. Let VaultConfigLocation accept PropertyTransformer. Extract prefix computation into its own method. Tweak documentation wording. See gh-488 Original pull request: gh-582.
This commit is contained in:
@@ -38,6 +38,22 @@ spring.config.import: vault://first/context/path, vault://other/path, vault://
|
||||
----
|
||||
====
|
||||
|
||||
Property names within a Spring `Environment` must be unique to avoid shadowing.
|
||||
If you use the same secret names in different context paths and you want to expose these as individual properties you can distinguish them by adding a `prefix` query parameter to the location.
|
||||
|
||||
.application.yml
|
||||
====
|
||||
[source,yaml]
|
||||
----
|
||||
spring.config.import: vault://my/path?prefix=foo., vault://my/other/path?prefix=bar.
|
||||
secret: ${foo.secret}
|
||||
other.secret: ${bar.secret}
|
||||
----
|
||||
|
||||
NOTE: Prefixes are added as-is to all property names returned by Vault. If you want key names to be separated with a dot between the prefix and key name, make sure to add a trailing dot to the prefix.
|
||||
|
||||
====
|
||||
|
||||
[[vault.configdata.location.optional]]
|
||||
=== Conditionally enable/disable Vault Configuration
|
||||
|
||||
@@ -50,18 +66,6 @@ Optional locations are skipped during application startup if Vault support was d
|
||||
|
||||
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.
|
||||
|
||||
If you have the same secret names in different paths, you can distinguish them by using a prefix on the path.
|
||||
|
||||
.application.yml
|
||||
====
|
||||
[source,yaml]
|
||||
----
|
||||
spring.config.import: vault://my/prefixed/path?prefix=prefix1, vault://my/other/path?prefix=prefix2
|
||||
secret: ${prefix1.secret}
|
||||
other.secret: ${prefix2.secret}
|
||||
----
|
||||
|
||||
====
|
||||
|
||||
[[vault.configdata.customization]]
|
||||
=== Infrastructure Customization
|
||||
|
||||
@@ -77,6 +77,7 @@ import org.springframework.web.util.UriComponentsBuilder;
|
||||
* required later on by {@link VaultConfigDataLoader}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @author Jeffrey van der Laan
|
||||
* @since 3.0
|
||||
* @see VaultConfigurer
|
||||
* @see BootstrapRegistry
|
||||
@@ -118,17 +119,20 @@ public class VaultConfigDataLocationResolver implements ConfigDataLocationResolv
|
||||
contextPath = contextPath.substring(1);
|
||||
}
|
||||
|
||||
return Collections.singletonList(
|
||||
new VaultConfigLocation(contextPath, getPropertyTransformer(contextPath), location.isOptional()));
|
||||
}
|
||||
|
||||
private static PropertyTransformer getPropertyTransformer(String contextPath) {
|
||||
|
||||
UriComponents uriComponents = UriComponentsBuilder.fromUriString(contextPath).build();
|
||||
String prefix = uriComponents.getQueryParams().getFirst("prefix");
|
||||
String path = uriComponents.getPath();
|
||||
if (StringUtils.hasLength(prefix) && StringUtils.hasLength(path)) {
|
||||
PropertyTransformer keyPrefixPropertyTransformer = PropertyTransformers.propertyNamePrefix(prefix);
|
||||
SecretBackendMetadata secretBackendMetadata = KeyValueSecretBackendMetadata.create(path, keyPrefixPropertyTransformer);
|
||||
return Collections.singletonList(new VaultConfigLocation(secretBackendMetadata, location.isOptional()));
|
||||
}
|
||||
else {
|
||||
return Collections.singletonList(new VaultConfigLocation(contextPath, location.isOptional()));
|
||||
|
||||
if (StringUtils.hasText(prefix) && StringUtils.hasText(uriComponents.getPath())) {
|
||||
return PropertyTransformers.propertyNamePrefix(prefix);
|
||||
}
|
||||
|
||||
return PropertyTransformers.noop();
|
||||
}
|
||||
|
||||
private static void registerVaultProperties(ConfigDataLocationResolverContext context) {
|
||||
|
||||
@@ -20,6 +20,8 @@ import org.springframework.boot.context.config.ConfigDataLocation;
|
||||
import org.springframework.boot.context.config.ConfigDataResource;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.vault.core.util.PropertyTransformer;
|
||||
import org.springframework.vault.core.util.PropertyTransformers;
|
||||
|
||||
/**
|
||||
* Vault-specific implementation for a {@link ConfigDataLocation}. Consists of a
|
||||
@@ -40,17 +42,38 @@ public class VaultConfigLocation extends ConfigDataResource {
|
||||
|
||||
private final boolean optional;
|
||||
|
||||
/**
|
||||
* Create a new {@link VaultConfigLocation} instance.
|
||||
* @param contextPath the context path
|
||||
* @param optional if the resource is optional
|
||||
*/
|
||||
public VaultConfigLocation(String contextPath, boolean optional) {
|
||||
this(contextPath, PropertyTransformers.noop(), optional);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link VaultConfigLocation} instance.
|
||||
* @param contextPath the context path
|
||||
* @param propertyTransformer the property transformer
|
||||
* @param optional if the resource is optional
|
||||
* @since 3.0.4
|
||||
*/
|
||||
public VaultConfigLocation(String contextPath, PropertyTransformer propertyTransformer, boolean optional) {
|
||||
|
||||
super(optional);
|
||||
|
||||
Assert.hasText(contextPath, "Location must not be empty");
|
||||
validatePath(contextPath);
|
||||
|
||||
this.secretBackendMetadata = KeyValueSecretBackendMetadata.create(contextPath);
|
||||
this.secretBackendMetadata = KeyValueSecretBackendMetadata.create(contextPath, propertyTransformer);
|
||||
this.optional = optional;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link VaultConfigLocation} instance.
|
||||
* @param secretBackendMetadata the backend descriptor.
|
||||
* @param optional if the resource is optional
|
||||
*/
|
||||
public VaultConfigLocation(SecretBackendMetadata secretBackendMetadata, boolean optional) {
|
||||
|
||||
Assert.notNull(secretBackendMetadata, "SecretBackendMetadata must not be null");
|
||||
|
||||
@@ -16,25 +16,19 @@
|
||||
|
||||
package org.springframework.cloud.vault.config;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.DefaultBootstrapContext;
|
||||
import org.springframework.boot.context.config.ConfigDataLocation;
|
||||
import org.springframework.boot.context.config.ConfigDataLocationResolverContext;
|
||||
import org.springframework.boot.context.config.Profiles;
|
||||
import org.springframework.boot.context.properties.bind.Binder;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.mockito.Mockito.mock;
|
||||
@@ -44,6 +38,7 @@ import static org.mockito.Mockito.when;
|
||||
* Unit tests for {@link VaultConfigDataLocationResolver}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @author Jeffrey van der Laan
|
||||
*/
|
||||
public class VaultConfigDataLocationResolverUnitTests {
|
||||
|
||||
@@ -106,10 +101,9 @@ public class VaultConfigDataLocationResolverUnitTests {
|
||||
VaultConfigDataLocationResolver resolver = new VaultConfigDataLocationResolver();
|
||||
|
||||
List<VaultConfigLocation> locations = resolver.resolveProfileSpecific(this.contextMock,
|
||||
ConfigDataLocation.of("vault://my/context/path?prefix=myPrefix"), this.profilesMock);
|
||||
ConfigDataLocation.of("vault://my/context/path?prefix=myPrefix."), this.profilesMock);
|
||||
|
||||
assertThat(locations).hasSize(1);
|
||||
assertThat(locations.get(0)).hasToString("VaultConfigLocation [path='my/context/path', optional=false]");
|
||||
assertThat(locations.get(0).getSecretBackendMetadata().getPropertyTransformer()
|
||||
.transformProperties(Collections.singletonMap("key", "value"))).containsEntry("myPrefix.key", "value");
|
||||
}
|
||||
@@ -123,7 +117,6 @@ public class VaultConfigDataLocationResolverUnitTests {
|
||||
ConfigDataLocation.of("vault://my/context/path?prefix="), this.profilesMock);
|
||||
|
||||
assertThat(locations).hasSize(1);
|
||||
assertThat(locations.get(0)).hasToString("VaultConfigLocation [path='my/context/path', optional=false]");
|
||||
assertThat(locations.get(0).getSecretBackendMetadata().getPropertyTransformer()
|
||||
.transformProperties(Collections.singletonMap("key", "value"))).containsEntry("key", "value");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user