Skip to content

Commit 30e36c3

Browse files
authored
Merge pull request #167 from scalecube/vault-miltiple-path
Vault miltiple path
2 parents 24fee4f + 6670df2 commit 30e36c3

File tree

2 files changed

+59
-26
lines changed

2 files changed

+59
-26
lines changed

config-vault/src/main/java/io/scalecube/config/vault/VaultConfigSource.java

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
import io.scalecube.config.ConfigSourceNotAvailableException;
88
import io.scalecube.config.source.ConfigSource;
99
import io.scalecube.config.source.LoadedConfigProperty;
10+
import java.util.ArrayList;
11+
import java.util.Arrays;
12+
import java.util.HashMap;
13+
import java.util.List;
1014
import java.util.Map;
1115
import java.util.Objects;
1216
import java.util.function.Function;
@@ -27,31 +31,35 @@ public class VaultConfigSource implements ConfigSource {
2731
private static final String VAULT_SECRETS_PATH = "VAULT_SECRETS_PATH";
2832

2933
private final VaultInvoker vault;
30-
private final String secretsPath;
34+
private final List<String> secretsPath;
3135

3236
/**
3337
* Create a new {@link VaultConfigSource}.
34-
*
35-
* @param vault vault invoker.
36-
* @param secretsPath secret path.
38+
* @param vault vault invoker.
39+
* @param secretsPaths secret path-s.
3740
*/
38-
private VaultConfigSource(VaultInvoker vault, String secretsPath) {
41+
private VaultConfigSource(VaultInvoker vault, List<String> secretsPaths) {
3942
this.vault = vault;
40-
this.secretsPath = secretsPath;
43+
this.secretsPath = secretsPaths;
4144
}
4245

4346
@Override
4447
public Map<String, ConfigProperty> loadConfig() {
45-
try {
46-
LogicalResponse response = vault.invoke(vault -> vault.logical().read(secretsPath));
47-
return response.getData().entrySet().stream()
48-
.map(LoadedConfigProperty::withNameAndValue)
49-
.map(LoadedConfigProperty.Builder::build)
50-
.collect(Collectors.toMap(LoadedConfigProperty::name, Function.identity()));
51-
} catch (Exception ex) {
52-
LOGGER.warn("unable to load config properties", ex);
53-
throw new ConfigSourceNotAvailableException(ex);
48+
Map<String, ConfigProperty> result = new HashMap<>();
49+
for (String path : secretsPath) {
50+
try {
51+
LogicalResponse response = vault.invoke(vault -> vault.logical().read(path));
52+
final Map<String, LoadedConfigProperty> pathProps = response.getData().entrySet().stream()
53+
.map(LoadedConfigProperty::withNameAndValue)
54+
.map(LoadedConfigProperty.Builder::build)
55+
.collect(Collectors.toMap(LoadedConfigProperty::name, Function.identity()));
56+
result.putAll(pathProps);
57+
} catch (Exception ex) {
58+
LOGGER.warn("unable to load config properties from {}",path, ex);
59+
throw new ConfigSourceNotAvailableException(ex);
60+
}
5461
}
62+
return result;
5563
}
5664

5765
/**
@@ -87,12 +95,12 @@ public static final class Builder {
8795
private Function<VaultInvoker.Builder, VaultInvoker.Builder> vault = Function.identity();
8896
private VaultInvoker invoker;
8997
private EnvironmentLoader environmentLoader = VaultInvoker.Builder.ENVIRONMENT_LOADER;
90-
private String secretsPath;
98+
private List<String> secretsPaths = new ArrayList<>();
9199

92100
private Builder() {}
93101

94102
public Builder secretsPath(String secretsPath) {
95-
this.secretsPath = secretsPath;
103+
this.secretsPaths.add(secretsPath);
96104
return this;
97105
}
98106

@@ -126,13 +134,13 @@ public VaultConfigSource build() {
126134
invoker != null
127135
? invoker
128136
: vault.apply(new VaultInvoker.Builder(environmentLoader)).build();
129-
secretsPath =
130-
Objects.requireNonNull(
131-
secretsPath != null
132-
? secretsPath
133-
: environmentLoader.loadVariable(VAULT_SECRETS_PATH),
134-
"Missing secretsPath");
135-
return new VaultConfigSource(vaultInvoker, secretsPath);
137+
if (secretsPaths.isEmpty()) {
138+
String envSecretPath = Objects
139+
.requireNonNull(environmentLoader.loadVariable(VAULT_SECRETS_PATH),
140+
"Missing secretsPath");
141+
secretsPaths = Arrays.asList(envSecretPath.split(":"));
142+
}
143+
return new VaultConfigSource(vaultInvoker, secretsPaths);
136144
}
137145
}
138146
}

config-vault/src/test/java/io/scalecube/config/vault/VaultConfigSourceTest.java

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ class VaultConfigSourceTest {
4949
static void beforeAll() {
5050
VaultInstance vaultInstance = vaultContainerExtension.vaultInstance();
5151
vaultInstance.putSecrets(
52-
VAULT_SECRETS_PATH1, "top_secret=password1", "db_password=dbpassword1");
52+
VAULT_SECRETS_PATH1, "top_secret=password1", "db_password=dbpassword1", "only_first=pss1");
5353
vaultInstance.putSecrets(
54-
VAULT_SECRETS_PATH2, "top_secret=password2", "db_password=dbpassword2");
54+
VAULT_SECRETS_PATH2, "top_secret=password2", "db_password=dbpassword2", "only_second=pss2");
5555
vaultInstance.putSecrets(VAULT_SECRETS_PATH3, "secret=password", "password=dbpassword");
5656
}
5757

@@ -88,6 +88,31 @@ void testSecondTenant() {
8888
assertThat(actual.valueAsString(""), equalTo("password2"));
8989
}
9090

91+
@Test
92+
void testMultiplePathsEnv() {
93+
String commonPath = VAULT_SECRETS_PATH1 + ":" + VAULT_SECRETS_PATH2;
94+
EnvironmentLoader multiLoader =
95+
new MockEnvironmentLoader(baseLoader).put(VAULT_SECRETS_PATH, commonPath);
96+
VaultConfigSource vaultConfigSource = VaultConfigSource.builder(multiLoader).build();
97+
Map<String, ConfigProperty> loadConfig = vaultConfigSource.loadConfig();
98+
99+
ConfigProperty commonSecret = loadConfig.get("top_secret");
100+
assertThat(commonSecret, notNullValue());
101+
assertThat(commonSecret.name(), equalTo("top_secret"));
102+
assertThat("Second path should override the first one", commonSecret.valueAsString(""),
103+
equalTo("password2"));
104+
105+
ConfigProperty fromFirstPath = loadConfig.get("only_first");
106+
assertThat(fromFirstPath.name(), equalTo("only_first"));
107+
assertThat("Secret defined only in first path expected", fromFirstPath.valueAsString(""),
108+
equalTo("pss1"));
109+
110+
ConfigProperty fromSecondPath = loadConfig.get("only_second");
111+
assertThat(fromSecondPath.name(), equalTo("only_second"));
112+
assertThat("Secret defined only in second path expected", fromSecondPath.valueAsString(""),
113+
equalTo("pss2"));
114+
}
115+
91116
@Test
92117
void testMissingProperty() {
93118
VaultConfigSource vaultConfigSource = VaultConfigSource.builder(loader3).build();

0 commit comments

Comments
 (0)