Skip to content

Commit 84f2c3b

Browse files
authored
Merge pull request #138 from scalecube/develop
Prepare release
2 parents 1cb4989 + ad61743 commit 84f2c3b

File tree

10 files changed

+577
-120
lines changed

10 files changed

+577
-120
lines changed

config-vault/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
<properties>
1414
<log4j.version>2.5</log4j.version>
1515
<vault-java-driver.version>5.0.0</vault-java-driver.version>
16-
<org.testcontainers.vault.version>1.12.1</org.testcontainers.vault.version>
16+
<org.testcontainers.vault.version>1.12.3</org.testcontainers.vault.version>
1717
</properties>
1818

1919
<dependencies>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package io.scalecube.config.vault;
2+
3+
import com.bettercloud.vault.EnvironmentLoader;
4+
import com.bettercloud.vault.VaultConfig;
5+
import java.util.Objects;
6+
7+
public class EnvironmentVaultTokenSupplier implements VaultTokenSupplier {
8+
9+
public String getToken(EnvironmentLoader environmentLoader, VaultConfig config) {
10+
return Objects.requireNonNull(config.getToken(), "vault token");
11+
}
12+
}
Lines changed: 43 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,14 @@
11
package io.scalecube.config.vault;
22

33
import com.bettercloud.vault.EnvironmentLoader;
4-
import com.bettercloud.vault.Vault;
54
import com.bettercloud.vault.VaultConfig;
6-
import com.bettercloud.vault.VaultException;
75
import com.bettercloud.vault.response.LogicalResponse;
86
import io.scalecube.config.ConfigProperty;
97
import io.scalecube.config.ConfigSourceNotAvailableException;
108
import io.scalecube.config.source.ConfigSource;
119
import io.scalecube.config.source.LoadedConfigProperty;
12-
import io.scalecube.config.utils.ThrowableUtil;
13-
import java.time.Duration;
1410
import java.util.Map;
1511
import java.util.Objects;
16-
import java.util.concurrent.Executors;
17-
import java.util.concurrent.ThreadFactory;
18-
import java.util.concurrent.TimeUnit;
1912
import java.util.function.Function;
2013
import java.util.function.UnaryOperator;
2114
import java.util.stream.Collectors;
@@ -31,95 +24,33 @@ public class VaultConfigSource implements ConfigSource {
3124

3225
private static final Logger LOGGER = LoggerFactory.getLogger(VaultConfigSource.class);
3326

34-
private static final ThreadFactory THREAD_FACTORY =
35-
r -> {
36-
Thread thread = new Thread(r);
37-
thread.setDaemon(true);
38-
thread.setName(VaultConfigSource.class.getSimpleName().toLowerCase() + "-token-renewer");
39-
return thread;
40-
};
41-
4227
private static final String VAULT_SECRETS_PATH = "VAULT_SECRETS_PATH";
43-
private static final String VAULT_RENEW_PERIOD = "VAULT_RENEW_PERIOD";
4428

45-
private final Vault vault;
29+
private final VaultInvoker vault;
4630
private final String secretsPath;
4731

4832
/**
49-
* Create a new {@link VaultConfigSource} with the given {@link Builder}.
33+
* Create a new {@link VaultConfigSource}.
5034
*
51-
* @param builder configuration to create vault access with.
35+
* @param vault vault invoker.
36+
* @param secretsPath secret path.
5237
*/
53-
private VaultConfigSource(Builder builder) throws VaultException {
54-
EnvironmentLoader environmentLoader =
55-
builder.environmentLoader != null ? builder.environmentLoader : new EnvironmentLoader();
56-
57-
secretsPath =
58-
Objects.requireNonNull(
59-
builder.secretsPath != null
60-
? builder.secretsPath
61-
: environmentLoader.loadVariable(VAULT_SECRETS_PATH),
62-
"Missing secretsPath");
63-
64-
VaultConfig vaultConfig =
65-
builder.config.apply(new VaultConfig()).environmentLoader(environmentLoader).build();
66-
String token = builder.tokenSupplier.getToken(environmentLoader, vaultConfig);
67-
vault = new Vault(vaultConfig.token(token));
68-
69-
Duration renewEvery =
70-
builder.renewEvery != null
71-
? builder.renewEvery
72-
: duration(environmentLoader.loadVariable(VAULT_RENEW_PERIOD));
73-
74-
if (renewEvery != null) {
75-
scheduleVaultTokenRenew(renewEvery);
76-
}
77-
}
78-
79-
private void scheduleVaultTokenRenew(Duration renewEvery) {
80-
long initialDelay = renewEvery.toMillis();
81-
long period = renewEvery.toMillis();
82-
Executors.newSingleThreadScheduledExecutor(THREAD_FACTORY)
83-
.scheduleAtFixedRate(
84-
() -> {
85-
try {
86-
this.vault.auth().renewSelf();
87-
LOGGER.info("renew token success");
88-
} catch (VaultException vaultException) {
89-
LOGGER.error("failed to renew token", vaultException);
90-
}
91-
},
92-
initialDelay,
93-
period,
94-
TimeUnit.MILLISECONDS);
95-
}
96-
97-
private void checkVaultStatus() throws VaultException {
98-
if (vault.seal().sealStatus().getSealed()) {
99-
throw new VaultException("Vault is sealed");
100-
}
101-
Boolean initialized = vault.debug().health().getInitialized();
102-
if (!initialized) {
103-
throw new VaultException("Vault not yet initialized");
104-
}
105-
}
106-
107-
private Duration duration(String duration) {
108-
return duration != null ? Duration.parse(duration) : null;
38+
private VaultConfigSource(VaultInvoker vault, String secretsPath) {
39+
this.vault = vault;
40+
this.secretsPath = secretsPath;
10941
}
11042

11143
@Override
11244
public Map<String, ConfigProperty> loadConfig() {
11345
try {
114-
checkVaultStatus();
115-
LogicalResponse response = vault.logical().read(this.secretsPath);
46+
LogicalResponse response = vault.invoke(vault -> vault.logical().read(secretsPath));
11647
return response.getData().entrySet().stream()
11748
.map(LoadedConfigProperty::withNameAndValue)
11849
.map(LoadedConfigProperty.Builder::build)
11950
.collect(Collectors.toMap(LoadedConfigProperty::name, Function.identity()));
120-
} catch (VaultException vaultException) {
121-
LOGGER.warn("unable to load config properties", vaultException);
122-
throw new ConfigSourceNotAvailableException(vaultException);
51+
} catch (Exception ex) {
52+
LOGGER.warn("unable to load config properties", ex);
53+
throw new ConfigSourceNotAvailableException(ex);
12354
}
12455
}
12556

@@ -135,7 +66,7 @@ public Map<String, ConfigProperty> loadConfig() {
13566
* </ul>
13667
*/
13768
public static Builder builder() {
138-
return builder(new EnvironmentLoader());
69+
return new Builder();
13970
}
14071

14172
/**
@@ -144,38 +75,44 @@ public static Builder builder() {
14475
* @param environmentLoader an {@link EnvironmentLoader}
14576
*/
14677
static Builder builder(EnvironmentLoader environmentLoader) {
147-
return new Builder(environmentLoader);
78+
final Builder builder = new Builder();
79+
if (environmentLoader != null) {
80+
builder.environmentLoader = environmentLoader;
81+
}
82+
return builder;
14883
}
14984

15085
public static final class Builder {
15186

152-
private Function<VaultConfig, VaultConfig> config = Function.identity();
153-
private VaultTokenSupplier tokenSupplier = new VaultTokenSupplier() {};
154-
private EnvironmentLoader environmentLoader;
87+
private Function<VaultInvoker.Builder, VaultInvoker.Builder> vault = Function.identity();
88+
private VaultInvoker invoker;
89+
private EnvironmentLoader environmentLoader = VaultInvoker.Builder.ENVIRONMENT_LOADER;
15590
private String secretsPath;
156-
private Duration renewEvery;
15791

158-
private Builder(EnvironmentLoader environmentLoader) {
159-
this.environmentLoader = environmentLoader;
92+
private Builder() {}
93+
94+
public Builder secretsPath(String secretsPath) {
95+
this.secretsPath = secretsPath;
96+
return this;
16097
}
16198

162-
public Builder renewEvery(Duration duration) {
163-
renewEvery = duration;
99+
public Builder invoker(VaultInvoker invoker) {
100+
this.invoker = invoker;
164101
return this;
165102
}
166103

167-
public Builder secretsPath(String secretsPath) {
168-
this.secretsPath = secretsPath;
104+
public Builder vault(UnaryOperator<VaultInvoker.Builder> config) {
105+
this.vault = this.vault.andThen(config);
169106
return this;
170107
}
171108

172-
public Builder config(UnaryOperator<VaultConfig> config) {
173-
this.config = this.config.andThen(config);
109+
public Builder config(UnaryOperator<VaultConfig> vaultConfig) {
110+
this.vault = this.vault.andThen(c -> c.options(vaultConfig));
174111
return this;
175112
}
176113

177114
public Builder tokenSupplier(VaultTokenSupplier supplier) {
178-
this.tokenSupplier = supplier;
115+
this.vault = this.vault.andThen(c -> c.tokenSupplier(supplier));
179116
return this;
180117
}
181118

@@ -185,12 +122,17 @@ public Builder tokenSupplier(VaultTokenSupplier supplier) {
185122
* @return instance of {@link VaultConfigSource}
186123
*/
187124
public VaultConfigSource build() {
188-
try {
189-
return new VaultConfigSource(this);
190-
} catch (VaultException e) {
191-
LOGGER.error("Unable to build " + VaultConfigSource.class.getSimpleName(), e);
192-
throw ThrowableUtil.propagate(e);
193-
}
125+
VaultInvoker vaultInvoker =
126+
invoker != null
127+
? invoker
128+
: 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);
194136
}
195137
}
196138
}

0 commit comments

Comments
 (0)