diff --git a/docs/modules/ROOT/pages/server/environment-repository/vault-backend.adoc b/docs/modules/ROOT/pages/server/environment-repository/vault-backend.adoc
index ef16a0df..ebbd6854 100644
--- a/docs/modules/ROOT/pages/server/environment-repository/vault-backend.adoc
+++ b/docs/modules/ROOT/pages/server/environment-repository/vault-backend.adoc
@@ -59,6 +59,12 @@ The following table describes configurable Vault properties:
|defaultKey
|application
+|defaultLabel
+|main (Only used when `enableLabel` is set to `true`)
+
+|enableLabel
+|false
+
|profileSeparator
|,
@@ -158,6 +164,24 @@ Properties written to `secret/application` are available to <<_vault_server,all
An application with the name, `myApp`, would have any properties written to `secret/myApp` and `secret/application` available to it.
When `myApp` has the `dev` profile enabled, properties written to all of the above paths would be available to it, with properties in the first path in the list taking priority over the others.
+[[enabling-serach-by-label]]
+== Enabling Search by Label
+
+By default, Vault backend does not use the label when searching for secrets. You can change this by
+setting the `enableLabel` feature flag to `true` and, optionally, setting the `defaultLabel`.
+When `defaultLabel` is not provided `main` will be used.
+
+When `enableLabel` feature flag is on, the secrets in Vault should always have all three segments(application name, profile and label) in their paths.
+So the example in previous section, with enabled feature flag, would be like :
+
+[source,sh]
+----
+secret/myApp,dev,myLabel
+secret/myApp,default,myLabel # default profile
+secret/application,dev,myLabel # default application name
+secret/application,default,myLabel # default application name and default profile.
+----
+
[[decrypting-vault-secrets]]
== Decrypting Vault Secrets in Property Sources
diff --git a/spring-cloud-config-sample/src/test/java/sample/ConfigDataOrderingVaultIntegrationTests.java b/spring-cloud-config-sample/src/test/java/sample/ConfigDataOrderingVaultIntegrationTests.java
index 408c55b9..56eb4d6d 100644
--- a/spring-cloud-config-sample/src/test/java/sample/ConfigDataOrderingVaultIntegrationTests.java
+++ b/spring-cloud-config-sample/src/test/java/sample/ConfigDataOrderingVaultIntegrationTests.java
@@ -18,11 +18,11 @@ package sample;
import java.io.IOException;
-import org.json.JSONException;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.BindMode;
+import org.testcontainers.containers.Container.ExecResult;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.DockerImageName;
@@ -36,9 +36,10 @@ import org.springframework.test.util.TestSocketUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
- * Integration test for https://github.com/spring-cloud/spring-cloud-config/issues/1997
- * The error only occurs if a profile specific config imports is used, otherwise
- * reordering does not take place. A profile specific config import is defined in
+ * Integration test for issue
+ * #1997 The
+ * error only occurs if a profile specific config imports is used, otherwise reordering
+ * does not take place. A profile specific config import is defined in
* vaultordering/client-dev.yml
*/
@Testcontainers
@@ -46,27 +47,26 @@ public class ConfigDataOrderingVaultIntegrationTests {
private static final int configServerPort = TestSocketUtils.findAvailableTcpPort();
- private static final int configClientPort = TestSocketUtils.findAvailableTcpPort();
-
private static ConfigurableApplicationContext client;
private static ConfigurableApplicationContext server;
@Container
- public static VaultContainer vaultContainer = new VaultContainer<>(DockerImageName.parse("vault:1.13.3"))
+ public static VaultContainer> vaultContainer = new VaultContainer<>(DockerImageName.parse("vault:1.13.3"))
.withVaultToken("my-root-token")
.withClasspathResourceMapping("vaultordering/vault_test_policy.txt", "/tmp/vault_test_policy.txt",
BindMode.READ_ONLY);
@BeforeAll
- public static void startConfigServer() throws IOException, InterruptedException, JSONException {
+ public static void startConfigServer() throws IOException, InterruptedException {
server = SpringApplication.run(TestConfigServerApplication.class,
"--spring.config.location=classpath:/vaultordering/", "--spring.config.name=server",
"--server.port=" + configServerPort,
"--spring.cloud.config.server.vault.port=" + vaultContainer.getFirstMappedPort());
- execInVault("vault", "kv", "put", "secret/client-app,dev", "my.prop=vaultdev");
- execInVault("vault", "kv", "put", "secret/client-app", "my.prop=vault");
+ execInVault("vault", "kv", "put", "secret/client-app,dev", "my.prop=value-in-dev");
+ execInVault("vault", "kv", "put", "secret/client-app,prod", "my.prop=value-in-prod");
+ execInVault("vault", "kv", "put", "secret/client-app", "my.prop=default-value");
}
@@ -81,22 +81,35 @@ public class ConfigDataOrderingVaultIntegrationTests {
}
@Test
- void propertyFromVaultIsUsed() {
- client = SpringApplication.run(TestConfigServerApplication.class, "--server.port=" + configClientPort,
+ void profileSpecificPropertyFromVaultIsUsed() {
+ client = SpringApplication.run(TestConfigServerApplication.class,
+ "--server.port=" + TestSocketUtils.findAvailableTcpPort(),
"--spring.config.location=classpath:/vaultordering/", "--spring.config.name=client",
"--spring.profiles.active=dev", "--spring.application.name=client-app",
"--spring.cloud.config.enabled=true", "--spring.cloud.config.server.enabled=false",
"--config.server.port=" + configServerPort);
- assertThat(client.getEnvironment().getProperty("my.prop")).isEqualTo("vaultdev");
+ assertThat(client.getEnvironment().getProperty("my.prop")).isEqualTo("value-in-dev");
}
- private static String execInVault(String... command) throws IOException, InterruptedException {
- org.testcontainers.containers.Container.ExecResult execResult = vaultContainer.execInContainer(command);
+ @Test
+ void profileSpecificPropertyFromVaultIsUsedInCorrectOrder() {
+ client = SpringApplication.run(TestConfigServerApplication.class,
+ "--server.port=" + TestSocketUtils.findAvailableTcpPort(),
+ "--spring.config.location=classpath:/vaultordering/", "--spring.config.name=client",
+ "--spring.profiles.active=dev,prod", "--spring.application.name=client-app",
+ "--spring.cloud.config.enabled=true", "--spring.cloud.config.server.enabled=false",
+ "--config.server.port=" + configServerPort);
+
+ assertThat(client.getEnvironment().getProperty("my.prop")).isEqualTo("value-in-prod");
+
+ }
+
+ private static void execInVault(String... command) throws IOException, InterruptedException {
+ ExecResult execResult = vaultContainer.execInContainer(command);
assertThat(execResult.getExitCode()).isZero();
assertThat(execResult.getStderr()).isEmpty();
- return execResult.getStdout();
}
}
diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/AbstractVaultEnvironmentRepository.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/AbstractVaultEnvironmentRepository.java
index 7d47d643..1917e19d 100644
--- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/AbstractVaultEnvironmentRepository.java
+++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/AbstractVaultEnvironmentRepository.java
@@ -16,11 +16,12 @@
package org.springframework.cloud.config.server.environment;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
-import java.util.Properties;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.constraints.NotEmpty;
@@ -33,6 +34,7 @@ import org.springframework.cloud.config.environment.Environment;
import org.springframework.cloud.config.environment.PropertySource;
import org.springframework.core.Ordered;
import org.springframework.core.io.ByteArrayResource;
+import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import static org.springframework.cloud.config.client.ConfigClientProperties.STATE_HEADER;
@@ -46,7 +48,9 @@ import static org.springframework.cloud.config.client.ConfigClientProperties.STA
*/
public abstract class AbstractVaultEnvironmentRepository implements EnvironmentRepository, Ordered {
- private static Log log = LogFactory.getLog(AbstractVaultEnvironmentRepository.class);
+ private static final String DEFAULT_PROFILE = "default";
+
+ private static final Log log = LogFactory.getLog(AbstractVaultEnvironmentRepository.class);
// TODO: move to watchState:String on findOne?
protected final ObjectProvider request;
@@ -65,12 +69,18 @@ public abstract class AbstractVaultEnvironmentRepository implements EnvironmentR
@NotEmpty
protected String profileSeparator;
+ protected final boolean enableLabel;
+
+ protected final String defaultLabel;
+
protected int order;
public AbstractVaultEnvironmentRepository(ObjectProvider request, EnvironmentWatch watch,
VaultEnvironmentProperties properties) {
this.defaultKey = properties.getDefaultKey();
this.profileSeparator = properties.getProfileSeparator();
+ this.enableLabel = properties.isEnableLabel();
+ this.defaultLabel = properties.getDefaultLabel();
this.order = properties.getOrder();
this.request = request;
this.watch = watch;
@@ -78,24 +88,32 @@ public abstract class AbstractVaultEnvironmentRepository implements EnvironmentR
@Override
public Environment findOne(String application, String profile, String label) {
- String[] profiles = StringUtils.commaDelimitedListToStringArray(profile);
- List scrubbedProfiles = scrubProfiles(profiles);
+ if (ObjectUtils.isEmpty(profile)) {
+ profile = DEFAULT_PROFILE;
+ }
+ if (ObjectUtils.isEmpty(label)) {
+ label = defaultLabel;
+ }
- List keys = findKeys(application, scrubbedProfiles);
+ var environment = new Environment(application, split(profile), label, null, getWatchState());
- Environment environment = new Environment(application, profiles, label, null, getWatchState());
+ var profiles = normalize(profile, DEFAULT_PROFILE);
+ var applications = normalize(application, this.defaultKey);
- for (String key : keys) {
- // read raw 'data' key from vault
- String data = read(key);
- if (data != null) {
- // data is in json format of which, yaml is a superset, so parse
- final YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
- yaml.setResources(new ByteArrayResource(data.getBytes()));
- Properties properties = yaml.getObject();
+ for (String prof : profiles) {
+ for (String app : applications) {
+ var key = vaultKey(app, prof, label);
+ // read raw 'data' key from vault
+ String data = read(key);
+ if (data != null) {
+ // data is in json format of which, yaml is a superset, so parse
+ var yaml = new YamlPropertiesFactoryBean();
+ yaml.setResources(new ByteArrayResource(data.getBytes()));
+ var properties = yaml.getObject();
- if (!properties.isEmpty()) {
- environment.add(new PropertySource("vault:" + key, properties));
+ if (properties != null && !properties.isEmpty()) {
+ environment.add(new PropertySource("vault:" + key, properties));
+ }
}
}
}
@@ -105,6 +123,22 @@ public abstract class AbstractVaultEnvironmentRepository implements EnvironmentR
protected abstract String read(String key);
+ private String vaultKey(String application, String profile, String label) {
+ var key = application;
+ if (this.enableLabel) {
+ // always append profile to the key, if flag is enabled.
+ key += this.profileSeparator + profile;
+ // always append label to the key, if flag is enabled.
+ key += this.profileSeparator + label;
+ }
+ else if (!DEFAULT_PROFILE.equals(profile)) {
+ // default profile should not be included in the key, if flag is not enabled.
+ key += this.profileSeparator + profile;
+ }
+
+ return key;
+ }
+
private String getWatchState() {
HttpServletRequest servletRequest = this.request.getIfAvailable();
if (servletRequest != null) {
@@ -120,35 +154,22 @@ public abstract class AbstractVaultEnvironmentRepository implements EnvironmentR
return null;
}
- private List findKeys(String application, List profiles) {
- List keys = new ArrayList<>();
+ /**
+ * Splits the comma delimited items and returns the reversed distinct items with given
+ * default item at the end.
+ */
+ private List normalize(String commaDelimitedItems, String defaultItem) {
+ var items = Stream.concat(Stream.of(defaultItem), Arrays.stream(split(commaDelimitedItems)))
+ .distinct()
+ .filter(Predicate.not(ObjectUtils::isEmpty))
+ .collect(Collectors.toList());
- if (StringUtils.hasText(this.defaultKey) && !this.defaultKey.equals(application)) {
- keys.add(this.defaultKey);
- addProfiles(keys, this.defaultKey, profiles);
- }
-
- // application may have comma-separated list of names
- String[] applications = StringUtils.commaDelimitedListToStringArray(application);
- for (String app : applications) {
- keys.add(app);
- addProfiles(keys, app, profiles);
- }
-
- Collections.reverse(keys);
- return keys;
+ Collections.reverse(items);
+ return items;
}
- private List scrubProfiles(String[] profiles) {
- List scrubbedProfiles = new ArrayList<>(Arrays.asList(profiles));
- scrubbedProfiles.remove("default");
- return scrubbedProfiles;
- }
-
- private void addProfiles(List contexts, String baseContext, List profiles) {
- for (String profile : profiles) {
- contexts.add(baseContext + this.profileSeparator + profile);
- }
+ private String[] split(String str) {
+ return StringUtils.commaDelimitedListToStringArray(str);
}
public void setDefaultKey(String defaultKey) {
diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/VaultEnvironmentProperties.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/VaultEnvironmentProperties.java
index f5413cf3..2e25ee90 100644
--- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/VaultEnvironmentProperties.java
+++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/VaultEnvironmentProperties.java
@@ -101,6 +101,17 @@ public class VaultEnvironmentProperties implements HttpEnvironmentRepositoryProp
*/
private String token;
+ /**
+ * Flag to indicate that the repository should use 'label' as well as
+ * 'application-name' and 'profile', for vault secrets. By default, the vault secrets
+ * are expected to be in 'application-name,profile' path. When this flag enabled, they
+ * are expected to be in `application-name,profile,label' path. To maintain
+ * compatibility this flag is not enabled by default.
+ */
+ private boolean enableLabel = false;
+
+ private String defaultLabel = "main";
+
private AppRoleProperties appRole = new AppRoleProperties();
private AwsEc2Properties awsEc2 = new AwsEc2Properties();
@@ -229,6 +240,22 @@ public class VaultEnvironmentProperties implements HttpEnvironmentRepositoryProp
this.token = token;
}
+ public boolean isEnableLabel() {
+ return enableLabel;
+ }
+
+ public void setEnableLabel(boolean enableLabel) {
+ this.enableLabel = enableLabel;
+ }
+
+ public String getDefaultLabel() {
+ return defaultLabel;
+ }
+
+ public void setDefaultLabel(String defaultLabel) {
+ this.defaultLabel = defaultLabel;
+ }
+
public AppRoleProperties getAppRole() {
return this.appRole;
}
diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/VaultEnvironmentRepositoryTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/VaultEnvironmentRepositoryTests.java
index c5711155..a68f2211 100644
--- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/VaultEnvironmentRepositoryTests.java
+++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/VaultEnvironmentRepositoryTests.java
@@ -23,7 +23,6 @@ import java.util.Map;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import org.assertj.core.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
@@ -57,12 +56,8 @@ public class VaultEnvironmentRepositoryTests {
@SuppressWarnings("unchecked")
ArgumentCaptor> requestHeaderCaptor = ArgumentCaptor.forClass(HttpEntity.class);
- @BeforeEach
- public void init() {
- }
-
@Test
- public void testFindOneNoDefaultKey() {
+ public void findOneWithNoDefaultKey() {
stubRestTemplate("secret/myapp", toEntityResponse("foo", "bar"));
stubRestTemplate("secret/application", toEntityResponse("def-foo", "def-bar"));
@@ -71,14 +66,33 @@ public class VaultEnvironmentRepositoryTests {
assertThat(e.getName()).isEqualTo("myapp");
assertThat(e.getPropertySources().size()).isEqualTo(2);
+ assertThat(e.getPropertySources().get(0).getName()).isEqualTo("vault:myapp");
assertThat(e.getPropertySources().get(0).getSource()).isEqualTo(Map.of("foo", "bar"));
+ assertThat(e.getPropertySources().get(1).getName()).isEqualTo("vault:application");
assertThat(e.getPropertySources().get(1).getSource()).isEqualTo(Map.of("def-foo", "def-bar"));
assertThat(requestHeaderCaptor.getValue().getHeaders()).containsEntry("X-Vault-Token", List.of("token"));
}
@Test
- public void testBackendWithSlashes() {
+ public void findOneWithEmptyDefaultKey() {
+ stubRestTemplate("secret/myapp", toEntityResponse("foo", "bar"));
+ stubRestTemplate("secret/application", toEntityResponse("def-foo", "def-bar"));
+
+ var properties = new VaultEnvironmentProperties();
+ properties.setDefaultKey("");
+
+ var e = vaultEnvironmentRepository(properties).findOne("myapp", null, "my-label");
+
+ assertThat(e.getName()).isEqualTo("myapp");
+
+ assertThat(e.getPropertySources().size()).isEqualTo(1);
+ assertThat(e.getPropertySources().get(0).getName()).isEqualTo("vault:myapp");
+ assertThat(e.getPropertySources().get(0).getSource()).isEqualTo(Map.of("foo", "bar"));
+ }
+
+ @Test
+ public void findOneWithSlashesInBackend() {
stubRestTemplate("foo/bar/secret/myapp", toEntityResponse("foo", "bar"));
stubRestTemplate("foo/bar/secret/application", toEntityResponse("def-foo", "def-bar"));
@@ -90,12 +104,14 @@ public class VaultEnvironmentRepositoryTests {
assertThat(e.getName()).isEqualTo("myapp");
assertThat(e.getPropertySources().size()).isEqualTo(2);
+ assertThat(e.getPropertySources().get(0).getName()).isEqualTo("vault:myapp");
assertThat(e.getPropertySources().get(0).getSource()).isEqualTo(Map.of("foo", "bar"));
+ assertThat(e.getPropertySources().get(1).getName()).isEqualTo("vault:application");
assertThat(e.getPropertySources().get(1).getSource()).isEqualTo(Map.of("def-foo", "def-bar"));
}
@Test
- public void testFindOneDefaultKeySetAndDifferentToApplication() {
+ public void findOneWithDefaultKeySet() {
stubRestTemplate("secret/myapp", toEntityResponse("foo", "bar"));
stubRestTemplate("secret/mydefaultkey", toEntityResponse("def-foo", "def-bar"));
@@ -107,12 +123,14 @@ public class VaultEnvironmentRepositoryTests {
assertThat(e.getName()).isEqualTo("myapp");
assertThat(e.getPropertySources().size()).isEqualTo(2);
+ assertThat(e.getPropertySources().get(0).getName()).isEqualTo("vault:myapp");
assertThat(e.getPropertySources().get(0).getSource()).isEqualTo(Map.of("foo", "bar"));
+ assertThat(e.getPropertySources().get(1).getName()).isEqualTo("vault:mydefaultkey");
assertThat(e.getPropertySources().get(1).getSource()).isEqualTo(Map.of("def-foo", "def-bar"));
}
@Test
- public void testFindOneDefaultKeySetAndDifferentToMultipleApplications() {
+ public void findOneWithDefaultKeyAndMultipleApplicationNames() {
stubRestTemplate("secret/myapp", toEntityResponse("myapp-foo", "myapp-bar"));
stubRestTemplate("secret/yourapp", toEntityResponse("yourapp-foo", "yourapp-bar"));
stubRestTemplate("secret/mydefaultkey", toEntityResponse("def-foo", "def-bar"));
@@ -126,28 +144,82 @@ public class VaultEnvironmentRepositoryTests {
assertThat(e.getPropertySources().size()).isEqualTo(3);
assertThat(e.getPropertySources().get(0).getSource()).isEqualTo(Map.of("yourapp-foo", "yourapp-bar"));
+ assertThat(e.getPropertySources().get(0).getName()).isEqualTo("vault:yourapp");
assertThat(e.getPropertySources().get(1).getSource()).isEqualTo(Map.of("myapp-foo", "myapp-bar"));
+ assertThat(e.getPropertySources().get(1).getName()).isEqualTo("vault:myapp");
assertThat(e.getPropertySources().get(2).getSource()).isEqualTo(Map.of("def-foo", "def-bar"));
+ assertThat(e.getPropertySources().get(2).getName()).isEqualTo("vault:mydefaultkey");
}
@Test
- public void testFindOneDefaultKeySetAndEqualToApplication() {
+ public void findOneWithDefaultKeySetToApplicationName() {
stubRestTemplate("secret/myapp", toEntityResponse("foo", "bar"));
stubRestTemplate("secret/application", toEntityResponse("def-foo", "def-bar"));
var properties = new VaultEnvironmentProperties();
properties.setDefaultKey("myapp");
- var e = vaultEnvironmentRepository(properties).findOne("myapp", null, null);
+ var e = vaultEnvironmentRepository(properties).findOne("myapp", null, "lbl");
assertThat(e.getName()).isEqualTo("myapp");
assertThat(e.getPropertySources().size()).isEqualTo(1);
+ assertThat(e.getPropertySources().get(0).getName()).isEqualTo("vault:myapp");
assertThat(e.getPropertySources().get(0).getSource()).isEqualTo(Map.of("foo", "bar"));
}
@Test
- public void missingConfigToken() {
+ public void findOneWithProfile() {
+ stubRestTemplate("secret/myapp", toEntityResponse("foo", "bar"));
+ stubRestTemplate("secret/myapp,my-profile", toEntityResponse("pro-foo", "pro-bar"));
+ stubRestTemplate("secret/application", toEntityResponse("def-foo", "def-bar"));
+ stubRestTemplate("secret/application,my-profile", toEntityResponse("def-pro-foo", "def-pro-bar"));
+
+ var e = vaultEnvironmentRepository().findOne("myapp", "my-profile", "lbl");
+
+ assertThat(e.getName()).isEqualTo("myapp");
+
+ assertThat(e.getPropertySources().size()).isEqualTo(4);
+ assertThat(e.getPropertySources().get(0).getName()).isEqualTo("vault:myapp,my-profile");
+ assertThat(e.getPropertySources().get(0).getSource()).isEqualTo(Map.of("pro-foo", "pro-bar"));
+ assertThat(e.getPropertySources().get(1).getName()).isEqualTo("vault:application,my-profile");
+ assertThat(e.getPropertySources().get(1).getSource()).isEqualTo(Map.of("def-pro-foo", "def-pro-bar"));
+ assertThat(e.getPropertySources().get(2).getName()).isEqualTo("vault:myapp");
+ assertThat(e.getPropertySources().get(2).getSource()).isEqualTo(Map.of("foo", "bar"));
+ assertThat(e.getPropertySources().get(3).getName()).isEqualTo("vault:application");
+ assertThat(e.getPropertySources().get(3).getSource()).isEqualTo(Map.of("def-foo", "def-bar"));
+ }
+
+ @Test
+ public void findOneWithMultipleProfiles() {
+ stubRestTemplate("secret/myapp", toEntityResponse("foo", "bar"));
+ stubRestTemplate("secret/myapp,pr1", toEntityResponse("pr1-foo", "pr1-bar"));
+ stubRestTemplate("secret/myapp,pr2", toEntityResponse("pr2-foo", "pr2-bar"));
+ stubRestTemplate("secret/application", toEntityResponse("def-foo", "def-bar"));
+ stubRestTemplate("secret/application,pr1", toEntityResponse("def-pr1-foo", "def-pr1-bar"));
+ stubRestTemplate("secret/application,pr2", toEntityResponse("def-pr2-foo", "def-pr2-bar"));
+
+ var e = vaultEnvironmentRepository().findOne("myapp", "pr1,pr2", null);
+
+ assertThat(e.getName()).isEqualTo("myapp");
+
+ assertThat(e.getPropertySources().size()).isEqualTo(6);
+ assertThat(e.getPropertySources().get(0).getName()).isEqualTo("vault:myapp,pr2");
+ assertThat(e.getPropertySources().get(0).getSource()).isEqualTo(Map.of("pr2-foo", "pr2-bar"));
+ assertThat(e.getPropertySources().get(1).getName()).isEqualTo("vault:application,pr2");
+ assertThat(e.getPropertySources().get(1).getSource()).isEqualTo(Map.of("def-pr2-foo", "def-pr2-bar"));
+ assertThat(e.getPropertySources().get(2).getName()).isEqualTo("vault:myapp,pr1");
+ assertThat(e.getPropertySources().get(2).getSource()).isEqualTo(Map.of("pr1-foo", "pr1-bar"));
+ assertThat(e.getPropertySources().get(3).getName()).isEqualTo("vault:application,pr1");
+ assertThat(e.getPropertySources().get(3).getSource()).isEqualTo(Map.of("def-pr1-foo", "def-pr1-bar"));
+ assertThat(e.getPropertySources().get(4).getName()).isEqualTo("vault:myapp");
+ assertThat(e.getPropertySources().get(4).getSource()).isEqualTo(Map.of("foo", "bar"));
+ assertThat(e.getPropertySources().get(5).getName()).isEqualTo("vault:application");
+ assertThat(e.getPropertySources().get(5).getSource()).isEqualTo(Map.of("def-foo", "def-bar"));
+ }
+
+ @Test
+ public void findOneWhenConfigTokenIsMissing() {
ConfigTokenProvider nullTokenProvider = () -> null;
Assertions.assertThatThrownBy(() -> vaultEnvironmentRepository(nullTokenProvider).findOne("myapp", null, null))
@@ -155,25 +227,28 @@ public class VaultEnvironmentRepositoryTests {
}
@Test
- public void testVaultVersioning() {
+ public void findOneWithVaultVersioning() {
stubRestTemplate("secret/data/myapp", toEntityResponse("data", Map.of("foo", "bar")));
stubRestTemplate("secret/data/application", toEntityResponse("data", Map.of("def-foo", "def-bar")));
var properties = new VaultEnvironmentProperties();
properties.setKvVersion(2);
- var e = vaultEnvironmentRepository(properties).findOne("myapp", null, null);
+ var e = vaultEnvironmentRepository(properties).findOne("myapp", null, "label");
assertThat(e.getName()).isEqualTo("myapp");
assertThat(e.getPropertySources().size()).isEqualTo(2);
+ assertThat(e.getPropertySources().get(0).getName()).isEqualTo("vault:myapp");
assertThat(e.getPropertySources().get(0).getSource()).isEqualTo(Map.of("foo", "bar"));
+ assertThat(e.getPropertySources().get(1).getName()).isEqualTo("vault:application");
+ assertThat(e.getPropertySources().get(1).getSource()).isEqualTo(Map.of("def-foo", "def-bar"));
assertThat(requestHeaderCaptor.getValue().getHeaders()).containsEntry("X-Vault-Token", List.of("token"));
}
@Test
- public void testVaultKV2WithPath2Key() {
+ public void findOneWithVaultKV2WithPath2Key() {
stubRestTemplate("secret/data/myorg/myapp", toEntityResponse("data", Map.of("foo", "bar")));
stubRestTemplate("secret/data/myorg/application", toEntityResponse("data", Map.of("def-foo", "def-bar")));
@@ -181,26 +256,112 @@ public class VaultEnvironmentRepositoryTests {
properties.setKvVersion(2);
properties.setPathToKey("myorg");
- var e = vaultEnvironmentRepository(properties).findOne("myapp", null, null);
+ var e = vaultEnvironmentRepository(properties).findOne("myapp", null, "lbl");
assertThat(e.getName()).isEqualTo("myapp");
assertThat(e.getPropertySources().size()).isEqualTo(2);
+ assertThat(e.getPropertySources().get(0).getName()).isEqualTo("vault:myapp");
assertThat(e.getPropertySources().get(0).getSource()).isEqualTo(Map.of("foo", "bar"));
+ assertThat(e.getPropertySources().get(1).getName()).isEqualTo("vault:application");
+ assertThat(e.getPropertySources().get(1).getSource()).isEqualTo(Map.of("def-foo", "def-bar"));
}
@Test
- public void testNamespaceHeaderSent() {
+ public void findOneWithNamespaceHeaderSent() {
stubRestTemplate("secret/myapp", toEntityResponse("foo", "bar"));
stubRestTemplate("secret/application", toEntityResponse("def-foo", "def-bar"));
var properties = new VaultEnvironmentProperties();
properties.setNamespace("mynamespace");
- vaultEnvironmentRepository(properties).findOne("myapp", null, null);
+ vaultEnvironmentRepository(properties).findOne("myapp", null, "lbl");
assertThat(requestHeaderCaptor.getValue().getHeaders()).containsEntry("X-Vault-Namespace",
List.of("mynamespace"));
+ assertThat(requestHeaderCaptor.getValue().getHeaders()).containsEntry("X-Vault-Token", List.of("token"));
+ }
+
+ @Test
+ public void findOneWithDefaultLabelWhenLabelEnabled() {
+ stubRestTemplate("secret/myapp,default,main", toEntityResponse("foo", "bar"));
+ stubRestTemplate("secret/application,default,main", toEntityResponse("def-foo", "def-bar"));
+
+ var properties = new VaultEnvironmentProperties();
+ properties.setEnableLabel(true);
+
+ var e = vaultEnvironmentRepository(properties).findOne("myapp", null, null);
+
+ assertThat(e.getName()).isEqualTo("myapp");
+
+ assertThat(e.getPropertySources().size()).isEqualTo(2);
+ assertThat(e.getPropertySources().get(0).getName()).isEqualTo("vault:myapp,default,main");
+ assertThat(e.getPropertySources().get(0).getSource()).isEqualTo(Map.of("foo", "bar"));
+ assertThat(e.getPropertySources().get(1).getName()).isEqualTo("vault:application,default,main");
+ assertThat(e.getPropertySources().get(1).getSource()).isEqualTo(Map.of("def-foo", "def-bar"));
+ }
+
+ @Test
+ public void findOneWithCustomDefaultLabelWhenLabelEnabled() {
+ stubRestTemplate("secret/myapp,default,custom", toEntityResponse("foo", "bar"));
+ stubRestTemplate("secret/application,default,custom", toEntityResponse("def-foo", "def-bar"));
+
+ var properties = new VaultEnvironmentProperties();
+ properties.setEnableLabel(true);
+ properties.setDefaultLabel("custom");
+
+ var e = vaultEnvironmentRepository(properties).findOne("myapp", null, null);
+
+ assertThat(e.getName()).isEqualTo("myapp");
+
+ assertThat(e.getPropertySources().size()).isEqualTo(2);
+ assertThat(e.getPropertySources().get(0).getName()).isEqualTo("vault:myapp,default,custom");
+ assertThat(e.getPropertySources().get(0).getSource()).isEqualTo(Map.of("foo", "bar"));
+ assertThat(e.getPropertySources().get(1).getName()).isEqualTo("vault:application,default,custom");
+ assertThat(e.getPropertySources().get(1).getSource()).isEqualTo(Map.of("def-foo", "def-bar"));
+ }
+
+ @Test
+ public void findOneWithCustomLabelWhenLabelEnabled() {
+ stubRestTemplate("secret/myapp,default,my-label", toEntityResponse("foo", "bar"));
+ stubRestTemplate("secret/application,default,my-label", toEntityResponse(Map.of()));
+
+ var properties = new VaultEnvironmentProperties();
+ properties.setEnableLabel(true);
+ properties.setDefaultLabel("custom");
+
+ var e = vaultEnvironmentRepository(properties).findOne("myapp", null, "my-label");
+
+ assertThat(e.getName()).isEqualTo("myapp");
+
+ assertThat(e.getPropertySources().size()).isEqualTo(1);
+ assertThat(e.getPropertySources().get(0).getName()).isEqualTo("vault:myapp,default,my-label");
+ assertThat(e.getPropertySources().get(0).getSource()).isEqualTo(Map.of("foo", "bar"));
+ }
+
+ @Test
+ public void findOneWithCustomLabelAndProfileWhenLabelEnabled() {
+ stubRestTemplate("secret/myapp,default,my-label", toEntityResponse("foo", "bar"));
+ stubRestTemplate("secret/myapp,pr1,my-label", toEntityResponse("pr1-foo", "pr1-bar"));
+ stubRestTemplate("secret/application,default,my-label", toEntityResponse("def-foo", "def-bar"));
+ stubRestTemplate("secret/application,pr1,my-label", toEntityResponse("def-pr1-foo", "def-pr1-bar"));
+
+ var properties = new VaultEnvironmentProperties();
+ properties.setEnableLabel(true);
+
+ var e = vaultEnvironmentRepository(properties).findOne("myapp", "pr1", "my-label");
+
+ assertThat(e.getName()).isEqualTo("myapp");
+
+ assertThat(e.getPropertySources().size()).isEqualTo(4);
+ assertThat(e.getPropertySources().get(0).getName()).isEqualTo("vault:myapp,pr1,my-label");
+ assertThat(e.getPropertySources().get(0).getSource()).isEqualTo(Map.of("pr1-foo", "pr1-bar"));
+ assertThat(e.getPropertySources().get(1).getName()).isEqualTo("vault:application,pr1,my-label");
+ assertThat(e.getPropertySources().get(1).getSource()).isEqualTo(Map.of("def-pr1-foo", "def-pr1-bar"));
+ assertThat(e.getPropertySources().get(2).getName()).isEqualTo("vault:myapp,default,my-label");
+ assertThat(e.getPropertySources().get(2).getSource()).isEqualTo(Map.of("foo", "bar"));
+ assertThat(e.getPropertySources().get(3).getName()).isEqualTo("vault:application,default,my-label");
+ assertThat(e.getPropertySources().get(3).getSource()).isEqualTo(Map.of("def-foo", "def-bar"));
}
private VaultEnvironmentRepository vaultEnvironmentRepository() {
diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/vault/SpringVaultEnvironmentRepositoryTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/vault/SpringVaultEnvironmentRepositoryTests.java
index 406aa612..9e3987c8 100644
--- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/vault/SpringVaultEnvironmentRepositoryTests.java
+++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/vault/SpringVaultEnvironmentRepositoryTests.java
@@ -45,17 +45,17 @@ public class SpringVaultEnvironmentRepositoryTests {
private final VaultKeyValueOperations keyValueTemplate = mock(VaultKeyValueOperations.class);
@Test
- public void testFindOneNoDefaultKey() {
+ public void findOneNoDefaultKey() {
defaultKeyTest("", 2);
}
@Test
- public void testPathKey() {
+ public void findOneWithPathKey() {
defaultKeyTest("mypath", 2);
}
@Test
- public void testPathKeyNotUsedWithVersionOne() {
+ public void findOneWithPathKeyNotUsedWithVersionOne() {
defaultKeyTest("mypath", 1);
}
@@ -77,12 +77,14 @@ public class SpringVaultEnvironmentRepositoryTests {
assertThat(e.getName()).isEqualTo("myapp");
assertThat(e.getPropertySources()).hasSize(2);
+ assertThat(e.getPropertySources().get(0).getName()).isEqualTo("vault:myapp");
assertThat(e.getPropertySources().get(0).getSource()).isEqualTo(Map.of("foo", "bar"));
+ assertThat(e.getPropertySources().get(1).getName()).isEqualTo("vault:application");
assertThat(e.getPropertySources().get(1).getSource()).isEqualTo(Map.of("def-foo", "def-bar"));
}
@Test
- public void testBackendWithSlashes() {
+ public void findOneWithSlashesInBackend() {
when(keyValueTemplate.get("myapp")).thenReturn(withVaultResponse("foo", "bar"));
when(keyValueTemplate.get("application")).thenReturn(withVaultResponse("def-foo", "def-bar"));
@@ -94,29 +96,50 @@ public class SpringVaultEnvironmentRepositoryTests {
assertThat(e.getName()).isEqualTo("myapp");
assertThat(e.getPropertySources()).hasSize(2);
+ assertThat(e.getPropertySources().get(0).getName()).isEqualTo("vault:myapp");
assertThat(e.getPropertySources().get(0).getSource()).isEqualTo(Map.of("foo", "bar"));
+ assertThat(e.getPropertySources().get(1).getName()).isEqualTo("vault:application");
assertThat(e.getPropertySources().get(1).getSource()).isEqualTo(Map.of("def-foo", "def-bar"));
}
@Test
- public void testFindOneDefaultKeySetAndDifferentToApplication() {
+ public void findOneWithDefaultKeySet() {
when(keyValueTemplate.get("myapp")).thenReturn(withVaultResponse("foo", "bar"));
when(keyValueTemplate.get("mydefaultkey")).thenReturn(withVaultResponse("def-foo", "def-bar"));
var properties = new VaultEnvironmentProperties();
properties.setDefaultKey("mydefaultkey");
- var e = springVaultEnvironmentRepository(properties).findOne("myapp", null, null);
+ var e = springVaultEnvironmentRepository(properties).findOne("myapp", null, "label");
assertThat(e.getName()).isEqualTo("myapp");
assertThat(e.getPropertySources()).hasSize(2);
+ assertThat(e.getPropertySources().get(0).getName()).isEqualTo("vault:myapp");
assertThat(e.getPropertySources().get(0).getSource()).isEqualTo(Map.of("foo", "bar"));
+ assertThat(e.getPropertySources().get(1).getName()).isEqualTo("vault:mydefaultkey");
assertThat(e.getPropertySources().get(1).getSource()).isEqualTo(Map.of("def-foo", "def-bar"));
}
@Test
- public void testFindOneDefaultKeySetAndDifferentToMultipleApplications() {
+ public void findOneWithEmptyDefaultKey() {
+ when(keyValueTemplate.get("myapp")).thenReturn(withVaultResponse("foo", "bar"));
+ when(keyValueTemplate.get("application")).thenReturn(withVaultResponse("def-foo", "def-bar"));
+
+ var properties = new VaultEnvironmentProperties();
+ properties.setDefaultKey("");
+
+ var e = springVaultEnvironmentRepository(properties).findOne("myapp", null, "label");
+
+ assertThat(e.getName()).isEqualTo("myapp");
+
+ assertThat(e.getPropertySources()).hasSize(1);
+ assertThat(e.getPropertySources().get(0).getName()).isEqualTo("vault:myapp");
+ assertThat(e.getPropertySources().get(0).getSource()).isEqualTo(Map.of("foo", "bar"));
+ }
+
+ @Test
+ public void findOneWithDefaultKeyAndMultipleApplicationNames() {
when(keyValueTemplate.get("myapp")).thenReturn(withVaultResponse("myapp-foo", "myapp-bar"));
when(keyValueTemplate.get("yourapp")).thenReturn(withVaultResponse("yourapp-foo", "yourapp-bar"));
when(keyValueTemplate.get("mydefaultkey")).thenReturn(withVaultResponse("def-foo", "def-bar"));
@@ -124,18 +147,21 @@ public class SpringVaultEnvironmentRepositoryTests {
var properties = new VaultEnvironmentProperties();
properties.setDefaultKey("mydefaultkey");
- var e = springVaultEnvironmentRepository(properties).findOne("myapp,yourapp", null, null);
+ var e = springVaultEnvironmentRepository(properties).findOne("myapp,yourapp", null, "lbl");
assertThat(e.getName()).isEqualTo("myapp,yourapp");
assertThat(e.getPropertySources()).hasSize(3);
+ assertThat(e.getPropertySources().get(0).getName()).isEqualTo("vault:yourapp");
assertThat(e.getPropertySources().get(0).getSource()).isEqualTo(Map.of("yourapp-foo", "yourapp-bar"));
+ assertThat(e.getPropertySources().get(1).getName()).isEqualTo("vault:myapp");
assertThat(e.getPropertySources().get(1).getSource()).isEqualTo(Map.of("myapp-foo", "myapp-bar"));
+ assertThat(e.getPropertySources().get(2).getName()).isEqualTo("vault:mydefaultkey");
assertThat(e.getPropertySources().get(2).getSource()).isEqualTo(Map.of("def-foo", "def-bar"));
}
@Test
- public void testFindOneDefaultKeySetAndEqualToApplication() {
+ public void findOneWithDefaultKeySetToApplicationName() {
when(keyValueTemplate.get("myapp")).thenReturn(withVaultResponse("foo", "bar"));
when(keyValueTemplate.get("application")).thenReturn(withVaultResponse("def-foo", "def-bar"));
@@ -147,11 +173,66 @@ public class SpringVaultEnvironmentRepositoryTests {
assertThat(e.getName()).isEqualTo("myapp");
assertThat(e.getPropertySources()).hasSize(1);
+ assertThat(e.getPropertySources().get(0).getName()).isEqualTo("vault:myapp");
assertThat(e.getPropertySources().get(0).getSource()).isEqualTo(Map.of("foo", "bar"));
}
@Test
- public void testVaultVersioning() {
+ public void findOneWithProfile() {
+ when(keyValueTemplate.get("myapp")).thenReturn(withVaultResponse("foo", "bar"));
+ when(keyValueTemplate.get("myapp,pr1")).thenReturn(withVaultResponse("foo-pr1", "bar-pr1"));
+ when(keyValueTemplate.get("application")).thenReturn(withVaultResponse("def-foo", "def-bar"));
+ when(keyValueTemplate.get("application,pr1")).thenReturn(withVaultResponse("def-pr1-foo", "def-pr1-bar"));
+
+ var properties = new VaultEnvironmentProperties();
+
+ var e = springVaultEnvironmentRepository(properties).findOne("myapp", "pr1", "lbl");
+
+ assertThat(e.getName()).isEqualTo("myapp");
+
+ assertThat(e.getPropertySources()).hasSize(4);
+ assertThat(e.getPropertySources().get(0).getName()).isEqualTo("vault:myapp,pr1");
+ assertThat(e.getPropertySources().get(0).getSource()).isEqualTo(Map.of("foo-pr1", "bar-pr1"));
+ assertThat(e.getPropertySources().get(1).getName()).isEqualTo("vault:application,pr1");
+ assertThat(e.getPropertySources().get(1).getSource()).isEqualTo(Map.of("def-pr1-foo", "def-pr1-bar"));
+ assertThat(e.getPropertySources().get(2).getName()).isEqualTo("vault:myapp");
+ assertThat(e.getPropertySources().get(2).getSource()).isEqualTo(Map.of("foo", "bar"));
+ assertThat(e.getPropertySources().get(3).getName()).isEqualTo("vault:application");
+ assertThat(e.getPropertySources().get(3).getSource()).isEqualTo(Map.of("def-foo", "def-bar"));
+ }
+
+ @Test
+ public void findOneWithMultipleProfiles() {
+ when(keyValueTemplate.get("myapp")).thenReturn(withVaultResponse("foo", "bar"));
+ when(keyValueTemplate.get("myapp,pr1")).thenReturn(withVaultResponse("foo-pr1", "bar-pr1"));
+ when(keyValueTemplate.get("myapp,pr2")).thenReturn(withVaultResponse("foo-pr2", "bar-pr2"));
+ when(keyValueTemplate.get("application")).thenReturn(withVaultResponse("def-foo", "def-bar"));
+ when(keyValueTemplate.get("application,pr1")).thenReturn(withVaultResponse("def-pr1-foo", "def-pr1-bar"));
+ when(keyValueTemplate.get("application,pr2")).thenReturn(withVaultResponse("def-pr2-foo", "def-pr2-bar"));
+
+ var properties = new VaultEnvironmentProperties();
+
+ var e = springVaultEnvironmentRepository(properties).findOne("myapp", "pr1,pr2", "lbl");
+
+ assertThat(e.getName()).isEqualTo("myapp");
+
+ assertThat(e.getPropertySources()).hasSize(6);
+ assertThat(e.getPropertySources().get(0).getName()).isEqualTo("vault:myapp,pr2");
+ assertThat(e.getPropertySources().get(0).getSource()).isEqualTo(Map.of("foo-pr2", "bar-pr2"));
+ assertThat(e.getPropertySources().get(1).getName()).isEqualTo("vault:application,pr2");
+ assertThat(e.getPropertySources().get(1).getSource()).isEqualTo(Map.of("def-pr2-foo", "def-pr2-bar"));
+ assertThat(e.getPropertySources().get(2).getName()).isEqualTo("vault:myapp,pr1");
+ assertThat(e.getPropertySources().get(2).getSource()).isEqualTo(Map.of("foo-pr1", "bar-pr1"));
+ assertThat(e.getPropertySources().get(3).getName()).isEqualTo("vault:application,pr1");
+ assertThat(e.getPropertySources().get(3).getSource()).isEqualTo(Map.of("def-pr1-foo", "def-pr1-bar"));
+ assertThat(e.getPropertySources().get(4).getName()).isEqualTo("vault:myapp");
+ assertThat(e.getPropertySources().get(4).getSource()).isEqualTo(Map.of("foo", "bar"));
+ assertThat(e.getPropertySources().get(5).getName()).isEqualTo("vault:application");
+ assertThat(e.getPropertySources().get(5).getSource()).isEqualTo(Map.of("def-foo", "def-bar"));
+ }
+
+ @Test
+ public void findOneWithVaultVersioning() {
when(keyValueTemplate.get("myapp")).thenReturn(withVaultResponse("foo", "bar"));
when(keyValueTemplate.get("application")).thenReturn(withVaultResponse("def-foo", "def-bar"));
@@ -163,7 +244,94 @@ public class SpringVaultEnvironmentRepositoryTests {
assertThat(e.getName()).isEqualTo("myapp");
assertThat(e.getPropertySources()).hasSize(2);
+ assertThat(e.getPropertySources().get(0).getName()).isEqualTo("vault:myapp");
assertThat(e.getPropertySources().get(0).getSource()).isEqualTo(Map.of("foo", "bar"));
+ assertThat(e.getPropertySources().get(1).getName()).isEqualTo("vault:application");
+ assertThat(e.getPropertySources().get(1).getSource()).isEqualTo(Map.of("def-foo", "def-bar"));
+ }
+
+ @Test
+ public void findOneWithDefaultLabelWhenLabelEnabled() {
+ when(keyValueTemplate.get("myapp,default,main")).thenReturn(withVaultResponse("foo", "bar"));
+ when(keyValueTemplate.get("application,default,main")).thenReturn(withVaultResponse("def-foo", "def-bar"));
+
+ var properties = new VaultEnvironmentProperties();
+ properties.setEnableLabel(true);
+
+ var e = springVaultEnvironmentRepository(properties).findOne("myapp", null, null);
+
+ assertThat(e.getName()).isEqualTo("myapp");
+
+ assertThat(e.getPropertySources()).hasSize(2);
+ assertThat(e.getPropertySources().get(0).getName()).isEqualTo("vault:myapp,default,main");
+ assertThat(e.getPropertySources().get(0).getSource()).isEqualTo(Map.of("foo", "bar"));
+ assertThat(e.getPropertySources().get(1).getName()).isEqualTo("vault:application,default,main");
+ assertThat(e.getPropertySources().get(1).getSource()).isEqualTo(Map.of("def-foo", "def-bar"));
+ }
+
+ @Test
+ public void findOneWithProfileAndDefaultLabelWhenLabelEnabled() {
+ when(keyValueTemplate.get("myapp,default,main")).thenReturn(withVaultResponse("foo", "bar"));
+ when(keyValueTemplate.get("myapp,pr1,main")).thenReturn(withVaultResponse("pr1-foo", "pr1-bar"));
+ when(keyValueTemplate.get("application,default,main")).thenReturn(withVaultResponse("def-foo", "def-bar"));
+ when(keyValueTemplate.get("application,pr1,main")).thenReturn(withVaultResponse("def-pr1-foo", "def-pr1-bar"));
+
+ var properties = new VaultEnvironmentProperties();
+ properties.setEnableLabel(true);
+
+ var e = springVaultEnvironmentRepository(properties).findOne("myapp", "pr1", null);
+
+ assertThat(e.getName()).isEqualTo("myapp");
+
+ assertThat(e.getPropertySources()).hasSize(4);
+ assertThat(e.getPropertySources().get(0).getName()).isEqualTo("vault:myapp,pr1,main");
+ assertThat(e.getPropertySources().get(0).getSource()).isEqualTo(Map.of("pr1-foo", "pr1-bar"));
+ assertThat(e.getPropertySources().get(1).getName()).isEqualTo("vault:application,pr1,main");
+ assertThat(e.getPropertySources().get(1).getSource()).isEqualTo(Map.of("def-pr1-foo", "def-pr1-bar"));
+ assertThat(e.getPropertySources().get(2).getName()).isEqualTo("vault:myapp,default,main");
+ assertThat(e.getPropertySources().get(2).getSource()).isEqualTo(Map.of("foo", "bar"));
+ assertThat(e.getPropertySources().get(3).getName()).isEqualTo("vault:application,default,main");
+ assertThat(e.getPropertySources().get(3).getSource()).isEqualTo(Map.of("def-foo", "def-bar"));
+ }
+
+ @Test
+ public void findOneWithCustomDefaultLabelWhenLabelEnabled() {
+ when(keyValueTemplate.get("myapp,default,custom")).thenReturn(withVaultResponse("foo", "bar"));
+ when(keyValueTemplate.get("application,default,custom")).thenReturn(withVaultResponse("def-foo", "def-bar"));
+
+ var properties = new VaultEnvironmentProperties();
+ properties.setEnableLabel(true);
+ properties.setDefaultLabel("custom");
+
+ var e = springVaultEnvironmentRepository(properties).findOne("myapp", null, null);
+
+ assertThat(e.getName()).isEqualTo("myapp");
+
+ assertThat(e.getPropertySources()).hasSize(2);
+ assertThat(e.getPropertySources().get(0).getName()).isEqualTo("vault:myapp,default,custom");
+ assertThat(e.getPropertySources().get(0).getSource()).isEqualTo(Map.of("foo", "bar"));
+ assertThat(e.getPropertySources().get(1).getName()).isEqualTo("vault:application,default,custom");
+ assertThat(e.getPropertySources().get(1).getSource()).isEqualTo(Map.of("def-foo", "def-bar"));
+ }
+
+ @Test
+ public void findOneWithCustomLabelWhenLabelEnabled() {
+ when(keyValueTemplate.get("myapp,default,my-label")).thenReturn(withVaultResponse("foo", "bar"));
+ when(keyValueTemplate.get("application,default,my-label")).thenReturn(withVaultResponse("def-foo", "def-bar"));
+
+ var properties = new VaultEnvironmentProperties();
+ properties.setEnableLabel(true);
+ properties.setDefaultLabel("custom");
+
+ var e = springVaultEnvironmentRepository(properties).findOne("myapp", null, "my-label");
+
+ assertThat(e.getName()).isEqualTo("myapp");
+
+ assertThat(e.getPropertySources()).hasSize(2);
+ assertThat(e.getPropertySources().get(0).getName()).isEqualTo("vault:myapp,default,my-label");
+ assertThat(e.getPropertySources().get(0).getSource()).isEqualTo(Map.of("foo", "bar"));
+ assertThat(e.getPropertySources().get(1).getName()).isEqualTo("vault:application,default,my-label");
+ assertThat(e.getPropertySources().get(1).getSource()).isEqualTo(Map.of("def-foo", "def-bar"));
}
private SpringVaultEnvironmentRepository springVaultEnvironmentRepository(VaultEnvironmentProperties properties) {