Polishing.

Convert spaces to tabs. Deprecate VaultPostgreSqlProperties and VaultMySqlProperties. Convert database integration test to use MySQL. Slightly reword reference documentation.

Upgrade lombok to 1.16.18 to use onMethod_ attributes.

Original pull request: gh-170.
Related ticket: gh-169.
This commit is contained in:
Mark Paluch
2017-10-27 11:38:08 +02:00
parent 9da5e83dc9
commit 08d2a2e4c3
7 changed files with 204 additions and 52 deletions

View File

@@ -670,15 +670,17 @@ JDBC secrets need to be configured separately.
[[vault.config.backends.database]]
=== Database
Spring Cloud Vault can obtain credentials for any Database listed at
Spring Cloud Vault can obtain credentials for any database listed at
https://www.vaultproject.io/api/secret/databases/index.html.
The integration can be enabled by setting
`spring.cloud.vault.database.enabled=true` (default `false`) and
providing the role name with `spring.cloud.vault.database.role=…`.
Username and password are stored in `spring.datasource.username`
and `spring.datasource.password` so using Spring Boot will
pick up the generated credentials without further configuration.
While the database backend is a generic one, `spring.cloud.vault.database`
specifically targets JDBC databases. Username and password are
stored in `spring.datasource.username` and `spring.datasource.password`
so using Spring Boot will pick up the generated credentials
for your `DataSource` without further configuration.
You can configure the property names by setting
`spring.cloud.vault.database.username-property` and
`spring.cloud.vault.database.password-property`.
@@ -704,11 +706,11 @@ spring.cloud.vault:
See also: https://www.vaultproject.io/docs/secrets/databases/index.html[Vault Documentation: Database Secrets backend]
[[vault.config.backends.cassandra]]
=== Apache Cassandra
This backend has been deprecated in Vault and it is recommended to use the `database` backend
and mount it as `cassandra`.
NOTE: The `cassandra` backend has been deprecated in Vault 0.7.1 and
it is recommended to use the `database` backend and mount it as `cassandra`.
Spring Cloud Vault can obtain credentials for Apache Cassandra.
The integration can be enabled by setting
@@ -746,8 +748,8 @@ See also: https://www.vaultproject.io/docs/secrets/cassandra/index.html[Vault Do
[[vault.config.backends.mongodb]]
=== MongoDB
This backend has been deprecated in Vault and it is recommended to use the `database` backend
and mount it as `mongodb`.
NOTE: The `mongodb` backend has been deprecated in Vault 0.7.1 and
it is recommended to use the `database` backend and mount it as `mongodb`.
Spring Cloud Vault can obtain credentials for MongoDB.
The integration can be enabled by setting
@@ -784,8 +786,10 @@ See also: https://www.vaultproject.io/docs/secrets/mongodb/index.html[Vault Docu
[[vault.config.backends.mysql]]
=== MySQL
This backend has been deprecated in Vault and it is recommended to use the `database` backend
and mount it as `mysql`.
NOTE: The `mysql` backend has been deprecated in Vault 0.7.1 and
it is recommended to use the `database` backend and mount it as `mysql`.
Configuration for `spring.cloud.vault.mysql` will be removed in a future version.
Spring Cloud Vault can obtain credentials for MySQL.
The integration can be enabled by setting
@@ -822,8 +826,10 @@ See also: https://www.vaultproject.io/docs/secrets/mysql/index.html[Vault Docume
[[vault.config.backends.postgresql]]
=== PostgreSQL
This backend has been deprecated in Vault and it is recommended to use the `database` backend
and mount it as `postgresql`.
NOTE: The `postgresql` backend has been deprecated in Vault 0.7.1 and
it is recommended to use the `database` backend and mount it as `postgresql`.
Configuration for `spring.cloud.vault.postgresql` will be removed in a future version.
Spring Cloud Vault can obtain credentials for PostgreSQL.
The integration can be enabled by setting

View File

@@ -144,6 +144,7 @@
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
<version>1.16.18</version>
<optional>true</optional>
</dependency>

View File

@@ -31,9 +31,10 @@ import org.springframework.vault.core.util.PropertyTransformer;
/**
* Bootstrap configuration providing support for the Database secret backends such as
* MySQL, PostreSQL, Apache Cassandra and MongoDB.
* Database, Apache Cassandra and MongoDB.
*
* @author Mark Paluch
* @author Per Abich
*/
@Configuration
@EnableConfigurationProperties({ VaultMySqlProperties.class,
@@ -51,8 +52,8 @@ public class VaultConfigDatabaseBootstrapConfiguration {
* {@link SecretBackendMetadataFactory} for Database integration using
* {@link DatabaseSecretProperties}.
*/
public static class DatabaseSecretBackendMetadataFactory
implements SecretBackendMetadataFactory<DatabaseSecretProperties> {
public static class DatabaseSecretBackendMetadataFactory implements
SecretBackendMetadataFactory<DatabaseSecretProperties> {
@Override
public SecretBackendMetadata createMetadata(
@@ -75,16 +76,15 @@ 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");
final 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() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,47 +15,49 @@
*/
package org.springframework.cloud.vault.config.databases;
import javax.validation.constraints.NotEmpty;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.NotEmpty;
/**
* Configuration properties for Vault using the Database integration.
*
* @author Per Abich
* @since 2.0
*/
@ConfigurationProperties("spring.cloud.vault.database")
@Data
@Validated
public class VaultDatabaseProperties implements DatabaseSecretProperties {
/**
* Enable database backend usage.
*/
private boolean enabled = false;
/**
* Enable database backend usage.
*/
private boolean enabled = false;
/**
* Role name for credentials.
*/
private String role;
/**
* Role name for credentials.
*/
private String role;
/**
* Database backend path.
*/
@NotEmpty
private String backend = "database";
/**
* Database backend path.
*/
@NotEmpty
private String backend = "database";
/**
* Target property for the obtained username.
*/
@NotEmpty
private String usernameProperty = "spring.datasource.username";
/**
* Target property for the obtained username.
*/
@NotEmpty
private String usernameProperty = "spring.datasource.username";
/**
* Target property for the obtained password.
*/
@NotEmpty
private String passwordProperty = "spring.datasource.password";
/**
* Target property for the obtained password.
*/
@NotEmpty
private String passwordProperty = "spring.datasource.password";
}

View File

@@ -18,8 +18,10 @@ package org.springframework.cloud.vault.config.databases;
import javax.validation.constraints.NotEmpty;
import lombok.Data;
import lombok.Getter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
import org.springframework.cloud.vault.config.VaultSecretBackendDescriptor;
import org.springframework.validation.annotation.Validated;
@@ -27,21 +29,25 @@ import org.springframework.validation.annotation.Validated;
* Configuration properties for Vault using the MySQL integration.
*
* @author Mark Paluch
* @deprecated since 2.0. Use {@link VaultDatabaseProperties}.
*/
@ConfigurationProperties("spring.cloud.vault.mysql")
@Data
@Validated
@Deprecated
public class VaultMySqlProperties implements DatabaseSecretProperties,
VaultSecretBackendDescriptor {
/**
* Enable mysql backend usage.
*/
@Getter(onMethod_ = { @DeprecatedConfigurationProperty(reason = "Use spring.cloud.vault.database") })
private boolean enabled = false;
/**
* Role name for credentials.
*/
@Getter(onMethod_ = { @DeprecatedConfigurationProperty(reason = "Use spring.cloud.vault.database") })
private String role;
/**

View File

@@ -15,30 +15,38 @@
*/
package org.springframework.cloud.vault.config.databases;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.NotEmpty;
import lombok.Data;
import lombok.Getter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
import org.springframework.validation.annotation.Validated;
/**
* Configuration properties for Vault using the PostgreSQL integration.
*
* @author Mark Paluch
* @deprecated since 2.0. Use {@link VaultDatabaseProperties}.
*/
@ConfigurationProperties("spring.cloud.vault.postgresql")
@Data
@Validated
@Deprecated
public class VaultPostgreSqlProperties implements DatabaseSecretProperties {
/**
* Enable postgresql backend usage.
*/
@Deprecated
@Getter(onMethod_ = { @DeprecatedConfigurationProperty(reason = "Use spring.cloud.vault.database") })
private boolean enabled = false;
/**
* Role name for credentials.
*/
@Getter(onMethod_ = { @DeprecatedConfigurationProperty(reason = "Use spring.cloud.vault.database") })
private String role;
/**

View File

@@ -0,0 +1,129 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.vault.config.databases;
import java.net.InetSocketAddress;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.vault.util.CanConnect;
import org.springframework.cloud.vault.util.VaultRule;
import org.springframework.cloud.vault.util.Version;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.vault.core.VaultOperations;
import static org.junit.Assume.assumeTrue;
/**
* Integration tests using the database secret backend. In case this test should fail
* because of SSL make sure you run the test within the
* spring-cloud-vault-config/spring-cloud-vault-config directory as the keystore is
* referenced with {@code ../work/keystore.jks}.
*
* @author Mark Paluch
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = VaultConfigMySqlDatabaseTests.TestApplication.class, properties = {
"spring.cloud.vault.database.enabled=true",
"spring.cloud.vault.database.role=readonly",
"spring.datasource.url=jdbc:mysql://localhost:3306/mysql?useSSL=false" })
public class VaultConfigMySqlDatabaseTests {
private final static int MYSQL_PORT = 3306;
private final static String MYSQL_HOST = "localhost";
private final static String ROOT_CREDENTIALS = String.format(
"springvault:springvault@tcp(%s:%d)/", MYSQL_HOST, MYSQL_PORT);
private final static String CREATE_USER_AND_GRANT_SQL = "CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';"
+ "GRANT SELECT ON *.* TO '{{name}}'@'%';";
/**
* Initialize the mysql secret backend.
*
* @throws Exception
*/
@BeforeClass
public static void beforeClass() throws Exception {
VaultRule vaultRule = new VaultRule();
vaultRule.before();
assumeTrue(CanConnect.to(new InetSocketAddress(MYSQL_HOST, MYSQL_PORT)));
assumeTrue(vaultRule.prepare().getVersion()
.isGreaterThanOrEqualTo(Version.parse("0.7.1")));
if (!vaultRule.prepare().hasSecretBackend("database")) {
vaultRule.prepare().mountSecret("database");
}
VaultOperations vaultOperations = vaultRule.prepare().getVaultOperations();
Map<String, String> config = new HashMap<>();
config.put("plugin_name", "mysql-legacy-database-plugin");
config.put("connection_url", ROOT_CREDENTIALS);
config.put("allowed_roles", "readonly");
vaultOperations.write("database/config/mysql", config);
Map<String, String> body = new HashMap<>();
body.put("db_name", "mysql");
body.put("creation_statements", CREATE_USER_AND_GRANT_SQL);
vaultOperations.write("database/roles/readonly", body);
}
@Value("${spring.datasource.username}")
String username;
@Value("${spring.datasource.password}")
String password;
@Autowired
DataSource dataSource;
@Test
public void shouldConnectUsingDataSource() throws SQLException {
dataSource.getConnection().close();
}
@Test
public void shouldConnectUsingJdbcUrlConnection() throws SQLException {
String url = String.format("jdbc:mysql://%s?useSSL=false", MYSQL_HOST);
DriverManager.getConnection(url, username, password).close();
}
@SpringBootApplication
public static class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
}