Flatten Vault JSON to Properties.

Fixes gh-61.
This commit is contained in:
Mark Paluch
2016-12-15 11:17:00 +01:00
parent 501e7013c6
commit 19c99b2ca8
2 changed files with 54 additions and 28 deletions

View File

@@ -15,13 +15,17 @@
*/
package org.springframework.cloud.vault.config;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.util.Assert;
import org.springframework.vault.client.VaultResponseEntity;
import org.springframework.vault.core.VaultOperations;
import lombok.extern.slf4j.Slf4j;
import org.springframework.vault.support.JsonMapFlattener;
import org.springframework.vault.support.VaultResponse;
/**
* Central class to retrieve configuration from Vault.
@@ -41,8 +45,7 @@ public class VaultConfigTemplate implements VaultConfigOperations {
* @param vaultOperations must not be {@literal null}.
* @param properties must not be {@literal null}.
*/
public VaultConfigTemplate(VaultOperations vaultOperations,
VaultProperties properties) {
public VaultConfigTemplate(VaultOperations vaultOperations, VaultProperties properties) {
Assert.notNull(vaultOperations, "VaultOperations must not be null!");
Assert.notNull(properties, "VaultProperties must not be null!");
@@ -56,14 +59,14 @@ public class VaultConfigTemplate implements VaultConfigOperations {
Assert.notNull(secretBackendMetadata, "SecureBackendAccessor must not be null!");
VaultResponseEntity<Secrets> response = vaultOperations.doWithVault(
new VaultOperations.SessionCallback<VaultResponseEntity<Secrets>>() {
VaultResponseEntity<VaultResponse> response = vaultOperations
.doWithVault(new VaultOperations.SessionCallback<VaultResponseEntity<VaultResponse>>() {
@Override
public VaultResponseEntity<Secrets> doWithVault(
public VaultResponseEntity<VaultResponse> doWithVault(
VaultOperations.VaultSession session) {
return session.exchange("{backend}/{key}", HttpMethod.GET, null,
Secrets.class, secretBackendMetadata.getVariables());
VaultResponse.class, secretBackendMetadata.getVariables());
}
});
@@ -71,27 +74,27 @@ public class VaultConfigTemplate implements VaultConfigOperations {
if (response.getStatusCode() == HttpStatus.OK) {
Secrets secrets = response.getBody();
VaultResponse vaultResponse = response.getBody();
Map<String, String> data = JsonMapFlattener.flatten(vaultResponse.getData());
PropertyTransformer propertyTransformer = secretBackendMetadata
.getPropertyTransformer();
if (propertyTransformer != null) {
secrets.setData(
propertyTransformer.transformProperties(secrets.getData()));
data = propertyTransformer.transformProperties(data);
}
return secrets;
return createSecrets(vaultResponse, data);
}
if (response.getStatusCode() == HttpStatus.NOT_FOUND) {
log.info(String.format("Could not locate PropertySource: %s",
"key not found"));
log.info(String
.format("Could not locate PropertySource: %s", "key not found"));
}
else if (properties.isFailFast()) {
throw new IllegalStateException(String.format(
"Could not locate PropertySource and the fail fast property is set, failing Status %d %s",
response.getStatusCode().value(), response.getMessage()));
throw new IllegalStateException(
String.format(
"Could not locate PropertySource and the fail fast property is set, failing Status %d %s",
response.getStatusCode().value(), response.getMessage()));
}
else {
log.warn(String.format("Could not locate PropertySource: Status %d %s",
@@ -101,6 +104,24 @@ public class VaultConfigTemplate implements VaultConfigOperations {
return null;
}
private Secrets createSecrets(VaultResponse vaultResponse, Map<String, String> data) {
Secrets secrets = new Secrets();
secrets.setData(data);
secrets.setAuth(vaultResponse.getAuth());
secrets.setLeaseDuration(vaultResponse.getLeaseDuration());
secrets.setMetadata(vaultResponse.getMetadata());
secrets.setLeaseId(vaultResponse.getLeaseId());
secrets.setRenewable(vaultResponse.isRenewable());
secrets.setRequestId(vaultResponse.getRequestId());
secrets.setWarnings(vaultResponse.getWarnings());
secrets.setWrapInfo(vaultResponse.getWrapInfo());
return secrets;
}
public VaultOperations getVaultOperations() {
return vaultOperations;
}

View File

@@ -16,6 +16,12 @@
package org.springframework.cloud.vault.config;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@@ -30,11 +36,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.vault.client.VaultClient;
import org.springframework.web.client.RestTemplate;
import static org.assertj.core.api.Assertions.*;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration test using config infrastructure with token authentication.
@@ -55,11 +57,11 @@ public class VaultConfigTests {
VaultRule vaultRule = new VaultRule();
vaultRule.before();
vaultRule
.prepare()
.getVaultOperations()
.write("secret/testVaultApp",
Collections.singletonMap("vault.value", "foo"));
Map<String, Object> object = new HashMap<>();
object.put("vault.value", "foo");
object.put("nested", Collections.singletonMap("key", "value"));
vaultRule.prepare().getVaultOperations().write("secret/testVaultApp", object);
}
@Value("${vault.value}")
@@ -81,6 +83,9 @@ public class VaultConfigTests {
assertThat(environment.containsProperty("vault.value")).isTrue();
assertThat(environment.getProperty("vault.value")).isEqualTo("foo");
assertThat(environment.containsProperty("nested.key")).isTrue();
assertThat(environment.getProperty("nested.key")).isEqualTo("value");
}
@Test