Polishing
Reformat code using new formatter Settings. See gh-482.
This commit is contained in:
@@ -49,8 +49,7 @@ public class VaultConfigAwsBootstrapConfiguration {
|
||||
* {@link SecretBackendMetadataFactory} for AWS integration using
|
||||
* {@link VaultAwsProperties}.
|
||||
*/
|
||||
public static class AwsSecretBackendMetadataFactory
|
||||
implements SecretBackendMetadataFactory<VaultAwsProperties> {
|
||||
public static class AwsSecretBackendMetadataFactory implements SecretBackendMetadataFactory<VaultAwsProperties> {
|
||||
|
||||
/**
|
||||
* Creates {@link SecretBackendMetadata} for a secret backend using
|
||||
@@ -66,23 +65,19 @@ public class VaultConfigAwsBootstrapConfiguration {
|
||||
Assert.notNull(properties, "VaultAwsProperties must not be null");
|
||||
|
||||
PropertyNameTransformer transformer = new PropertyNameTransformer();
|
||||
transformer.addKeyTransformation("access_key",
|
||||
properties.getAccessKeyProperty());
|
||||
transformer.addKeyTransformation("secret_key",
|
||||
properties.getSecretKeyProperty());
|
||||
transformer.addKeyTransformation("access_key", properties.getAccessKeyProperty());
|
||||
transformer.addKeyTransformation("secret_key", properties.getSecretKeyProperty());
|
||||
|
||||
return new SecretBackendMetadata() {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return String.format("%s with Role %s", properties.getBackend(),
|
||||
properties.getRole());
|
||||
return String.format("%s with Role %s", properties.getBackend(), properties.getRole());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return String.format("%s/creds/%s", properties.getBackend(),
|
||||
properties.getRole());
|
||||
return String.format("%s/creds/%s", properties.getBackend(), properties.getRole());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -104,8 +99,7 @@ public class VaultConfigAwsBootstrapConfiguration {
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecretBackendMetadata createMetadata(
|
||||
VaultAwsProperties backendDescriptor) {
|
||||
public SecretBackendMetadata createMetadata(VaultAwsProperties backendDescriptor) {
|
||||
return forAws(backendDescriptor);
|
||||
}
|
||||
|
||||
|
||||
@@ -64,8 +64,7 @@ public class AwsSecretIntegrationTests extends IntegrationTestSupport {
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
assumeTrue(StringUtils.hasText(AWS_ACCESS_KEY)
|
||||
&& StringUtils.hasText(AWS_SECRET_KEY));
|
||||
assumeTrue(StringUtils.hasText(AWS_ACCESS_KEY) && StringUtils.hasText(AWS_SECRET_KEY));
|
||||
|
||||
this.aws.setEnabled(true);
|
||||
this.aws.setRole("readonly");
|
||||
@@ -81,25 +80,20 @@ public class AwsSecretIntegrationTests extends IntegrationTestSupport {
|
||||
connection.put("access_key", AWS_ACCESS_KEY);
|
||||
connection.put("secret_key", AWS_SECRET_KEY);
|
||||
|
||||
vaultOperations.write(String.format("%s/config/root", this.aws.getBackend()),
|
||||
connection);
|
||||
vaultOperations.write(String.format("%s/config/root", this.aws.getBackend()), connection);
|
||||
|
||||
vaultOperations.write(
|
||||
String.format("%s/roles/%s", this.aws.getBackend(), this.aws.getRole()),
|
||||
vaultOperations.write(String.format("%s/roles/%s", this.aws.getBackend(), this.aws.getRole()),
|
||||
Collections.singletonMap("arn", ARN));
|
||||
|
||||
this.configOperations = new VaultConfigTemplate(vaultOperations,
|
||||
this.vaultProperties);
|
||||
this.configOperations = new VaultConfigTemplate(vaultOperations, this.vaultProperties);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateCredentialsCorrectly() {
|
||||
|
||||
Map<String, Object> secretProperties = this.configOperations
|
||||
.read(forAws(this.aws)).getData();
|
||||
Map<String, Object> secretProperties = this.configOperations.read(forAws(this.aws)).getData();
|
||||
|
||||
assertThat(secretProperties).containsKeys("cloud.aws.credentials.accessKey",
|
||||
"cloud.aws.credentials.secretKey");
|
||||
assertThat(secretProperties).containsKeys("cloud.aws.credentials.accessKey", "cloud.aws.credentials.secretKey");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -39,9 +39,8 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = CustomBootstrapConfiguration.class,
|
||||
properties = { "VaultConfigAwsBootstrapConfigurationTests.custom.config=true",
|
||||
"spring.cloud.vault.aws.role=foo" })
|
||||
@SpringBootTest(classes = CustomBootstrapConfiguration.class, properties = {
|
||||
"VaultConfigAwsBootstrapConfigurationTests.custom.config=true", "spring.cloud.vault.aws.role=foo" })
|
||||
public class VaultConfigAwsBootstrapConfigurationTests extends IntegrationTestSupport {
|
||||
|
||||
@Autowired
|
||||
@@ -68,10 +67,8 @@ public class VaultConfigAwsBootstrapConfigurationTests extends IntegrationTestSu
|
||||
|
||||
return new AwsSecretBackendMetadataFactory() {
|
||||
@Override
|
||||
public SecretBackendMetadata createMetadata(
|
||||
VaultAwsProperties backendDescriptor) {
|
||||
return KeyValueSecretBackendMetadata
|
||||
.create(backendDescriptor.getRole());
|
||||
public SecretBackendMetadata createMetadata(VaultAwsProperties backendDescriptor) {
|
||||
return KeyValueSecretBackendMetadata.create(backendDescriptor.getRole());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -51,9 +51,8 @@ import static org.junit.Assume.assumeTrue;
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = VaultConfigAwsTests.TestApplication.class,
|
||||
properties = { "spring.cloud.vault.aws.enabled=true",
|
||||
"spring.cloud.vault.aws.role=readonly", "cloud.aws.region.auto=false",
|
||||
"cloud.aws.region.static=eu-west-1" })
|
||||
properties = { "spring.cloud.vault.aws.enabled=true", "spring.cloud.vault.aws.role=readonly",
|
||||
"cloud.aws.region.auto=false", "cloud.aws.region.static=eu-west-1" })
|
||||
public class VaultConfigAwsTests {
|
||||
|
||||
private static final String AWS_REGION = "eu-west-1";
|
||||
@@ -76,8 +75,7 @@ public class VaultConfigAwsTests {
|
||||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
|
||||
assumeTrue(StringUtils.hasText(AWS_ACCESS_KEY)
|
||||
&& StringUtils.hasText(AWS_SECRET_KEY));
|
||||
assumeTrue(StringUtils.hasText(AWS_ACCESS_KEY) && StringUtils.hasText(AWS_SECRET_KEY));
|
||||
|
||||
VaultRule vaultRule = new VaultRule();
|
||||
vaultRule.before();
|
||||
|
||||
@@ -43,8 +43,8 @@ class ConsulBackendMetadata implements LeasingSecretBackendMetadata {
|
||||
|
||||
private final ApplicationEventPublisher eventPublisher;
|
||||
|
||||
ConsulBackendMetadata(VaultConsulProperties properties,
|
||||
PropertyTransformer transformer, ApplicationEventPublisher eventPublisher) {
|
||||
ConsulBackendMetadata(VaultConsulProperties properties, PropertyTransformer transformer,
|
||||
ApplicationEventPublisher eventPublisher) {
|
||||
this.properties = properties;
|
||||
this.transformer = transformer;
|
||||
this.eventPublisher = eventPublisher;
|
||||
@@ -52,14 +52,12 @@ class ConsulBackendMetadata implements LeasingSecretBackendMetadata {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return String.format("%s with Role %s", this.properties.getBackend(),
|
||||
this.properties.getRole());
|
||||
return String.format("%s with Role %s", this.properties.getBackend(), this.properties.getRole());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return String.format("%s/creds/%s", this.properties.getBackend(),
|
||||
this.properties.getRole());
|
||||
return String.format("%s/creds/%s", this.properties.getBackend(), this.properties.getRole());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -84,12 +82,10 @@ class ConsulBackendMetadata implements LeasingSecretBackendMetadata {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterRegistration(RequestedSecret secret,
|
||||
SecretLeaseContainer container) {
|
||||
public void afterRegistration(RequestedSecret secret, SecretLeaseContainer container) {
|
||||
container.addLeaseListener(leaseEvent -> {
|
||||
|
||||
if (leaseEvent.getSource() == secret
|
||||
&& leaseEvent instanceof SecretLeaseCreatedEvent) {
|
||||
if (leaseEvent.getSource() == secret && leaseEvent instanceof SecretLeaseCreatedEvent) {
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Publishing a RebindConsulEvent");
|
||||
}
|
||||
|
||||
@@ -38,8 +38,7 @@ public class VaultConfigConsulAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ConsulSecretRebindListener consulSecretRebindListener(
|
||||
ConfigurationPropertiesRebinder rebinder,
|
||||
public ConsulSecretRebindListener consulSecretRebindListener(ConfigurationPropertiesRebinder rebinder,
|
||||
ConfigurableApplicationContext context) {
|
||||
// TODO: some other way? Maybe a BootstrapApplicationContextHolder bean
|
||||
// provided by spring cloud commons
|
||||
@@ -81,8 +80,8 @@ public class VaultConfigConsulAutoConfiguration {
|
||||
boolean success = this.rebinder.rebind(bean);
|
||||
if (this.log.isInfoEnabled()) {
|
||||
this.log.info(String.format(
|
||||
"Attempted to rebind Consul bean '%s' with updated ACL token from vault, success: %s",
|
||||
bean, success));
|
||||
"Attempted to rebind Consul bean '%s' with updated ACL token from vault, success: %s", bean,
|
||||
success));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,8 +41,7 @@ public class VaultConfigConsulBootstrapConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ConsulSecretBackendMetadataFactory consulSecretBackendMetadataFactory(
|
||||
ApplicationContext context) {
|
||||
public ConsulSecretBackendMetadataFactory consulSecretBackendMetadataFactory(ApplicationContext context) {
|
||||
return new ConsulSecretBackendMetadataFactory(context);
|
||||
}
|
||||
|
||||
@@ -85,10 +84,8 @@ public class VaultConfigConsulBootstrapConfiguration {
|
||||
PropertyTransformer transformer = input -> {
|
||||
|
||||
Map<String, Object> transformed = new LinkedHashMap<>();
|
||||
transformed.put("spring.cloud.consul.config.acl-token",
|
||||
input.get("token"));
|
||||
transformed.put("spring.cloud.consul.discovery.acl-token",
|
||||
input.get("token"));
|
||||
transformed.put("spring.cloud.consul.config.acl-token", input.get("token"));
|
||||
transformed.put("spring.cloud.consul.discovery.acl-token", input.get("token"));
|
||||
|
||||
return transformed;
|
||||
};
|
||||
@@ -97,8 +94,7 @@ public class VaultConfigConsulBootstrapConfiguration {
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecretBackendMetadata createMetadata(
|
||||
VaultConsulProperties backendDescriptor) {
|
||||
public SecretBackendMetadata createMetadata(VaultConsulProperties backendDescriptor) {
|
||||
return forConsul(backendDescriptor);
|
||||
}
|
||||
|
||||
|
||||
@@ -57,8 +57,7 @@ public class ConsulSecretIntegrationTests extends IntegrationTestSupport {
|
||||
|
||||
private static final int CONSUL_PORT = 8500;
|
||||
|
||||
private static final String CONNECTION_URL = String.format("%s:%d", CONSUL_HOST,
|
||||
CONSUL_PORT);
|
||||
private static final String CONNECTION_URL = String.format("%s:%d", CONSUL_HOST, CONSUL_PORT);
|
||||
|
||||
private static final String POLICY = "key \"\" { policy = \"read\" }";
|
||||
|
||||
@@ -94,21 +93,19 @@ public class ConsulSecretIntegrationTests extends IntegrationTestSupport {
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.add("X-Consul-Token", CONSUL_ACL_MASTER_TOKEN);
|
||||
HttpEntity<String> requestEntity = new HttpEntity<>(
|
||||
"{\"Name\": \"sample\", \"Type\": \"management\"}", headers);
|
||||
HttpEntity<String> requestEntity = new HttpEntity<>("{\"Name\": \"sample\", \"Type\": \"management\"}",
|
||||
headers);
|
||||
|
||||
try {
|
||||
ResponseEntity<Map<String, String>> tokenResponse = this.restTemplate
|
||||
.exchange("http://{host}:{port}/v1/acl/create", HttpMethod.PUT,
|
||||
requestEntity, STRING_MAP, CONSUL_HOST, CONSUL_PORT);
|
||||
ResponseEntity<Map<String, String>> tokenResponse = this.restTemplate.exchange(
|
||||
"http://{host}:{port}/v1/acl/create", HttpMethod.PUT, requestEntity, STRING_MAP, CONSUL_HOST,
|
||||
CONSUL_PORT);
|
||||
|
||||
Map<String, String> consulAccess = new HashMap<>();
|
||||
consulAccess.put("address", CONNECTION_URL);
|
||||
consulAccess.put("token", tokenResponse.getBody().get("ID"));
|
||||
|
||||
vaultOperations.write(
|
||||
String.format("%s/config/access", this.consul.getBackend()),
|
||||
consulAccess);
|
||||
vaultOperations.write(String.format("%s/config/access", this.consul.getBackend()), consulAccess);
|
||||
}
|
||||
catch (HttpStatusCodeException e) {
|
||||
|
||||
@@ -118,23 +115,17 @@ public class ConsulSecretIntegrationTests extends IntegrationTestSupport {
|
||||
throw e;
|
||||
}
|
||||
|
||||
vaultOperations.write(
|
||||
String.format("%s/roles/%s", this.consul.getBackend(),
|
||||
this.consul.getRole()),
|
||||
Collections.singletonMap("policy",
|
||||
Base64Utils.encodeToString(POLICY.getBytes())));
|
||||
vaultOperations.write(String.format("%s/roles/%s", this.consul.getBackend(), this.consul.getRole()),
|
||||
Collections.singletonMap("policy", Base64Utils.encodeToString(POLICY.getBytes())));
|
||||
|
||||
this.configOperations = new VaultConfigTemplate(vaultOperations,
|
||||
this.vaultProperties);
|
||||
this.configOperations = new VaultConfigTemplate(vaultOperations, this.vaultProperties);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateCredentialsCorrectly() {
|
||||
|
||||
ConsulSecretBackendMetadataFactory factory = new ConsulSecretBackendMetadataFactory(
|
||||
null);
|
||||
Map<String, Object> secretProperties = this.configOperations
|
||||
.read(factory.forConsul(this.consul)).getData();
|
||||
ConsulSecretBackendMetadataFactory factory = new ConsulSecretBackendMetadataFactory(null);
|
||||
Map<String, Object> secretProperties = this.configOperations.read(factory.forConsul(this.consul)).getData();
|
||||
|
||||
assertThat(secretProperties).containsKeys("spring.cloud.consul.config.acl-token",
|
||||
"spring.cloud.consul.discovery.acl-token");
|
||||
|
||||
@@ -64,8 +64,7 @@ public class DiscoveryBootstrapConfigurationTests extends IntegrationTestSupport
|
||||
|
||||
ConsulClient client = new ConsulClient();
|
||||
|
||||
Response<List<CatalogService>> response = client.getCatalogService("vault",
|
||||
QueryParams.DEFAULT);
|
||||
Response<List<CatalogService>> response = client.getCatalogService("vault", QueryParams.DEFAULT);
|
||||
|
||||
if (response.getValue().isEmpty()) {
|
||||
|
||||
|
||||
@@ -42,8 +42,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = CustomBootstrapConfiguration.class,
|
||||
properties = { "VaultConfigConsulBootstrapConfigurationTests.custom.config=true",
|
||||
"spring.cloud.vault.consul.role=foo",
|
||||
"spring.cloud.vault.consul.enabled=true",
|
||||
"spring.cloud.vault.consul.role=foo", "spring.cloud.vault.consul.enabled=true",
|
||||
"spring.cloud.consul.config.enabled=false" })
|
||||
public class VaultConfigConsulBootstrapConfigurationTests extends IntegrationTestSupport {
|
||||
|
||||
@@ -67,15 +66,12 @@ public class VaultConfigConsulBootstrapConfigurationTests extends IntegrationTes
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty("VaultConfigConsulBootstrapConfigurationTests.custom.config")
|
||||
ConsulSecretBackendMetadataFactory customFactory(
|
||||
ConfigurationPropertiesRebinder rebinder) {
|
||||
ConsulSecretBackendMetadataFactory customFactory(ConfigurationPropertiesRebinder rebinder) {
|
||||
|
||||
return new ConsulSecretBackendMetadataFactory(null) {
|
||||
@Override
|
||||
public SecretBackendMetadata createMetadata(
|
||||
VaultConsulProperties backendDescriptor) {
|
||||
return KeyValueSecretBackendMetadata
|
||||
.create(backendDescriptor.getRole());
|
||||
public SecretBackendMetadata createMetadata(VaultConsulProperties backendDescriptor) {
|
||||
return KeyValueSecretBackendMetadata.create(backendDescriptor.getRole());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -61,8 +61,7 @@ import static org.junit.Assume.assumeTrue;
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = VaultConfigConsulTests.TestApplication.class,
|
||||
properties = { "spring.cloud.vault.consul.enabled=true",
|
||||
"spring.cloud.vault.consul.role=readonly",
|
||||
properties = { "spring.cloud.vault.consul.enabled=true", "spring.cloud.vault.consul.role=readonly",
|
||||
"spring.cloud.consul.discovery.catalog-services-watch.enabled=false" })
|
||||
public class VaultConfigConsulTests {
|
||||
|
||||
@@ -70,8 +69,7 @@ public class VaultConfigConsulTests {
|
||||
|
||||
private static final int CONSUL_PORT = 8500;
|
||||
|
||||
private static final String CONNECTION_URL = String.format("%s:%d", CONSUL_HOST,
|
||||
CONSUL_PORT);
|
||||
private static final String CONNECTION_URL = String.format("%s:%d", CONSUL_HOST, CONSUL_PORT);
|
||||
|
||||
private static final String POLICY = "key \"\" { policy = \"read\" }";
|
||||
|
||||
@@ -115,13 +113,13 @@ public class VaultConfigConsulTests {
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.add("X-Consul-Token", CONSUL_ACL_MASTER_TOKEN);
|
||||
HttpEntity<String> requestEntity = new HttpEntity<>(
|
||||
"{\"Name\": \"sample\", \"Type\": \"management\"}", headers);
|
||||
HttpEntity<String> requestEntity = new HttpEntity<>("{\"Name\": \"sample\", \"Type\": \"management\"}",
|
||||
headers);
|
||||
|
||||
try {
|
||||
ResponseEntity<Map<String, String>> tokenResponse = restTemplate.exchange(
|
||||
"http://{host}:{port}/v1/acl/create", HttpMethod.PUT, requestEntity,
|
||||
STRING_MAP, CONSUL_HOST, CONSUL_PORT);
|
||||
"http://{host}:{port}/v1/acl/create", HttpMethod.PUT, requestEntity, STRING_MAP, CONSUL_HOST,
|
||||
CONSUL_PORT);
|
||||
|
||||
Map<String, String> consulAccess = new HashMap<>();
|
||||
consulAccess.put("address", CONNECTION_URL);
|
||||
@@ -154,10 +152,8 @@ public class VaultConfigConsulTests {
|
||||
|
||||
Thread.sleep(8_000L);
|
||||
|
||||
assertThat(this.configProperties.getAclToken()).isNotEmpty()
|
||||
.isNotEqualTo(configToken);
|
||||
assertThat(this.discoveryProperties.getAclToken()).isNotEmpty()
|
||||
.isNotEqualTo(discoveryToken);
|
||||
assertThat(this.configProperties.getAclToken()).isNotEmpty().isNotEqualTo(configToken);
|
||||
assertThat(this.discoveryProperties.getAclToken()).isNotEmpty().isNotEqualTo(discoveryToken);
|
||||
}
|
||||
|
||||
@SpringBootApplication
|
||||
|
||||
@@ -39,9 +39,8 @@ import org.springframework.vault.core.util.PropertyTransformer;
|
||||
* @author Sebastien Nahelou
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableConfigurationProperties({ VaultMySqlProperties.class,
|
||||
VaultPostgreSqlProperties.class, VaultCassandraProperties.class,
|
||||
VaultMongoProperties.class, VaultElasticsearchProperties.class,
|
||||
@EnableConfigurationProperties({ VaultMySqlProperties.class, VaultPostgreSqlProperties.class,
|
||||
VaultCassandraProperties.class, VaultMongoProperties.class, VaultElasticsearchProperties.class,
|
||||
VaultDatabaseProperties.class })
|
||||
public class VaultConfigDatabaseBootstrapConfiguration {
|
||||
|
||||
@@ -67,32 +66,26 @@ public class VaultConfigDatabaseBootstrapConfiguration {
|
||||
* @param properties must not be {@literal null}.
|
||||
* @return the {@link SecretBackendMetadata}
|
||||
*/
|
||||
static SecretBackendMetadata forDatabase(
|
||||
final DatabaseSecretProperties properties) {
|
||||
static SecretBackendMetadata forDatabase(final DatabaseSecretProperties properties) {
|
||||
|
||||
Assert.notNull(properties, "DatabaseSecretProperties must not be null");
|
||||
|
||||
PropertyNameTransformer transformer = new PropertyNameTransformer();
|
||||
transformer.addKeyTransformation("username",
|
||||
properties.getUsernameProperty());
|
||||
transformer.addKeyTransformation("password",
|
||||
properties.getPasswordProperty());
|
||||
transformer.addKeyTransformation("username", properties.getUsernameProperty());
|
||||
transformer.addKeyTransformation("password", properties.getPasswordProperty());
|
||||
|
||||
return new SecretBackendMetadata() {
|
||||
|
||||
private final String credPath = properties.isStaticRole() ? "static-creds"
|
||||
: "creds";
|
||||
private final String credPath = properties.isStaticRole() ? "static-creds" : "creds";
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return String.format("%s with Role %s", properties.getBackend(),
|
||||
properties.getRole());
|
||||
return String.format("%s with Role %s", properties.getBackend(), properties.getRole());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return String.format("%s/%s/%s", properties.getBackend(),
|
||||
this.credPath, properties.getRole());
|
||||
return String.format("%s/%s/%s", properties.getBackend(), this.credPath, properties.getRole());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -105,16 +98,14 @@ public class VaultConfigDatabaseBootstrapConfiguration {
|
||||
|
||||
Map<String, String> variables = new HashMap<>();
|
||||
variables.put("backend", properties.getBackend());
|
||||
variables.put("key",
|
||||
String.format("%s/%s", this.credPath, properties.getRole()));
|
||||
variables.put("key", String.format("%s/%s", this.credPath, properties.getRole()));
|
||||
return variables;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecretBackendMetadata createMetadata(
|
||||
DatabaseSecretProperties backendDescriptor) {
|
||||
public SecretBackendMetadata createMetadata(DatabaseSecretProperties backendDescriptor) {
|
||||
return forDatabase(backendDescriptor);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,8 +31,7 @@ import org.springframework.validation.annotation.Validated;
|
||||
@ConfigurationProperties("spring.cloud.vault.mysql")
|
||||
@Validated
|
||||
@Deprecated
|
||||
public class VaultMySqlProperties
|
||||
implements DatabaseSecretProperties, VaultSecretBackendDescriptor {
|
||||
public class VaultMySqlProperties implements DatabaseSecretProperties, VaultSecretBackendDescriptor {
|
||||
|
||||
/**
|
||||
* Enable mysql backend usage.
|
||||
|
||||
@@ -84,30 +84,25 @@ public class CassandraSecretIntegrationTests extends IntegrationTestSupport {
|
||||
connection.put("password", CASSANDRA_PASSWORD);
|
||||
connection.put("protocol_version", 3);
|
||||
|
||||
vaultOperations.write(
|
||||
String.format("%s/config/connection", this.cassandra.getBackend()),
|
||||
connection);
|
||||
vaultOperations.write(String.format("%s/config/connection", this.cassandra.getBackend()), connection);
|
||||
|
||||
Map<String, String> role = new HashMap<>();
|
||||
|
||||
role.put("creation_cql", CREATE_USER_AND_GRANT_CQL);
|
||||
role.put("consistency", "All");
|
||||
|
||||
vaultOperations.write(String.format("%s/roles/%s", this.cassandra.getBackend(),
|
||||
this.cassandra.getRole()), role);
|
||||
vaultOperations.write(String.format("%s/roles/%s", this.cassandra.getBackend(), this.cassandra.getRole()),
|
||||
role);
|
||||
|
||||
this.configOperations = new VaultConfigTemplate(vaultOperations,
|
||||
this.vaultProperties);
|
||||
this.configOperations = new VaultConfigTemplate(vaultOperations, this.vaultProperties);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateCredentialsCorrectly() {
|
||||
|
||||
Map<String, Object> secretProperties = this.configOperations
|
||||
.read(forDatabase(this.cassandra)).getData();
|
||||
Map<String, Object> secretProperties = this.configOperations.read(forDatabase(this.cassandra)).getData();
|
||||
|
||||
assertThat(secretProperties).containsKeys("spring.data.cassandra.username",
|
||||
"spring.data.cassandra.password");
|
||||
assertThat(secretProperties).containsKeys("spring.data.cassandra.username", "spring.data.cassandra.password");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -63,8 +63,7 @@ public class ElasticsearchSecretIntegrationTests extends IntegrationTestSupport
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
assumeTrue(CanConnect
|
||||
.to(new InetSocketAddress(ELASTICSEARCH_HOST, ELASTICSEARCH_PORT)));
|
||||
assumeTrue(CanConnect.to(new InetSocketAddress(ELASTICSEARCH_HOST, ELASTICSEARCH_PORT)));
|
||||
assumeTrue(prepare().getVersion().isGreaterThanOrEqualTo(Version.parse("1.3.0")));
|
||||
|
||||
this.elasticsearch.setEnabled(true);
|
||||
@@ -82,16 +81,13 @@ public class ElasticsearchSecretIntegrationTests extends IntegrationTestSupport
|
||||
config.put("allowed_roles", "readonly");
|
||||
config.put("username", "elastic");
|
||||
config.put("password", "elastic");
|
||||
config.put("url",
|
||||
String.format("http://%s:%d", ELASTICSEARCH_HOST, ELASTICSEARCH_PORT));
|
||||
config.put("url", String.format("http://%s:%d", ELASTICSEARCH_HOST, ELASTICSEARCH_PORT));
|
||||
|
||||
config.put("ca_cert", String.format("%s/elastic-stack-ca.crt", ES_HOME));
|
||||
config.put("client_cert", String.format("%s/elastic-certificates.crt", ES_HOME));
|
||||
config.put("client_key", String.format("%s/elastic-certificates.key", ES_HOME));
|
||||
|
||||
vaultOperations.write(
|
||||
String.format("%s/config/%s", this.elasticsearch.getBackend(), database),
|
||||
config);
|
||||
vaultOperations.write(String.format("%s/config/%s", this.elasticsearch.getBackend(), database), config);
|
||||
|
||||
Map<String, Object> role = new LinkedHashMap<>();
|
||||
role.put("db_name", database);
|
||||
@@ -99,18 +95,15 @@ public class ElasticsearchSecretIntegrationTests extends IntegrationTestSupport
|
||||
"{\"elasticsearch_role_definition\": {\"indices\": [{\"names\":[\"*\"], \"privileges\":[\"read\"]}]}}");
|
||||
role.put("default_ttl", "1h");
|
||||
|
||||
vaultOperations.write(this.elasticsearch.getBackend() + "/roles/"
|
||||
+ this.elasticsearch.getRole(), role);
|
||||
vaultOperations.write(this.elasticsearch.getBackend() + "/roles/" + this.elasticsearch.getRole(), role);
|
||||
|
||||
this.configOperations = new VaultConfigTemplate(vaultOperations,
|
||||
this.vaultProperties);
|
||||
this.configOperations = new VaultConfigTemplate(vaultOperations, this.vaultProperties);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateCredentialsCorrectly() {
|
||||
|
||||
Map<String, Object> secretProperties = this.configOperations
|
||||
.read(forDatabase(this.elasticsearch)).getData();
|
||||
Map<String, Object> secretProperties = this.configOperations.read(forDatabase(this.elasticsearch)).getData();
|
||||
|
||||
assertThat(secretProperties).containsKeys("spring.elasticsearch.rest.username",
|
||||
"spring.elasticsearch.rest.password");
|
||||
|
||||
@@ -49,9 +49,8 @@ public class MongoSecretIntegrationTests extends IntegrationTestSupport {
|
||||
|
||||
private static final String MONGODB_HOST = "localhost";
|
||||
|
||||
private static final String ROOT_CREDENTIALS = String.format(
|
||||
"mongodb://springvault:springvault@%s:%d/admin?ssl=false", MONGODB_HOST,
|
||||
MONGODB_PORT);
|
||||
private static final String ROOT_CREDENTIALS = String
|
||||
.format("mongodb://springvault:springvault@%s:%d/admin?ssl=false", MONGODB_HOST, MONGODB_PORT);
|
||||
|
||||
private static final String ROLES = "[ \"readWrite\", { \"role\": \"read\", \"db\": \"admin\" } ]";
|
||||
|
||||
@@ -79,29 +78,24 @@ public class MongoSecretIntegrationTests extends IntegrationTestSupport {
|
||||
|
||||
VaultOperations vaultOperations = this.vaultRule.prepare().getVaultOperations();
|
||||
|
||||
vaultOperations.write(
|
||||
String.format("%s/config/connection", this.mongodb.getBackend()),
|
||||
vaultOperations.write(String.format("%s/config/connection", this.mongodb.getBackend()),
|
||||
Collections.singletonMap("uri", ROOT_CREDENTIALS));
|
||||
|
||||
Map<String, String> role = new HashMap<>();
|
||||
role.put("db", "admin");
|
||||
role.put("roles", ROLES);
|
||||
|
||||
vaultOperations.write(String.format("%s/roles/%s", this.mongodb.getBackend(),
|
||||
this.mongodb.getRole()), role);
|
||||
vaultOperations.write(String.format("%s/roles/%s", this.mongodb.getBackend(), this.mongodb.getRole()), role);
|
||||
|
||||
this.configOperations = new VaultConfigTemplate(vaultOperations,
|
||||
this.vaultProperties);
|
||||
this.configOperations = new VaultConfigTemplate(vaultOperations, this.vaultProperties);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateCredentialsCorrectly() {
|
||||
|
||||
Map<String, Object> secretProperties = this.configOperations
|
||||
.read(forDatabase(this.mongodb)).getData();
|
||||
Map<String, Object> secretProperties = this.configOperations.read(forDatabase(this.mongodb)).getData();
|
||||
|
||||
assertThat(secretProperties).containsKeys("spring.data.mongodb.username",
|
||||
"spring.data.mongodb.password");
|
||||
assertThat(secretProperties).containsKeys("spring.data.mongodb.username", "spring.data.mongodb.password");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -49,8 +49,8 @@ public class MySqlDatabaseSecretIntegrationTests extends IntegrationTestSupport
|
||||
|
||||
private static final String MYSQL_HOST = "localhost";
|
||||
|
||||
private static final String ROOT_CREDENTIALS = String
|
||||
.format("springvault:springvault@tcp(%s:%d)/", MYSQL_HOST, MYSQL_PORT);
|
||||
private static final String ROOT_CREDENTIALS = String.format("springvault:springvault@tcp(%s:%d)/", MYSQL_HOST,
|
||||
MYSQL_PORT);
|
||||
|
||||
private static final String CREATE_USER_AND_GRANT_SQL = "CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';"
|
||||
+ "GRANT SELECT ON *.* TO '{{name}}'@'%';";
|
||||
@@ -86,28 +86,23 @@ public class MySqlDatabaseSecretIntegrationTests extends IntegrationTestSupport
|
||||
config.put("connection_url", ROOT_CREDENTIALS);
|
||||
config.put("allowed_roles", "readonly");
|
||||
|
||||
vaultOperations.write(String.format("%s/config/mysql", this.mySql.getBackend()),
|
||||
config);
|
||||
vaultOperations.write(String.format("%s/config/mysql", this.mySql.getBackend()), config);
|
||||
|
||||
Map<String, String> body = new HashMap<>();
|
||||
body.put("db_name", "mysql");
|
||||
body.put("creation_statements", CREATE_USER_AND_GRANT_SQL);
|
||||
|
||||
vaultOperations.write(String.format("%s/roles/%s", this.mySql.getBackend(),
|
||||
this.mySql.getRole()), body);
|
||||
vaultOperations.write(String.format("%s/roles/%s", this.mySql.getBackend(), this.mySql.getRole()), body);
|
||||
|
||||
this.configOperations = new VaultConfigTemplate(vaultOperations,
|
||||
this.vaultProperties);
|
||||
this.configOperations = new VaultConfigTemplate(vaultOperations, this.vaultProperties);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateCredentialsCorrectly() {
|
||||
|
||||
Map<String, Object> secretProperties = this.configOperations
|
||||
.read(forDatabase(this.mySql)).getData();
|
||||
Map<String, Object> secretProperties = this.configOperations.read(forDatabase(this.mySql)).getData();
|
||||
|
||||
assertThat(secretProperties).containsKeys("spring.datasource.username",
|
||||
"spring.datasource.password");
|
||||
assertThat(secretProperties).containsKeys("spring.datasource.username", "spring.datasource.password");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -47,8 +47,8 @@ public class MySqlSecretIntegrationTests extends IntegrationTestSupport {
|
||||
|
||||
private static final String MYSQL_HOST = "localhost";
|
||||
|
||||
private static final String ROOT_CREDENTIALS = String
|
||||
.format("springvault:springvault@tcp(%s:%d)/", MYSQL_HOST, MYSQL_PORT);
|
||||
private static final String ROOT_CREDENTIALS = String.format("springvault:springvault@tcp(%s:%d)/", MYSQL_HOST,
|
||||
MYSQL_PORT);
|
||||
|
||||
private static final String CREATE_USER_AND_GRANT_SQL = "CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';"
|
||||
+ "GRANT SELECT ON *.* TO '{{name}}'@'%';";
|
||||
@@ -77,27 +77,21 @@ public class MySqlSecretIntegrationTests extends IntegrationTestSupport {
|
||||
|
||||
VaultOperations vaultOperations = this.vaultRule.prepare().getVaultOperations();
|
||||
|
||||
vaultOperations.write(
|
||||
String.format("%s/config/connection", this.mySql.getBackend()),
|
||||
vaultOperations.write(String.format("%s/config/connection", this.mySql.getBackend()),
|
||||
Collections.singletonMap("connection_url", ROOT_CREDENTIALS));
|
||||
|
||||
vaultOperations.write(
|
||||
String.format("%s/roles/%s", this.mySql.getBackend(),
|
||||
this.mySql.getRole()),
|
||||
vaultOperations.write(String.format("%s/roles/%s", this.mySql.getBackend(), this.mySql.getRole()),
|
||||
Collections.singletonMap("sql", CREATE_USER_AND_GRANT_SQL));
|
||||
|
||||
this.configOperations = new VaultConfigTemplate(vaultOperations,
|
||||
this.vaultProperties);
|
||||
this.configOperations = new VaultConfigTemplate(vaultOperations, this.vaultProperties);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateCredentialsCorrectly() {
|
||||
|
||||
Map<String, Object> secretProperties = this.configOperations
|
||||
.read(forDatabase(this.mySql)).getData();
|
||||
Map<String, Object> secretProperties = this.configOperations.read(forDatabase(this.mySql)).getData();
|
||||
|
||||
assertThat(secretProperties).containsKeys("spring.datasource.username",
|
||||
"spring.datasource.password");
|
||||
assertThat(secretProperties).containsKeys("spring.datasource.username", "spring.datasource.password");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -50,8 +50,7 @@ public class PostgreSqlSecretIntegrationTests extends IntegrationTestSupport {
|
||||
private static final int POSTGRES_PORT = 5432;
|
||||
|
||||
private static final String CONNECTION_URL = String.format(
|
||||
"postgresql://springvault:springvault@%s:%d/postgres?sslmode=disable",
|
||||
POSTGRES_HOST, POSTGRES_PORT);
|
||||
"postgresql://springvault:springvault@%s:%d/postgres?sslmode=disable", POSTGRES_HOST, POSTGRES_PORT);
|
||||
|
||||
private static final String CREATE_USER_AND_GRANT_SQL = "CREATE ROLE \"{{name}}\" WITH "
|
||||
+ "LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}';\n"
|
||||
@@ -81,28 +80,22 @@ public class PostgreSqlSecretIntegrationTests extends IntegrationTestSupport {
|
||||
|
||||
VaultOperations vaultOperations = this.vaultRule.prepare().getVaultOperations();
|
||||
|
||||
vaultOperations.write(
|
||||
String.format("%s/config/connection", this.postgreSql.getBackend()),
|
||||
vaultOperations.write(String.format("%s/config/connection", this.postgreSql.getBackend()),
|
||||
Collections.singletonMap("connection_url", CONNECTION_URL));
|
||||
|
||||
vaultOperations.write(
|
||||
String.format("%s/roles/%s", this.postgreSql.getBackend(),
|
||||
this.postgreSql.getRole()),
|
||||
vaultOperations.write(String.format("%s/roles/%s", this.postgreSql.getBackend(), this.postgreSql.getRole()),
|
||||
Collections.singletonMap("sql", CREATE_USER_AND_GRANT_SQL));
|
||||
|
||||
this.configOperations = new VaultConfigTemplate(vaultOperations,
|
||||
this.vaultProperties);
|
||||
this.configOperations = new VaultConfigTemplate(vaultOperations, this.vaultProperties);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateCredentialsCorrectly() {
|
||||
|
||||
Map<String, Object> secretProperties = this.configOperations
|
||||
.read(forDatabase(this.postgreSql)).getData();
|
||||
Map<String, Object> secretProperties = this.configOperations.read(forDatabase(this.postgreSql)).getData();
|
||||
|
||||
assertThat(secretProperties).containsKeys("spring.datasource.username",
|
||||
"spring.datasource.password");
|
||||
assertThat(secretProperties).containsKeys("spring.datasource.username", "spring.datasource.password");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -48,8 +48,7 @@ import static org.junit.Assume.assumeTrue;
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = VaultConfigCassandraTests.TestApplication.class,
|
||||
properties = { "spring.cloud.vault.cassandra.enabled=true",
|
||||
"spring.cloud.vault.cassandra.role=readonly",
|
||||
properties = { "spring.cloud.vault.cassandra.enabled=true", "spring.cloud.vault.cassandra.role=readonly",
|
||||
"spring.data.cassandra.jmx-enabled=false" })
|
||||
public class VaultConfigCassandraTests {
|
||||
|
||||
@@ -96,8 +95,7 @@ public class VaultConfigCassandraTests {
|
||||
connection.put("password", CASSANDRA_PASSWORD);
|
||||
connection.put("protocol_version", 3);
|
||||
|
||||
vaultOperations.write(String.format("%s/config/connection", "cassandra"),
|
||||
connection);
|
||||
vaultOperations.write(String.format("%s/config/connection", "cassandra"), connection);
|
||||
|
||||
Map<String, String> role = new HashMap<>();
|
||||
|
||||
|
||||
@@ -39,11 +39,10 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = CustomBootstrapConfiguration.class, properties = {
|
||||
"VaultConfigDatabaseBootstrapConfigurationTests.custom.config=true",
|
||||
"spring.cloud.vault.mysql.role=foo", "spring.cloud.vault.mysql.enabled=true" })
|
||||
public class VaultConfigDatabaseBootstrapConfigurationTests
|
||||
extends IntegrationTestSupport {
|
||||
@SpringBootTest(classes = CustomBootstrapConfiguration.class,
|
||||
properties = { "VaultConfigDatabaseBootstrapConfigurationTests.custom.config=true",
|
||||
"spring.cloud.vault.mysql.role=foo", "spring.cloud.vault.mysql.enabled=true" })
|
||||
public class VaultConfigDatabaseBootstrapConfigurationTests extends IntegrationTestSupport {
|
||||
|
||||
@Autowired
|
||||
DatabaseSecretBackendMetadataFactory factory;
|
||||
@@ -70,10 +69,8 @@ public class VaultConfigDatabaseBootstrapConfigurationTests
|
||||
|
||||
return new DatabaseSecretBackendMetadataFactory() {
|
||||
@Override
|
||||
public SecretBackendMetadata createMetadata(
|
||||
DatabaseSecretProperties backendDescriptor) {
|
||||
return KeyValueSecretBackendMetadata
|
||||
.create(backendDescriptor.getRole());
|
||||
public SecretBackendMetadata createMetadata(DatabaseSecretProperties backendDescriptor) {
|
||||
return KeyValueSecretBackendMetadata.create(backendDescriptor.getRole());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -53,19 +53,16 @@ import static org.junit.Assume.assumeTrue;
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = VaultConfigMongoTests.TestApplication.class,
|
||||
properties = { "spring.cloud.vault.mongodb.enabled=true",
|
||||
"spring.cloud.vault.mongodb.role=readonly",
|
||||
"spring.data.mongodb.url=mongodb://localhost",
|
||||
"spring.data.mongodb.database=admin" })
|
||||
properties = { "spring.cloud.vault.mongodb.enabled=true", "spring.cloud.vault.mongodb.role=readonly",
|
||||
"spring.data.mongodb.url=mongodb://localhost", "spring.data.mongodb.database=admin" })
|
||||
public class VaultConfigMongoTests {
|
||||
|
||||
private static final int MONGODB_PORT = 27017;
|
||||
|
||||
private static final String MONGODB_HOST = "localhost";
|
||||
|
||||
private static final String ROOT_CREDENTIALS = String.format(
|
||||
"mongodb://springvault:springvault@%s:%d/admin?ssl=false", MONGODB_HOST,
|
||||
MONGODB_PORT);
|
||||
private static final String ROOT_CREDENTIALS = String
|
||||
.format("mongodb://springvault:springvault@%s:%d/admin?ssl=false", MONGODB_HOST, MONGODB_PORT);
|
||||
|
||||
private static final String ROLES = "[ \"readWrite\", { \"role\": \"read\", \"db\": \"admin\" } ]";
|
||||
|
||||
@@ -89,8 +86,7 @@ public class VaultConfigMongoTests {
|
||||
VaultRule vaultRule = new VaultRule();
|
||||
vaultRule.before();
|
||||
|
||||
assumeTrue(vaultRule.prepare().getVersion()
|
||||
.isGreaterThanOrEqualTo(Version.parse("0.6.2")));
|
||||
assumeTrue(vaultRule.prepare().getVersion().isGreaterThanOrEqualTo(Version.parse("0.6.2")));
|
||||
|
||||
if (!vaultRule.prepare().hasSecretBackend("mongodb")) {
|
||||
vaultRule.prepare().mountSecret("mongodb");
|
||||
@@ -98,8 +94,7 @@ public class VaultConfigMongoTests {
|
||||
|
||||
VaultOperations vaultOperations = vaultRule.prepare().getVaultOperations();
|
||||
|
||||
vaultOperations.write("mongodb/config/connection",
|
||||
Collections.singletonMap("uri", ROOT_CREDENTIALS));
|
||||
vaultOperations.write("mongodb/config/connection", Collections.singletonMap("uri", ROOT_CREDENTIALS));
|
||||
|
||||
Map<String, String> role = new HashMap<>();
|
||||
role.put("db", "admin");
|
||||
@@ -113,8 +108,7 @@ public class VaultConfigMongoTests {
|
||||
|
||||
MongoDatabase mongoDatabase = this.mongoClient.getDatabase("admin");
|
||||
|
||||
List<Document> collections = mongoDatabase.listCollections()
|
||||
.into(new ArrayList<>());
|
||||
List<Document> collections = mongoDatabase.listCollections().into(new ArrayList<>());
|
||||
|
||||
for (Document collection : collections) {
|
||||
if (collection.getString("name").equals("hello")) {
|
||||
|
||||
@@ -51,8 +51,7 @@ import static org.junit.Assume.assumeTrue;
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = VaultConfigMySqlDatabaseTests.TestApplication.class,
|
||||
properties = { "spring.cloud.vault.database.enabled=true",
|
||||
"spring.cloud.vault.database.role=readonly",
|
||||
properties = { "spring.cloud.vault.database.enabled=true", "spring.cloud.vault.database.role=readonly",
|
||||
"spring.datasource.url=jdbc:mysql://localhost:3306/mysql?useSSL=false&serverTimezone=UTC",
|
||||
"spring.main.allow-bean-definition-overriding=true" })
|
||||
public class VaultConfigMySqlDatabaseTests {
|
||||
@@ -61,8 +60,8 @@ public class VaultConfigMySqlDatabaseTests {
|
||||
|
||||
private static final String MYSQL_HOST = "localhost";
|
||||
|
||||
private static final String ROOT_CREDENTIALS = String
|
||||
.format("springvault:springvault@tcp(%s:%d)/", MYSQL_HOST, MYSQL_PORT);
|
||||
private static final String ROOT_CREDENTIALS = String.format("springvault:springvault@tcp(%s:%d)/", MYSQL_HOST,
|
||||
MYSQL_PORT);
|
||||
|
||||
private static final String CREATE_USER_AND_GRANT_SQL = "CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';"
|
||||
+ "GRANT SELECT ON *.* TO '{{name}}'@'%';";
|
||||
@@ -86,8 +85,7 @@ public class VaultConfigMySqlDatabaseTests {
|
||||
vaultRule.before();
|
||||
|
||||
assumeTrue(CanConnect.to(new InetSocketAddress(MYSQL_HOST, MYSQL_PORT)));
|
||||
assumeTrue(vaultRule.prepare().getVersion()
|
||||
.isGreaterThanOrEqualTo(Version.parse("0.7.1")));
|
||||
assumeTrue(vaultRule.prepare().getVersion().isGreaterThanOrEqualTo(Version.parse("0.7.1")));
|
||||
|
||||
if (!vaultRule.prepare().hasSecretBackend("database")) {
|
||||
vaultRule.prepare().mountSecret("database");
|
||||
@@ -118,8 +116,7 @@ public class VaultConfigMySqlDatabaseTests {
|
||||
@Test
|
||||
public void shouldConnectUsingJdbcUrlConnection() throws SQLException {
|
||||
|
||||
String url = String.format("jdbc:mysql://%s?useSSL=false&serverTimezone=UTC",
|
||||
MYSQL_HOST);
|
||||
String url = String.format("jdbc:mysql://%s?useSSL=false&serverTimezone=UTC", MYSQL_HOST);
|
||||
DriverManager.getConnection(url, this.username, this.password).close();
|
||||
}
|
||||
|
||||
|
||||
@@ -48,18 +48,18 @@ import static org.junit.Assume.assumeTrue;
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = VaultConfigMySqlTests.TestApplication.class, properties = {
|
||||
"spring.cloud.vault.mysql.enabled=true", "spring.cloud.vault.mysql.role=readonly",
|
||||
"spring.datasource.url=jdbc:mysql://localhost:3306/mysql?useSSL=false&serverTimezone=UTC",
|
||||
"spring.main.allow-bean-definition-overriding=true" })
|
||||
@SpringBootTest(classes = VaultConfigMySqlTests.TestApplication.class,
|
||||
properties = { "spring.cloud.vault.mysql.enabled=true", "spring.cloud.vault.mysql.role=readonly",
|
||||
"spring.datasource.url=jdbc:mysql://localhost:3306/mysql?useSSL=false&serverTimezone=UTC",
|
||||
"spring.main.allow-bean-definition-overriding=true" })
|
||||
public class VaultConfigMySqlTests {
|
||||
|
||||
private static final int MYSQL_PORT = 3306;
|
||||
|
||||
private static final String MYSQL_HOST = "localhost";
|
||||
|
||||
private static final String ROOT_CREDENTIALS = String
|
||||
.format("springvault:springvault@tcp(%s:%d)/", MYSQL_HOST, MYSQL_PORT);
|
||||
private static final String ROOT_CREDENTIALS = String.format("springvault:springvault@tcp(%s:%d)/", MYSQL_HOST,
|
||||
MYSQL_PORT);
|
||||
|
||||
private static final String CREATE_USER_AND_GRANT_SQL = "CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';"
|
||||
+ "GRANT SELECT ON *.* TO '{{name}}'@'%';";
|
||||
@@ -90,11 +90,9 @@ public class VaultConfigMySqlTests {
|
||||
|
||||
VaultOperations vaultOperations = vaultRule.prepare().getVaultOperations();
|
||||
|
||||
vaultOperations.write("mysql/config/connection",
|
||||
Collections.singletonMap("connection_url", ROOT_CREDENTIALS));
|
||||
vaultOperations.write("mysql/config/connection", Collections.singletonMap("connection_url", ROOT_CREDENTIALS));
|
||||
|
||||
vaultOperations.write("mysql/roles/readonly",
|
||||
Collections.singletonMap("sql", CREATE_USER_AND_GRANT_SQL));
|
||||
vaultOperations.write("mysql/roles/readonly", Collections.singletonMap("sql", CREATE_USER_AND_GRANT_SQL));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -106,8 +104,7 @@ public class VaultConfigMySqlTests {
|
||||
@Test
|
||||
public void shouldConnectUsingJdbcUrlConnection() throws SQLException {
|
||||
|
||||
String url = String.format("jdbc:mysql://%s?useSSL=false&serverTimezone=UTC",
|
||||
MYSQL_HOST);
|
||||
String url = String.format("jdbc:mysql://%s?useSSL=false&serverTimezone=UTC", MYSQL_HOST);
|
||||
DriverManager.getConnection(url, this.username, this.password).close();
|
||||
}
|
||||
|
||||
|
||||
@@ -50,11 +50,10 @@ import static org.junit.Assume.assumeTrue;
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = VaultConfigPostgreSqlTests.TestApplication.class, properties = {
|
||||
"spring.cloud.vault.postgresql.enabled=true",
|
||||
"spring.cloud.vault.postgresql.role=readonly",
|
||||
"spring.datasource.url=jdbc:postgresql://localhost:5432/postgres?ssl=false",
|
||||
"spring.main.allow-bean-definition-overriding=true" })
|
||||
@SpringBootTest(classes = VaultConfigPostgreSqlTests.TestApplication.class,
|
||||
properties = { "spring.cloud.vault.postgresql.enabled=true", "spring.cloud.vault.postgresql.role=readonly",
|
||||
"spring.datasource.url=jdbc:postgresql://localhost:5432/postgres?ssl=false",
|
||||
"spring.main.allow-bean-definition-overriding=true" })
|
||||
public class VaultConfigPostgreSqlTests {
|
||||
|
||||
private static final String POSTGRES_HOST = "localhost";
|
||||
@@ -62,8 +61,7 @@ public class VaultConfigPostgreSqlTests {
|
||||
private static final int POSTGRES_PORT = 5432;
|
||||
|
||||
private static final String CONNECTION_URL = String.format(
|
||||
"postgresql://springvault:springvault@%s:%d/postgres?sslmode=disable",
|
||||
POSTGRES_HOST, POSTGRES_PORT);
|
||||
"postgresql://springvault:springvault@%s:%d/postgres?sslmode=disable", POSTGRES_HOST, POSTGRES_PORT);
|
||||
|
||||
private static final String CREATE_USER_AND_GRANT_SQL = "CREATE ROLE \"{{name}}\" WITH "
|
||||
+ "LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}';\n"
|
||||
@@ -98,8 +96,7 @@ public class VaultConfigPostgreSqlTests {
|
||||
vaultOperations.write("postgresql/config/connection",
|
||||
Collections.singletonMap("connection_url", CONNECTION_URL));
|
||||
|
||||
vaultOperations.write("postgresql/roles/readonly",
|
||||
Collections.singletonMap("sql", CREATE_USER_AND_GRANT_SQL));
|
||||
vaultOperations.write("postgresql/roles/readonly", Collections.singletonMap("sql", CREATE_USER_AND_GRANT_SQL));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -114,8 +111,7 @@ public class VaultConfigPostgreSqlTests {
|
||||
@Test
|
||||
public void shouldConnectUsingJdbcUrlConnection() throws SQLException {
|
||||
|
||||
String url = String.format("jdbc:postgresql://%s:%d/postgres?ssl=false",
|
||||
POSTGRES_HOST, POSTGRES_PORT);
|
||||
String url = String.format("jdbc:postgresql://%s:%d/postgres?ssl=false", POSTGRES_HOST, POSTGRES_PORT);
|
||||
DriverManager.getConnection(url, this.username, this.password).close();
|
||||
}
|
||||
|
||||
|
||||
@@ -66,29 +66,24 @@ public class VaultConfigRabbitMqBootstrapConfiguration {
|
||||
* @param properties must not be {@literal null}.
|
||||
* @return the {@link SecretBackendMetadata}
|
||||
*/
|
||||
static SecretBackendMetadata forRabbitMq(
|
||||
final VaultRabbitMqProperties properties) {
|
||||
static SecretBackendMetadata forRabbitMq(final VaultRabbitMqProperties properties) {
|
||||
|
||||
Assert.notNull(properties, "VaultRabbitMqProperties must not be null");
|
||||
|
||||
PropertyNameTransformer transformer = new PropertyNameTransformer();
|
||||
transformer.addKeyTransformation("username",
|
||||
properties.getUsernameProperty());
|
||||
transformer.addKeyTransformation("password",
|
||||
properties.getPasswordProperty());
|
||||
transformer.addKeyTransformation("username", properties.getUsernameProperty());
|
||||
transformer.addKeyTransformation("password", properties.getPasswordProperty());
|
||||
|
||||
return new SecretBackendMetadata() {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return String.format("%s with Role %s", properties.getBackend(),
|
||||
properties.getRole());
|
||||
return String.format("%s with Role %s", properties.getBackend(), properties.getRole());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return String.format("%s/creds/%s", properties.getBackend(),
|
||||
properties.getRole());
|
||||
return String.format("%s/creds/%s", properties.getBackend(), properties.getRole());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -110,8 +105,7 @@ public class VaultConfigRabbitMqBootstrapConfiguration {
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecretBackendMetadata createMetadata(
|
||||
VaultRabbitMqProperties backendDescriptor) {
|
||||
public SecretBackendMetadata createMetadata(VaultRabbitMqProperties backendDescriptor) {
|
||||
return forRabbitMq(backendDescriptor);
|
||||
}
|
||||
|
||||
|
||||
@@ -52,8 +52,8 @@ public class RabbitMqSecretIntegrationTests extends IntegrationTestSupport {
|
||||
|
||||
private static final String RABBITMQ_PASSWORD = "guest";
|
||||
|
||||
private static final String RABBITMQ_URI = String.format("http://%s:%d",
|
||||
RABBITMQ_HOST, RABBITMQ_HTTP_MANAGEMENT_PORT);
|
||||
private static final String RABBITMQ_URI = String.format("http://%s:%d", RABBITMQ_HOST,
|
||||
RABBITMQ_HTTP_MANAGEMENT_PORT);
|
||||
|
||||
private static final String VHOSTS_ROLE = "{\"/\":{\"write\": \".*\", \"read\": \".*\"}}";
|
||||
|
||||
@@ -69,8 +69,7 @@ public class RabbitMqSecretIntegrationTests extends IntegrationTestSupport {
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
assumeTrue(CanConnect
|
||||
.to(new InetSocketAddress(RABBITMQ_HOST, RABBITMQ_HTTP_MANAGEMENT_PORT)));
|
||||
assumeTrue(CanConnect.to(new InetSocketAddress(RABBITMQ_HOST, RABBITMQ_HTTP_MANAGEMENT_PORT)));
|
||||
assumeTrue(prepare().getVersion().isGreaterThanOrEqualTo(Version.parse("0.6.2")));
|
||||
|
||||
this.rabbitmq.setEnabled(true);
|
||||
@@ -87,27 +86,20 @@ public class RabbitMqSecretIntegrationTests extends IntegrationTestSupport {
|
||||
|
||||
VaultOperations vaultOperations = prepare().getVaultOperations();
|
||||
|
||||
vaultOperations.write(
|
||||
String.format("%s/config/connection", this.rabbitmq.getBackend()),
|
||||
connection);
|
||||
vaultOperations.write(String.format("%s/config/connection", this.rabbitmq.getBackend()), connection);
|
||||
|
||||
vaultOperations.write(
|
||||
String.format("%s/roles/%s", this.rabbitmq.getBackend(),
|
||||
this.rabbitmq.getRole()),
|
||||
vaultOperations.write(String.format("%s/roles/%s", this.rabbitmq.getBackend(), this.rabbitmq.getRole()),
|
||||
Collections.singletonMap("vhosts", VHOSTS_ROLE));
|
||||
|
||||
this.configOperations = new VaultConfigTemplate(vaultOperations,
|
||||
this.vaultProperties);
|
||||
this.configOperations = new VaultConfigTemplate(vaultOperations, this.vaultProperties);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateCredentialsCorrectly() {
|
||||
|
||||
Map<String, Object> secretProperties = this.configOperations
|
||||
.read(forRabbitMq(this.rabbitmq)).getData();
|
||||
Map<String, Object> secretProperties = this.configOperations.read(forRabbitMq(this.rabbitmq)).getData();
|
||||
|
||||
assertThat(secretProperties).containsKeys("spring.rabbitmq.username",
|
||||
"spring.rabbitmq.password");
|
||||
assertThat(secretProperties).containsKeys("spring.rabbitmq.username", "spring.rabbitmq.password");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -39,12 +39,9 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = CustomBootstrapConfiguration.class,
|
||||
properties = {
|
||||
"VaultConfigRabbitMqBootstrapConfigurationTests.custom.config=true",
|
||||
"spring.cloud.vault.rabbitmq.role=foo" })
|
||||
public class VaultConfigRabbitMqBootstrapConfigurationTests
|
||||
extends IntegrationTestSupport {
|
||||
@SpringBootTest(classes = CustomBootstrapConfiguration.class, properties = {
|
||||
"VaultConfigRabbitMqBootstrapConfigurationTests.custom.config=true", "spring.cloud.vault.rabbitmq.role=foo" })
|
||||
public class VaultConfigRabbitMqBootstrapConfigurationTests extends IntegrationTestSupport {
|
||||
|
||||
@Autowired
|
||||
RabbitMqSecretBackendMetadataFactory factory;
|
||||
@@ -70,10 +67,8 @@ public class VaultConfigRabbitMqBootstrapConfigurationTests
|
||||
|
||||
return new RabbitMqSecretBackendMetadataFactory() {
|
||||
@Override
|
||||
public SecretBackendMetadata createMetadata(
|
||||
VaultRabbitMqProperties backendDescriptor) {
|
||||
return KeyValueSecretBackendMetadata
|
||||
.create(backendDescriptor.getRole());
|
||||
public SecretBackendMetadata createMetadata(VaultRabbitMqProperties backendDescriptor) {
|
||||
return KeyValueSecretBackendMetadata.create(backendDescriptor.getRole());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -50,8 +50,7 @@ import static org.junit.Assume.assumeTrue;
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = VaultConfigRabbitMqTests.TestApplication.class,
|
||||
properties = { "spring.cloud.vault.rabbitmq.enabled=true",
|
||||
"spring.cloud.vault.rabbitmq.role=readonly",
|
||||
properties = { "spring.cloud.vault.rabbitmq.enabled=true", "spring.cloud.vault.rabbitmq.role=readonly",
|
||||
"spring.rabbitmq.address=localhost" })
|
||||
public class VaultConfigRabbitMqTests {
|
||||
|
||||
@@ -65,8 +64,8 @@ public class VaultConfigRabbitMqTests {
|
||||
|
||||
private static final String RABBITMQ_PASSWORD = "guest";
|
||||
|
||||
private static final String RABBITMQ_URI = String.format("http://%s:%d",
|
||||
RABBITMQ_HOST, RABBITMQ_HTTP_MANAGEMENT_PORT);
|
||||
private static final String RABBITMQ_URI = String.format("http://%s:%d", RABBITMQ_HOST,
|
||||
RABBITMQ_HTTP_MANAGEMENT_PORT);
|
||||
|
||||
private static final String VHOSTS_ROLE = "{\"/\":{\"write\": \".*\", \"read\": \".*\"}}";
|
||||
|
||||
@@ -85,14 +84,12 @@ public class VaultConfigRabbitMqTests {
|
||||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
|
||||
assumeTrue(CanConnect
|
||||
.to(new InetSocketAddress(RABBITMQ_HOST, RABBITMQ_HTTP_MANAGEMENT_PORT)));
|
||||
assumeTrue(CanConnect.to(new InetSocketAddress(RABBITMQ_HOST, RABBITMQ_HTTP_MANAGEMENT_PORT)));
|
||||
|
||||
VaultRule vaultRule = new VaultRule();
|
||||
vaultRule.before();
|
||||
|
||||
assumeTrue(vaultRule.prepare().getVersion()
|
||||
.isGreaterThanOrEqualTo(Version.parse("0.6.2")));
|
||||
assumeTrue(vaultRule.prepare().getVersion().isGreaterThanOrEqualTo(Version.parse("0.6.2")));
|
||||
|
||||
if (!vaultRule.prepare().hasSecretBackend("rabbitmq")) {
|
||||
vaultRule.prepare().mountSecret("rabbitmq");
|
||||
|
||||
@@ -92,8 +92,8 @@ class ClientAuthenticationFactory {
|
||||
|
||||
private final RestOperations externalRestOperations;
|
||||
|
||||
ClientAuthenticationFactory(VaultProperties vaultProperties,
|
||||
RestOperations restOperations, RestOperations externalRestOperations) {
|
||||
ClientAuthenticationFactory(VaultProperties vaultProperties, RestOperations restOperations,
|
||||
RestOperations externalRestOperations) {
|
||||
this.vaultProperties = vaultProperties;
|
||||
this.restOperations = restOperations;
|
||||
this.externalRestOperations = externalRestOperations;
|
||||
@@ -140,32 +140,28 @@ class ClientAuthenticationFactory {
|
||||
return pcfAuthentication(this.vaultProperties);
|
||||
|
||||
case TOKEN:
|
||||
Assert.hasText(this.vaultProperties.getToken(),
|
||||
"Token (spring.cloud.vault.token) must not be empty");
|
||||
Assert.hasText(this.vaultProperties.getToken(), "Token (spring.cloud.vault.token) must not be empty");
|
||||
return new TokenAuthentication(this.vaultProperties.getToken());
|
||||
}
|
||||
|
||||
throw new UnsupportedOperationException(
|
||||
String.format("Client authentication %s not supported",
|
||||
this.vaultProperties.getAuthentication()));
|
||||
String.format("Client authentication %s not supported", this.vaultProperties.getAuthentication()));
|
||||
}
|
||||
|
||||
private ClientAuthentication appIdAuthentication(VaultProperties vaultProperties) {
|
||||
|
||||
VaultProperties.AppIdProperties appId = vaultProperties.getAppId();
|
||||
Assert.hasText(appId.getUserId(),
|
||||
"UserId (spring.cloud.vault.app-id.user-id) must not be empty");
|
||||
Assert.hasText(appId.getUserId(), "UserId (spring.cloud.vault.app-id.user-id) must not be empty");
|
||||
|
||||
AppIdAuthenticationOptions authenticationOptions = AppIdAuthenticationOptions
|
||||
.builder().appId(vaultProperties.getApplicationName()) //
|
||||
AppIdAuthenticationOptions authenticationOptions = AppIdAuthenticationOptions.builder()
|
||||
.appId(vaultProperties.getApplicationName()) //
|
||||
.path(appId.getAppIdPath()) //
|
||||
.userIdMechanism(getAppIdMechanism(appId)).build();
|
||||
|
||||
return new AppIdAuthentication(authenticationOptions, this.restOperations);
|
||||
}
|
||||
|
||||
private AppIdUserIdMechanism getAppIdMechanism(
|
||||
VaultProperties.AppIdProperties appId) {
|
||||
private AppIdUserIdMechanism getAppIdMechanism(VaultProperties.AppIdProperties appId) {
|
||||
|
||||
try {
|
||||
Class<?> userIdClass = ClassUtils.forName(appId.getUserId(), null);
|
||||
@@ -182,8 +178,7 @@ class ClientAuthenticationFactory {
|
||||
|
||||
if (StringUtils.hasText(appId.getNetworkInterface())) {
|
||||
try {
|
||||
return new MacAddressUserId(
|
||||
Integer.parseInt(appId.getNetworkInterface()));
|
||||
return new MacAddressUserId(Integer.parseInt(appId.getNetworkInterface()));
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
return new MacAddressUserId(appId.getNetworkInterface());
|
||||
@@ -199,19 +194,17 @@ class ClientAuthenticationFactory {
|
||||
|
||||
private ClientAuthentication appRoleAuthentication(VaultProperties vaultProperties) {
|
||||
|
||||
AppRoleAuthenticationOptions options = getAppRoleAuthenticationOptions(
|
||||
vaultProperties);
|
||||
AppRoleAuthenticationOptions options = getAppRoleAuthenticationOptions(vaultProperties);
|
||||
|
||||
return new AppRoleAuthentication(options, this.restOperations);
|
||||
}
|
||||
|
||||
static AppRoleAuthenticationOptions getAppRoleAuthenticationOptions(
|
||||
VaultProperties vaultProperties) {
|
||||
static AppRoleAuthenticationOptions getAppRoleAuthenticationOptions(VaultProperties vaultProperties) {
|
||||
|
||||
AppRoleProperties appRole = vaultProperties.getAppRole();
|
||||
|
||||
AppRoleAuthenticationOptionsBuilder builder = AppRoleAuthenticationOptions
|
||||
.builder().path(appRole.getAppRolePath());
|
||||
AppRoleAuthenticationOptionsBuilder builder = AppRoleAuthenticationOptions.builder()
|
||||
.path(appRole.getAppRolePath());
|
||||
|
||||
if (StringUtils.hasText(appRole.getRole())) {
|
||||
builder.appRole(appRole.getRole());
|
||||
@@ -225,15 +218,13 @@ class ClientAuthenticationFactory {
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private static RoleId getRoleId(VaultProperties vaultProperties,
|
||||
AppRoleProperties appRole) {
|
||||
private static RoleId getRoleId(VaultProperties vaultProperties, AppRoleProperties appRole) {
|
||||
|
||||
if (StringUtils.hasText(appRole.getRoleId())) {
|
||||
return RoleId.provided(appRole.getRoleId());
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(vaultProperties.getToken())
|
||||
&& StringUtils.hasText(appRole.getRole())) {
|
||||
if (StringUtils.hasText(vaultProperties.getToken()) && StringUtils.hasText(appRole.getRole())) {
|
||||
return RoleId.pull(VaultToken.of(vaultProperties.getToken()));
|
||||
}
|
||||
|
||||
@@ -245,15 +236,13 @@ class ClientAuthenticationFactory {
|
||||
"Cannot configure RoleId. Any of role-id, initial token, or initial toke and role name must be configured.");
|
||||
}
|
||||
|
||||
private static SecretId getSecretId(VaultProperties vaultProperties,
|
||||
AppRoleProperties appRole) {
|
||||
private static SecretId getSecretId(VaultProperties vaultProperties, AppRoleProperties appRole) {
|
||||
|
||||
if (StringUtils.hasText(appRole.getSecretId())) {
|
||||
return SecretId.provided(appRole.getSecretId());
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(vaultProperties.getToken())
|
||||
&& StringUtils.hasText(appRole.getRole())) {
|
||||
if (StringUtils.hasText(vaultProperties.getToken()) && StringUtils.hasText(appRole.getRole())) {
|
||||
return SecretId.pull(VaultToken.of(vaultProperties.getToken()));
|
||||
}
|
||||
|
||||
@@ -268,29 +257,25 @@ class ClientAuthenticationFactory {
|
||||
|
||||
VaultProperties.AwsEc2Properties awsEc2 = vaultProperties.getAwsEc2();
|
||||
|
||||
Nonce nonce = StringUtils.hasText(awsEc2.getNonce())
|
||||
? Nonce.provided(awsEc2.getNonce().toCharArray()) : Nonce.generated();
|
||||
Nonce nonce = StringUtils.hasText(awsEc2.getNonce()) ? Nonce.provided(awsEc2.getNonce().toCharArray())
|
||||
: Nonce.generated();
|
||||
|
||||
AwsEc2AuthenticationOptions authenticationOptions = AwsEc2AuthenticationOptions
|
||||
.builder().role(awsEc2.getRole()) //
|
||||
AwsEc2AuthenticationOptions authenticationOptions = AwsEc2AuthenticationOptions.builder().role(awsEc2.getRole()) //
|
||||
.path(awsEc2.getAwsEc2Path()) //
|
||||
.nonce(nonce) //
|
||||
.identityDocumentUri(URI.create(awsEc2.getIdentityDocument())) //
|
||||
.build();
|
||||
|
||||
return new AwsEc2Authentication(authenticationOptions, this.restOperations,
|
||||
this.externalRestOperations);
|
||||
return new AwsEc2Authentication(authenticationOptions, this.restOperations, this.externalRestOperations);
|
||||
}
|
||||
|
||||
private ClientAuthentication awsIamAuthentication(VaultProperties vaultProperties) {
|
||||
|
||||
AwsIamProperties awsIam = vaultProperties.getAwsIam();
|
||||
|
||||
AWSCredentialsProvider credentialsProvider = AwsCredentialProvider
|
||||
.getAwsCredentialsProvider();
|
||||
AWSCredentialsProvider credentialsProvider = AwsCredentialProvider.getAwsCredentialsProvider();
|
||||
|
||||
AwsIamAuthenticationOptionsBuilder builder = AwsIamAuthenticationOptions
|
||||
.builder();
|
||||
AwsIamAuthenticationOptionsBuilder builder = AwsIamAuthenticationOptions.builder();
|
||||
|
||||
if (StringUtils.hasText(awsIam.getRole())) {
|
||||
builder.role(awsIam.getRole());
|
||||
@@ -307,8 +292,7 @@ class ClientAuthenticationFactory {
|
||||
builder.path(awsIam.getAwsPath()) //
|
||||
.credentialsProvider(credentialsProvider);
|
||||
|
||||
AwsIamAuthenticationOptions options = builder
|
||||
.credentialsProvider(credentialsProvider).build();
|
||||
AwsIamAuthenticationOptions options = builder.credentialsProvider(credentialsProvider).build();
|
||||
|
||||
return new AwsIamAuthentication(options, this.restOperations);
|
||||
}
|
||||
@@ -317,14 +301,12 @@ class ClientAuthenticationFactory {
|
||||
|
||||
AzureMsiProperties azureMsi = vaultProperties.getAzureMsi();
|
||||
|
||||
Assert.hasText(azureMsi.getRole(),
|
||||
"Azure role (spring.cloud.vault.azure-msi.role) must not be empty");
|
||||
Assert.hasText(azureMsi.getRole(), "Azure role (spring.cloud.vault.azure-msi.role) must not be empty");
|
||||
|
||||
AzureMsiAuthenticationOptions options = AzureMsiAuthenticationOptions.builder()
|
||||
.role(azureMsi.getRole()).build();
|
||||
AzureMsiAuthenticationOptions options = AzureMsiAuthenticationOptions.builder().role(azureMsi.getRole())
|
||||
.build();
|
||||
|
||||
return new AzureMsiAuthentication(options, this.restOperations,
|
||||
this.externalRestOperations);
|
||||
return new AzureMsiAuthentication(options, this.restOperations, this.externalRestOperations);
|
||||
}
|
||||
|
||||
private ClientAuthentication cubbyholeAuthentication() {
|
||||
@@ -344,30 +326,26 @@ class ClientAuthenticationFactory {
|
||||
|
||||
VaultProperties.GcpGceProperties gcp = vaultProperties.getGcpGce();
|
||||
|
||||
Assert.hasText(gcp.getRole(),
|
||||
"Role (spring.cloud.vault.gcp-gce.role) must not be empty");
|
||||
Assert.hasText(gcp.getRole(), "Role (spring.cloud.vault.gcp-gce.role) must not be empty");
|
||||
|
||||
GcpComputeAuthenticationOptionsBuilder builder = GcpComputeAuthenticationOptions
|
||||
.builder().path(gcp.getGcpPath()).role(gcp.getRole());
|
||||
GcpComputeAuthenticationOptionsBuilder builder = GcpComputeAuthenticationOptions.builder()
|
||||
.path(gcp.getGcpPath()).role(gcp.getRole());
|
||||
|
||||
if (StringUtils.hasText(gcp.getServiceAccount())) {
|
||||
builder.serviceAccount(gcp.getServiceAccount());
|
||||
}
|
||||
|
||||
return new GcpComputeAuthentication(builder.build(), this.restOperations,
|
||||
this.externalRestOperations);
|
||||
return new GcpComputeAuthentication(builder.build(), this.restOperations, this.externalRestOperations);
|
||||
}
|
||||
|
||||
private ClientAuthentication gcpIamAuthentication(VaultProperties vaultProperties) {
|
||||
|
||||
VaultProperties.GcpIamProperties gcp = vaultProperties.getGcpIam();
|
||||
|
||||
Assert.hasText(gcp.getRole(),
|
||||
"Role (spring.cloud.vault.gcp-iam.role) must not be empty");
|
||||
Assert.hasText(gcp.getRole(), "Role (spring.cloud.vault.gcp-iam.role) must not be empty");
|
||||
|
||||
GcpIamAuthenticationOptionsBuilder builder = GcpIamAuthenticationOptions.builder()
|
||||
.path(gcp.getGcpPath()).role(gcp.getRole())
|
||||
.jwtValidity(gcp.getJwtValidity());
|
||||
GcpIamAuthenticationOptionsBuilder builder = GcpIamAuthenticationOptions.builder().path(gcp.getGcpPath())
|
||||
.role(gcp.getRole()).jwtValidity(gcp.getJwtValidity());
|
||||
|
||||
if (StringUtils.hasText(gcp.getProjectId())) {
|
||||
builder.projectId(gcp.getProjectId());
|
||||
@@ -385,38 +363,32 @@ class ClientAuthenticationFactory {
|
||||
return new GcpIamAuthentication(options, this.restOperations);
|
||||
}
|
||||
|
||||
private GoogleCredential getGoogleCredential(GcpIamProperties gcp)
|
||||
throws IOException {
|
||||
private GoogleCredential getGoogleCredential(GcpIamProperties gcp) throws IOException {
|
||||
|
||||
GcpCredentials credentialProperties = gcp.getCredentials();
|
||||
if (credentialProperties.getLocation() != null) {
|
||||
return GoogleCredential
|
||||
.fromStream(credentialProperties.getLocation().getInputStream());
|
||||
return GoogleCredential.fromStream(credentialProperties.getLocation().getInputStream());
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(credentialProperties.getEncodedKey())) {
|
||||
return GoogleCredential.fromStream(new ByteArrayInputStream(
|
||||
Base64.getDecoder().decode(credentialProperties.getEncodedKey())));
|
||||
return GoogleCredential.fromStream(
|
||||
new ByteArrayInputStream(Base64.getDecoder().decode(credentialProperties.getEncodedKey())));
|
||||
}
|
||||
|
||||
return GoogleCredential.getApplicationDefault();
|
||||
}
|
||||
|
||||
private ClientAuthentication kubernetesAuthentication(
|
||||
VaultProperties vaultProperties) {
|
||||
private ClientAuthentication kubernetesAuthentication(VaultProperties vaultProperties) {
|
||||
|
||||
VaultProperties.KubernetesProperties kubernetes = vaultProperties.getKubernetes();
|
||||
|
||||
Assert.hasText(kubernetes.getRole(),
|
||||
"Role (spring.cloud.vault.kubernetes.role) must not be empty");
|
||||
Assert.hasText(kubernetes.getRole(), "Role (spring.cloud.vault.kubernetes.role) must not be empty");
|
||||
Assert.hasText(kubernetes.getServiceAccountTokenFile(),
|
||||
"Service account token file (spring.cloud.vault.kubernetes.service-account-token-file) must not be empty");
|
||||
|
||||
KubernetesAuthenticationOptions options = KubernetesAuthenticationOptions
|
||||
.builder().path(kubernetes.getKubernetesPath()).role(kubernetes.getRole())
|
||||
.jwtSupplier(new KubernetesServiceAccountTokenFile(
|
||||
kubernetes.getServiceAccountTokenFile()))
|
||||
.build();
|
||||
KubernetesAuthenticationOptions options = KubernetesAuthenticationOptions.builder()
|
||||
.path(kubernetes.getKubernetesPath()).role(kubernetes.getRole())
|
||||
.jwtSupplier(new KubernetesServiceAccountTokenFile(kubernetes.getServiceAccountTokenFile())).build();
|
||||
|
||||
return new KubernetesAuthentication(options, this.restOperations);
|
||||
}
|
||||
@@ -425,24 +397,19 @@ class ClientAuthenticationFactory {
|
||||
|
||||
VaultProperties.PcfProperties pcfProperties = vaultProperties.getPcf();
|
||||
|
||||
Assert.isTrue(
|
||||
ClassUtils.isPresent("org.bouncycastle.crypto.signers.PSSSigner",
|
||||
getClass().getClassLoader()),
|
||||
Assert.isTrue(ClassUtils.isPresent("org.bouncycastle.crypto.signers.PSSSigner", getClass().getClassLoader()),
|
||||
"BouncyCastle (bcpkix-jdk15on) must be on the classpath");
|
||||
Assert.hasText(pcfProperties.getRole(),
|
||||
"Role (spring.cloud.vault.pcf.role) must not be empty");
|
||||
Assert.hasText(pcfProperties.getRole(), "Role (spring.cloud.vault.pcf.role) must not be empty");
|
||||
|
||||
PcfAuthenticationOptions.PcfAuthenticationOptionsBuilder builder = PcfAuthenticationOptions
|
||||
.builder().role(pcfProperties.getRole()).path(pcfProperties.getPcfPath());
|
||||
PcfAuthenticationOptions.PcfAuthenticationOptionsBuilder builder = PcfAuthenticationOptions.builder()
|
||||
.role(pcfProperties.getRole()).path(pcfProperties.getPcfPath());
|
||||
|
||||
if (pcfProperties.getInstanceCertificate() != null) {
|
||||
builder.instanceCertificate(new ResourceCredentialSupplier(
|
||||
pcfProperties.getInstanceCertificate()));
|
||||
builder.instanceCertificate(new ResourceCredentialSupplier(pcfProperties.getInstanceCertificate()));
|
||||
}
|
||||
|
||||
if (pcfProperties.getInstanceKey() != null) {
|
||||
builder.instanceKey(
|
||||
new ResourceCredentialSupplier(pcfProperties.getInstanceKey()));
|
||||
builder.instanceKey(new ResourceCredentialSupplier(pcfProperties.getInstanceKey()));
|
||||
}
|
||||
|
||||
return new PcfAuthentication(builder.build(), this.restOperations);
|
||||
|
||||
@@ -34,8 +34,7 @@ import org.springframework.vault.core.util.PropertyTransformers;
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
class DefaultSecretBackendConfigurer
|
||||
implements SecretBackendConfigurer, PropertySourceLocatorConfiguration {
|
||||
class DefaultSecretBackendConfigurer implements SecretBackendConfigurer, PropertySourceLocatorConfiguration {
|
||||
|
||||
private final Map<String, SecretBackendMetadata> secretBackends = new LinkedHashMap<>();
|
||||
|
||||
@@ -52,8 +51,7 @@ class DefaultSecretBackendConfigurer
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecretBackendConfigurer add(String path,
|
||||
PropertyTransformer propertyTransformer) {
|
||||
public SecretBackendConfigurer add(String path, PropertyTransformer propertyTransformer) {
|
||||
|
||||
Assert.hasLength(path, "Path must not be empty");
|
||||
Assert.notNull(propertyTransformer, "PropertyTransformer must not be null");
|
||||
@@ -61,8 +59,7 @@ class DefaultSecretBackendConfigurer
|
||||
return add(createMetadata(path, propertyTransformer));
|
||||
}
|
||||
|
||||
private SimpleSecretBackendMetadata createMetadata(String path,
|
||||
PropertyTransformer propertyTransformer) {
|
||||
private SimpleSecretBackendMetadata createMetadata(String path, PropertyTransformer propertyTransformer) {
|
||||
return new SimpleSecretBackendMetadata(path, propertyTransformer);
|
||||
}
|
||||
|
||||
@@ -85,32 +82,27 @@ class DefaultSecretBackendConfigurer
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecretBackendConfigurer add(RequestedSecret requestedSecret,
|
||||
PropertyTransformer propertyTransformer) {
|
||||
public SecretBackendConfigurer add(RequestedSecret requestedSecret, PropertyTransformer propertyTransformer) {
|
||||
|
||||
Assert.notNull(requestedSecret, "RequestedSecret must not be null");
|
||||
Assert.notNull(propertyTransformer, "PropertyTransformer must not be null");
|
||||
|
||||
this.secretBackends.put(requestedSecret.getPath(),
|
||||
new SimpleLeasingSecretBackendMetadata(
|
||||
createMetadata(requestedSecret.getPath(), propertyTransformer),
|
||||
requestedSecret.getMode()));
|
||||
this.secretBackends.put(requestedSecret.getPath(), new SimpleLeasingSecretBackendMetadata(
|
||||
createMetadata(requestedSecret.getPath(), propertyTransformer), requestedSecret.getMode()));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public SecretBackendConfigurer registerDefaultKeyValueSecretBackends(
|
||||
boolean registerDefault) {
|
||||
public SecretBackendConfigurer registerDefaultKeyValueSecretBackends(boolean registerDefault) {
|
||||
this.registerDefaultKeyValueSecretBackends = registerDefault;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecretBackendConfigurer registerDefaultDiscoveredSecretBackends(
|
||||
boolean registerDefault) {
|
||||
public SecretBackendConfigurer registerDefaultDiscoveredSecretBackends(boolean registerDefault) {
|
||||
|
||||
this.registerDefaultDiscoveredSecretBackends = registerDefault;
|
||||
|
||||
@@ -136,8 +128,7 @@ class DefaultSecretBackendConfigurer
|
||||
|
||||
private final PropertyTransformer propertyTransformer;
|
||||
|
||||
SimpleSecretBackendMetadata(String path,
|
||||
PropertyTransformer propertyTransformer) {
|
||||
SimpleSecretBackendMetadata(String path, PropertyTransformer propertyTransformer) {
|
||||
this.path = path;
|
||||
this.propertyTransformer = propertyTransformer;
|
||||
}
|
||||
@@ -164,8 +155,8 @@ class DefaultSecretBackendConfigurer
|
||||
|
||||
}
|
||||
|
||||
private static class SimpleLeasingSecretBackendMetadata
|
||||
extends SecretBackendMetadataWrapper implements LeasingSecretBackendMetadata {
|
||||
private static class SimpleLeasingSecretBackendMetadata extends SecretBackendMetadataWrapper
|
||||
implements LeasingSecretBackendMetadata {
|
||||
|
||||
private final Mode mode;
|
||||
|
||||
|
||||
@@ -58,16 +58,14 @@ public class DiscoveryClientVaultBootstrapConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty(name = "spring.cloud.vault.enabled", matchIfMissing = true)
|
||||
public VaultServiceInstanceProvider vaultServerInstanceProvider(
|
||||
DiscoveryClient discoveryClient) {
|
||||
public VaultServiceInstanceProvider vaultServerInstanceProvider(DiscoveryClient discoveryClient) {
|
||||
return new DiscoveryClientVaultServiceInstanceProvider(discoveryClient);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty(name = "spring.cloud.vault.enabled", matchIfMissing = true)
|
||||
public VaultEndpointProvider vaultEndpointProvider(
|
||||
VaultServiceInstanceProvider instanceProvider) {
|
||||
public VaultEndpointProvider vaultEndpointProvider(VaultServiceInstanceProvider instanceProvider) {
|
||||
|
||||
String serviceId = this.vaultProperties.getDiscovery().getServiceId();
|
||||
String fallbackScheme;
|
||||
@@ -81,8 +79,7 @@ public class DiscoveryClientVaultBootstrapConfiguration {
|
||||
|
||||
ServiceInstance server = instanceProvider.getVaultServerInstance(serviceId);
|
||||
|
||||
VaultEndpoint vaultEndpoint = VaultEndpoint.create(server.getHost(),
|
||||
server.getPort());
|
||||
VaultEndpoint vaultEndpoint = VaultEndpoint.create(server.getHost(), server.getPort());
|
||||
|
||||
if (server.getMetadata().containsKey("scheme")) {
|
||||
vaultEndpoint.setScheme(server.getMetadata().get("scheme"));
|
||||
|
||||
@@ -30,11 +30,9 @@ import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
* @author Mark Paluch
|
||||
* @since 1.1
|
||||
*/
|
||||
public class DiscoveryClientVaultServiceInstanceProvider
|
||||
implements VaultServiceInstanceProvider {
|
||||
public class DiscoveryClientVaultServiceInstanceProvider implements VaultServiceInstanceProvider {
|
||||
|
||||
private static final Log log = LogFactory
|
||||
.getLog(DiscoveryClientVaultServiceInstanceProvider.class);
|
||||
private static final Log log = LogFactory.getLog(DiscoveryClientVaultServiceInstanceProvider.class);
|
||||
|
||||
private final DiscoveryClient client;
|
||||
|
||||
@@ -50,8 +48,7 @@ public class DiscoveryClientVaultServiceInstanceProvider
|
||||
List<ServiceInstance> instances = this.client.getInstances(serviceId);
|
||||
|
||||
if (instances.isEmpty()) {
|
||||
throw new IllegalStateException(
|
||||
"No instances found of Vault server (" + serviceId + ")");
|
||||
throw new IllegalStateException("No instances found of Vault server (" + serviceId + ")");
|
||||
}
|
||||
|
||||
ServiceInstance instance = instances.get(0);
|
||||
|
||||
@@ -47,8 +47,7 @@ final class HealthBuilderDelegate {
|
||||
builder.up().withDetail("state", "Vault in performance standby");
|
||||
}
|
||||
else if (healthResponse.isRecoveryReplicationSecondary()) {
|
||||
builder.up().withDetail("state",
|
||||
"Vault in recovery replication secondary mode");
|
||||
builder.up().withDetail("state", "Vault in recovery replication secondary mode");
|
||||
}
|
||||
else {
|
||||
builder.up();
|
||||
|
||||
@@ -36,8 +36,7 @@ import org.springframework.vault.core.util.PropertyTransformers;
|
||||
* @author Mark Paluch
|
||||
* @since 2.0
|
||||
*/
|
||||
public class KeyValueSecretBackendMetadata extends SecretBackendMetadataSupport
|
||||
implements SecretBackendMetadata {
|
||||
public class KeyValueSecretBackendMetadata extends SecretBackendMetadataSupport implements SecretBackendMetadata {
|
||||
|
||||
private final String path;
|
||||
|
||||
@@ -47,8 +46,7 @@ public class KeyValueSecretBackendMetadata extends SecretBackendMetadataSupport
|
||||
this(path, PropertyTransformers.noop());
|
||||
}
|
||||
|
||||
private KeyValueSecretBackendMetadata(String path,
|
||||
PropertyTransformer propertyTransformer) {
|
||||
private KeyValueSecretBackendMetadata(String path, PropertyTransformer propertyTransformer) {
|
||||
|
||||
Assert.hasText(path, "Secret backend path must not be empty");
|
||||
Assert.notNull(propertyTransformer, "PropertyTransformer must not be null");
|
||||
@@ -70,12 +68,10 @@ public class KeyValueSecretBackendMetadata extends SecretBackendMetadataSupport
|
||||
*/
|
||||
public static SecretBackendMetadata create(String secretBackendPath, String key) {
|
||||
|
||||
Assert.hasText(secretBackendPath,
|
||||
"Secret backend path must not be null or empty");
|
||||
Assert.hasText(secretBackendPath, "Secret backend path must not be null or empty");
|
||||
Assert.hasText(key, "Key must not be null or empty");
|
||||
|
||||
return create(String.format("%s/%s", secretBackendPath, key),
|
||||
UnwrappingPropertyTransformer.unwrap("data"));
|
||||
return create(String.format("%s/%s", secretBackendPath, key), UnwrappingPropertyTransformer.unwrap("data"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,8 +93,7 @@ public class KeyValueSecretBackendMetadata extends SecretBackendMetadataSupport
|
||||
* @param propertyTransformer property transformer.
|
||||
* @return the {@link SecretBackendMetadata}
|
||||
*/
|
||||
public static SecretBackendMetadata create(String path,
|
||||
PropertyTransformer propertyTransformer) {
|
||||
public static SecretBackendMetadata create(String path, PropertyTransformer propertyTransformer) {
|
||||
return new KeyValueSecretBackendMetadata(path, propertyTransformer);
|
||||
}
|
||||
|
||||
@@ -109,19 +104,16 @@ public class KeyValueSecretBackendMetadata extends SecretBackendMetadataSupport
|
||||
* @param profiles active application profiles.
|
||||
* @return list of context paths.
|
||||
*/
|
||||
public static List<String> buildContexts(
|
||||
VaultKeyValueBackendPropertiesSupport properties, List<String> profiles) {
|
||||
public static List<String> buildContexts(VaultKeyValueBackendPropertiesSupport properties, List<String> profiles) {
|
||||
|
||||
String appName = properties.getApplicationName();
|
||||
Set<String> contexts = new LinkedHashSet<>();
|
||||
|
||||
String defaultContext = properties.getDefaultContext();
|
||||
contexts.addAll(buildContexts(defaultContext, profiles,
|
||||
properties.getProfileSeparator()));
|
||||
contexts.addAll(buildContexts(defaultContext, profiles, properties.getProfileSeparator()));
|
||||
|
||||
for (String applicationName : StringUtils.commaDelimitedListToSet(appName)) {
|
||||
contexts.addAll(buildContexts(applicationName, profiles,
|
||||
properties.getProfileSeparator()));
|
||||
contexts.addAll(buildContexts(applicationName, profiles, properties.getProfileSeparator()));
|
||||
}
|
||||
|
||||
List<String> result = new ArrayList<>(contexts);
|
||||
@@ -141,8 +133,7 @@ public class KeyValueSecretBackendMetadata extends SecretBackendMetadataSupport
|
||||
* profile name.
|
||||
* @return list of context names.
|
||||
*/
|
||||
public static List<String> buildContexts(String applicationName,
|
||||
List<String> profiles, String profileSeparator) {
|
||||
public static List<String> buildContexts(String applicationName, List<String> profiles, String profileSeparator) {
|
||||
|
||||
List<String> contexts = new ArrayList<>();
|
||||
|
||||
@@ -207,16 +198,14 @@ public class KeyValueSecretBackendMetadata extends SecretBackendMetadataSupport
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> transformProperties(
|
||||
Map<String, ? extends Object> input) {
|
||||
public Map<String, Object> transformProperties(Map<String, ? extends Object> input) {
|
||||
|
||||
Map<String, Object> target = new LinkedHashMap<>(input.size(), 1);
|
||||
|
||||
for (Entry<String, ? extends Object> entry : input.entrySet()) {
|
||||
|
||||
if (entry.getKey().startsWith(this.prefixToStrip + ".")) {
|
||||
target.put(entry.getKey().substring(this.prefixToStrip.length() + 1),
|
||||
entry.getValue());
|
||||
target.put(entry.getKey().substring(this.prefixToStrip.length() + 1), entry.getValue());
|
||||
}
|
||||
else {
|
||||
target.put(entry.getKey(), entry.getValue());
|
||||
|
||||
@@ -47,8 +47,7 @@ public interface LeasingSecretBackendMetadata extends SecretBackendMetadata {
|
||||
* @param container the lease container that was used to request the secret.
|
||||
* @since 3.0
|
||||
*/
|
||||
default void beforeRegistration(RequestedSecret secret,
|
||||
SecretLeaseContainer container) {
|
||||
default void beforeRegistration(RequestedSecret secret, SecretLeaseContainer container) {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,8 +60,7 @@ public interface LeasingSecretBackendMetadata extends SecretBackendMetadata {
|
||||
* @param container the lease container that was used to request the secret.
|
||||
* @since 3.0
|
||||
*/
|
||||
default void afterRegistration(RequestedSecret secret,
|
||||
SecretLeaseContainer container) {
|
||||
default void afterRegistration(RequestedSecret secret, SecretLeaseContainer container) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,8 +34,7 @@ import org.springframework.vault.core.lease.event.LeaseErrorListener;
|
||||
* @author Mark Paluch
|
||||
* @see LeaseAwareVaultPropertySource
|
||||
*/
|
||||
class LeasingVaultPropertySourceLocator extends VaultPropertySourceLocatorSupport
|
||||
implements PriorityOrdered {
|
||||
class LeasingVaultPropertySourceLocator extends VaultPropertySourceLocatorSupport implements PriorityOrdered {
|
||||
|
||||
private final SecretLeaseContainer secretLeaseContainer;
|
||||
|
||||
@@ -72,8 +71,7 @@ class LeasingVaultPropertySourceLocator extends VaultPropertySourceLocatorSuppor
|
||||
* @param accessor the {@link SecretBackendMetadata}.
|
||||
* @return the {@link VaultPropertySource} to use.
|
||||
*/
|
||||
protected PropertySource<?> createVaultPropertySource(
|
||||
SecretBackendMetadata accessor) {
|
||||
protected PropertySource<?> createVaultPropertySource(SecretBackendMetadata accessor) {
|
||||
|
||||
RequestedSecret secret = getRequestedSecret(accessor);
|
||||
|
||||
@@ -89,8 +87,7 @@ class LeasingVaultPropertySourceLocator extends VaultPropertySourceLocatorSuppor
|
||||
if (accessor instanceof LeasingSecretBackendMetadata) {
|
||||
|
||||
LeasingSecretBackendMetadata leasingBackend = (LeasingSecretBackendMetadata) accessor;
|
||||
return RequestedSecret.from(leasingBackend.getLeaseMode(),
|
||||
accessor.getPath());
|
||||
return RequestedSecret.from(leasingBackend.getLeaseMode(), accessor.getPath());
|
||||
}
|
||||
|
||||
if (accessor instanceof KeyValueSecretBackendMetadata) {
|
||||
@@ -132,28 +129,23 @@ class LeasingVaultPropertySourceLocator extends VaultPropertySourceLocatorSuppor
|
||||
throw (VaultException) exception;
|
||||
}
|
||||
throw new VaultException(
|
||||
String.format("Cannot initialize PropertySource for secret at %s",
|
||||
secret.getPath()),
|
||||
String.format("Cannot initialize PropertySource for secret at %s", secret.getPath()),
|
||||
exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private PropertySource<?> createVaultPropertySource(RequestedSecret secret,
|
||||
SecretBackendMetadata accessor) {
|
||||
private PropertySource<?> createVaultPropertySource(RequestedSecret secret, SecretBackendMetadata accessor) {
|
||||
|
||||
if (accessor instanceof LeasingSecretBackendMetadata) {
|
||||
((LeasingSecretBackendMetadata) accessor).beforeRegistration(secret,
|
||||
this.secretLeaseContainer);
|
||||
((LeasingSecretBackendMetadata) accessor).beforeRegistration(secret, this.secretLeaseContainer);
|
||||
}
|
||||
|
||||
LeaseAwareVaultPropertySource propertySource = new LeaseAwareVaultPropertySource(
|
||||
accessor.getName(), this.secretLeaseContainer, secret,
|
||||
accessor.getPropertyTransformer());
|
||||
LeaseAwareVaultPropertySource propertySource = new LeaseAwareVaultPropertySource(accessor.getName(),
|
||||
this.secretLeaseContainer, secret, accessor.getPropertyTransformer());
|
||||
|
||||
if (accessor instanceof LeasingSecretBackendMetadata) {
|
||||
((LeasingSecretBackendMetadata) accessor).afterRegistration(secret,
|
||||
this.secretLeaseContainer);
|
||||
((LeasingSecretBackendMetadata) accessor).afterRegistration(secret, this.secretLeaseContainer);
|
||||
}
|
||||
|
||||
return propertySource;
|
||||
|
||||
@@ -79,8 +79,7 @@ public interface SecretBackendConfigurer {
|
||||
* @param propertyTransformer must not be {@literal null}.
|
||||
* @return {@code this} {@link SecretBackendConfigurer}.
|
||||
*/
|
||||
SecretBackendConfigurer add(RequestedSecret requestedSecret,
|
||||
PropertyTransformer propertyTransformer);
|
||||
SecretBackendConfigurer add(RequestedSecret requestedSecret, PropertyTransformer propertyTransformer);
|
||||
|
||||
/**
|
||||
* Register default key-value secret backend property sources.
|
||||
@@ -89,8 +88,7 @@ public interface SecretBackendConfigurer {
|
||||
* @return {@code this} {@link SecretBackendConfigurer}.
|
||||
* @since 2.3.3
|
||||
*/
|
||||
SecretBackendConfigurer registerDefaultKeyValueSecretBackends(
|
||||
boolean registerDefault);
|
||||
SecretBackendConfigurer registerDefaultKeyValueSecretBackends(boolean registerDefault);
|
||||
|
||||
/**
|
||||
* Register default discovered secret backend property sources from
|
||||
@@ -99,7 +97,6 @@ public interface SecretBackendConfigurer {
|
||||
* registration via {@link VaultSecretBackendDescriptor} beans.
|
||||
* @return {@code this} {@link SecretBackendConfigurer}.
|
||||
*/
|
||||
SecretBackendConfigurer registerDefaultDiscoveredSecretBackends(
|
||||
boolean registerDefault);
|
||||
SecretBackendConfigurer registerDefaultDiscoveredSecretBackends(boolean registerDefault);
|
||||
|
||||
}
|
||||
|
||||
@@ -49,12 +49,10 @@ final class SecretBackendFactories {
|
||||
continue;
|
||||
}
|
||||
|
||||
SecretBackendMetadata metadata = createSecretBackendMetadata(factories,
|
||||
vaultSecretBackendDescriptor);
|
||||
SecretBackendMetadata metadata = createSecretBackendMetadata(factories, vaultSecretBackendDescriptor);
|
||||
|
||||
if (metadata == null) {
|
||||
log.warn(String.format("Cannot create SecretBackendMetadata for %s",
|
||||
vaultSecretBackendDescriptor));
|
||||
log.warn(String.format("Cannot create SecretBackendMetadata for %s", vaultSecretBackendDescriptor));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -94,8 +94,7 @@ public class VaultBootstrapConfiguration implements InitializingBean {
|
||||
private RestOperations externalRestOperations;
|
||||
|
||||
public VaultBootstrapConfiguration(ConfigurableApplicationContext applicationContext,
|
||||
VaultProperties vaultProperties,
|
||||
ObjectProvider<VaultEndpointProvider> endpointProvider,
|
||||
VaultProperties vaultProperties, ObjectProvider<VaultEndpointProvider> endpointProvider,
|
||||
ObjectProvider<List<RestTemplateCustomizer>> customizers,
|
||||
ObjectProvider<List<RestTemplateRequestCustomizer<?>>> requestCustomizers) {
|
||||
|
||||
@@ -105,17 +104,14 @@ public class VaultBootstrapConfiguration implements InitializingBean {
|
||||
VaultEndpointProvider provider = endpointProvider.getIfAvailable();
|
||||
|
||||
if (provider == null) {
|
||||
provider = SimpleVaultEndpointProvider
|
||||
.of(VaultConfigurationUtil.createVaultEndpoint(vaultProperties));
|
||||
provider = SimpleVaultEndpointProvider.of(VaultConfigurationUtil.createVaultEndpoint(vaultProperties));
|
||||
}
|
||||
|
||||
this.endpointProvider = provider;
|
||||
this.customizers = new ArrayList<>(
|
||||
customizers.getIfAvailable(Collections::emptyList));
|
||||
this.customizers = new ArrayList<>(customizers.getIfAvailable(Collections::emptyList));
|
||||
AnnotationAwareOrderComparator.sort(this.customizers);
|
||||
|
||||
this.requestCustomizers = new ArrayList<>(
|
||||
requestCustomizers.getIfAvailable(Collections::emptyList));
|
||||
this.requestCustomizers = new ArrayList<>(requestCustomizers.getIfAvailable(Collections::emptyList));
|
||||
AnnotationAwareOrderComparator.sort(this.requestCustomizers);
|
||||
}
|
||||
|
||||
@@ -125,8 +121,7 @@ public class VaultBootstrapConfiguration implements InitializingBean {
|
||||
ClientHttpRequestFactory clientHttpRequestFactory = clientHttpRequestFactoryWrapper()
|
||||
.getClientHttpRequestFactory();
|
||||
|
||||
this.restTemplateBuilder = RestTemplateBuilder.builder()
|
||||
.requestFactory(clientHttpRequestFactory)
|
||||
this.restTemplateBuilder = RestTemplateBuilder.builder().requestFactory(clientHttpRequestFactory)
|
||||
.endpointProvider(this.endpointProvider);
|
||||
|
||||
this.customizers.forEach(this.restTemplateBuilder::customizers);
|
||||
@@ -153,15 +148,13 @@ public class VaultBootstrapConfiguration implements InitializingBean {
|
||||
@ConditionalOnMissingBean
|
||||
public ClientFactoryWrapper clientHttpRequestFactoryWrapper() {
|
||||
|
||||
ClientOptions clientOptions = new ClientOptions(
|
||||
Duration.ofMillis(this.vaultProperties.getConnectionTimeout()),
|
||||
ClientOptions clientOptions = new ClientOptions(Duration.ofMillis(this.vaultProperties.getConnectionTimeout()),
|
||||
Duration.ofMillis(this.vaultProperties.getReadTimeout()));
|
||||
|
||||
SslConfiguration sslConfiguration = VaultConfigurationUtil
|
||||
.createSslConfiguration(this.vaultProperties.getSsl());
|
||||
|
||||
return new ClientFactoryWrapper(
|
||||
ClientHttpRequestFactoryFactory.create(clientOptions, sslConfiguration));
|
||||
return new ClientFactoryWrapper(ClientHttpRequestFactoryFactory.create(clientOptions, sslConfiguration));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -173,15 +166,13 @@ public class VaultBootstrapConfiguration implements InitializingBean {
|
||||
@ConditionalOnMissingBean(VaultOperations.class)
|
||||
public VaultTemplate vaultTemplate() {
|
||||
|
||||
VaultProperties.AuthenticationMethod authentication = this.vaultProperties
|
||||
.getAuthentication();
|
||||
VaultProperties.AuthenticationMethod authentication = this.vaultProperties.getAuthentication();
|
||||
|
||||
if (authentication == VaultProperties.AuthenticationMethod.NONE) {
|
||||
return new VaultTemplate(this.restTemplateBuilder);
|
||||
}
|
||||
|
||||
return new VaultTemplate(this.restTemplateBuilder,
|
||||
this.applicationContext.getBean(SessionManager.class));
|
||||
return new VaultTemplate(this.restTemplateBuilder, this.applicationContext.getBean(SessionManager.class));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -221,16 +212,14 @@ public class VaultBootstrapConfiguration implements InitializingBean {
|
||||
public SessionManager vaultSessionManager(ClientAuthentication clientAuthentication,
|
||||
ObjectFactory<TaskSchedulerWrapper> asyncTaskExecutorFactory) {
|
||||
|
||||
VaultProperties.SessionLifecycle lifecycle = this.vaultProperties.getSession()
|
||||
.getLifecycle();
|
||||
VaultProperties.SessionLifecycle lifecycle = this.vaultProperties.getSession().getLifecycle();
|
||||
|
||||
if (lifecycle.isEnabled()) {
|
||||
RestTemplate restTemplate = this.restTemplateBuilder.build();
|
||||
LifecycleAwareSessionManagerSupport.RefreshTrigger trigger = new LifecycleAwareSessionManagerSupport.FixedTimeoutRefreshTrigger(
|
||||
lifecycle.getRefreshBeforeExpiry(), lifecycle.getExpiryThreshold());
|
||||
return new LifecycleAwareSessionManager(clientAuthentication,
|
||||
asyncTaskExecutorFactory.getObject().getTaskScheduler(), restTemplate,
|
||||
trigger);
|
||||
asyncTaskExecutorFactory.getObject().getTaskScheduler(), restTemplate, trigger);
|
||||
}
|
||||
|
||||
return new SimpleSessionManager(clientAuthentication);
|
||||
@@ -248,8 +237,8 @@ public class VaultBootstrapConfiguration implements InitializingBean {
|
||||
public ClientAuthentication clientAuthentication() {
|
||||
|
||||
RestTemplate restTemplate = this.restTemplateBuilder.build();
|
||||
ClientAuthenticationFactory factory = new ClientAuthenticationFactory(
|
||||
this.vaultProperties, restTemplate, this.externalRestOperations);
|
||||
ClientAuthenticationFactory factory = new ClientAuthenticationFactory(this.vaultProperties, restTemplate,
|
||||
this.externalRestOperations);
|
||||
|
||||
return factory.createClientAuthentication();
|
||||
}
|
||||
|
||||
@@ -59,8 +59,7 @@ public class VaultBootstrapPropertySourceConfiguration implements InitializingBe
|
||||
|
||||
private Collection<SecretBackendMetadataFactory<? super VaultSecretBackendDescriptor>> factories;
|
||||
|
||||
public VaultBootstrapPropertySourceConfiguration(
|
||||
ConfigurableApplicationContext applicationContext) {
|
||||
public VaultBootstrapPropertySourceConfiguration(ConfigurableApplicationContext applicationContext) {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
@@ -68,27 +67,24 @@ public class VaultBootstrapPropertySourceConfiguration implements InitializingBe
|
||||
@SuppressWarnings("unchecked")
|
||||
public void afterPropertiesSet() {
|
||||
|
||||
this.vaultSecretBackendDescriptors = this.applicationContext
|
||||
.getBeansOfType(VaultSecretBackendDescriptor.class).values();
|
||||
this.vaultSecretBackendDescriptors = this.applicationContext.getBeansOfType(VaultSecretBackendDescriptor.class)
|
||||
.values();
|
||||
|
||||
this.factories = (Collection) this.applicationContext
|
||||
.getBeansOfType(SecretBackendMetadataFactory.class).values();
|
||||
this.factories = (Collection) this.applicationContext.getBeansOfType(SecretBackendMetadataFactory.class)
|
||||
.values();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PropertySourceLocator vaultPropertySourceLocator(VaultOperations operations,
|
||||
VaultProperties vaultProperties,
|
||||
public PropertySourceLocator vaultPropertySourceLocator(VaultOperations operations, VaultProperties vaultProperties,
|
||||
VaultKeyValueBackendProperties kvBackendProperties,
|
||||
ObjectFactory<SecretLeaseContainer> secretLeaseContainerObjectFactory) {
|
||||
|
||||
VaultConfigTemplate vaultConfigTemplate = new VaultConfigTemplate(operations,
|
||||
vaultProperties);
|
||||
VaultConfigTemplate vaultConfigTemplate = new VaultConfigTemplate(operations, vaultProperties);
|
||||
|
||||
PropertySourceLocatorConfiguration configuration = getPropertySourceConfiguration(
|
||||
Collections.singletonList(kvBackendProperties));
|
||||
|
||||
VaultProperties.ConfigLifecycle lifecycle = vaultProperties.getConfig()
|
||||
.getLifecycle();
|
||||
VaultProperties.ConfigLifecycle lifecycle = vaultProperties.getConfig().getLifecycle();
|
||||
|
||||
if (lifecycle.isEnabled()) {
|
||||
|
||||
@@ -96,17 +92,14 @@ public class VaultBootstrapPropertySourceConfiguration implements InitializingBe
|
||||
// otherwise, the bootstrap context is not shut down cleanly
|
||||
this.applicationContext.registerShutdownHook();
|
||||
|
||||
SecretLeaseContainer secretLeaseContainer = secretLeaseContainerObjectFactory
|
||||
.getObject();
|
||||
SecretLeaseContainer secretLeaseContainer = secretLeaseContainerObjectFactory.getObject();
|
||||
|
||||
secretLeaseContainer.start();
|
||||
|
||||
return new LeasingVaultPropertySourceLocator(vaultProperties, configuration,
|
||||
secretLeaseContainer);
|
||||
return new LeasingVaultPropertySourceLocator(vaultProperties, configuration, secretLeaseContainer);
|
||||
}
|
||||
|
||||
return new VaultPropertySourceLocator(vaultConfigTemplate, vaultProperties,
|
||||
configuration);
|
||||
return new VaultPropertySourceLocator(vaultConfigTemplate, vaultProperties, configuration);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -117,8 +110,8 @@ public class VaultBootstrapPropertySourceConfiguration implements InitializingBe
|
||||
private PropertySourceLocatorConfiguration getPropertySourceConfiguration(
|
||||
List<VaultKeyValueBackendPropertiesSupport> keyValueBackends) {
|
||||
|
||||
Collection<VaultConfigurer> configurers = this.applicationContext
|
||||
.getBeansOfType(VaultConfigurer.class).values();
|
||||
Collection<VaultConfigurer> configurers = this.applicationContext.getBeansOfType(VaultConfigurer.class)
|
||||
.values();
|
||||
|
||||
DefaultSecretBackendConfigurer secretBackendConfigurer = new DefaultSecretBackendConfigurer();
|
||||
|
||||
@@ -141,18 +134,17 @@ public class VaultBootstrapPropertySourceConfiguration implements InitializingBe
|
||||
continue;
|
||||
}
|
||||
|
||||
List<String> contexts = KeyValueSecretBackendMetadata
|
||||
.buildContexts(keyValueBackend, keyValueBackend.getProfiles());
|
||||
List<String> contexts = KeyValueSecretBackendMetadata.buildContexts(keyValueBackend,
|
||||
keyValueBackend.getProfiles());
|
||||
|
||||
for (String context : contexts) {
|
||||
secretBackendConfigurer.add(KeyValueSecretBackendMetadata
|
||||
.create(keyValueBackend.getBackend(), context));
|
||||
secretBackendConfigurer
|
||||
.add(KeyValueSecretBackendMetadata.create(keyValueBackend.getBackend(), context));
|
||||
}
|
||||
}
|
||||
|
||||
Collection<SecretBackendMetadata> backendAccessors = SecretBackendFactories
|
||||
.createSecretBackendMetadata(this.vaultSecretBackendDescriptors,
|
||||
this.factories);
|
||||
.createSecretBackendMetadata(this.vaultSecretBackendDescriptors, this.factories);
|
||||
|
||||
backendAccessors.forEach(secretBackendConfigurer::add);
|
||||
}
|
||||
@@ -160,8 +152,7 @@ public class VaultBootstrapPropertySourceConfiguration implements InitializingBe
|
||||
if (secretBackendConfigurer.isRegisterDefaultDiscoveredSecretBackends()) {
|
||||
|
||||
Collection<SecretBackendMetadata> backendAccessors = SecretBackendFactories
|
||||
.createSecretBackendMetadata(this.vaultSecretBackendDescriptors,
|
||||
this.factories);
|
||||
.createSecretBackendMetadata(this.vaultSecretBackendDescriptors, this.factories);
|
||||
|
||||
backendAccessors.forEach(secretBackendConfigurer::add);
|
||||
}
|
||||
@@ -180,11 +171,10 @@ public class VaultBootstrapPropertySourceConfiguration implements InitializingBe
|
||||
@Bean
|
||||
@Lazy
|
||||
@ConditionalOnMissingBean
|
||||
public SecretLeaseContainer secretLeaseContainer(VaultProperties vaultProperties,
|
||||
VaultOperations vaultOperations, TaskSchedulerWrapper taskSchedulerWrapper) {
|
||||
public SecretLeaseContainer secretLeaseContainer(VaultProperties vaultProperties, VaultOperations vaultOperations,
|
||||
TaskSchedulerWrapper taskSchedulerWrapper) {
|
||||
|
||||
VaultProperties.ConfigLifecycle lifecycle = vaultProperties.getConfig()
|
||||
.getLifecycle();
|
||||
VaultProperties.ConfigLifecycle lifecycle = vaultProperties.getConfig().getLifecycle();
|
||||
|
||||
SecretLeaseContainer container = new SecretLeaseContainer(vaultOperations,
|
||||
taskSchedulerWrapper.getTaskScheduler());
|
||||
@@ -194,8 +184,7 @@ public class VaultBootstrapPropertySourceConfiguration implements InitializingBe
|
||||
return container;
|
||||
}
|
||||
|
||||
static void customizeContainer(VaultProperties.ConfigLifecycle lifecycle,
|
||||
SecretLeaseContainer container) {
|
||||
static void customizeContainer(VaultProperties.ConfigLifecycle lifecycle, SecretLeaseContainer container) {
|
||||
|
||||
if (lifecycle.isEnabled()) {
|
||||
|
||||
|
||||
@@ -50,8 +50,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!");
|
||||
@@ -66,32 +65,27 @@ public class VaultConfigTemplate implements VaultConfigOperations {
|
||||
|
||||
Assert.notNull(secretBackendMetadata, "SecureBackendAccessor must not be null!");
|
||||
|
||||
log.info(String.format("Fetching config from Vault at: %s",
|
||||
secretBackendMetadata.getPath()));
|
||||
log.info(String.format("Fetching config from Vault at: %s", secretBackendMetadata.getPath()));
|
||||
|
||||
try {
|
||||
|
||||
VaultResponse vaultResponse;
|
||||
|
||||
if (this.keyValueDelegate.isVersioned(secretBackendMetadata.getPath())) {
|
||||
vaultResponse = this.keyValueDelegate
|
||||
.getSecret(secretBackendMetadata.getPath());
|
||||
vaultResponse = this.keyValueDelegate.getSecret(secretBackendMetadata.getPath());
|
||||
}
|
||||
else {
|
||||
vaultResponse = this.vaultOperations
|
||||
.read(secretBackendMetadata.getPath());
|
||||
vaultResponse = this.vaultOperations.read(secretBackendMetadata.getPath());
|
||||
}
|
||||
|
||||
if (vaultResponse == null) {
|
||||
|
||||
log.info(String.format("Could not locate PropertySource: %s",
|
||||
"key not found"));
|
||||
log.info(String.format("Could not locate PropertySource: %s", "key not found"));
|
||||
return null;
|
||||
}
|
||||
|
||||
Map<String, Object> data = JsonMapFlattener.flatten(vaultResponse.getData());
|
||||
PropertyTransformer propertyTransformer = secretBackendMetadata
|
||||
.getPropertyTransformer();
|
||||
PropertyTransformer propertyTransformer = secretBackendMetadata.getPropertyTransformer();
|
||||
|
||||
if (propertyTransformer != null) {
|
||||
data = propertyTransformer.transformProperties(data);
|
||||
@@ -103,12 +97,10 @@ public class VaultConfigTemplate implements VaultConfigOperations {
|
||||
|
||||
if (this.properties.isFailFast()) {
|
||||
throw new IllegalStateException(
|
||||
"Could not locate PropertySource and the fail fast property is set, failing.",
|
||||
e);
|
||||
"Could not locate PropertySource and the fail fast property is set, failing.", e);
|
||||
}
|
||||
else {
|
||||
log.warn(String.format("Could not locate PropertySource: %s",
|
||||
e.getMessage()));
|
||||
log.warn(String.format("Could not locate PropertySource: %s", e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,8 +52,7 @@ final class VaultConfigurationUtil {
|
||||
|
||||
if (ssl.getKeyStore() != null) {
|
||||
if (StringUtils.hasText(ssl.getKeyStorePassword())) {
|
||||
keyStore = KeyStoreConfiguration.of(ssl.getKeyStore(),
|
||||
ssl.getKeyStorePassword().toCharArray());
|
||||
keyStore = KeyStoreConfiguration.of(ssl.getKeyStore(), ssl.getKeyStorePassword().toCharArray());
|
||||
}
|
||||
else {
|
||||
keyStore = KeyStoreConfiguration.of(ssl.getKeyStore());
|
||||
@@ -63,8 +62,7 @@ final class VaultConfigurationUtil {
|
||||
if (ssl.getTrustStore() != null) {
|
||||
|
||||
if (StringUtils.hasText(ssl.getTrustStorePassword())) {
|
||||
trustStore = KeyStoreConfiguration.of(ssl.getTrustStore(),
|
||||
ssl.getTrustStorePassword().toCharArray());
|
||||
trustStore = KeyStoreConfiguration.of(ssl.getTrustStore(), ssl.getTrustStorePassword().toCharArray());
|
||||
}
|
||||
else {
|
||||
trustStore = KeyStoreConfiguration.of(ssl.getTrustStore());
|
||||
|
||||
@@ -39,8 +39,7 @@ import org.springframework.context.annotation.Import;
|
||||
@ConditionalOnClass(HealthIndicator.class)
|
||||
@ConditionalOnProperty(name = "spring.cloud.vault.enabled", matchIfMissing = true)
|
||||
@AutoConfigureBefore(HealthContributorAutoConfiguration.class)
|
||||
@Import({ VaultHealthIndicatorConfiguration.class,
|
||||
VaultReactiveHealthIndicatorConfiguration.class })
|
||||
@Import({ VaultHealthIndicatorConfiguration.class, VaultReactiveHealthIndicatorConfiguration.class })
|
||||
public class VaultHealthIndicatorAutoConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@@ -35,8 +35,8 @@ import org.springframework.vault.core.VaultOperations;
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnBean(VaultOperations.class)
|
||||
class VaultHealthIndicatorConfiguration extends
|
||||
CompositeHealthContributorConfiguration<VaultHealthIndicator, VaultOperations> {
|
||||
class VaultHealthIndicatorConfiguration
|
||||
extends CompositeHealthContributorConfiguration<VaultHealthIndicator, VaultOperations> {
|
||||
|
||||
private final Map<String, VaultOperations> vaultTemplates;
|
||||
|
||||
|
||||
@@ -38,8 +38,7 @@ import org.springframework.validation.annotation.Validated;
|
||||
*/
|
||||
@ConfigurationProperties("spring.cloud.vault.kv")
|
||||
@Validated
|
||||
public class VaultKeyValueBackendProperties
|
||||
implements EnvironmentAware, VaultKeyValueBackendPropertiesSupport {
|
||||
public class VaultKeyValueBackendProperties implements EnvironmentAware, VaultKeyValueBackendPropertiesSupport {
|
||||
|
||||
/**
|
||||
* Enable the kev-value backend.
|
||||
@@ -89,8 +88,7 @@ public class VaultKeyValueBackendProperties
|
||||
@Override
|
||||
public void setEnvironment(Environment environment) {
|
||||
|
||||
String springCloudVaultAppName = environment
|
||||
.getProperty("spring.cloud.vault.application-name");
|
||||
String springCloudVaultAppName = environment.getProperty("spring.cloud.vault.application-name");
|
||||
|
||||
if (StringUtils.hasText(springCloudVaultAppName)) {
|
||||
this.applicationName = springCloudVaultAppName;
|
||||
|
||||
@@ -75,8 +75,7 @@ class VaultPropertySource extends EnumerablePropertySource<VaultConfigOperations
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
|
||||
String message = String.format(
|
||||
"Unable to read properties from Vault using %s for %s ", getName(),
|
||||
String message = String.format("Unable to read properties from Vault using %s for %s ", getName(),
|
||||
this.secretBackendMetadata.getVariables());
|
||||
|
||||
if (this.failFast) {
|
||||
|
||||
@@ -30,8 +30,7 @@ import org.springframework.util.Assert;
|
||||
* @author Jean-Philippe Bélanger
|
||||
* @author Ryan Hoegg
|
||||
*/
|
||||
class VaultPropertySourceLocator extends VaultPropertySourceLocatorSupport
|
||||
implements PriorityOrdered {
|
||||
class VaultPropertySourceLocator extends VaultPropertySourceLocatorSupport implements PriorityOrdered {
|
||||
|
||||
private final VaultConfigOperations operations;
|
||||
|
||||
@@ -44,8 +43,7 @@ class VaultPropertySourceLocator extends VaultPropertySourceLocatorSupport
|
||||
* @param propertySourceLocatorConfiguration must not be {@literal null}.
|
||||
* @since 1.1
|
||||
*/
|
||||
VaultPropertySourceLocator(VaultConfigOperations operations,
|
||||
VaultProperties properties,
|
||||
VaultPropertySourceLocator(VaultConfigOperations operations, VaultProperties properties,
|
||||
PropertySourceLocatorConfiguration propertySourceLocatorConfiguration) {
|
||||
|
||||
super("vault", propertySourceLocatorConfiguration);
|
||||
@@ -80,10 +78,8 @@ class VaultPropertySourceLocator extends VaultPropertySourceLocatorSupport
|
||||
* @param accessor the {@link SecretBackendMetadata}.
|
||||
* @return the {@link VaultPropertySource} to use.
|
||||
*/
|
||||
protected PropertySource<?> createVaultPropertySource(
|
||||
SecretBackendMetadata accessor) {
|
||||
return new VaultPropertySource(this.operations, this.properties.isFailFast(),
|
||||
accessor);
|
||||
protected PropertySource<?> createVaultPropertySource(SecretBackendMetadata accessor) {
|
||||
return new VaultPropertySource(this.operations, this.properties.isFailFast(), accessor);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -53,18 +53,15 @@ public abstract class VaultPropertySourceLocatorSupport implements PropertySourc
|
||||
PropertySourceLocatorConfiguration propertySourceLocatorConfiguration) {
|
||||
|
||||
Assert.hasText(propertySourceName, "PropertySource name must not be empty");
|
||||
Assert.notNull(propertySourceLocatorConfiguration,
|
||||
"PropertySourceLocatorConfiguration must not be null");
|
||||
Assert.notNull(propertySourceLocatorConfiguration, "PropertySourceLocatorConfiguration must not be null");
|
||||
|
||||
this.propertySourceName = propertySourceName;
|
||||
this.propertySourceLocatorConfiguration = propertySourceLocatorConfiguration;
|
||||
}
|
||||
|
||||
static PropertySourceLocatorConfiguration createConfiguration(
|
||||
VaultKeyValueBackendProperties kvBackendProperties) {
|
||||
static PropertySourceLocatorConfiguration createConfiguration(VaultKeyValueBackendProperties kvBackendProperties) {
|
||||
|
||||
Assert.notNull(kvBackendProperties,
|
||||
"VaultKeyValueBackendProperties must not be null");
|
||||
Assert.notNull(kvBackendProperties, "VaultKeyValueBackendProperties must not be null");
|
||||
|
||||
return new KeyValuePropertySourceLocatorConfiguration(kvBackendProperties);
|
||||
}
|
||||
@@ -73,12 +70,10 @@ public abstract class VaultPropertySourceLocatorSupport implements PropertySourc
|
||||
public PropertySource<?> locate(Environment environment) {
|
||||
|
||||
if (this.propertySourceLocatorConfiguration instanceof EnvironmentAware) {
|
||||
((EnvironmentAware) this.propertySourceLocatorConfiguration)
|
||||
.setEnvironment(environment);
|
||||
((EnvironmentAware) this.propertySourceLocatorConfiguration).setEnvironment(environment);
|
||||
}
|
||||
|
||||
CompositePropertySource propertySource = createCompositePropertySource(
|
||||
environment);
|
||||
CompositePropertySource propertySource = createCompositePropertySource(environment);
|
||||
initialize(propertySource);
|
||||
|
||||
return propertySource;
|
||||
@@ -101,8 +96,7 @@ public abstract class VaultPropertySourceLocatorSupport implements PropertySourc
|
||||
* @param environment must not be {@literal null}.
|
||||
* @return the composite {@link PropertySource}.
|
||||
*/
|
||||
protected CompositePropertySource createCompositePropertySource(
|
||||
Environment environment) {
|
||||
protected CompositePropertySource createCompositePropertySource(Environment environment) {
|
||||
|
||||
List<PropertySource<?>> propertySources = doCreatePropertySources(environment);
|
||||
|
||||
@@ -117,8 +111,7 @@ public abstract class VaultPropertySourceLocatorSupport implements PropertySourc
|
||||
*/
|
||||
protected List<PropertySource<?>> doCreatePropertySources(Environment environment) {
|
||||
|
||||
Collection<SecretBackendMetadata> secretBackends = this.propertySourceLocatorConfiguration
|
||||
.getSecretBackends();
|
||||
Collection<SecretBackendMetadata> secretBackends = this.propertySourceLocatorConfiguration.getSecretBackends();
|
||||
List<SecretBackendMetadata> sorted = new ArrayList<>(secretBackends);
|
||||
List<PropertySource<?>> propertySources = new ArrayList<>();
|
||||
|
||||
@@ -128,8 +121,7 @@ public abstract class VaultPropertySourceLocatorSupport implements PropertySourc
|
||||
|
||||
for (SecretBackendMetadata backendAccessor : sorted) {
|
||||
|
||||
PropertySource<?> vaultPropertySource = createVaultPropertySource(
|
||||
backendAccessor);
|
||||
PropertySource<?> vaultPropertySource = createVaultPropertySource(backendAccessor);
|
||||
propertySources.add(vaultPropertySource);
|
||||
}
|
||||
|
||||
@@ -143,8 +135,7 @@ public abstract class VaultPropertySourceLocatorSupport implements PropertySourc
|
||||
* @param environment must not be {@literal null}.
|
||||
* @return {@link List} of {@link PropertySource}s.
|
||||
*/
|
||||
protected List<PropertySource<?>> doCreateKeyValuePropertySources(
|
||||
Environment environment) {
|
||||
protected List<PropertySource<?>> doCreateKeyValuePropertySources(Environment environment) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@@ -155,11 +146,10 @@ public abstract class VaultPropertySourceLocatorSupport implements PropertySourc
|
||||
* @param propertySources the property sources.
|
||||
* @return the {@link CompositePropertySource} to use.
|
||||
*/
|
||||
protected CompositePropertySource doCreateCompositePropertySource(
|
||||
String propertySourceName, List<PropertySource<?>> propertySources) {
|
||||
protected CompositePropertySource doCreateCompositePropertySource(String propertySourceName,
|
||||
List<PropertySource<?>> propertySources) {
|
||||
|
||||
CompositePropertySource compositePropertySource = new CompositePropertySource(
|
||||
propertySourceName);
|
||||
CompositePropertySource compositePropertySource = new CompositePropertySource(propertySourceName);
|
||||
|
||||
for (PropertySource<?> propertySource : propertySources) {
|
||||
compositePropertySource.addPropertySource(propertySource);
|
||||
@@ -174,16 +164,13 @@ public abstract class VaultPropertySourceLocatorSupport implements PropertySourc
|
||||
* @param accessor the {@link SecretBackendMetadata}.
|
||||
* @return the {@link VaultPropertySource} to use.
|
||||
*/
|
||||
protected abstract PropertySource<?> createVaultPropertySource(
|
||||
SecretBackendMetadata accessor);
|
||||
protected abstract PropertySource<?> createVaultPropertySource(SecretBackendMetadata accessor);
|
||||
|
||||
private static class KeyValuePropertySourceLocatorConfiguration
|
||||
implements PropertySourceLocatorConfiguration {
|
||||
private static class KeyValuePropertySourceLocatorConfiguration implements PropertySourceLocatorConfiguration {
|
||||
|
||||
private final VaultKeyValueBackendPropertiesSupport keyValueBackendProperties;
|
||||
|
||||
KeyValuePropertySourceLocatorConfiguration(
|
||||
VaultKeyValueBackendPropertiesSupport keyValueBackendProperties) {
|
||||
KeyValuePropertySourceLocatorConfiguration(VaultKeyValueBackendPropertiesSupport keyValueBackendProperties) {
|
||||
this.keyValueBackendProperties = keyValueBackendProperties;
|
||||
}
|
||||
|
||||
@@ -192,15 +179,14 @@ public abstract class VaultPropertySourceLocatorSupport implements PropertySourc
|
||||
|
||||
if (this.keyValueBackendProperties.isEnabled()) {
|
||||
|
||||
List<String> contexts = KeyValueSecretBackendMetadata.buildContexts(
|
||||
this.keyValueBackendProperties,
|
||||
List<String> contexts = KeyValueSecretBackendMetadata.buildContexts(this.keyValueBackendProperties,
|
||||
this.keyValueBackendProperties.getProfiles());
|
||||
|
||||
List<SecretBackendMetadata> result = new ArrayList<>(contexts.size());
|
||||
|
||||
for (String context : contexts) {
|
||||
result.add(KeyValueSecretBackendMetadata.create(
|
||||
this.keyValueBackendProperties.getBackend(), context));
|
||||
result.add(
|
||||
KeyValueSecretBackendMetadata.create(this.keyValueBackendProperties.getBackend(), context));
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -211,8 +197,7 @@ public abstract class VaultPropertySourceLocatorSupport implements PropertySourc
|
||||
|
||||
}
|
||||
|
||||
private static class WrappedPropertySourceLocatorConfiguration
|
||||
implements PropertySourceLocatorConfiguration {
|
||||
private static class WrappedPropertySourceLocatorConfiguration implements PropertySourceLocatorConfiguration {
|
||||
|
||||
private final List<SecretBackendMetadata> metadata;
|
||||
|
||||
@@ -232,11 +217,9 @@ public abstract class VaultPropertySourceLocatorSupport implements PropertySourc
|
||||
|
||||
private final List<PropertySourceLocatorConfiguration> configurations;
|
||||
|
||||
CompositePropertySourceConfiguration(
|
||||
PropertySourceLocatorConfiguration... configurations) {
|
||||
CompositePropertySourceConfiguration(PropertySourceLocatorConfiguration... configurations) {
|
||||
|
||||
List<PropertySourceLocatorConfiguration> copy = new ArrayList<>(
|
||||
Arrays.asList(configurations));
|
||||
List<PropertySourceLocatorConfiguration> copy = new ArrayList<>(Arrays.asList(configurations));
|
||||
|
||||
AnnotationAwareOrderComparator.sortIfNecessary(copy);
|
||||
|
||||
|
||||
@@ -80,8 +80,7 @@ import org.springframework.web.reactive.function.client.WebClient;
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnProperty(name = "spring.cloud.vault.enabled", matchIfMissing = true)
|
||||
@ConditionalOnExpression("${spring.cloud.vault.reactive.enabled:true}")
|
||||
@ConditionalOnClass({ Flux.class, WebClient.class, ReactiveVaultOperations.class,
|
||||
HttpClient.class })
|
||||
@ConditionalOnClass({ Flux.class, WebClient.class, ReactiveVaultOperations.class, HttpClient.class })
|
||||
@EnableConfigurationProperties({ VaultProperties.class })
|
||||
@Order(Ordered.LOWEST_PRECEDENCE - 10)
|
||||
public class VaultReactiveBootstrapConfiguration {
|
||||
@@ -95,8 +94,7 @@ public class VaultReactiveBootstrapConfiguration {
|
||||
*/
|
||||
private final WebClientBuilder webClientBuilder;
|
||||
|
||||
public VaultReactiveBootstrapConfiguration(BeanFactory beanFactory,
|
||||
VaultProperties vaultProperties,
|
||||
public VaultReactiveBootstrapConfiguration(BeanFactory beanFactory, VaultProperties vaultProperties,
|
||||
ObjectProvider<VaultEndpointProvider> endpointProvider,
|
||||
ObjectProvider<List<WebClientCustomizer>> webClientCustomizers) {
|
||||
|
||||
@@ -106,12 +104,10 @@ public class VaultReactiveBootstrapConfiguration {
|
||||
VaultEndpointProvider provider = endpointProvider.getIfAvailable();
|
||||
|
||||
if (provider == null) {
|
||||
provider = SimpleVaultEndpointProvider
|
||||
.of(VaultConfigurationUtil.createVaultEndpoint(vaultProperties));
|
||||
provider = SimpleVaultEndpointProvider.of(VaultConfigurationUtil.createVaultEndpoint(vaultProperties));
|
||||
}
|
||||
|
||||
this.webClientBuilder = WebClientBuilder.builder()
|
||||
.httpConnector(createConnector(this.vaultProperties))
|
||||
this.webClientBuilder = WebClientBuilder.builder().httpConnector(createConnector(this.vaultProperties))
|
||||
.endpointProvider(provider);
|
||||
List<WebClientCustomizer> customizers = new ArrayList<>(
|
||||
webClientCustomizers.getIfAvailable(Collections::emptyList));
|
||||
@@ -120,8 +116,7 @@ public class VaultReactiveBootstrapConfiguration {
|
||||
customizers.forEach(this.webClientBuilder::customizers);
|
||||
|
||||
if (StringUtils.hasText(this.vaultProperties.getNamespace())) {
|
||||
this.webClientBuilder.defaultHeader(VaultHttpHeaders.VAULT_NAMESPACE,
|
||||
this.vaultProperties.getNamespace());
|
||||
this.webClientBuilder.defaultHeader(VaultHttpHeaders.VAULT_NAMESPACE, this.vaultProperties.getNamespace());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,12 +129,10 @@ public class VaultReactiveBootstrapConfiguration {
|
||||
*/
|
||||
private static ClientHttpConnector createConnector(VaultProperties vaultProperties) {
|
||||
|
||||
ClientOptions clientOptions = new ClientOptions(
|
||||
Duration.ofMillis(vaultProperties.getConnectionTimeout()),
|
||||
ClientOptions clientOptions = new ClientOptions(Duration.ofMillis(vaultProperties.getConnectionTimeout()),
|
||||
Duration.ofMillis(vaultProperties.getReadTimeout()));
|
||||
|
||||
SslConfiguration sslConfiguration = VaultConfigurationUtil
|
||||
.createSslConfiguration(vaultProperties.getSsl());
|
||||
SslConfiguration sslConfiguration = VaultConfigurationUtil.createSslConfiguration(vaultProperties.getSsl());
|
||||
|
||||
return ClientHttpConnectorFactory.create(clientOptions, sslConfiguration);
|
||||
}
|
||||
@@ -153,13 +146,11 @@ public class VaultReactiveBootstrapConfiguration {
|
||||
@ConditionalOnMissingBean(ReactiveVaultOperations.class)
|
||||
public ReactiveVaultTemplate reactiveVaultTemplate() {
|
||||
|
||||
if (this.vaultProperties
|
||||
.getAuthentication() == VaultProperties.AuthenticationMethod.NONE) {
|
||||
if (this.vaultProperties.getAuthentication() == VaultProperties.AuthenticationMethod.NONE) {
|
||||
return new ReactiveVaultTemplate(this.webClientBuilder);
|
||||
}
|
||||
|
||||
return new ReactiveVaultTemplate(this.webClientBuilder,
|
||||
beanFactory.getBean(ReactiveSessionManager.class));
|
||||
return new ReactiveVaultTemplate(this.webClientBuilder, beanFactory.getBean(ReactiveSessionManager.class));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -176,18 +167,15 @@ public class VaultReactiveBootstrapConfiguration {
|
||||
public ReactiveSessionManager reactiveVaultSessionManager(BeanFactory beanFactory,
|
||||
ObjectFactory<TaskSchedulerWrapper> asyncTaskExecutorFactory) {
|
||||
|
||||
VaultTokenSupplier vaultTokenSupplier = beanFactory.getBean("vaultTokenSupplier",
|
||||
VaultTokenSupplier.class);
|
||||
VaultTokenSupplier vaultTokenSupplier = beanFactory.getBean("vaultTokenSupplier", VaultTokenSupplier.class);
|
||||
|
||||
VaultProperties.SessionLifecycle lifecycle = this.vaultProperties.getSession()
|
||||
.getLifecycle();
|
||||
VaultProperties.SessionLifecycle lifecycle = this.vaultProperties.getSession().getLifecycle();
|
||||
if (lifecycle.isEnabled()) {
|
||||
WebClient webClient = this.webClientBuilder.build();
|
||||
ReactiveLifecycleAwareSessionManager.RefreshTrigger trigger = new ReactiveLifecycleAwareSessionManager.FixedTimeoutRefreshTrigger(
|
||||
lifecycle.getRefreshBeforeExpiry(), lifecycle.getExpiryThreshold());
|
||||
return new ReactiveLifecycleAwareSessionManager(vaultTokenSupplier,
|
||||
asyncTaskExecutorFactory.getObject().getTaskScheduler(), webClient,
|
||||
trigger);
|
||||
asyncTaskExecutorFactory.getObject().getTaskScheduler(), webClient, trigger);
|
||||
}
|
||||
|
||||
return CachingVaultTokenSupplier.of(vaultTokenSupplier);
|
||||
@@ -204,8 +192,7 @@ public class VaultReactiveBootstrapConfiguration {
|
||||
return () -> {
|
||||
|
||||
VaultToken token = sessionManager.getSessionToken().block();
|
||||
Assert.state(token != null,
|
||||
"ReactiveSessionManager returned a null VaultToken");
|
||||
Assert.state(token != null, "ReactiveSessionManager returned a null VaultToken");
|
||||
return token;
|
||||
};
|
||||
}
|
||||
@@ -224,23 +211,19 @@ public class VaultReactiveBootstrapConfiguration {
|
||||
|
||||
Assert.notNull(beanFactory, "BeanFactory must not be null");
|
||||
|
||||
String[] authStepsFactories = beanFactory
|
||||
.getBeanNamesForType(AuthenticationStepsFactory.class);
|
||||
String[] authStepsFactories = beanFactory.getBeanNamesForType(AuthenticationStepsFactory.class);
|
||||
|
||||
if (!ObjectUtils.isEmpty(authStepsFactories)) {
|
||||
|
||||
AuthenticationStepsFactory factory = beanFactory
|
||||
.getBean(AuthenticationStepsFactory.class);
|
||||
AuthenticationStepsFactory factory = beanFactory.getBean(AuthenticationStepsFactory.class);
|
||||
return createAuthenticationStepsOperator(factory);
|
||||
}
|
||||
|
||||
String[] clientAuthentications = beanFactory
|
||||
.getBeanNamesForType(ClientAuthentication.class);
|
||||
String[] clientAuthentications = beanFactory.getBeanNamesForType(ClientAuthentication.class);
|
||||
|
||||
if (!ObjectUtils.isEmpty(clientAuthentications)) {
|
||||
|
||||
ClientAuthentication clientAuthentication = beanFactory
|
||||
.getBean(ClientAuthentication.class);
|
||||
ClientAuthentication clientAuthentication = beanFactory.getBean(ClientAuthentication.class);
|
||||
|
||||
if (clientAuthentication instanceof TokenAuthentication) {
|
||||
|
||||
@@ -249,13 +232,11 @@ public class VaultReactiveBootstrapConfiguration {
|
||||
}
|
||||
|
||||
if (clientAuthentication instanceof AuthenticationStepsFactory) {
|
||||
return createAuthenticationStepsOperator(
|
||||
(AuthenticationStepsFactory) clientAuthentication);
|
||||
return createAuthenticationStepsOperator((AuthenticationStepsFactory) clientAuthentication);
|
||||
}
|
||||
|
||||
throw new IllegalStateException(String.format(
|
||||
"Cannot construct VaultTokenSupplier from %s. "
|
||||
+ "ClientAuthentication must implement AuthenticationStepsFactory or be TokenAuthentication",
|
||||
throw new IllegalStateException(String.format("Cannot construct VaultTokenSupplier from %s. "
|
||||
+ "ClientAuthentication must implement AuthenticationStepsFactory or be TokenAuthentication",
|
||||
clientAuthentication));
|
||||
}
|
||||
|
||||
@@ -263,11 +244,9 @@ public class VaultReactiveBootstrapConfiguration {
|
||||
"Cannot construct VaultTokenSupplier. Please configure VaultTokenSupplier bean named vaultTokenSupplier.");
|
||||
}
|
||||
|
||||
private VaultTokenSupplier createAuthenticationStepsOperator(
|
||||
AuthenticationStepsFactory factory) {
|
||||
private VaultTokenSupplier createAuthenticationStepsOperator(AuthenticationStepsFactory factory) {
|
||||
WebClient webClient = this.webClientBuilder.build();
|
||||
return new AuthenticationStepsOperator(factory.getAuthenticationSteps(),
|
||||
webClient);
|
||||
return new AuthenticationStepsOperator(factory.getAuthenticationSteps(), webClient);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -47,13 +47,11 @@ public class VaultReactiveHealthIndicator extends AbstractReactiveHealthIndicato
|
||||
this.vaultOperations = vaultOperations;
|
||||
}
|
||||
|
||||
private static Mono<? extends VaultHealthImpl> deserializeError(
|
||||
WebClientResponseException e) {
|
||||
private static Mono<? extends VaultHealthImpl> deserializeError(WebClientResponseException e) {
|
||||
|
||||
try {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
return Mono.just(mapper.readValue(e.getResponseBodyAsByteArray(),
|
||||
VaultHealthImpl.class));
|
||||
return Mono.just(mapper.readValue(e.getResponseBodyAsByteArray(), VaultHealthImpl.class));
|
||||
}
|
||||
catch (Exception jsonError) {
|
||||
UndeclaredThrowableException t = new UndeclaredThrowableException(jsonError);
|
||||
@@ -62,8 +60,7 @@ public class VaultReactiveHealthIndicator extends AbstractReactiveHealthIndicato
|
||||
}
|
||||
}
|
||||
|
||||
private static Health getHealth(Builder builder,
|
||||
VaultHealthImpl vaultHealthResponse) {
|
||||
private static Health getHealth(Builder builder, VaultHealthImpl vaultHealthResponse) {
|
||||
|
||||
HealthBuilderDelegate.contributeToHealth(vaultHealthResponse, builder);
|
||||
return builder.build();
|
||||
@@ -73,11 +70,10 @@ public class VaultReactiveHealthIndicator extends AbstractReactiveHealthIndicato
|
||||
protected Mono<Health> doHealthCheck(Builder builder) {
|
||||
|
||||
return this.vaultOperations
|
||||
.doWithSession((it) -> it.get().uri("sys/health")
|
||||
.header(VaultHttpHeaders.VAULT_NAMESPACE, "").exchange())
|
||||
.doWithSession(
|
||||
(it) -> it.get().uri("sys/health").header(VaultHttpHeaders.VAULT_NAMESPACE, "").exchange())
|
||||
.flatMap((it) -> it.bodyToMono(VaultHealthImpl.class))
|
||||
.onErrorResume(WebClientResponseException.class,
|
||||
VaultReactiveHealthIndicator::deserializeError)
|
||||
.onErrorResume(WebClientResponseException.class, VaultReactiveHealthIndicator::deserializeError)
|
||||
.map((vaultHealthResponse) -> getHealth(builder, vaultHealthResponse));
|
||||
}
|
||||
|
||||
@@ -99,13 +95,11 @@ public class VaultReactiveHealthIndicator extends AbstractReactiveHealthIndicato
|
||||
@Nullable
|
||||
private final String version;
|
||||
|
||||
VaultHealthImpl(@JsonProperty("initialized") boolean initialized,
|
||||
@JsonProperty("sealed") boolean sealed,
|
||||
VaultHealthImpl(@JsonProperty("initialized") boolean initialized, @JsonProperty("sealed") boolean sealed,
|
||||
@JsonProperty("standby") boolean standby,
|
||||
@JsonProperty("performance_standby") boolean performanceStandby,
|
||||
@Nullable @JsonProperty("replication_dr_mode") String replicationRecoverySecondary,
|
||||
@JsonProperty("server_time_utc") int serverTimeUtc,
|
||||
@Nullable @JsonProperty("version") String version) {
|
||||
@JsonProperty("server_time_utc") int serverTimeUtc, @Nullable @JsonProperty("version") String version) {
|
||||
|
||||
this.initialized = initialized;
|
||||
this.sealed = sealed;
|
||||
@@ -155,19 +149,16 @@ public class VaultReactiveHealthIndicator extends AbstractReactiveHealthIndicato
|
||||
return false;
|
||||
}
|
||||
VaultHealthImpl that = (VaultHealthImpl) o;
|
||||
return this.initialized == that.initialized && this.sealed == that.sealed
|
||||
&& this.standby == that.standby
|
||||
return this.initialized == that.initialized && this.sealed == that.sealed && this.standby == that.standby
|
||||
&& this.performanceStandby == that.performanceStandby
|
||||
&& this.replicationRecoverySecondary == that.replicationRecoverySecondary
|
||||
&& this.serverTimeUtc == that.serverTimeUtc
|
||||
&& Objects.equals(this.version, that.version);
|
||||
&& this.serverTimeUtc == that.serverTimeUtc && Objects.equals(this.version, that.version);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.initialized, this.sealed, this.standby,
|
||||
this.performanceStandby, this.replicationRecoverySecondary,
|
||||
this.serverTimeUtc, this.version);
|
||||
return Objects.hash(this.initialized, this.sealed, this.standby, this.performanceStandby,
|
||||
this.replicationRecoverySecondary, this.serverTimeUtc, this.version);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,13 +38,12 @@ import org.springframework.vault.core.ReactiveVaultOperations;
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(Flux.class)
|
||||
@ConditionalOnBean(ReactiveVaultOperations.class)
|
||||
class VaultReactiveHealthIndicatorConfiguration extends
|
||||
CompositeReactiveHealthContributorConfiguration<VaultReactiveHealthIndicator, ReactiveVaultOperations> {
|
||||
class VaultReactiveHealthIndicatorConfiguration
|
||||
extends CompositeReactiveHealthContributorConfiguration<VaultReactiveHealthIndicator, ReactiveVaultOperations> {
|
||||
|
||||
private final Map<String, ReactiveVaultOperations> reactiveVaultTemplates;
|
||||
|
||||
VaultReactiveHealthIndicatorConfiguration(
|
||||
Map<String, ReactiveVaultOperations> reactiveVaultTemplates) {
|
||||
VaultReactiveHealthIndicatorConfiguration(Map<String, ReactiveVaultOperations> reactiveVaultTemplates) {
|
||||
this.reactiveVaultTemplates = reactiveVaultTemplates;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,9 +37,8 @@ public class ApplicationFailFastTests {
|
||||
@Test
|
||||
public void contextLoadsWithFailFastUsingLeasing() {
|
||||
try {
|
||||
new SpringApplicationBuilder().sources(ApplicationFailFastTests.class).run(
|
||||
"--server.port=0", "--spring.cloud.vault.failFast=true",
|
||||
"--spring.cloud.vault.config.lifecycle.enabled=true",
|
||||
new SpringApplicationBuilder().sources(ApplicationFailFastTests.class).run("--server.port=0",
|
||||
"--spring.cloud.vault.failFast=true", "--spring.cloud.vault.config.lifecycle.enabled=true",
|
||||
"--spring.cloud.vault.port=9999");
|
||||
fail("failFast option did not produce an exception");
|
||||
}
|
||||
@@ -51,11 +50,9 @@ public class ApplicationFailFastTests {
|
||||
@Test
|
||||
public void contextLoadsWithFailFastWithoutLeasing() {
|
||||
try {
|
||||
new SpringApplicationBuilder().sources(ApplicationFailFastTests.class).run(
|
||||
"--server.port=0", "--spring.cloud.vault.failFast=true",
|
||||
"--spring.cloud.vault.config.lifecycle.enabled=false",
|
||||
"--spring.cloud.vault.session.lifecycle.enabled=false",
|
||||
"--spring.cloud.vault.port=9999");
|
||||
new SpringApplicationBuilder().sources(ApplicationFailFastTests.class).run("--server.port=0",
|
||||
"--spring.cloud.vault.failFast=true", "--spring.cloud.vault.config.lifecycle.enabled=false",
|
||||
"--spring.cloud.vault.session.lifecycle.enabled=false", "--spring.cloud.vault.port=9999");
|
||||
fail("failFast option did not produce an exception");
|
||||
}
|
||||
catch (Exception e) {
|
||||
@@ -66,9 +63,8 @@ public class ApplicationFailFastTests {
|
||||
@Test
|
||||
@Ignore("Fails because of method errors in Discovery health check")
|
||||
public void contextLoadsWithoutFailFast() {
|
||||
new SpringApplicationBuilder().sources(ApplicationFailFastTests.class).run(
|
||||
"--server.port=0", "--spring.cloud.vault.failFast=false",
|
||||
"--spring.cloud.vault.port=9999");
|
||||
new SpringApplicationBuilder().sources(ApplicationFailFastTests.class).run("--server.port=0",
|
||||
"--spring.cloud.vault.failFast=false", "--spring.cloud.vault.port=9999");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -44,12 +44,10 @@ public class ClientAuthenticationFactoryUnitTests {
|
||||
properties.getAppRole().setRoleId("foo");
|
||||
properties.getAppRole().setSecretId("bar");
|
||||
|
||||
AppRoleAuthenticationOptions options = ClientAuthenticationFactory
|
||||
.getAppRoleAuthenticationOptions(properties);
|
||||
AppRoleAuthenticationOptions options = ClientAuthenticationFactory.getAppRoleAuthenticationOptions(properties);
|
||||
|
||||
assertThat(options.getRoleId()).isInstanceOf(RoleId.provided("foo").getClass());
|
||||
assertThat(options.getSecretId())
|
||||
.isInstanceOf(SecretId.provided("bar").getClass());
|
||||
assertThat(options.getSecretId()).isInstanceOf(SecretId.provided("bar").getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -58,8 +56,7 @@ public class ClientAuthenticationFactoryUnitTests {
|
||||
VaultProperties properties = new VaultProperties();
|
||||
properties.getAppRole().setRoleId("foo");
|
||||
|
||||
AppRoleAuthenticationOptions options = ClientAuthenticationFactory
|
||||
.getAppRoleAuthenticationOptions(properties);
|
||||
AppRoleAuthenticationOptions options = ClientAuthenticationFactory.getAppRoleAuthenticationOptions(properties);
|
||||
|
||||
assertThat(options.getRoleId()).isInstanceOf(RoleId.provided("foo").getClass());
|
||||
assertThat(options.getSecretId()).isInstanceOf(SecretId.absent().getClass());
|
||||
@@ -73,13 +70,11 @@ public class ClientAuthenticationFactoryUnitTests {
|
||||
properties.getAppRole().setRoleId("foo");
|
||||
properties.getAppRole().setRole("my-role");
|
||||
|
||||
AppRoleAuthenticationOptions options = ClientAuthenticationFactory
|
||||
.getAppRoleAuthenticationOptions(properties);
|
||||
AppRoleAuthenticationOptions options = ClientAuthenticationFactory.getAppRoleAuthenticationOptions(properties);
|
||||
|
||||
assertThat(options.getAppRole()).isEqualTo("my-role");
|
||||
assertThat(options.getRoleId()).isInstanceOf(RoleId.provided("foo").getClass());
|
||||
assertThat(options.getSecretId())
|
||||
.isInstanceOf(SecretId.pull(VaultToken.of("token")).getClass());
|
||||
assertThat(options.getSecretId()).isInstanceOf(SecretId.pull(VaultToken.of("token")).getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -89,14 +84,11 @@ public class ClientAuthenticationFactoryUnitTests {
|
||||
properties.setToken("token");
|
||||
properties.getAppRole().setRole("my-role");
|
||||
|
||||
AppRoleAuthenticationOptions options = ClientAuthenticationFactory
|
||||
.getAppRoleAuthenticationOptions(properties);
|
||||
AppRoleAuthenticationOptions options = ClientAuthenticationFactory.getAppRoleAuthenticationOptions(properties);
|
||||
|
||||
assertThat(options.getAppRole()).isEqualTo("my-role");
|
||||
assertThat(options.getRoleId())
|
||||
.isInstanceOf(RoleId.pull(VaultToken.of("token")).getClass());
|
||||
assertThat(options.getSecretId())
|
||||
.isInstanceOf(SecretId.pull(VaultToken.of("token")).getClass());
|
||||
assertThat(options.getRoleId()).isInstanceOf(RoleId.pull(VaultToken.of("token")).getClass());
|
||||
assertThat(options.getSecretId()).isInstanceOf(SecretId.pull(VaultToken.of("token")).getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -105,13 +97,10 @@ public class ClientAuthenticationFactoryUnitTests {
|
||||
VaultProperties properties = new VaultProperties();
|
||||
properties.setToken("token");
|
||||
|
||||
AppRoleAuthenticationOptions options = ClientAuthenticationFactory
|
||||
.getAppRoleAuthenticationOptions(properties);
|
||||
AppRoleAuthenticationOptions options = ClientAuthenticationFactory.getAppRoleAuthenticationOptions(properties);
|
||||
|
||||
assertThat(options.getRoleId())
|
||||
.isInstanceOf(RoleId.wrapped(VaultToken.of("token")).getClass());
|
||||
assertThat(options.getSecretId())
|
||||
.isInstanceOf(SecretId.wrapped(VaultToken.of("token")).getClass());
|
||||
assertThat(options.getRoleId()).isInstanceOf(RoleId.wrapped(VaultToken.of("token")).getClass());
|
||||
assertThat(options.getSecretId()).isInstanceOf(SecretId.wrapped(VaultToken.of("token")).getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -121,13 +110,10 @@ public class ClientAuthenticationFactoryUnitTests {
|
||||
properties.setToken("token");
|
||||
properties.getAppRole().setSecretId("bar");
|
||||
|
||||
AppRoleAuthenticationOptions options = ClientAuthenticationFactory
|
||||
.getAppRoleAuthenticationOptions(properties);
|
||||
AppRoleAuthenticationOptions options = ClientAuthenticationFactory.getAppRoleAuthenticationOptions(properties);
|
||||
|
||||
assertThat(options.getRoleId())
|
||||
.isInstanceOf(RoleId.wrapped(VaultToken.of("token")).getClass());
|
||||
assertThat(options.getSecretId())
|
||||
.isInstanceOf(SecretId.provided("bar").getClass());
|
||||
assertThat(options.getRoleId()).isInstanceOf(RoleId.wrapped(VaultToken.of("token")).getClass());
|
||||
assertThat(options.getSecretId()).isInstanceOf(SecretId.provided("bar").getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -137,12 +123,10 @@ public class ClientAuthenticationFactoryUnitTests {
|
||||
properties.setToken("token");
|
||||
properties.getAppRole().setRoleId("foo");
|
||||
|
||||
AppRoleAuthenticationOptions options = ClientAuthenticationFactory
|
||||
.getAppRoleAuthenticationOptions(properties);
|
||||
AppRoleAuthenticationOptions options = ClientAuthenticationFactory.getAppRoleAuthenticationOptions(properties);
|
||||
|
||||
assertThat(options.getRoleId()).isInstanceOf(RoleId.provided("foo").getClass());
|
||||
assertThat(options.getSecretId())
|
||||
.isInstanceOf(SecretId.wrapped(VaultToken.of("token")).getClass());
|
||||
assertThat(options.getSecretId()).isInstanceOf(SecretId.wrapped(VaultToken.of("token")).getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -150,9 +134,8 @@ public class ClientAuthenticationFactoryUnitTests {
|
||||
|
||||
VaultProperties properties = new VaultProperties();
|
||||
|
||||
assertThatThrownBy(() -> ClientAuthenticationFactory
|
||||
.getAppRoleAuthenticationOptions(properties))
|
||||
.isInstanceOf(IllegalArgumentException.class);
|
||||
assertThatThrownBy(() -> ClientAuthenticationFactory.getAppRoleAuthenticationOptions(properties))
|
||||
.isInstanceOf(IllegalArgumentException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -161,9 +144,8 @@ public class ClientAuthenticationFactoryUnitTests {
|
||||
VaultProperties properties = new VaultProperties();
|
||||
properties.getAppRole().setRole("my-role");
|
||||
|
||||
assertThatThrownBy(() -> ClientAuthenticationFactory
|
||||
.getAppRoleAuthenticationOptions(properties))
|
||||
.isInstanceOf(IllegalArgumentException.class);
|
||||
assertThatThrownBy(() -> ClientAuthenticationFactory.getAppRoleAuthenticationOptions(properties))
|
||||
.isInstanceOf(IllegalArgumentException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -173,12 +155,10 @@ public class ClientAuthenticationFactoryUnitTests {
|
||||
properties.setAuthentication(VaultProperties.AuthenticationMethod.PCF);
|
||||
properties.getPcf().setRole("my-role");
|
||||
properties.getPcf().setInstanceKey(new ClassPathResource("bootstrap.yml"));
|
||||
properties.getPcf()
|
||||
.setInstanceCertificate(new ClassPathResource("bootstrap.yml"));
|
||||
properties.getPcf().setInstanceCertificate(new ClassPathResource("bootstrap.yml"));
|
||||
|
||||
ClientAuthentication clientAuthentication = new ClientAuthenticationFactory(
|
||||
properties, new RestTemplate(), new RestTemplate())
|
||||
.createClientAuthentication();
|
||||
ClientAuthentication clientAuthentication = new ClientAuthenticationFactory(properties, new RestTemplate(),
|
||||
new RestTemplate()).createClientAuthentication();
|
||||
|
||||
assertThat(clientAuthentication).isInstanceOf(PcfAuthentication.class);
|
||||
}
|
||||
|
||||
@@ -44,25 +44,20 @@ import static org.mockito.Mockito.when;
|
||||
*/
|
||||
public class DiscoveryClientVaultBootstrapConfigurationTests {
|
||||
|
||||
private ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(
|
||||
DiscoveryClientVaultBootstrapConfiguration.class,
|
||||
VaultBootstrapConfiguration.class));
|
||||
private ApplicationContextRunner contextRunner = new ApplicationContextRunner().withConfiguration(
|
||||
AutoConfigurations.of(DiscoveryClientVaultBootstrapConfiguration.class, VaultBootstrapConfiguration.class));
|
||||
|
||||
@Test
|
||||
public void shouldRegisterDefaultBeans() {
|
||||
|
||||
this.contextRunner.withUserConfiguration(DiscoveryConfiguration.class)
|
||||
.withPropertyValues("spring.cloud.vault.token=foo",
|
||||
"spring.cloud.vault.discovery.enabled=true")
|
||||
.withPropertyValues("spring.cloud.vault.token=foo", "spring.cloud.vault.discovery.enabled=true")
|
||||
.run(context -> {
|
||||
|
||||
assertThat(context.getBean(VaultServiceInstanceProvider.class))
|
||||
.isInstanceOf(
|
||||
DiscoveryClientVaultServiceInstanceProvider.class);
|
||||
.isInstanceOf(DiscoveryClientVaultServiceInstanceProvider.class);
|
||||
|
||||
VaultEndpointProvider endpointProvider = context
|
||||
.getBean(VaultEndpointProvider.class);
|
||||
VaultEndpointProvider endpointProvider = context.getBean(VaultEndpointProvider.class);
|
||||
VaultEndpoint vaultEndpoint = endpointProvider.getVaultEndpoint();
|
||||
assertThat(vaultEndpoint.getPort()).isEqualTo(1234);
|
||||
});
|
||||
@@ -72,13 +67,10 @@ public class DiscoveryClientVaultBootstrapConfigurationTests {
|
||||
public void shouldNotRegisterBeansIfDiscoveryDisabled() {
|
||||
|
||||
this.contextRunner.withUserConfiguration(DiscoveryConfiguration.class)
|
||||
.withPropertyValues("spring.cloud.vault.token=foo",
|
||||
"spring.cloud.vault.discovery.enabled=false")
|
||||
.withPropertyValues("spring.cloud.vault.token=foo", "spring.cloud.vault.discovery.enabled=false")
|
||||
.run(context -> {
|
||||
|
||||
assertThat(context
|
||||
.getBeanNamesForType(VaultServiceInstanceProvider.class))
|
||||
.isEmpty();
|
||||
assertThat(context.getBeanNamesForType(VaultServiceInstanceProvider.class)).isEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -86,13 +78,9 @@ public class DiscoveryClientVaultBootstrapConfigurationTests {
|
||||
public void shouldNotRegisterBeansIfVaultDisabled() {
|
||||
|
||||
this.contextRunner.withUserConfiguration(DiscoveryConfiguration.class)
|
||||
.withPropertyValues("spring.cloud.vault.token=foo",
|
||||
"spring.cloud.vault.enabled=false")
|
||||
.run(context -> {
|
||||
.withPropertyValues("spring.cloud.vault.token=foo", "spring.cloud.vault.enabled=false").run(context -> {
|
||||
|
||||
assertThat(context
|
||||
.getBeanNamesForType(VaultServiceInstanceProvider.class))
|
||||
.isEmpty();
|
||||
assertThat(context.getBeanNamesForType(VaultServiceInstanceProvider.class)).isEmpty();
|
||||
});
|
||||
|
||||
}
|
||||
@@ -104,8 +92,8 @@ public class DiscoveryClientVaultBootstrapConfigurationTests {
|
||||
DiscoveryClient discoveryClient() {
|
||||
|
||||
DiscoveryClient mock = Mockito.mock(DiscoveryClient.class);
|
||||
when(mock.getInstances(anyString())).thenReturn(Collections.singletonList(
|
||||
new SimpleServiceInstance(URI.create("https://foo:1234"))));
|
||||
when(mock.getInstances(anyString()))
|
||||
.thenReturn(Collections.singletonList(new SimpleServiceInstance(URI.create("https://foo:1234"))));
|
||||
|
||||
return mock;
|
||||
}
|
||||
|
||||
@@ -36,8 +36,7 @@ public class KeyValueSecretBackendMetadataUnitTests {
|
||||
@Test
|
||||
public void shouldCreateDefaultContexts() {
|
||||
|
||||
List<String> contexts = KeyValueSecretBackendMetadata
|
||||
.buildContexts(this.properties, Collections.emptyList());
|
||||
List<String> contexts = KeyValueSecretBackendMetadata.buildContexts(this.properties, Collections.emptyList());
|
||||
|
||||
assertThat(contexts).hasSize(1).contains("application");
|
||||
}
|
||||
@@ -47,8 +46,7 @@ public class KeyValueSecretBackendMetadataUnitTests {
|
||||
|
||||
this.properties.setApplicationName("my-app");
|
||||
|
||||
List<String> contexts = KeyValueSecretBackendMetadata
|
||||
.buildContexts(this.properties, Collections.emptyList());
|
||||
List<String> contexts = KeyValueSecretBackendMetadata.buildContexts(this.properties, Collections.emptyList());
|
||||
|
||||
assertThat(contexts).hasSize(2).containsSequence("my-app", "application");
|
||||
}
|
||||
@@ -58,11 +56,11 @@ public class KeyValueSecretBackendMetadataUnitTests {
|
||||
|
||||
this.properties.setApplicationName("my-app");
|
||||
|
||||
List<String> contexts = KeyValueSecretBackendMetadata
|
||||
.buildContexts(this.properties, Arrays.asList("cloud", "local"));
|
||||
List<String> contexts = KeyValueSecretBackendMetadata.buildContexts(this.properties,
|
||||
Arrays.asList("cloud", "local"));
|
||||
|
||||
assertThat(contexts).hasSize(6).containsSequence("my-app/local", "my-app/cloud",
|
||||
"my-app", "application/local", "application/cloud", "application");
|
||||
assertThat(contexts).hasSize(6).containsSequence("my-app/local", "my-app/cloud", "my-app", "application/local",
|
||||
"application/cloud", "application");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -71,8 +69,7 @@ public class KeyValueSecretBackendMetadataUnitTests {
|
||||
this.properties.setApplicationName("my-app");
|
||||
this.properties.setDefaultContext("");
|
||||
|
||||
List<String> contexts = KeyValueSecretBackendMetadata
|
||||
.buildContexts(this.properties, Collections.emptyList());
|
||||
List<String> contexts = KeyValueSecretBackendMetadata.buildContexts(this.properties, Collections.emptyList());
|
||||
|
||||
assertThat(contexts).hasSize(1).containsSequence("my-app");
|
||||
}
|
||||
@@ -82,8 +79,7 @@ public class KeyValueSecretBackendMetadataUnitTests {
|
||||
|
||||
this.properties.setApplicationName("foo,bar");
|
||||
|
||||
List<String> contexts = KeyValueSecretBackendMetadata
|
||||
.buildContexts(this.properties, Collections.emptyList());
|
||||
List<String> contexts = KeyValueSecretBackendMetadata.buildContexts(this.properties, Collections.emptyList());
|
||||
|
||||
assertThat(contexts).hasSize(3).containsSequence("bar", "foo", "application");
|
||||
}
|
||||
@@ -93,12 +89,11 @@ public class KeyValueSecretBackendMetadataUnitTests {
|
||||
|
||||
this.properties.setApplicationName("foo,bar");
|
||||
|
||||
List<String> contexts = KeyValueSecretBackendMetadata
|
||||
.buildContexts(this.properties, Arrays.asList("cloud", "local"));
|
||||
List<String> contexts = KeyValueSecretBackendMetadata.buildContexts(this.properties,
|
||||
Arrays.asList("cloud", "local"));
|
||||
|
||||
assertThat(contexts).hasSize(9).containsSequence("bar/local", "bar/cloud", "bar",
|
||||
"foo/local", "foo/cloud", "foo", "application/local", "application/cloud",
|
||||
"application");
|
||||
assertThat(contexts).hasSize(9).containsSequence("bar/local", "bar/cloud", "bar", "foo/local", "foo/cloud",
|
||||
"foo", "application/local", "application/cloud", "application");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -44,16 +44,14 @@ public class KeyValueSecretIntegrationTests extends IntegrationTestSupport {
|
||||
this.vaultProperties.setFailFast(false);
|
||||
prepare().getVaultOperations().write("secret/app-name", createData());
|
||||
|
||||
this.configOperations = new VaultConfigTemplate(prepare().getVaultOperations(),
|
||||
this.vaultProperties);
|
||||
this.configOperations = new VaultConfigTemplate(prepare().getVaultOperations(), this.vaultProperties);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnSecretsCorrectly() {
|
||||
|
||||
Map<String, Object> secretProperties = this.configOperations
|
||||
.read(KeyValueSecretBackendMetadata.create("secret", "app-name"))
|
||||
.getData();
|
||||
.read(KeyValueSecretBackendMetadata.create("secret", "app-name")).getData();
|
||||
|
||||
assertThat(secretProperties).containsAllEntriesOf(createExpectedMap());
|
||||
}
|
||||
@@ -61,8 +59,7 @@ public class KeyValueSecretIntegrationTests extends IntegrationTestSupport {
|
||||
@Test
|
||||
public void shouldReturnNullIfNotFound() {
|
||||
|
||||
Secrets secrets = this.configOperations
|
||||
.read(KeyValueSecretBackendMetadata.create("secret", "missing"));
|
||||
Secrets secrets = this.configOperations.read(KeyValueSecretBackendMetadata.create("secret", "missing"));
|
||||
|
||||
assertThat(secrets).isNull();
|
||||
}
|
||||
|
||||
@@ -52,10 +52,8 @@ public class LeasingVaultPropertySourceLocatorUnitTests {
|
||||
@Before
|
||||
public void before() {
|
||||
|
||||
this.propertySourceLocator = new LeasingVaultPropertySourceLocator(
|
||||
new VaultProperties(),
|
||||
VaultPropertySourceLocatorSupport.createConfiguration(this.properties),
|
||||
this.secretLeaseContainer);
|
||||
this.propertySourceLocator = new LeasingVaultPropertySourceLocator(new VaultProperties(),
|
||||
VaultPropertySourceLocatorSupport.createConfiguration(this.properties), this.secretLeaseContainer);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -64,9 +62,8 @@ public class LeasingVaultPropertySourceLocatorUnitTests {
|
||||
VaultProperties vaultProperties = new VaultProperties();
|
||||
vaultProperties.getConfig().setOrder(10);
|
||||
|
||||
this.propertySourceLocator = new LeasingVaultPropertySourceLocator(
|
||||
vaultProperties, VaultPropertySourceLocatorSupport.createConfiguration(
|
||||
new VaultKeyValueBackendProperties()),
|
||||
this.propertySourceLocator = new LeasingVaultPropertySourceLocator(vaultProperties,
|
||||
VaultPropertySourceLocatorSupport.createConfiguration(new VaultKeyValueBackendProperties()),
|
||||
this.secretLeaseContainer);
|
||||
|
||||
assertThat(this.propertySourceLocator.getOrder()).isEqualTo(10);
|
||||
@@ -75,15 +72,13 @@ public class LeasingVaultPropertySourceLocatorUnitTests {
|
||||
@Test
|
||||
public void shouldLocatePropertySources() {
|
||||
|
||||
PropertySource<?> propertySource = this.propertySourceLocator
|
||||
.locate(this.configurableEnvironment);
|
||||
PropertySource<?> propertySource = this.propertySourceLocator.locate(this.configurableEnvironment);
|
||||
|
||||
assertThat(propertySource).isInstanceOf(CompositePropertySource.class);
|
||||
|
||||
CompositePropertySource composite = (CompositePropertySource) propertySource;
|
||||
assertThat(composite.getPropertySources()).hasSize(1);
|
||||
verify(this.secretLeaseContainer)
|
||||
.addRequestedSecret(RequestedSecret.rotating("secret/application"));
|
||||
verify(this.secretLeaseContainer).addRequestedSecret(RequestedSecret.rotating("secret/application"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -94,17 +89,16 @@ public class LeasingVaultPropertySourceLocatorUnitTests {
|
||||
configurer.add(rotating);
|
||||
configurer.add("database/mysql/creds/readonly");
|
||||
|
||||
this.propertySourceLocator = new LeasingVaultPropertySourceLocator(
|
||||
new VaultProperties(), configurer, this.secretLeaseContainer);
|
||||
this.propertySourceLocator = new LeasingVaultPropertySourceLocator(new VaultProperties(), configurer,
|
||||
this.secretLeaseContainer);
|
||||
|
||||
PropertySource<?> propertySource = this.propertySourceLocator
|
||||
.locate(this.configurableEnvironment);
|
||||
PropertySource<?> propertySource = this.propertySourceLocator.locate(this.configurableEnvironment);
|
||||
|
||||
assertThat(propertySource).isInstanceOf(CompositePropertySource.class);
|
||||
|
||||
verify(this.secretLeaseContainer).addRequestedSecret(rotating);
|
||||
verify(this.secretLeaseContainer).addRequestedSecret(
|
||||
RequestedSecret.renewable("database/mysql/creds/readonly"));
|
||||
verify(this.secretLeaseContainer)
|
||||
.addRequestedSecret(RequestedSecret.renewable("database/mysql/creds/readonly"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -40,8 +40,8 @@ public class PropertyNameTransformerUnitTests {
|
||||
map.put("old-key", "value");
|
||||
map.put("other-key", "other-value");
|
||||
|
||||
assertThat(transformer.transformProperties(map)).containsEntry("new-key", "value")
|
||||
.containsEntry("other-key", "other-value");
|
||||
assertThat(transformer.transformProperties(map)).containsEntry("new-key", "value").containsEntry("other-key",
|
||||
"other-value");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -35,15 +35,15 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
*/
|
||||
public class ReactiveVaultBootstrapConfigurationTests {
|
||||
|
||||
private ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(VaultBootstrapConfiguration.class,
|
||||
VaultReactiveBootstrapConfiguration.class));
|
||||
private ApplicationContextRunner contextRunner = new ApplicationContextRunner().withConfiguration(
|
||||
AutoConfigurations.of(VaultBootstrapConfiguration.class, VaultReactiveBootstrapConfiguration.class));
|
||||
|
||||
@Test
|
||||
public void shouldConfigureWithoutAuthentication() {
|
||||
|
||||
this.contextRunner.withPropertyValues("spring.cloud.vault.kv.enabled=false",
|
||||
"spring.cloud.vault.authentication=NONE").run(context -> {
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.cloud.vault.kv.enabled=false", "spring.cloud.vault.authentication=NONE")
|
||||
.run(context -> {
|
||||
|
||||
assertThat(context).doesNotHaveBean(SessionManager.class);
|
||||
assertThat(context).doesNotHaveBean(ClientAuthentication.class);
|
||||
|
||||
@@ -47,8 +47,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = ReactiveVaultOperationsTests.TestApplication.class,
|
||||
properties = { "spring.cloud.vault.host=foo",
|
||||
"spring.cloud.vault.uri=https://localhost:8200" })
|
||||
properties = { "spring.cloud.vault.host=foo", "spring.cloud.vault.uri=https://localhost:8200" })
|
||||
public class ReactiveVaultOperationsTests {
|
||||
|
||||
@Autowired
|
||||
@@ -70,10 +69,9 @@ public class ReactiveVaultOperationsTests {
|
||||
@Test
|
||||
public void shouldAccessVault() {
|
||||
|
||||
StepVerifier.create(this.reactiveOperations.read("secret/testVaultApp"))
|
||||
.consumeNextWith(actual -> {
|
||||
assertThat(actual.getData()).containsEntry("vault.value", "foo");
|
||||
}).verifyComplete();
|
||||
StepVerifier.create(this.reactiveOperations.read("secret/testVaultApp")).consumeNextWith(actual -> {
|
||||
assertThat(actual.getData()).containsEntry("vault.value", "foo");
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@SpringBootApplication
|
||||
|
||||
@@ -42,22 +42,19 @@ import static org.mockito.Mockito.verify;
|
||||
public class VaultBootstrapPropertySourceConfigurationTests {
|
||||
|
||||
private ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations
|
||||
.of(VaultBootstrapPropertySourceConfiguration.class));
|
||||
.withConfiguration(AutoConfigurations.of(VaultBootstrapPropertySourceConfiguration.class));
|
||||
|
||||
@Test
|
||||
public void shouldConfigureExpiryTimeouts() {
|
||||
|
||||
this.contextRunner.withUserConfiguration(MockConfiguration.class)
|
||||
.withAllowBeanDefinitionOverriding(true)
|
||||
this.contextRunner.withUserConfiguration(MockConfiguration.class).withAllowBeanDefinitionOverriding(true)
|
||||
.withPropertyValues("spring.cloud.vault.kv.enabled=false",
|
||||
"spring.cloud.vault.config.lifecycle.expiry-threshold=5m",
|
||||
"spring.cloud.vault.config.lifecycle.min-renewal=6m",
|
||||
"spring.cloud.vault.config.lifecycle.lease-endpoints=SysLeases")
|
||||
.run(context -> {
|
||||
|
||||
SecretLeaseContainer container = context
|
||||
.getBean(SecretLeaseContainer.class);
|
||||
SecretLeaseContainer container = context.getBean(SecretLeaseContainer.class);
|
||||
verify(container).setExpiryThreshold(Duration.ofMinutes(5));
|
||||
verify(container).setMinRenewal(Duration.ofMinutes(6));
|
||||
verify(container).setLeaseEndpoints(LeaseEndpoints.SysLeases);
|
||||
@@ -75,8 +72,7 @@ public class VaultBootstrapPropertySourceConfigurationTests {
|
||||
|
||||
@Bean
|
||||
VaultBootstrapConfiguration.TaskSchedulerWrapper taskSchedulerWrapper() {
|
||||
return new VaultBootstrapConfiguration.TaskSchedulerWrapper(
|
||||
mock(ThreadPoolTaskScheduler.class));
|
||||
return new VaultBootstrapConfiguration.TaskSchedulerWrapper(mock(ThreadPoolTaskScheduler.class));
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -84,8 +80,7 @@ public class VaultBootstrapPropertySourceConfigurationTests {
|
||||
|
||||
SecretLeaseContainer mock = mock(SecretLeaseContainer.class);
|
||||
|
||||
VaultBootstrapPropertySourceConfiguration
|
||||
.customizeContainer(properties.getConfig().getLifecycle(), mock);
|
||||
VaultBootstrapPropertySourceConfiguration.customizeContainer(properties.getConfig().getLifecycle(), mock);
|
||||
|
||||
return mock;
|
||||
}
|
||||
|
||||
@@ -79,20 +79,17 @@ public class VaultConfigAppIdCustomMechanismTests {
|
||||
+ " }\n" //
|
||||
+ "}";
|
||||
|
||||
vaultOperations.write("sys/policy/testpolicy",
|
||||
Collections.singletonMap("rules", rules));
|
||||
vaultOperations.write("sys/policy/testpolicy", Collections.singletonMap("rules", rules));
|
||||
|
||||
String appId = VaultConfigAppIdCustomMechanismTests.class.getSimpleName();
|
||||
|
||||
vaultOperations.write("secret/" + appId,
|
||||
Collections.singletonMap("vault.value", appId));
|
||||
vaultOperations.write("secret/" + appId, Collections.singletonMap("vault.value", appId));
|
||||
|
||||
Map<String, String> appIdData = new HashMap<>();
|
||||
appIdData.put("value", "testpolicy"); // policy
|
||||
appIdData.put("display_name", "this is my test application");
|
||||
|
||||
vaultOperations.write(String.format("auth/app-id/map/app-id/%s", appId),
|
||||
appIdData);
|
||||
vaultOperations.write(String.format("auth/app-id/map/app-id/%s", appId), appIdData);
|
||||
|
||||
Map<String, String> userIdData = new HashMap<>();
|
||||
userIdData.put("value", appId); // name of the app-id
|
||||
@@ -100,8 +97,7 @@ public class VaultConfigAppIdCustomMechanismTests {
|
||||
|
||||
String userId = new StaticUserIdMechanism().createUserId();
|
||||
|
||||
vaultOperations.write(String.format("auth/app-id/map/user-id/%s", userId),
|
||||
userIdData);
|
||||
vaultOperations.write(String.format("auth/app-id/map/user-id/%s", userId), userIdData);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -125,15 +121,11 @@ public class VaultConfigAppIdCustomMechanismTests {
|
||||
@Bean
|
||||
ClientAuthentication clientAuthentication() {
|
||||
|
||||
RestTemplate restTemplate = TestRestTemplateFactory
|
||||
.create(Settings.createSslConfiguration());
|
||||
RestTemplate restTemplate = TestRestTemplateFactory.create(Settings.createSslConfiguration());
|
||||
|
||||
return new AppIdAuthentication(
|
||||
AppIdAuthenticationOptions.builder()
|
||||
.appId(VaultConfigAppIdCustomMechanismTests.class
|
||||
.getSimpleName())
|
||||
.userIdMechanism(new StaticUserIdMechanism()).build(),
|
||||
restTemplate);
|
||||
return new AppIdAuthentication(AppIdAuthenticationOptions.builder()
|
||||
.appId(VaultConfigAppIdCustomMechanismTests.class.getSimpleName())
|
||||
.userIdMechanism(new StaticUserIdMechanism()).build(), restTemplate);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -48,8 +48,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = VaultConfigAppIdTests.TestApplication.class,
|
||||
properties = { "spring.cloud.vault.authentication=appid",
|
||||
"spring.cloud.vault.app-id.user-id=IP_ADDRESS",
|
||||
properties = { "spring.cloud.vault.authentication=appid", "spring.cloud.vault.app-id.user-id=IP_ADDRESS",
|
||||
"spring.cloud.vault.application-name=VaultConfigAppIdTests" })
|
||||
// see
|
||||
// https://github.com/spring-cloud/spring-cloud-commons/issues/214
|
||||
@@ -80,8 +79,7 @@ public class VaultConfigAppIdTests {
|
||||
+ " }\n" //
|
||||
+ "}";
|
||||
|
||||
vaultOperations.write("sys/policy/testpolicy",
|
||||
Collections.singletonMap("rules", rules));
|
||||
vaultOperations.write("sys/policy/testpolicy", Collections.singletonMap("rules", rules));
|
||||
|
||||
String appId = VaultConfigAppIdTests.class.getSimpleName();
|
||||
|
||||
@@ -92,8 +90,7 @@ public class VaultConfigAppIdTests {
|
||||
appIdData.put("value", "testpolicy"); // policy
|
||||
appIdData.put("display_name", "this is my test application");
|
||||
|
||||
vaultOperations.write(String.format("auth/app-id/map/app-id/%s", appId),
|
||||
appIdData);
|
||||
vaultOperations.write(String.format("auth/app-id/map/app-id/%s", appId), appIdData);
|
||||
|
||||
Map<String, String> userIdData = new HashMap<>();
|
||||
userIdData.put("value", appId); // name of the app-id
|
||||
@@ -101,8 +98,7 @@ public class VaultConfigAppIdTests {
|
||||
|
||||
String userId = new IpAddressUserId().createUserId();
|
||||
|
||||
vaultOperations.write(String.format("auth/app-id/map/user-id/%s", userId),
|
||||
userIdData);
|
||||
vaultOperations.write(String.format("auth/app-id/map/user-id/%s", userId), userIdData);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -48,9 +48,8 @@ import static org.junit.Assume.assumeTrue;
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = VaultConfigAppRoleTests.TestApplication.class,
|
||||
properties = { "spring.cloud.vault.authentication=approle",
|
||||
"spring.cloud.vault.application-name=VaultConfigAppRoleTests" })
|
||||
@SpringBootTest(classes = VaultConfigAppRoleTests.TestApplication.class, properties = {
|
||||
"spring.cloud.vault.authentication=approle", "spring.cloud.vault.application-name=VaultConfigAppRoleTests" })
|
||||
// see
|
||||
// https://github.com/spring-cloud/spring-cloud-commons/issues/214
|
||||
public class VaultConfigAppRoleTests {
|
||||
@@ -64,8 +63,7 @@ public class VaultConfigAppRoleTests {
|
||||
VaultRule vaultRule = new VaultRule();
|
||||
vaultRule.before();
|
||||
|
||||
assumeTrue(vaultRule.prepare().getVersion()
|
||||
.isGreaterThanOrEqualTo(Version.parse("0.6.1")));
|
||||
assumeTrue(vaultRule.prepare().getVersion().isGreaterThanOrEqualTo(Version.parse("0.6.1")));
|
||||
|
||||
VaultProperties vaultProperties = Settings.createVaultProperties();
|
||||
|
||||
@@ -81,8 +79,7 @@ public class VaultConfigAppRoleTests {
|
||||
+ " }\n" //
|
||||
+ "}";
|
||||
|
||||
vaultOperations.write("sys/policy/testpolicy",
|
||||
Collections.singletonMap("rules", rules));
|
||||
vaultOperations.write("sys/policy/testpolicy", Collections.singletonMap("rules", rules));
|
||||
|
||||
String appId = VaultConfigAppRoleTests.class.getSimpleName();
|
||||
|
||||
@@ -96,13 +93,11 @@ public class VaultConfigAppRoleTests {
|
||||
|
||||
vaultOperations.write("auth/approle/role/with-secret-id", withSecretId);
|
||||
|
||||
String roleId = (String) vaultOperations
|
||||
.read("auth/approle/role/with-secret-id/role-id").getData()
|
||||
String roleId = (String) vaultOperations.read("auth/approle/role/with-secret-id/role-id").getData()
|
||||
.get("role_id");
|
||||
String secretId = (String) vaultOperations
|
||||
.write(String.format("auth/approle/role/with-secret-id/secret-id",
|
||||
"with-secret-id"), null)
|
||||
.getData().get("secret_id");
|
||||
.write(String.format("auth/approle/role/with-secret-id/secret-id", "with-secret-id"), null).getData()
|
||||
.get("secret_id");
|
||||
|
||||
System.setProperty("spring.cloud.vault.app-role.role-id", roleId);
|
||||
System.setProperty("spring.cloud.vault.app-role.secret-id", secretId);
|
||||
|
||||
@@ -63,23 +63,19 @@ public class VaultConfigCubbyholeAuthenticationTests {
|
||||
VaultRule vaultRule = new VaultRule();
|
||||
vaultRule.before();
|
||||
|
||||
assumeTrue(vaultRule.prepare().getVersion()
|
||||
.isGreaterThanOrEqualTo(Version.parse("0.6.1")));
|
||||
assumeTrue(vaultRule.prepare().getVersion().isGreaterThanOrEqualTo(Version.parse("0.6.1")));
|
||||
|
||||
VaultOperations vaultOperations = vaultRule.prepare().getVaultOperations();
|
||||
|
||||
vaultOperations.write(
|
||||
"secret/" + VaultConfigCubbyholeAuthenticationTests.class.getSimpleName(),
|
||||
Collections.singletonMap("vault.value",
|
||||
VaultConfigCubbyholeAuthenticationTests.class.getSimpleName()));
|
||||
vaultOperations.write("secret/" + VaultConfigCubbyholeAuthenticationTests.class.getSimpleName(),
|
||||
Collections.singletonMap("vault.value", VaultConfigCubbyholeAuthenticationTests.class.getSimpleName()));
|
||||
|
||||
VaultResponse vaultResponse = vaultOperations.doWithSession(restOperations -> {
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.add("X-Vault-Wrap-TTL", "1h");
|
||||
|
||||
return restOperations.postForObject("/auth/token/create",
|
||||
new HttpEntity<>(headers), VaultResponse.class);
|
||||
return restOperations.postForObject("/auth/token/create", new HttpEntity<>(headers), VaultResponse.class);
|
||||
});
|
||||
|
||||
String initialToken = vaultResponse.getWrapInfo().get("token");
|
||||
|
||||
@@ -77,8 +77,7 @@ public class VaultConfigDisabledTests {
|
||||
ApplicationContext parent = this.applicationContext.getParent();
|
||||
|
||||
assertThat(parent.getBeanNamesForType(VaultTemplate.class)).isEmpty();
|
||||
assertThat(parent.getBeanNamesForType(VaultPropertySourceLocator.class))
|
||||
.isEmpty();
|
||||
assertThat(parent.getBeanNamesForType(VaultPropertySourceLocator.class)).isEmpty();
|
||||
}
|
||||
|
||||
@SpringBootApplication
|
||||
|
||||
@@ -50,11 +50,10 @@ import static org.springframework.cloud.vault.util.Settings.findWorkDir;
|
||||
* @author Michal Budzyn
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = VaultConfigKubernetesTests.TestApplication.class, properties = {
|
||||
"spring.cloud.vault.authentication=kubernetes",
|
||||
"spring.cloud.vault.kubernetes.role=my-role",
|
||||
"spring.cloud.vault.kubernetes.service-account-token-file=../work/minikube/hello-minikube-token",
|
||||
"spring.cloud.vault.application-name=VaultConfigKubernetesTests" })
|
||||
@SpringBootTest(classes = VaultConfigKubernetesTests.TestApplication.class,
|
||||
properties = { "spring.cloud.vault.authentication=kubernetes", "spring.cloud.vault.kubernetes.role=my-role",
|
||||
"spring.cloud.vault.kubernetes.service-account-token-file=../work/minikube/hello-minikube-token",
|
||||
"spring.cloud.vault.application-name=VaultConfigKubernetesTests" })
|
||||
public class VaultConfigKubernetesTests {
|
||||
|
||||
@Value("${vault.value}")
|
||||
@@ -67,8 +66,8 @@ public class VaultConfigKubernetesTests {
|
||||
vaultRule.before();
|
||||
|
||||
String minikubeIp = System.getProperty("MINIKUBE_IP");
|
||||
assumeTrue(StringUtils.hasText(minikubeIp) && vaultRule.prepare().getVersion()
|
||||
.isGreaterThanOrEqualTo(Version.parse("0.8.3")));
|
||||
assumeTrue(StringUtils.hasText(minikubeIp)
|
||||
&& vaultRule.prepare().getVersion().isGreaterThanOrEqualTo(Version.parse("0.8.3")));
|
||||
|
||||
if (!vaultRule.prepare().hasAuth("kubernetes")) {
|
||||
vaultRule.prepare().mountAuth("kubernetes");
|
||||
@@ -76,18 +75,15 @@ public class VaultConfigKubernetesTests {
|
||||
|
||||
VaultOperations vaultOperations = vaultRule.prepare().getVaultOperations();
|
||||
|
||||
Policy policy = Policy.of(
|
||||
Rule.builder().path("*").capabilities(BuiltinCapabilities.READ).build());
|
||||
Policy policy = Policy.of(Rule.builder().path("*").capabilities(BuiltinCapabilities.READ).build());
|
||||
|
||||
vaultOperations.opsForSys().createOrUpdatePolicy("testpolicy", policy);
|
||||
|
||||
vaultOperations.write(
|
||||
"secret/" + VaultConfigKubernetesTests.class.getSimpleName(),
|
||||
vaultOperations.write("secret/" + VaultConfigKubernetesTests.class.getSimpleName(),
|
||||
Collections.singletonMap("vault.value", "foo"));
|
||||
|
||||
File workDir = findWorkDir();
|
||||
String certificate = Files.contentOf(new File(workDir, "minikube/ca.crt"),
|
||||
StandardCharsets.US_ASCII);
|
||||
String certificate = Files.contentOf(new File(workDir, "minikube/ca.crt"), StandardCharsets.US_ASCII);
|
||||
|
||||
String host = String.format("https://%s:8443", minikubeIp);
|
||||
Map<String, String> kubeConfig = new HashMap<>();
|
||||
|
||||
@@ -37,8 +37,7 @@ public class VaultConfigTemplateIntegrationTests extends IntegrationTestSupport
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
prepare().getVaultOperations().write("secret/myapp",
|
||||
Collections.singletonMap("key", "value"));
|
||||
prepare().getVaultOperations().write("secret/myapp", Collections.singletonMap("key", "value"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -46,11 +45,9 @@ public class VaultConfigTemplateIntegrationTests extends IntegrationTestSupport
|
||||
|
||||
VaultProperties vaultProperties = Settings.createVaultProperties();
|
||||
|
||||
VaultConfigTemplate template = new VaultConfigTemplate(
|
||||
prepare().getVaultOperations(), vaultProperties);
|
||||
VaultConfigTemplate template = new VaultConfigTemplate(prepare().getVaultOperations(), vaultProperties);
|
||||
|
||||
Secrets secrets = template
|
||||
.read(KeyValueSecretBackendMetadata.create("secret", "myapp"));
|
||||
Secrets secrets = template.read(KeyValueSecretBackendMetadata.create("secret", "myapp"));
|
||||
|
||||
assertThat(secrets.getData()).containsEntry("key", "value");
|
||||
}
|
||||
@@ -58,20 +55,16 @@ public class VaultConfigTemplateIntegrationTests extends IntegrationTestSupport
|
||||
@Test
|
||||
public void shouldReadVersionedValue() {
|
||||
|
||||
assumeTrue(this.vaultRule.prepare().getVersion()
|
||||
.isGreaterThanOrEqualTo(Version.parse("0.10.0")));
|
||||
assumeTrue(this.vaultRule.prepare().getVersion().isGreaterThanOrEqualTo(Version.parse("0.10.0")));
|
||||
|
||||
this.vaultRule.prepare().getVaultOperations().write("versioned/data/testVaultApp",
|
||||
Collections.singletonMap("data",
|
||||
Collections.singletonMap("key", "value")));
|
||||
Collections.singletonMap("data", Collections.singletonMap("key", "value")));
|
||||
|
||||
VaultProperties vaultProperties = Settings.createVaultProperties();
|
||||
|
||||
VaultConfigTemplate template = new VaultConfigTemplate(
|
||||
prepare().getVaultOperations(), vaultProperties);
|
||||
VaultConfigTemplate template = new VaultConfigTemplate(prepare().getVaultOperations(), vaultProperties);
|
||||
|
||||
Secrets secrets = template
|
||||
.read(KeyValueSecretBackendMetadata.create("versioned", "testVaultApp"));
|
||||
Secrets secrets = template.read(KeyValueSecretBackendMetadata.create("versioned", "testVaultApp"));
|
||||
|
||||
assertThat(secrets.getData()).containsEntry("key", "value");
|
||||
}
|
||||
|
||||
@@ -52,8 +52,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = VaultConfigTests.TestApplication.class,
|
||||
properties = { "spring.cloud.vault.host=foo", "spring.cloud.vault.port=80",
|
||||
"spring.cloud.vault.uri=https://localhost:8200",
|
||||
"spring.cloud.vault.application-name=testVaultApp" })
|
||||
"spring.cloud.vault.uri=https://localhost:8200", "spring.cloud.vault.application-name=testVaultApp" })
|
||||
// see
|
||||
// https://github.com/spring-cloud/spring-cloud-commons/issues/214
|
||||
public class VaultConfigTests {
|
||||
@@ -102,8 +101,7 @@ public class VaultConfigTests {
|
||||
ApplicationContext parent = this.applicationContext.getParent();
|
||||
|
||||
assertThat(parent.getBeanNamesForType(VaultTemplate.class)).isNotEmpty();
|
||||
assertThat(parent.getBeanNamesForType(LeasingVaultPropertySourceLocator.class))
|
||||
.isNotEmpty();
|
||||
assertThat(parent.getBeanNamesForType(LeasingVaultPropertySourceLocator.class)).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -79,17 +79,14 @@ public class VaultConfigTlsCertAuthenticationTests {
|
||||
+ " }\n" //
|
||||
+ "}";
|
||||
|
||||
vaultOperations.write("sys/policy/testpolicy",
|
||||
Collections.singletonMap("rules", rules));
|
||||
vaultOperations.write("sys/policy/testpolicy", Collections.singletonMap("rules", rules));
|
||||
|
||||
vaultOperations.write(
|
||||
"secret/" + VaultConfigTlsCertAuthenticationTests.class.getSimpleName(),
|
||||
vaultOperations.write("secret/" + VaultConfigTlsCertAuthenticationTests.class.getSimpleName(),
|
||||
Collections.singletonMap("vault.value", "foo"));
|
||||
|
||||
File workDir = findWorkDir();
|
||||
|
||||
String certificate = Files.contentOf(
|
||||
new File(workDir, "ca/certs/client.cert.pem"), StandardCharsets.US_ASCII);
|
||||
String certificate = Files.contentOf(new File(workDir, "ca/certs/client.cert.pem"), StandardCharsets.US_ASCII);
|
||||
|
||||
Map<String, String> role = new HashMap<>();
|
||||
role.put("certificate", certificate);
|
||||
|
||||
@@ -62,11 +62,9 @@ public class VaultConfigWithContextTests {
|
||||
|
||||
VaultOperations vaultOperations = vaultRule.prepare().getVaultOperations();
|
||||
|
||||
vaultOperations.write("secret/testVaultApp/my-profile",
|
||||
Collections.singletonMap("vault.value", "hello"));
|
||||
vaultOperations.write("secret/testVaultApp/my-profile", Collections.singletonMap("vault.value", "hello"));
|
||||
|
||||
vaultOperations.write("secret/testVaultApp",
|
||||
Collections.singletonMap("vault.value", "world"));
|
||||
vaultOperations.write("secret/testVaultApp", Collections.singletonMap("vault.value", "world"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -63,8 +63,7 @@ public class VaultConfigWithVaultConfigurerTests {
|
||||
vaultOperations.write("secret/VaultConfigWithVaultConfigurerTests",
|
||||
Collections.singletonMap("vault.value", "hello"));
|
||||
|
||||
vaultOperations.write("secret/testVaultApp",
|
||||
Collections.singletonMap("vault.value", "world"));
|
||||
vaultOperations.write("secret/testVaultApp", Collections.singletonMap("vault.value", "world"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -86,8 +85,7 @@ public class VaultConfigWithVaultConfigurerTests {
|
||||
@ConditionalOnProperty("VaultConfigWithVaultConfigurerTests.custom.config")
|
||||
@Bean
|
||||
VaultConfigurer vaultConfigurer() {
|
||||
return configurer -> configurer
|
||||
.add("secret/VaultConfigWithVaultConfigurerTests");
|
||||
return configurer -> configurer.add("secret/VaultConfigWithVaultConfigurerTests");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -124,8 +124,7 @@ public class VaultHealthIndicatorUnitTests {
|
||||
Health health = this.healthIndicator.health();
|
||||
|
||||
assertThat(health.getStatus()).isEqualTo(Status.UP);
|
||||
assertThat(health.getDetails()).containsEntry("state",
|
||||
"Vault in performance standby");
|
||||
assertThat(health.getDetails()).containsEntry("state", "Vault in performance standby");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -137,8 +136,7 @@ public class VaultHealthIndicatorUnitTests {
|
||||
Health health = this.healthIndicator.health();
|
||||
|
||||
assertThat(health.getStatus()).isEqualTo(Status.UP);
|
||||
assertThat(health.getDetails()).containsEntry("state",
|
||||
"Vault in recovery replication secondary mode");
|
||||
assertThat(health.getDetails()).containsEntry("state", "Vault in recovery replication secondary mode");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -63,16 +63,14 @@ public class VaultNamespaceTests {
|
||||
@ClassRule
|
||||
public static VaultRule vaultRule = new VaultRule();
|
||||
|
||||
static final Policy POLICY = Policy.of(Policy.Rule.builder().path("/*")
|
||||
.capabilities(Policy.BuiltinCapabilities.READ,
|
||||
Policy.BuiltinCapabilities.CREATE, Policy.BuiltinCapabilities.UPDATE)
|
||||
.build());
|
||||
static final Policy POLICY = Policy
|
||||
.of(Policy.Rule.builder().path("/*").capabilities(Policy.BuiltinCapabilities.READ,
|
||||
Policy.BuiltinCapabilities.CREATE, Policy.BuiltinCapabilities.UPDATE).build());
|
||||
|
||||
RestTemplateBuilder maketingRestTemplate;
|
||||
|
||||
WebClientBuilder marketingWebClientBuilder = WebClientBuilder.builder()
|
||||
.httpConnector(ClientHttpConnectorFactory.create(new ClientOptions(),
|
||||
Settings.createSslConfiguration()))
|
||||
.httpConnector(ClientHttpConnectorFactory.create(new ClientOptions(), Settings.createSslConfiguration()))
|
||||
.endpoint(TestRestTemplateFactory.TEST_VAULT_ENDPOINT)
|
||||
.defaultHeader(VaultHttpHeaders.VAULT_NAMESPACE, "marketing");
|
||||
|
||||
@@ -84,18 +82,16 @@ public class VaultNamespaceTests {
|
||||
this.vaultRule.prepare().getVersion().isEnterprise());
|
||||
|
||||
List<String> namespaces = new ArrayList<>(Arrays.asList("dev/", "marketing/"));
|
||||
List<String> list = this.vaultRule.prepare().getVaultOperations()
|
||||
.list("sys/namespaces");
|
||||
List<String> list = this.vaultRule.prepare().getVaultOperations().list("sys/namespaces");
|
||||
namespaces.removeAll(list);
|
||||
|
||||
for (String namespace : namespaces) {
|
||||
this.vaultRule.prepare().getVaultOperations()
|
||||
.write("sys/namespaces/" + namespace.replaceAll("/", ""));
|
||||
this.vaultRule.prepare().getVaultOperations().write("sys/namespaces/" + namespace.replaceAll("/", ""));
|
||||
}
|
||||
|
||||
this.maketingRestTemplate = RestTemplateBuilder.builder()
|
||||
.requestFactory(ClientHttpRequestFactoryFactory
|
||||
.create(new ClientOptions(), Settings.createSslConfiguration()))
|
||||
.requestFactory(
|
||||
ClientHttpRequestFactoryFactory.create(new ClientOptions(), Settings.createSslConfiguration()))
|
||||
.endpoint(TestRestTemplateFactory.TEST_VAULT_ENDPOINT)
|
||||
.defaultHeader(VaultHttpHeaders.VAULT_NAMESPACE, "marketing");
|
||||
|
||||
@@ -104,8 +100,7 @@ public class VaultNamespaceTests {
|
||||
|
||||
mountKv(marketing, "marketing-secrets");
|
||||
marketing.opsForSys().createOrUpdatePolicy("relaxed", POLICY);
|
||||
this.marketingToken = marketing.opsForToken()
|
||||
.create(VaultTokenRequest.builder().withPolicy("relaxed").build())
|
||||
this.marketingToken = marketing.opsForToken().create(VaultTokenRequest.builder().withPolicy("relaxed").build())
|
||||
.getToken().getToken();
|
||||
}
|
||||
|
||||
@@ -116,8 +111,8 @@ public class VaultNamespaceTests {
|
||||
Map<String, VaultMount> mounts = vaultSysOperations.getMounts();
|
||||
|
||||
if (!mounts.containsKey(path + "/")) {
|
||||
vaultSysOperations.mount(path, VaultMount.builder().type("kv")
|
||||
.options(Collections.singletonMap("version", "1")).build());
|
||||
vaultSysOperations.mount(path,
|
||||
VaultMount.builder().type("kv").options(Collections.singletonMap("version", "1")).build());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,16 +131,13 @@ public class VaultNamespaceTests {
|
||||
@Test
|
||||
public void shouldReportReactiveHealth() {
|
||||
|
||||
ReactiveVaultTemplate reactiveMarketing = new ReactiveVaultTemplate(
|
||||
this.marketingWebClientBuilder,
|
||||
ReactiveVaultTemplate reactiveMarketing = new ReactiveVaultTemplate(this.marketingWebClientBuilder,
|
||||
() -> Mono.just(VaultToken.of(this.marketingToken)));
|
||||
|
||||
Health.Builder builder = Health.unknown();
|
||||
|
||||
new VaultReactiveHealthIndicator(reactiveMarketing).doHealthCheck(builder)
|
||||
.as(StepVerifier::create)
|
||||
.assertNext(actual -> assertThat(actual.getStatus()).isEqualTo(Status.UP))
|
||||
.verifyComplete();
|
||||
new VaultReactiveHealthIndicator(reactiveMarketing).doHealthCheck(builder).as(StepVerifier::create)
|
||||
.assertNext(actual -> assertThat(actual.getStatus()).isEqualTo(Status.UP)).verifyComplete();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,8 +37,7 @@ public class VaultPropertySourceIntegrationTests extends IntegrationTestSupport
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
prepare().getVaultOperations().write("secret/myapp",
|
||||
Collections.singletonMap("key", "value"));
|
||||
prepare().getVaultOperations().write("secret/myapp", Collections.singletonMap("key", "value"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -47,8 +46,8 @@ public class VaultPropertySourceIntegrationTests extends IntegrationTestSupport
|
||||
VaultProperties vaultProperties = Settings.createVaultProperties();
|
||||
|
||||
VaultPropertySource propertySource = new VaultPropertySource(
|
||||
new VaultConfigTemplate(prepare().getVaultOperations(), vaultProperties),
|
||||
false, KeyValueSecretBackendMetadata.create("secret", "myapp"));
|
||||
new VaultConfigTemplate(prepare().getVaultOperations(), vaultProperties), false,
|
||||
KeyValueSecretBackendMetadata.create("secret", "myapp"));
|
||||
|
||||
propertySource.init();
|
||||
|
||||
@@ -59,18 +58,16 @@ public class VaultPropertySourceIntegrationTests extends IntegrationTestSupport
|
||||
@Test
|
||||
public void shouldReadVersionedValue() {
|
||||
|
||||
assumeTrue(this.vaultRule.prepare().getVersion()
|
||||
.isGreaterThanOrEqualTo(Version.parse("0.10.0")));
|
||||
assumeTrue(this.vaultRule.prepare().getVersion().isGreaterThanOrEqualTo(Version.parse("0.10.0")));
|
||||
|
||||
this.vaultRule.prepare().getVaultOperations().write("versioned/data/testVaultApp",
|
||||
Collections.singletonMap("data",
|
||||
Collections.singletonMap("key", "value")));
|
||||
Collections.singletonMap("data", Collections.singletonMap("key", "value")));
|
||||
|
||||
VaultProperties vaultProperties = Settings.createVaultProperties();
|
||||
|
||||
VaultPropertySource propertySource = new VaultPropertySource(
|
||||
new VaultConfigTemplate(prepare().getVaultOperations(), vaultProperties),
|
||||
false, KeyValueSecretBackendMetadata.create("versioned", "testVaultApp"));
|
||||
new VaultConfigTemplate(prepare().getVaultOperations(), vaultProperties), false,
|
||||
KeyValueSecretBackendMetadata.create("versioned", "testVaultApp"));
|
||||
|
||||
propertySource.init();
|
||||
|
||||
|
||||
@@ -40,10 +40,8 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(
|
||||
classes = VaultPropertySourceLocatorIntegrationTests.TestApplication.class,
|
||||
properties = { "spring.application.name=wintermute",
|
||||
"spring.cloud.vault.application-name=neuromancer",
|
||||
@SpringBootTest(classes = VaultPropertySourceLocatorIntegrationTests.TestApplication.class,
|
||||
properties = { "spring.application.name=wintermute", "spring.cloud.vault.application-name=neuromancer",
|
||||
"spring.cloud.vault.kv.application-name=neuromancer,icebreaker" })
|
||||
@ActiveProfiles({ "integrationtest" })
|
||||
public class VaultPropertySourceLocatorIntegrationTests extends IntegrationTestSupport {
|
||||
@@ -62,32 +60,26 @@ public class VaultPropertySourceLocatorIntegrationTests extends IntegrationTestS
|
||||
|
||||
vaultRule.prepare().getVaultOperations().write("secret/wintermute",
|
||||
Collections.singletonMap("vault.value", "spring.application.name value"));
|
||||
vaultRule.prepare().getVaultOperations()
|
||||
.write("secret/wintermute/integrationtest", Collections.singletonMap(
|
||||
"vault.value", "spring.application.name:integrationtest value"));
|
||||
vaultRule.prepare().getVaultOperations().write("secret/neuromancer", Collections
|
||||
.singletonMap("vault.value", "spring.cloud.vault.applicationName value"));
|
||||
vaultRule.prepare().getVaultOperations()
|
||||
.write("secret/neuromancer/integrationtest", Collections.singletonMap(
|
||||
"vault.value",
|
||||
"spring.cloud.vault.applicationName:integrationtest value"));
|
||||
vaultRule.prepare().getVaultOperations().write("secret/wintermute/integrationtest",
|
||||
Collections.singletonMap("vault.value", "spring.application.name:integrationtest value"));
|
||||
vaultRule.prepare().getVaultOperations().write("secret/neuromancer",
|
||||
Collections.singletonMap("vault.value", "spring.cloud.vault.applicationName value"));
|
||||
vaultRule.prepare().getVaultOperations().write("secret/neuromancer/integrationtest",
|
||||
Collections.singletonMap("vault.value", "spring.cloud.vault.applicationName:integrationtest value"));
|
||||
vaultRule.prepare().getVaultOperations().write("secret/icebreaker",
|
||||
Collections.singletonMap("icebreaker.value", "additional context value"));
|
||||
vaultRule.prepare().getVaultOperations()
|
||||
.write("secret/icebreaker/integrationtest", Collections.singletonMap(
|
||||
"icebreaker.value", "additional context:integrationtest value"));
|
||||
vaultRule.prepare().getVaultOperations().write("secret/icebreaker/integrationtest",
|
||||
Collections.singletonMap("icebreaker.value", "additional context:integrationtest value"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getsSecretFromVaultUsingVaultApplicationName() {
|
||||
assertThat(this.configValue)
|
||||
.isEqualTo("spring.cloud.vault.applicationName:integrationtest value");
|
||||
assertThat(this.configValue).isEqualTo("spring.cloud.vault.applicationName:integrationtest value");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getsSecretFromVaultUsingAdditionalContext() {
|
||||
assertThat(this.additionalValue)
|
||||
.isEqualTo("additional context:integrationtest value");
|
||||
assertThat(this.additionalValue).isEqualTo("additional context:integrationtest value");
|
||||
}
|
||||
|
||||
@SpringBootApplication
|
||||
|
||||
@@ -40,14 +40,11 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(
|
||||
classes = VaultPropertySourceLocatorProfilesIntegrationTests.TestApplication.class,
|
||||
properties = { "spring.application.name=my-profiles-app",
|
||||
"spring.cloud.vault.kv.profiles=hello, world",
|
||||
@SpringBootTest(classes = VaultPropertySourceLocatorProfilesIntegrationTests.TestApplication.class,
|
||||
properties = { "spring.application.name=my-profiles-app", "spring.cloud.vault.kv.profiles=hello, world",
|
||||
"spring.cloud.vault.kv.default-context=" })
|
||||
@ActiveProfiles({ "other" })
|
||||
public class VaultPropertySourceLocatorProfilesIntegrationTests
|
||||
extends IntegrationTestSupport {
|
||||
public class VaultPropertySourceLocatorProfilesIntegrationTests extends IntegrationTestSupport {
|
||||
|
||||
@Autowired
|
||||
Environment environment;
|
||||
|
||||
@@ -52,8 +52,7 @@ public class VaultPropertySourceLocatorUnitTests {
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
this.propertySourceLocator = new VaultPropertySourceLocator(this.operations,
|
||||
new VaultProperties(),
|
||||
this.propertySourceLocator = new VaultPropertySourceLocator(this.operations, new VaultProperties(),
|
||||
VaultPropertySourceLocatorSupport.createConfiguration(this.properties));
|
||||
}
|
||||
|
||||
@@ -63,9 +62,8 @@ public class VaultPropertySourceLocatorUnitTests {
|
||||
VaultProperties vaultProperties = new VaultProperties();
|
||||
vaultProperties.getConfig().setOrder(42);
|
||||
|
||||
this.propertySourceLocator = new VaultPropertySourceLocator(this.operations,
|
||||
vaultProperties, VaultPropertySourceLocatorSupport
|
||||
.createConfiguration(new VaultKeyValueBackendProperties()));
|
||||
this.propertySourceLocator = new VaultPropertySourceLocator(this.operations, vaultProperties,
|
||||
VaultPropertySourceLocatorSupport.createConfiguration(new VaultKeyValueBackendProperties()));
|
||||
|
||||
assertThat(this.propertySourceLocator.getOrder()).isEqualTo(42);
|
||||
}
|
||||
@@ -73,8 +71,7 @@ public class VaultPropertySourceLocatorUnitTests {
|
||||
@Test
|
||||
public void shouldLocateOnePropertySourceWithEmptyProfiles() {
|
||||
|
||||
PropertySource<?> propertySource = this.propertySourceLocator
|
||||
.locate(this.configurableEnvironment);
|
||||
PropertySource<?> propertySource = this.propertySourceLocator.locate(this.configurableEnvironment);
|
||||
|
||||
assertThat(propertySource).isInstanceOf(CompositePropertySource.class);
|
||||
|
||||
@@ -87,14 +84,13 @@ public class VaultPropertySourceLocatorUnitTests {
|
||||
|
||||
this.properties.setProfiles(Arrays.asList("vermillion", "periwinkle"));
|
||||
|
||||
PropertySource<?> propertySource = this.propertySourceLocator
|
||||
.locate(this.configurableEnvironment);
|
||||
PropertySource<?> propertySource = this.propertySourceLocator.locate(this.configurableEnvironment);
|
||||
|
||||
assertThat(propertySource).isInstanceOf(CompositePropertySource.class);
|
||||
|
||||
CompositePropertySource composite = (CompositePropertySource) propertySource;
|
||||
assertThat(composite.getPropertySources()).extracting("name").containsSequence(
|
||||
"secret/application/periwinkle", "secret/application/vermillion");
|
||||
assertThat(composite.getPropertySources()).extracting("name").containsSequence("secret/application/periwinkle",
|
||||
"secret/application/vermillion");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -104,19 +100,16 @@ public class VaultPropertySourceLocatorUnitTests {
|
||||
backendProperties.setApplicationName("wintermute");
|
||||
backendProperties.setProfiles(Arrays.asList("vermillion", "periwinkle"));
|
||||
|
||||
this.propertySourceLocator = new VaultPropertySourceLocator(this.operations,
|
||||
new VaultProperties(),
|
||||
this.propertySourceLocator = new VaultPropertySourceLocator(this.operations, new VaultProperties(),
|
||||
VaultPropertySourceLocatorSupport.createConfiguration(backendProperties));
|
||||
|
||||
PropertySource<?> propertySource = this.propertySourceLocator
|
||||
.locate(this.configurableEnvironment);
|
||||
PropertySource<?> propertySource = this.propertySourceLocator.locate(this.configurableEnvironment);
|
||||
|
||||
assertThat(propertySource).isInstanceOf(CompositePropertySource.class);
|
||||
|
||||
CompositePropertySource composite = (CompositePropertySource) propertySource;
|
||||
assertThat(composite.getPropertySources()).extracting("name").containsSequence(
|
||||
"secret/wintermute/periwinkle", "secret/wintermute/vermillion",
|
||||
"secret/wintermute");
|
||||
assertThat(composite.getPropertySources()).extracting("name").containsSequence("secret/wintermute/periwinkle",
|
||||
"secret/wintermute/vermillion", "secret/wintermute");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -126,21 +119,17 @@ public class VaultPropertySourceLocatorUnitTests {
|
||||
backendProperties.setApplicationName("wintermute,straylight,icebreaker/armitage");
|
||||
backendProperties.setProfiles(Arrays.asList("vermillion", "periwinkle"));
|
||||
|
||||
this.propertySourceLocator = new VaultPropertySourceLocator(this.operations,
|
||||
new VaultProperties(),
|
||||
this.propertySourceLocator = new VaultPropertySourceLocator(this.operations, new VaultProperties(),
|
||||
VaultPropertySourceLocatorSupport.createConfiguration(backendProperties));
|
||||
|
||||
PropertySource<?> propertySource = this.propertySourceLocator
|
||||
.locate(this.configurableEnvironment);
|
||||
PropertySource<?> propertySource = this.propertySourceLocator.locate(this.configurableEnvironment);
|
||||
|
||||
assertThat(propertySource).isInstanceOf(CompositePropertySource.class);
|
||||
|
||||
CompositePropertySource composite = (CompositePropertySource) propertySource;
|
||||
assertThat(composite.getPropertySources()).extracting("name").contains(
|
||||
"secret/wintermute", "secret/straylight", "secret/icebreaker/armitage",
|
||||
"secret/wintermute/vermillion", "secret/wintermute/periwinkle",
|
||||
"secret/straylight/vermillion", "secret/straylight/periwinkle",
|
||||
"secret/icebreaker/armitage/vermillion",
|
||||
assertThat(composite.getPropertySources()).extracting("name").contains("secret/wintermute", "secret/straylight",
|
||||
"secret/icebreaker/armitage", "secret/wintermute/vermillion", "secret/wintermute/periwinkle",
|
||||
"secret/straylight/vermillion", "secret/straylight/periwinkle", "secret/icebreaker/armitage/vermillion",
|
||||
"secret/icebreaker/armitage/periwinkle");
|
||||
}
|
||||
|
||||
@@ -151,17 +140,14 @@ public class VaultPropertySourceLocatorUnitTests {
|
||||
configurer.add(new MySecondSecretBackendMetadata());
|
||||
configurer.add(new MyFirstSecretBackendMetadata());
|
||||
|
||||
this.propertySourceLocator = new VaultPropertySourceLocator(this.operations,
|
||||
new VaultProperties(), configurer);
|
||||
this.propertySourceLocator = new VaultPropertySourceLocator(this.operations, new VaultProperties(), configurer);
|
||||
|
||||
PropertySource<?> propertySource = this.propertySourceLocator
|
||||
.locate(this.configurableEnvironment);
|
||||
PropertySource<?> propertySource = this.propertySourceLocator.locate(this.configurableEnvironment);
|
||||
|
||||
assertThat(propertySource).isInstanceOf(CompositePropertySource.class);
|
||||
|
||||
CompositePropertySource composite = (CompositePropertySource) propertySource;
|
||||
assertThat(composite.getPropertySources()).extracting("name")
|
||||
.containsSequence("foo", "bar");
|
||||
assertThat(composite.getPropertySources()).extracting("name").containsSequence("foo", "bar");
|
||||
}
|
||||
|
||||
@Order(1)
|
||||
|
||||
@@ -41,19 +41,15 @@ public class VaultReactiveHealthIndicatorIntegrationTests extends IntegrationTes
|
||||
@Test
|
||||
public void shouldReturnHealthState() {
|
||||
|
||||
ReactiveVaultTemplate vaultTemplate = new ReactiveVaultTemplate(
|
||||
TestRestTemplateFactory.TEST_VAULT_ENDPOINT,
|
||||
ClientHttpConnectorFactory.create(new ClientOptions(),
|
||||
Settings.createSslConfiguration()),
|
||||
ReactiveVaultTemplate vaultTemplate = new ReactiveVaultTemplate(TestRestTemplateFactory.TEST_VAULT_ENDPOINT,
|
||||
ClientHttpConnectorFactory.create(new ClientOptions(), Settings.createSslConfiguration()),
|
||||
() -> Mono.just(Settings.token()));
|
||||
|
||||
VaultReactiveHealthIndicator healthIndicator = new VaultReactiveHealthIndicator(
|
||||
vaultTemplate);
|
||||
VaultReactiveHealthIndicator healthIndicator = new VaultReactiveHealthIndicator(vaultTemplate);
|
||||
|
||||
healthIndicator.doHealthCheck(Health.up()).as(StepVerifier::create)
|
||||
.consumeNextWith(actual -> {
|
||||
assertThat(actual.getStatus()).isEqualTo(Status.UP);
|
||||
}).verifyComplete();
|
||||
healthIndicator.doHealthCheck(Health.up()).as(StepVerifier::create).consumeNextWith(actual -> {
|
||||
assertThat(actual.getStatus()).isEqualTo(Status.UP);
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -54,10 +54,8 @@ import static org.junit.Assume.assumeTrue;
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = VaultVersionedKvBackendConfigTests.TestApplication.class,
|
||||
properties = { "spring.cloud.vault.host=foo", "spring.cloud.vault.port=80",
|
||||
"spring.cloud.vault.uri=https://localhost:8200",
|
||||
"spring.cloud.vault.kv.enabled=true",
|
||||
"spring.cloud.vault.kv.backend=versioned",
|
||||
"spring.cloud.vault.application-name=testVaultApp" })
|
||||
"spring.cloud.vault.uri=https://localhost:8200", "spring.cloud.vault.kv.enabled=true",
|
||||
"spring.cloud.vault.kv.backend=versioned", "spring.cloud.vault.application-name=testVaultApp" })
|
||||
public class VaultVersionedKvBackendConfigTests {
|
||||
|
||||
@Value("${vault.value}")
|
||||
@@ -75,8 +73,7 @@ public class VaultVersionedKvBackendConfigTests {
|
||||
VaultRule vaultRule = new VaultRule();
|
||||
vaultRule.before();
|
||||
|
||||
assumeTrue(vaultRule.prepare().getVersion()
|
||||
.isGreaterThanOrEqualTo(Version.parse("0.10.0")));
|
||||
assumeTrue(vaultRule.prepare().getVersion().isGreaterThanOrEqualTo(Version.parse("0.10.0")));
|
||||
|
||||
Map<String, Object> object = new HashMap<>();
|
||||
object.put("vault.value", "foo");
|
||||
@@ -108,8 +105,7 @@ public class VaultVersionedKvBackendConfigTests {
|
||||
ApplicationContext parent = this.applicationContext.getParent();
|
||||
|
||||
assertThat(parent.getBeanNamesForType(VaultTemplate.class)).isNotEmpty();
|
||||
assertThat(parent.getBeanNamesForType(LeasingVaultPropertySourceLocator.class))
|
||||
.isNotEmpty();
|
||||
assertThat(parent.getBeanNamesForType(LeasingVaultPropertySourceLocator.class)).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -62,8 +62,7 @@ public class PrepareVault {
|
||||
|
||||
for (int i = 0; i < requiredKeys; i++) {
|
||||
|
||||
VaultUnsealStatus unsealStatus = this.vaultOperations.opsForSys()
|
||||
.unseal(initialized.getKeys().get(i));
|
||||
VaultUnsealStatus unsealStatus = this.vaultOperations.opsForSys().unseal(initialized.getKeys().get(i));
|
||||
|
||||
if (!unsealStatus.isSealed()) {
|
||||
break;
|
||||
@@ -87,8 +86,7 @@ public class PrepareVault {
|
||||
builder.withPolicy(policy);
|
||||
}
|
||||
|
||||
VaultTokenResponse vaultTokenResponse = this.vaultOperations.opsForToken()
|
||||
.create(builder.build());
|
||||
VaultTokenResponse vaultTokenResponse = this.vaultOperations.opsForToken().create(builder.build());
|
||||
return vaultTokenResponse.getToken();
|
||||
}
|
||||
|
||||
@@ -97,8 +95,7 @@ public class PrepareVault {
|
||||
* @return whether Vault is available.
|
||||
*/
|
||||
public boolean isAvailable() {
|
||||
return this.adminOperations.isInitialized()
|
||||
&& !this.adminOperations.health().isSealed();
|
||||
return this.adminOperations.isInitialized() && !this.adminOperations.health().isSealed();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -138,15 +135,13 @@ public class PrepareVault {
|
||||
* @param path must not be {@literal null} or empty.
|
||||
* @param config must not be {@literal null}.
|
||||
*/
|
||||
public void mountSecret(String secretBackend, String path,
|
||||
Map<String, Object> config) {
|
||||
public void mountSecret(String secretBackend, String path, Map<String, Object> config) {
|
||||
|
||||
Assert.hasText(secretBackend, "SecretBackend must not be empty");
|
||||
Assert.hasText(path, "Mount path must not be empty");
|
||||
Assert.notNull(config, "Configuration must not be null");
|
||||
|
||||
VaultMount mount = VaultMount.builder().type(secretBackend).config(config)
|
||||
.build();
|
||||
VaultMount mount = VaultMount.builder().type(secretBackend).config(config).build();
|
||||
this.adminOperations.mount(path, mount);
|
||||
}
|
||||
|
||||
@@ -159,8 +154,7 @@ public class PrepareVault {
|
||||
|
||||
Assert.hasText(secretBackend, "SecretBackend must not be empty");
|
||||
Map<String, VaultMount> mounts = this.adminOperations.getMounts();
|
||||
return mounts.containsKey(secretBackend)
|
||||
|| mounts.containsKey(secretBackend + "/");
|
||||
return mounts.containsKey(secretBackend) || mounts.containsKey(secretBackend + "/");
|
||||
}
|
||||
|
||||
public VaultOperations getVaultOperations() {
|
||||
@@ -197,16 +191,15 @@ public class PrepareVault {
|
||||
|
||||
this.vaultOperations.opsForSys().unmount("secret");
|
||||
|
||||
VaultMount kv = VaultMount.builder().type("kv")
|
||||
.config(Collections.singletonMap("versioned", false)).build();
|
||||
VaultMount kv = VaultMount.builder().type("kv").config(Collections.singletonMap("versioned", false)).build();
|
||||
this.vaultOperations.opsForSys().mount("secret", kv);
|
||||
}
|
||||
|
||||
public void mountVersionedKvBackend() {
|
||||
|
||||
mountSecret("kv", "versioned", Collections.emptyMap());
|
||||
this.vaultOperations.write("sys/mounts/versioned/tune", Collections
|
||||
.singletonMap("options", Collections.singletonMap("version", "2")));
|
||||
this.vaultOperations.write("sys/mounts/versioned/tune",
|
||||
Collections.singletonMap("options", Collections.singletonMap("version", "2")));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -39,8 +39,7 @@ public class Settings {
|
||||
|
||||
VaultProperties vaultProperties = new VaultProperties();
|
||||
vaultProperties.getSsl().setTrustStorePassword("changeit");
|
||||
vaultProperties.getSsl()
|
||||
.setTrustStore(new FileSystemResource(new File(workDir, "keystore.jks")));
|
||||
vaultProperties.getSsl().setTrustStore(new FileSystemResource(new File(workDir, "keystore.jks")));
|
||||
vaultProperties.setToken(token().getToken());
|
||||
|
||||
return vaultProperties;
|
||||
@@ -53,8 +52,7 @@ public class Settings {
|
||||
|
||||
File workDir = findWorkDir();
|
||||
|
||||
return SslConfiguration.forTrustStore(
|
||||
new FileSystemResource(new File(workDir, "keystore.jks")),
|
||||
return SslConfiguration.forTrustStore(new FileSystemResource(new File(workDir, "keystore.jks")),
|
||||
"changeit".toCharArray());
|
||||
}
|
||||
|
||||
@@ -77,8 +75,7 @@ public class Settings {
|
||||
public static File findWorkDir(File directory) {
|
||||
|
||||
File searchLevel = directory;
|
||||
while (searchLevel.getParentFile() != null
|
||||
&& searchLevel.getParentFile() != searchLevel) {
|
||||
while (searchLevel.getParentFile() != null && searchLevel.getParentFile() != searchLevel) {
|
||||
|
||||
File work = new File(searchLevel, "work");
|
||||
if (work.isDirectory() && work.exists()) {
|
||||
@@ -88,8 +85,7 @@ public class Settings {
|
||||
searchLevel = searchLevel.getParentFile();
|
||||
}
|
||||
|
||||
throw new IllegalStateException(String.format(
|
||||
"Cannot find work directory in %s or any parent directories",
|
||||
throw new IllegalStateException(String.format("Cannot find work directory in %s or any parent directories",
|
||||
directory.getAbsoluteFile()));
|
||||
}
|
||||
|
||||
@@ -97,8 +93,7 @@ public class Settings {
|
||||
* @return the token to use during tests.
|
||||
*/
|
||||
public static VaultToken token() {
|
||||
return VaultToken.of(System.getProperty("vault.token",
|
||||
"00000000-0000-0000-0000-000000000000"));
|
||||
return VaultToken.of(System.getProperty("vault.token", "00000000-0000-0000-0000-000000000000"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -79,8 +79,7 @@ public class TestRestTemplateFactory {
|
||||
return VaultClients.createRestTemplate(TEST_VAULT_ENDPOINT, requestFactory);
|
||||
}
|
||||
|
||||
private static void initializeClientHttpRequestFactory(
|
||||
SslConfiguration sslConfiguration) throws Exception {
|
||||
private static void initializeClientHttpRequestFactory(SslConfiguration sslConfiguration) throws Exception {
|
||||
|
||||
if (factoryCache.get() != null) {
|
||||
return;
|
||||
@@ -97,19 +96,18 @@ public class TestRestTemplateFactory {
|
||||
|
||||
if (clientHttpRequestFactory instanceof DisposableBean) {
|
||||
|
||||
Runtime.getRuntime().addShutdownHook(
|
||||
new Thread("ClientHttpRequestFactory Shutdown Hook") {
|
||||
Runtime.getRuntime().addShutdownHook(new Thread("ClientHttpRequestFactory Shutdown Hook") {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
((DisposableBean) clientHttpRequestFactory).destroy();
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
((DisposableBean) clientHttpRequestFactory).destroy();
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,8 +52,7 @@ public class VaultRule extends ExternalResource {
|
||||
* @see VaultEndpoint
|
||||
*/
|
||||
public VaultRule() {
|
||||
this(Settings.createSslConfiguration(),
|
||||
TestRestTemplateFactory.TEST_VAULT_ENDPOINT);
|
||||
this(Settings.createSslConfiguration(), TestRestTemplateFactory.TEST_VAULT_ENDPOINT);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -67,11 +66,9 @@ public class VaultRule extends ExternalResource {
|
||||
Assert.notNull(sslConfiguration, "SslConfiguration must not be null");
|
||||
Assert.notNull(vaultEndpoint, "VaultEndpoint must not be null");
|
||||
|
||||
ClientHttpRequestFactory requestFactory = TestRestTemplateFactory
|
||||
.create(sslConfiguration).getRequestFactory();
|
||||
ClientHttpRequestFactory requestFactory = TestRestTemplateFactory.create(sslConfiguration).getRequestFactory();
|
||||
|
||||
VaultTemplate vaultTemplate = new VaultTemplate(vaultEndpoint, requestFactory,
|
||||
new PreparingSessionManager());
|
||||
VaultTemplate vaultTemplate = new VaultTemplate(vaultEndpoint, requestFactory, new PreparingSessionManager());
|
||||
|
||||
this.token = Settings.token();
|
||||
this.prepareVault = new PrepareVault(vaultTemplate);
|
||||
@@ -83,13 +80,12 @@ public class VaultRule extends ExternalResource {
|
||||
|
||||
try (Socket socket = new Socket()) {
|
||||
|
||||
socket.connect(new InetSocketAddress(InetAddress.getByName("localhost"),
|
||||
this.vaultEndpoint.getPort()));
|
||||
socket.connect(new InetSocketAddress(InetAddress.getByName("localhost"), this.vaultEndpoint.getPort()));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException(String.format(
|
||||
"Vault is not running on localhost:%d which is required to run a test using @Rule %s",
|
||||
this.vaultEndpoint.getPort(), getClass().getSimpleName()));
|
||||
throw new IllegalStateException(
|
||||
String.format("Vault is not running on localhost:%d which is required to run a test using @Rule %s",
|
||||
this.vaultEndpoint.getPort(), getClass().getSimpleName()));
|
||||
}
|
||||
|
||||
if (!this.prepareVault.isAvailable()) {
|
||||
@@ -97,8 +93,7 @@ public class VaultRule extends ExternalResource {
|
||||
this.token = this.prepareVault.initializeVault();
|
||||
this.prepareVault.createToken(Settings.token().getToken(), "root");
|
||||
|
||||
if (this.prepareVault.getVersion()
|
||||
.isGreaterThanOrEqualTo(VERSIONING_INTRODUCED_WITH)) {
|
||||
if (this.prepareVault.getVersion().isGreaterThanOrEqualTo(VERSIONING_INTRODUCED_WITH)) {
|
||||
this.prepareVault.disableGenericVersioning();
|
||||
this.prepareVault.mountVersionedKvBackend();
|
||||
}
|
||||
|
||||
@@ -50,8 +50,7 @@ public final class Version implements Comparable<Version> {
|
||||
private Version(boolean enterprise, int... parts) {
|
||||
|
||||
Assert.notNull(parts, "Parts must not be null!");
|
||||
Assert.isTrue(parts.length > 0 && parts.length < 5,
|
||||
"Parts must contain 1 to 5 segments!");
|
||||
Assert.isTrue(parts.length > 0 && parts.length < 5, "Parts must contain 1 to 5 segments!");
|
||||
|
||||
this.major = parts[0];
|
||||
this.minor = parts.length > 1 ? parts[1] : 0;
|
||||
@@ -80,16 +79,14 @@ public final class Version implements Comparable<Version> {
|
||||
|
||||
for (int i = 0; i < parts.length; i++) {
|
||||
|
||||
String input = i == parts.length - 1 ? parts[i].replaceAll("\\D.*", "")
|
||||
: parts[i];
|
||||
String input = i == parts.length - 1 ? parts[i].replaceAll("\\D.*", "") : parts[i];
|
||||
|
||||
if (StringUtils.hasText(input)) {
|
||||
try {
|
||||
intParts[i] = Integer.parseInt(input);
|
||||
}
|
||||
catch (IllegalArgumentException o_O) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format(VERSION_PARSE_ERROR, input, version), o_O);
|
||||
throw new IllegalArgumentException(String.format(VERSION_PARSE_ERROR, input, version), o_O);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -198,8 +195,7 @@ public final class Version implements Comparable<Version> {
|
||||
digits.add(this.build);
|
||||
}
|
||||
|
||||
return StringUtils.collectionToDelimitedString(digits, ".")
|
||||
+ (isEnterprise() ? "+ent" : "");
|
||||
return StringUtils.collectionToDelimitedString(digits, ".") + (isEnterprise() ? "+ent" : "");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -211,15 +207,13 @@ public final class Version implements Comparable<Version> {
|
||||
return false;
|
||||
}
|
||||
Version version = (Version) o;
|
||||
return this.major == version.major && this.minor == version.minor
|
||||
&& this.bugfix == version.bugfix && this.build == version.build
|
||||
&& this.enterprise == version.enterprise;
|
||||
return this.major == version.major && this.minor == version.minor && this.bugfix == version.bugfix
|
||||
&& this.build == version.build && this.enterprise == version.enterprise;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.major, this.minor, this.bugfix, this.build,
|
||||
this.enterprise);
|
||||
return Objects.hash(this.major, this.minor, this.bugfix, this.build, this.enterprise);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user