Added HealthIndicator functionality as well as health API support.
Resolves #24
This commit is contained in:
20
README.adoc
20
README.adoc
@@ -198,6 +198,12 @@ https://github.com/spring-cloud-incubator/spring-cloud-vault-config/blob/master/
|
||||
chapters in the
|
||||
https://github.com/spring-cloud-incubator/spring-cloud-vault-config/blob/master/docs/src/main/asciidoc/spring-cloud-vault-config.adoc[reference guide].
|
||||
|
||||
If the application imports the `spring-boot-starter-actuator` project, the
|
||||
status of the vault server will be available via the `\health` endpoint.
|
||||
|
||||
The vault health indicator can be enabled or disabled through the
|
||||
property `health.vault.enabled` (default `true`)
|
||||
|
||||
== Building
|
||||
|
||||
==== Build requirements for Vault
|
||||
@@ -206,6 +212,20 @@ Spring Cloud Vault Config requires SSL certificates and a running
|
||||
Vault instance listening on `localhost:8200`. Certificates and the Vault
|
||||
setup are scripted, the scripts are located in `src/test/bash`.
|
||||
|
||||
The following scripts need to be run prior to building the project for the tests to pass.
|
||||
|
||||
$ ./src/test/bash/install_vault.sh
|
||||
$ ./src/test/bash/create_certificates.sh
|
||||
$ ./src/test/bash/local_run_vault.sh
|
||||
|
||||
Changes to the documentation should be made to the adocs found under `docs/src/main/asciidoc/`
|
||||
|
||||
README.adoc can be re-generated via the following
|
||||
|
||||
$ ./docs/src/main/ruby/generate_readme.sh > README.adoc
|
||||
|
||||
This script requires ruby and the asciidoctor gem installed (`gem install asciidoctor`)
|
||||
|
||||
:jdkversion: 1.7
|
||||
|
||||
=== Basic Compile and Test
|
||||
|
||||
@@ -25,6 +25,20 @@ Spring Cloud Vault Config requires SSL certificates and a running
|
||||
Vault instance listening on `localhost:8200`. Certificates and the Vault
|
||||
setup are scripted, the scripts are located in `src/test/bash`.
|
||||
|
||||
The following scripts need to be run prior to building the project for the tests to pass.
|
||||
|
||||
$ ./src/test/bash/install_vault.sh
|
||||
$ ./src/test/bash/create_certificates.sh
|
||||
$ ./src/test/bash/local_run_vault.sh
|
||||
|
||||
Changes to the documentation should be made to the adocs found under `docs/src/main/asciidoc/`
|
||||
|
||||
README.adoc can be re-generated via the following
|
||||
|
||||
$ ./docs/src/main/ruby/generate_readme.sh > README.adoc
|
||||
|
||||
This script requires ruby and the asciidoctor gem installed (`gem install asciidoctor`)
|
||||
|
||||
include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/docs/src/main/asciidoc/building.adoc[]
|
||||
|
||||
== Contributing
|
||||
|
||||
@@ -178,3 +178,9 @@ https://github.com/spring-cloud-incubator/spring-cloud-vault-config/blob/master/
|
||||
https://github.com/spring-cloud-incubator/spring-cloud-vault-config/blob/master/docs/src/main/asciidoc/spring-cloud-vault-config.adoc#token-authentication[authentication]. Checkout these
|
||||
chapters in the
|
||||
https://github.com/spring-cloud-incubator/spring-cloud-vault-config/blob/master/docs/src/main/asciidoc/spring-cloud-vault-config.adoc[reference guide].
|
||||
|
||||
If the application imports the `spring-boot-starter-actuator` project, the
|
||||
status of the vault server will be available via the `\health` endpoint.
|
||||
|
||||
The vault health indicator can be enabled or disabled through the
|
||||
property `health.vault.enabled` (default `true`)
|
||||
|
||||
@@ -21,6 +21,11 @@
|
||||
<artifactId>spring-cloud-vault-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-vault-core</artifactId>
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2016 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;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.HealthIndicatorAutoConfiguration;
|
||||
import org.springframework.boot.actuate.health.HealthIndicator;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.vault.VaultBootstrapConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author Stuart Ingram
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties
|
||||
@ConditionalOnBean(VaultBootstrapConfiguration.class)
|
||||
@ConditionalOnProperty(name = "spring.cloud.vault.enabled", matchIfMissing = true)
|
||||
@ConditionalOnExpression("${health.vault.enabled:true}")
|
||||
@AutoConfigureBefore({ EndpointAutoConfiguration.class })
|
||||
@AutoConfigureAfter({ HealthIndicatorAutoConfiguration.class })
|
||||
public class VaultConfigBootstrapHealthIndicator{
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "vaultHealthIndicator")
|
||||
public HealthIndicator vaultHealthIndicator() {
|
||||
return new VaultHealthIndicator();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2016 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;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.health.Health;
|
||||
import org.springframework.boot.actuate.health.HealthIndicator;
|
||||
import org.springframework.cloud.vault.VaultHealthResponse;
|
||||
|
||||
/**
|
||||
* @author Stuart Ingram
|
||||
*/
|
||||
public class VaultHealthIndicator implements HealthIndicator {
|
||||
@Autowired
|
||||
private VaultTemplate vaultTemplate;
|
||||
|
||||
@Override
|
||||
public Health health() {
|
||||
try {
|
||||
VaultHealthResponse vaultHealthResponse = vaultTemplate.health();
|
||||
if(!vaultHealthResponse.isInitialized()) {
|
||||
return Health.down().withDetail("Vault uninitialized",null).build();
|
||||
} else if (vaultHealthResponse.isSealed()) {
|
||||
return Health.down().withDetail("Vault sealed",null).build();
|
||||
} else if (vaultHealthResponse.isStandby()) {
|
||||
return Health.outOfService().withDetail("Vault in standby",null).build();
|
||||
} else {
|
||||
return Health.up().build();
|
||||
}
|
||||
}
|
||||
catch(Exception e) {
|
||||
return Health.down().build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.cloud.vault.ClientAuthentication;
|
||||
import org.springframework.cloud.vault.VaultClient;
|
||||
import org.springframework.cloud.vault.VaultClientResponse;
|
||||
import org.springframework.cloud.vault.VaultHealthResponse;
|
||||
import org.springframework.cloud.vault.VaultProperties;
|
||||
import org.springframework.cloud.vault.VaultToken;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -112,4 +113,30 @@ public class VaultTemplate implements InitializingBean, VaultOperations {
|
||||
URI uri = client.buildUri(properties, pathTemplate, variables);
|
||||
return sessionCallback.doWithVault(uri, vaultSession);
|
||||
}
|
||||
|
||||
private final static String HEALTH_URL_TEMPLATE = "sys/health";
|
||||
|
||||
/**
|
||||
* Query the current Vault service for it's health status
|
||||
*
|
||||
* @return A {@link VaultHealthResponse} containing the current service status.
|
||||
*/
|
||||
public VaultHealthResponse health() {
|
||||
URI uri = client.buildUri(properties, HEALTH_URL_TEMPLATE);
|
||||
return client.health(uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether Vault is available (vault created and unsealed).
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isAvailable() {
|
||||
try{
|
||||
VaultHealthResponse health = health();
|
||||
return health.isInitialized() && !health.isSealed();
|
||||
} catch(Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# Bootstrap Configuration
|
||||
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
|
||||
org.springframework.cloud.vault.config.VaultConfigBootstrapConfiguration
|
||||
org.springframework.cloud.vault.config.VaultConfigBootstrapConfiguration,\
|
||||
org.springframework.cloud.vault.config.VaultConfigBootstrapHealthIndicator
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.cloud.vault;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -26,6 +28,7 @@ import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
import org.springframework.web.client.HttpServerErrorException;
|
||||
import org.springframework.web.client.HttpStatusCodeException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import lombok.Getter;
|
||||
@@ -102,6 +105,29 @@ public class VaultClient {
|
||||
createHeaders(vaultToken)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Query the current Vault service for it's health status
|
||||
*
|
||||
* @param uri must not be {@literal null}.
|
||||
* @return A {@link VaultHealthResponse} containing the current service status.
|
||||
*/
|
||||
public VaultHealthResponse health(URI uri) {
|
||||
try {
|
||||
ResponseEntity<VaultHealthResponse> healthResponse = this.restTemplate.exchange(
|
||||
uri, HttpMethod.GET, null,
|
||||
VaultHealthResponse.class);
|
||||
return healthResponse.getBody();
|
||||
} catch (HttpStatusCodeException responseError) {
|
||||
try {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
return mapper.readValue(responseError.getResponseBodyAsString(), VaultHealthResponse.class);
|
||||
}
|
||||
catch (Exception jsonError) {
|
||||
throw responseError;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private VaultClientResponse exchange(URI uri, HttpMethod httpMethod,
|
||||
HttpEntity<?> httpEntity) {
|
||||
|
||||
@@ -143,7 +169,7 @@ public class VaultClient {
|
||||
* Build the Vault {@link URI} based on the given {@link VaultProperties} and
|
||||
* {@code pathTemplate}. URI template variables will be expanded using
|
||||
* {@code uriVariables}.
|
||||
*
|
||||
*
|
||||
* @param properties must not be {@literal null}.
|
||||
* @param pathTemplate must not be empty or {@literal null}.
|
||||
* @param uriVariables must not be {@literal null}.
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2016 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;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* Value object to bind HTTP API responses for sys/health
|
||||
*
|
||||
* @author Stuart Ingram
|
||||
* @author Bill Koch
|
||||
*/
|
||||
@Data
|
||||
public class VaultHealthResponse {
|
||||
private boolean initialized;
|
||||
private boolean sealed;
|
||||
private boolean standby;
|
||||
@JsonProperty("server_time_utc")
|
||||
private int serverTimeUtc;
|
||||
}
|
||||
Reference in New Issue
Block a user