Skip to content

Commit b21a351

Browse files
committed
Get rid of EnvironmentLoader in public configuration. Made settings come via config properties setter methods (initialization from ENV variables remained as default option).
1 parent 30e36c3 commit b21a351

File tree

6 files changed

+189
-188
lines changed

6 files changed

+189
-188
lines changed
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
package io.scalecube.config.vault;
22

3-
import com.bettercloud.vault.EnvironmentLoader;
43
import com.bettercloud.vault.VaultConfig;
54
import java.util.Objects;
65

76
public class EnvironmentVaultTokenSupplier implements VaultTokenSupplier {
87

9-
public String getToken(EnvironmentLoader environmentLoader, VaultConfig config) {
8+
public String getToken(VaultConfig config) {
109
return Objects.requireNonNull(config.getToken(), "vault token");
1110
}
1211
}

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

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,45 @@
1212

1313
public class KubernetesVaultTokenSupplier implements VaultTokenSupplier {
1414

15-
private static final String VAULT_ROLE = "VAULT_ROLE";
16-
private static final String VAULT_JWT_PROVIDER = "VAULT_JWT_PROVIDER";
17-
private static final String DEFAULT_JWT_PROVIDER = "kubernetes";
18-
private static final String SERVICE_ACCOUNT_TOKEN_PATH =
19-
"/var/run/secrets/kubernetes.io/serviceaccount/token";
15+
private static final EnvironmentLoader ENVIRONMENT_LOADER = new EnvironmentLoader();
16+
17+
private String vaultRole = ENVIRONMENT_LOADER.loadVariable("VAULT_ROLE");
18+
19+
private String vaultJwtProvider =
20+
Optional.ofNullable(ENVIRONMENT_LOADER.loadVariable("VAULT_JWT_PROVIDER"))
21+
.orElse("kubernetes");
22+
23+
private String serviceAccountTokenPath =
24+
Optional.ofNullable(ENVIRONMENT_LOADER.loadVariable("SERVICE_ACCOUNT_TOKEN_PATH"))
25+
.orElse("/var/run/secrets/kubernetes.io/serviceaccount/token");
26+
27+
public KubernetesVaultTokenSupplier vaultRole(String vaultRole) {
28+
this.vaultRole = vaultRole;
29+
return this;
30+
}
31+
32+
public KubernetesVaultTokenSupplier vaultJwtProvider(String vaultJwtProvider) {
33+
this.vaultJwtProvider = vaultJwtProvider;
34+
return this;
35+
}
36+
37+
public KubernetesVaultTokenSupplier serviceAccountTokenPath(String serviceAccountTokenPath) {
38+
this.serviceAccountTokenPath = serviceAccountTokenPath;
39+
return this;
40+
}
2041

2142
@Override
22-
public String getToken(EnvironmentLoader environmentLoader, VaultConfig config) {
23-
String role = Objects.requireNonNull(environmentLoader.loadVariable(VAULT_ROLE), "vault role");
43+
public String getToken(VaultConfig config) {
44+
Objects.requireNonNull(vaultRole, "vault role");
45+
Objects.requireNonNull(vaultJwtProvider, "jwt provider");
46+
Objects.requireNonNull(serviceAccountTokenPath, "k8s service account token path");
2447
try {
25-
String jwt = Files.lines(Paths.get(SERVICE_ACCOUNT_TOKEN_PATH)).collect(Collectors.joining());
26-
String provider =
27-
Optional.ofNullable(environmentLoader.loadVariable(VAULT_JWT_PROVIDER))
28-
.orElse(DEFAULT_JWT_PROVIDER);
48+
String jwt = Files.lines(Paths.get(serviceAccountTokenPath)).collect(Collectors.joining());
2949
return Objects.requireNonNull(
30-
new Vault(config).auth().loginByJwt(provider, role, jwt).getAuthClientToken(),
50+
new Vault(config)
51+
.auth()
52+
.loginByJwt(vaultJwtProvider, vaultRole, jwt)
53+
.getAuthClientToken(),
3154
"vault token");
3255
} catch (Exception e) {
3356
throw ThrowableUtil.propagate(e);

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

Lines changed: 51 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@
99
import io.scalecube.config.source.LoadedConfigProperty;
1010
import java.util.ArrayList;
1111
import java.util.Arrays;
12+
import java.util.Collection;
13+
import java.util.Collections;
1214
import java.util.HashMap;
1315
import java.util.List;
1416
import java.util.Map;
15-
import java.util.Objects;
17+
import java.util.Optional;
1618
import java.util.function.Function;
1719
import java.util.function.UnaryOperator;
1820
import java.util.stream.Collectors;
@@ -28,99 +30,99 @@ public class VaultConfigSource implements ConfigSource {
2830

2931
private static final Logger LOGGER = LoggerFactory.getLogger(VaultConfigSource.class);
3032

31-
private static final String VAULT_SECRETS_PATH = "VAULT_SECRETS_PATH";
33+
private static final EnvironmentLoader ENVIRONMENT_LOADER = new EnvironmentLoader();
3234

3335
private final VaultInvoker vault;
34-
private final List<String> secretsPath;
36+
private final List<String> secretsPaths;
3537

36-
/**
37-
* Create a new {@link VaultConfigSource}.
38-
* @param vault vault invoker.
39-
* @param secretsPaths secret path-s.
40-
*/
4138
private VaultConfigSource(VaultInvoker vault, List<String> secretsPaths) {
4239
this.vault = vault;
43-
this.secretsPath = secretsPaths;
40+
this.secretsPaths = new ArrayList<>(secretsPaths);
4441
}
4542

4643
@Override
4744
public Map<String, ConfigProperty> loadConfig() {
4845
Map<String, ConfigProperty> result = new HashMap<>();
49-
for (String path : secretsPath) {
46+
for (String path : secretsPaths) {
5047
try {
5148
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()));
49+
final Map<String, LoadedConfigProperty> pathProps =
50+
response.getData().entrySet().stream()
51+
.map(LoadedConfigProperty::withNameAndValue)
52+
.map(LoadedConfigProperty.Builder::build)
53+
.collect(Collectors.toMap(LoadedConfigProperty::name, Function.identity()));
5654
result.putAll(pathProps);
5755
} catch (Exception ex) {
58-
LOGGER.warn("unable to load config properties from {}",path, ex);
56+
LOGGER.warn("Unable to load config properties from {}", path, ex);
5957
throw new ConfigSourceNotAvailableException(ex);
6058
}
6159
}
6260
return result;
6361
}
6462

65-
/**
66-
* This builder method is used internally for test purposes. please use it only for tests. Please
67-
* note the following required environment variables are required.
68-
*
69-
* <ul>
70-
* <li><code>VAULT_SECRETS_PATH</code> is the path to use (defaults to <code>secret</code>)
71-
* <li><code>VAULT_TOKEN</code> is the {@link VaultConfig#token(String) token} to use
72-
* <li><code>VAULT_ADDR</code> is the {@link VaultConfig#address(String) address} of the vault
73-
* (API)
74-
* </ul>
75-
*/
7663
public static Builder builder() {
7764
return new Builder();
7865
}
7966

80-
/**
81-
* This builder method is used internally for test purposes. please use it only for tests
82-
*
83-
* @param environmentLoader an {@link EnvironmentLoader}
84-
*/
85-
static Builder builder(EnvironmentLoader environmentLoader) {
86-
final Builder builder = new Builder();
87-
if (environmentLoader != null) {
88-
builder.environmentLoader = environmentLoader;
89-
}
90-
return builder;
91-
}
92-
9367
public static final class Builder {
9468

95-
private Function<VaultInvoker.Builder, VaultInvoker.Builder> vault = Function.identity();
69+
private Function<VaultInvoker.Builder, VaultInvoker.Builder> builderFunction = b -> b;
70+
9671
private VaultInvoker invoker;
97-
private EnvironmentLoader environmentLoader = VaultInvoker.Builder.ENVIRONMENT_LOADER;
98-
private List<String> secretsPaths = new ArrayList<>();
72+
73+
private List<String> secretsPaths =
74+
Optional.ofNullable(ENVIRONMENT_LOADER.loadVariable("VAULT_SECRETS_PATH"))
75+
.or(() -> Optional.ofNullable(ENVIRONMENT_LOADER.loadVariable("VAULT_SECRETS_PATHS")))
76+
.map(s -> s.split(":"))
77+
.map(Arrays::asList)
78+
.orElseGet(ArrayList::new);
9979

10080
private Builder() {}
10181

82+
/**
83+
* @deprecated will be removed in future releases without notice, use {@link
84+
* #addSecretsPath(String...)} or {@link #secretsPaths(Collection)}.
85+
*/
86+
@Deprecated
10287
public Builder secretsPath(String secretsPath) {
103-
this.secretsPaths.add(secretsPath);
88+
this.secretsPaths.addAll(toSecretsPaths(Collections.singletonList(secretsPath)));
89+
return this;
90+
}
91+
92+
public Builder addSecretsPath(String... secretsPath) {
93+
this.secretsPaths.addAll(toSecretsPaths(Arrays.asList(secretsPath)));
94+
return this;
95+
}
96+
97+
public Builder secretsPaths(Collection<String> secretsPaths) {
98+
this.secretsPaths = toSecretsPaths(secretsPaths);
10499
return this;
105100
}
106101

102+
private static List<String> toSecretsPaths(Collection<String> secretsPaths) {
103+
return secretsPaths.stream()
104+
.flatMap(s -> Arrays.stream(s.split(":")))
105+
.distinct()
106+
.collect(Collectors.toList());
107+
}
108+
107109
public Builder invoker(VaultInvoker invoker) {
108110
this.invoker = invoker;
109111
return this;
110112
}
111113

112114
public Builder vault(UnaryOperator<VaultInvoker.Builder> config) {
113-
this.vault = this.vault.andThen(config);
115+
this.builderFunction = this.builderFunction.andThen(config);
114116
return this;
115117
}
116118

117119
public Builder config(UnaryOperator<VaultConfig> vaultConfig) {
118-
this.vault = this.vault.andThen(c -> c.options(vaultConfig));
120+
this.builderFunction = this.builderFunction.andThen(c -> c.options(vaultConfig));
119121
return this;
120122
}
121123

122124
public Builder tokenSupplier(VaultTokenSupplier supplier) {
123-
this.vault = this.vault.andThen(c -> c.tokenSupplier(supplier));
125+
this.builderFunction = this.builderFunction.andThen(c -> c.tokenSupplier(supplier));
124126
return this;
125127
}
126128

@@ -130,17 +132,9 @@ public Builder tokenSupplier(VaultTokenSupplier supplier) {
130132
* @return instance of {@link VaultConfigSource}
131133
*/
132134
public VaultConfigSource build() {
133-
VaultInvoker vaultInvoker =
134-
invoker != null
135-
? invoker
136-
: vault.apply(new VaultInvoker.Builder(environmentLoader)).build();
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);
135+
return new VaultConfigSource(
136+
invoker != null ? invoker : builderFunction.apply(new VaultInvoker.Builder()).build(),
137+
secretsPaths);
144138
}
145139
}
146140
}

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

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,17 @@ public class VaultInvoker {
3030

3131
private static final long MIN_REFRESH_MARGIN = TimeUnit.MINUTES.toSeconds(10);
3232

33-
private final Builder config;
33+
private final Builder builder;
3434

3535
private Vault vault;
3636
private Timer timer;
3737

3838
public static Builder builder() {
39-
return new Builder(Builder.ENVIRONMENT_LOADER);
39+
return new Builder();
4040
}
4141

42-
private VaultInvoker(Builder config) {
43-
this.config = config;
42+
private VaultInvoker(Builder builder) {
43+
this.builder = builder;
4444
}
4545

4646
/**
@@ -81,12 +81,11 @@ private synchronized Vault recreateVault(Vault prev) throws VaultException {
8181
vault = null;
8282

8383
VaultConfig vaultConfig =
84-
config
84+
builder
8585
.options
86-
.apply(new VaultConfig())
87-
.environmentLoader(config.environmentLoader)
86+
.apply(new VaultConfig().environmentLoader(new EnvironmentLoader()))
8887
.build();
89-
String token = config.tokenSupplier.getToken(config.environmentLoader, vaultConfig);
88+
String token = builder.tokenSupplier.getToken(vaultConfig);
9089
Vault vault = new Vault(vaultConfig.token(token));
9190
checkVault(vault);
9291
LookupResponse lookupSelf = vault.auth().lookupSelf();
@@ -211,23 +210,9 @@ public void run() {
211210
}
212211

213212
public static class Builder {
214-
public static final EnvironmentLoader ENVIRONMENT_LOADER = new EnvironmentLoader();
215-
public static final VaultTokenSupplier TOKEN_SUPPLIER = new EnvironmentVaultTokenSupplier();
216213

217214
private Function<VaultConfig, VaultConfig> options = Function.identity();
218-
private VaultTokenSupplier tokenSupplier = TOKEN_SUPPLIER;
219-
private EnvironmentLoader environmentLoader = ENVIRONMENT_LOADER;
220-
221-
/**
222-
* This builder method is used internally for test purposes. please use it only for tests
223-
*
224-
* @param environmentLoader an {@link EnvironmentLoader}
225-
*/
226-
Builder(EnvironmentLoader environmentLoader) {
227-
if (environmentLoader != null) {
228-
this.environmentLoader = environmentLoader;
229-
}
230-
}
215+
private VaultTokenSupplier tokenSupplier = new EnvironmentVaultTokenSupplier();
231216

232217
public Builder options(UnaryOperator<VaultConfig> config) {
233218
this.options = this.options.andThen(config);
@@ -245,7 +230,7 @@ public Builder tokenSupplier(VaultTokenSupplier supplier) {
245230
* @return instance of {@link VaultInvoker}
246231
*/
247232
public VaultInvoker build() {
248-
Builder builder = new Builder(environmentLoader);
233+
Builder builder = new Builder();
249234
builder.options = options;
250235
builder.tokenSupplier = tokenSupplier;
251236
return new VaultInvoker(builder);
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
package io.scalecube.config.vault;
22

3-
import com.bettercloud.vault.EnvironmentLoader;
43
import com.bettercloud.vault.VaultConfig;
54

65
@FunctionalInterface
76
public interface VaultTokenSupplier {
87

9-
String getToken(EnvironmentLoader environmentLoader, VaultConfig config);
8+
String getToken(VaultConfig config);
109
}

0 commit comments

Comments
 (0)