Polishing

Add this for field dereference. Tweak renewal timing for shorter test runtime. Move lifecycle configuration into SecretLeaseContainer bean method.

Closes gh-393.
This commit is contained in:
Mark Paluch
2020-03-20 14:11:11 +01:00
parent f74ff1f9a4
commit 3d0672e159
10 changed files with 74 additions and 52 deletions

View File

@@ -90,12 +90,10 @@ class ConsulBackendMetadata implements LeasingSecretBackendMetadata {
if (leaseEvent.getSource() == secret
&& leaseEvent instanceof SecretLeaseCreatedEvent) {
if (this.eventPublisher != null) {
if (log.isDebugEnabled()) {
log.debug("Publishing a RebindConsulEvent");
}
this.eventPublisher.publishEvent(new RebindConsulEvent(this));
if (this.log.isDebugEnabled()) {
this.log.debug("Publishing a RebindConsulEvent");
}
this.eventPublisher.publishEvent(new RebindConsulEvent(this));
}
});

View File

@@ -31,7 +31,7 @@ import org.springframework.context.annotation.Configuration;
/**
* Bootstrap configuration providing support for the Consul secret backend.
*
* @author Mark Paluch
* @author Spencer Gibb
*/
@Configuration(proxyBeanMethods = false)
public class VaultConfigConsulAutoConfiguration {
@@ -69,8 +69,8 @@ public class VaultConfigConsulAutoConfiguration {
@Override
public void onApplicationEvent(ConsulBackendMetadata.RebindConsulEvent event) {
if (log.isDebugEnabled()) {
log.debug("received RebindConsulEvent");
if (this.log.isDebugEnabled()) {
this.log.debug("received RebindConsulEvent");
}
rebind("consulDiscoveryProperties");
rebind("consulConfigProperties");

View File

@@ -136,7 +136,8 @@ public class ConsulSecretIntegrationTests extends IntegrationTestSupport {
Map<String, Object> secretProperties = this.configOperations
.read(factory.forConsul(this.consul)).getData();
assertThat(secretProperties).containsKeys("spring.cloud.consul.token");
assertThat(secretProperties).containsKeys("spring.cloud.consul.config.acl-token",
"spring.cloud.consul.discovery.acl-token");
}
}

View File

@@ -67,7 +67,8 @@ public class VaultConfigConsulBootstrapConfigurationTests extends IntegrationTes
@Bean
@ConditionalOnProperty("VaultConfigConsulBootstrapConfigurationTests.custom.config")
ConsulSecretBackendMetadataFactory customFactory(ConfigurationPropertiesRebinder rebinder) {
ConsulSecretBackendMetadataFactory customFactory(
ConfigurationPropertiesRebinder rebinder) {
return new ConsulSecretBackendMetadataFactory(null) {
@Override

View File

@@ -57,6 +57,7 @@ import static org.junit.Assume.assumeTrue;
* referenced with {@code ../work/keystore.jks}.
*
* @author Mark Paluch
* @author Spencer Gibb
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = VaultConfigConsulTests.TestApplication.class,
@@ -130,8 +131,8 @@ public class VaultConfigConsulTests {
Map<String, Object> role = new LinkedHashMap<>();
role.put("policy", new String(Base64.getEncoder().encode(POLICY.getBytes())));
role.put("ttl", "15s");
role.put("max_ttl", "15s");
role.put("ttl", "5s");
role.put("max_ttl", "5s");
vaultOperations.write("consul/roles/readonly", role);
}
@@ -144,11 +145,6 @@ public class VaultConfigConsulTests {
}
}
/*
* @Test public void shouldHaveToken() { assertThat(this.token).isNotEmpty();
* assertThat(this.discoveryProperties.getAclToken()).isEqualTo(this.token); }
*/
@Test
public void shouldHaveRenewedToken() throws InterruptedException {
assertThat(configToken).isNotEmpty();
@@ -156,9 +152,8 @@ public class VaultConfigConsulTests {
assertThat(this.configProperties.getAclToken()).isEqualTo(configToken);
assertThat(this.discoveryProperties.getAclToken()).isEqualTo(discoveryToken);
Thread.sleep(20_000L);
Thread.sleep(8_000L);
// TODO: The properties weren't rebound so this test fails.
assertThat(this.configProperties.getAclToken()).isNotEmpty()
.isNotEqualTo(configToken);
assertThat(this.discoveryProperties.getAclToken()).isNotEmpty()

View File

@@ -3,3 +3,6 @@ spring:
cloud.vault.token: 00000000-0000-0000-0000-000000000000
cloud.vault.ssl.trust-store: file:../work/keystore.jks
cloud.vault.ssl.trust-store-password: changeit
cloud.vault.config.lifecycle.min-renewal: 3s
cloud.vault.config.lifecycle.expiry-threshold: 3s

View File

@@ -40,26 +40,29 @@ public interface LeasingSecretBackendMetadata extends SecretBackendMetadata {
Mode getLeaseMode();
/**
* Callback method before registering a {@link RequestedSecret secret} with {@link SecretLeaseContainer}.
* Registering a {@code before} callback allows event consumption before the secrets are visible in the associated property source.
*
* Callback method before registering a {@link RequestedSecret secret} with
* {@link SecretLeaseContainer}. Registering a {@code before} callback allows event
* consumption before the secrets are visible in the associated property source.
* @param secret the requested secret.
* @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) {
}
/**
* Callback method after registering a {@link RequestedSecret secret} with {@link SecretLeaseContainer}.
* Registering a {@code after} callback allows event consumption after the secrets are visible in the associated property source.
* Note that this callback does not necessarily guarantee notification of the initial secrets retrieval.
*
* Callback method after registering a {@link RequestedSecret secret} with
* {@link SecretLeaseContainer}. Registering a {@code after} callback allows event
* consumption after the secrets are visible in the associated property source. Note
* that this callback does not necessarily guarantee notification of the initial
* secrets retrieval.
* @param secret the requested secret.
* @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) {
}
}

View File

@@ -148,17 +148,17 @@ class LeasingVaultPropertySourceLocator extends VaultPropertySourceLocatorSuppor
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;

View File

@@ -100,18 +100,6 @@ public class VaultBootstrapPropertySourceConfiguration implements InitializingBe
SecretLeaseContainer secretLeaseContainer = secretLeaseContainerObjectFactory
.getObject();
if (lifecycle.getMinRenewal() != null) {
secretLeaseContainer.setMinRenewal(lifecycle.getMinRenewal());
}
if (lifecycle.getExpiryThreshold() != null) {
secretLeaseContainer.setExpiryThreshold(lifecycle.getExpiryThreshold());
}
if (lifecycle.getLeaseEndpoints() != null) {
secretLeaseContainer.setLeaseEndpoints(lifecycle.getLeaseEndpoints());
}
secretLeaseContainer.start();
return new LeasingVaultPropertySourceLocator(vaultProperties, configuration,
@@ -184,6 +172,7 @@ public class VaultBootstrapPropertySourceConfiguration implements InitializingBe
}
/**
* @param vaultProperties the {@link VaultProperties}.
* @param vaultOperations the {@link VaultOperations}.
* @param taskSchedulerWrapper the {@link TaskSchedulerWrapper}.
* @return the {@link SessionManager} for Vault session management.
@@ -193,10 +182,36 @@ public class VaultBootstrapPropertySourceConfiguration implements InitializingBe
@Bean
@Lazy
@ConditionalOnMissingBean
public SecretLeaseContainer secretLeaseContainer(VaultOperations vaultOperations,
TaskSchedulerWrapper taskSchedulerWrapper) {
return new SecretLeaseContainer(vaultOperations,
public SecretLeaseContainer secretLeaseContainer(VaultProperties vaultProperties,
VaultOperations vaultOperations, TaskSchedulerWrapper taskSchedulerWrapper) {
VaultProperties.Lifecycle lifecycle = vaultProperties.getConfig().getLifecycle();
SecretLeaseContainer container = new SecretLeaseContainer(vaultOperations,
taskSchedulerWrapper.getTaskScheduler());
customizeContainer(lifecycle, container);
return container;
}
static void customizeContainer(VaultProperties.Lifecycle lifecycle,
SecretLeaseContainer container) {
if (lifecycle.isEnabled()) {
if (lifecycle.getMinRenewal() != null) {
container.setMinRenewal(lifecycle.getMinRenewal());
}
if (lifecycle.getExpiryThreshold() != null) {
container.setExpiryThreshold(lifecycle.getExpiryThreshold());
}
if (lifecycle.getLeaseEndpoints() != null) {
container.setLeaseEndpoints(lifecycle.getLeaseEndpoints());
}
}
}
}

View File

@@ -80,8 +80,14 @@ public class VaultBootstrapPropertySourceConfigurationTests {
}
@Bean
SecretLeaseContainer secretLeaseContainer() {
return mock(SecretLeaseContainer.class);
SecretLeaseContainer secretLeaseContainer(VaultProperties properties) {
SecretLeaseContainer mock = mock(SecretLeaseContainer.class);
VaultBootstrapPropertySourceConfiguration
.customizeContainer(properties.getConfig().getLifecycle(), mock);
return mock;
}
}