From 19c99b2ca8f39b68e8cc73e5767eee36f4724c0b Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Thu, 15 Dec 2016 11:17:00 +0100 Subject: [PATCH] Flatten Vault JSON to Properties. Fixes gh-61. --- .../vault/config/VaultConfigTemplate.java | 57 +++++++++++++------ .../cloud/vault/config/VaultConfigTests.java | 25 ++++---- 2 files changed, 54 insertions(+), 28 deletions(-) diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultConfigTemplate.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultConfigTemplate.java index 891ebf8c..4b29a03d 100644 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultConfigTemplate.java +++ b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultConfigTemplate.java @@ -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 response = vaultOperations.doWithVault( - new VaultOperations.SessionCallback>() { + VaultResponseEntity response = vaultOperations + .doWithVault(new VaultOperations.SessionCallback>() { @Override - public VaultResponseEntity doWithVault( + public VaultResponseEntity 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 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 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; } diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigTests.java index 8edc9640..9026a815 100644 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigTests.java +++ b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigTests.java @@ -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 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