Health status query and response model implemented (#15)
This commit is contained in:
parent
23419e94f1
commit
df7de5dd73
@ -1,3 +1,6 @@
|
|||||||
|
## 0.7.0 [work in progress]
|
||||||
|
* [feature] Retrieval of health status via `getHealth()`
|
||||||
|
|
||||||
## 0.6.2 [2017-08-19]
|
## 0.6.2 [2017-08-19]
|
||||||
* [fix] Prevent potential NPE on SecretResponse getter
|
* [fix] Prevent potential NPE on SecretResponse getter
|
||||||
* [fix] Removed stack traces on PUT request and response deserialization (#13)
|
* [fix] Removed stack traces on PUT request and response deserialization (#13)
|
||||||
|
2
pom.xml
2
pom.xml
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
<groupId>de.stklcode.jvault</groupId>
|
<groupId>de.stklcode.jvault</groupId>
|
||||||
<artifactId>connector</artifactId>
|
<artifactId>connector</artifactId>
|
||||||
<version>0.6.2</version>
|
<version>0.7.0-SNAPSHOT</version>
|
||||||
|
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
@ -59,6 +59,7 @@ public class HTTPVaultConnector implements VaultConnector {
|
|||||||
private static final String PATH_AUTH_APPID = "auth/app-id/";
|
private static final String PATH_AUTH_APPID = "auth/app-id/";
|
||||||
private static final String PATH_AUTH_APPROLE = "auth/approle/";
|
private static final String PATH_AUTH_APPROLE = "auth/approle/";
|
||||||
private static final String PATH_REVOKE = "sys/revoke/";
|
private static final String PATH_REVOKE = "sys/revoke/";
|
||||||
|
private static final String PATH_HEALTH = "sys/health";
|
||||||
|
|
||||||
private static final String HEADER_VAULT_TOKEN = "X-Vault-Token";
|
private static final String HEADER_VAULT_TOKEN = "X-Vault-Token";
|
||||||
|
|
||||||
@ -249,6 +250,25 @@ public class HTTPVaultConnector implements VaultConnector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HealthResponse getHealth() throws VaultConnectorException {
|
||||||
|
/* Force status code to be 200, so we don't need to modify the request sequence. */
|
||||||
|
Map<String, String> param = new HashMap<>();
|
||||||
|
param.put("standbycode", "200"); // Default: 429.
|
||||||
|
param.put("sealedcode", "200"); // Default: 503.
|
||||||
|
param.put("uninitcode", "200"); // Default: 501.
|
||||||
|
try {
|
||||||
|
String response = requestGet(PATH_HEALTH, param);
|
||||||
|
/* Parse response */
|
||||||
|
return jsonMapper.readValue(response, HealthResponse.class);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new InvalidResponseException("Unable to parse response", e);
|
||||||
|
} catch (URISyntaxException e) {
|
||||||
|
/* this should never occur and may leak sensible information */
|
||||||
|
throw new InvalidRequestException("Invalid URI format");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final boolean isAuthorized() {
|
public final boolean isAuthorized() {
|
||||||
return authorized && (tokenTTL == 0 || tokenTTL >= System.currentTimeMillis());
|
return authorized && (tokenTTL == 0 || tokenTTL >= System.currentTimeMillis());
|
||||||
|
@ -71,6 +71,15 @@ public interface VaultConnector extends AutoCloseable {
|
|||||||
return unseal(key, null);
|
return unseal(key, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query server health information.
|
||||||
|
*
|
||||||
|
* @return Health information.
|
||||||
|
* @throws VaultConnectorException on error
|
||||||
|
* @since 0.7.0
|
||||||
|
*/
|
||||||
|
HealthResponse getHealth() throws VaultConnectorException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all availale authentication backends.
|
* Get all availale authentication backends.
|
||||||
*
|
*
|
||||||
|
@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016-2017 Stefan Kalscheuer
|
||||||
|
*
|
||||||
|
* 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 de.stklcode.jvault.connector.model.response;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vault response for health query.
|
||||||
|
*
|
||||||
|
* @author Stefan Kalscheuer
|
||||||
|
* @since 0.7.0
|
||||||
|
*/
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
public final class HealthResponse implements VaultResponse {
|
||||||
|
@JsonProperty("cluster_id")
|
||||||
|
private String clusterID;
|
||||||
|
|
||||||
|
@JsonProperty("cluster_name")
|
||||||
|
private String clusterName;
|
||||||
|
|
||||||
|
@JsonProperty("version")
|
||||||
|
private String version;
|
||||||
|
|
||||||
|
@JsonProperty("server_time_utc")
|
||||||
|
private Long serverTimeUTC;
|
||||||
|
|
||||||
|
@JsonProperty("standby")
|
||||||
|
private Boolean standby;
|
||||||
|
|
||||||
|
@JsonProperty("sealed")
|
||||||
|
private Boolean sealed;
|
||||||
|
|
||||||
|
@JsonProperty("initialized")
|
||||||
|
private Boolean initialized;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The Cluster ID.
|
||||||
|
*/
|
||||||
|
public String getClusterID() {
|
||||||
|
return clusterID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The Cluster name.
|
||||||
|
*/
|
||||||
|
public String getClusterName() {
|
||||||
|
return clusterName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Vault version.
|
||||||
|
*/
|
||||||
|
public String getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Server time UTC (timestamp).
|
||||||
|
*/
|
||||||
|
public Long getServerTimeUTC() {
|
||||||
|
return serverTimeUTC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Server standby status.
|
||||||
|
*/
|
||||||
|
public Boolean isStandby() {
|
||||||
|
return standby;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Server seal status.
|
||||||
|
*/
|
||||||
|
public Boolean isSealed() {
|
||||||
|
return sealed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Server initialization status.
|
||||||
|
*/
|
||||||
|
public Boolean isInitialized() {
|
||||||
|
return initialized;
|
||||||
|
}
|
||||||
|
}
|
@ -48,6 +48,7 @@ import static org.junit.Assume.*;
|
|||||||
* @since 0.1
|
* @since 0.1
|
||||||
*/
|
*/
|
||||||
public class HTTPVaultConnectorTest {
|
public class HTTPVaultConnectorTest {
|
||||||
|
private static String VAULT_VERISON = "0.8.1"; // the vault version this test is supposed to run against
|
||||||
private static String KEY = "81011a8061e5c028bd0d9503eeba40bd9054b9af0408d080cb24f57405c27a61";
|
private static String KEY = "81011a8061e5c028bd0d9503eeba40bd9054b9af0408d080cb24f57405c27a61";
|
||||||
private static String TOKEN_ROOT = "d1bd50e2-587b-6e68-d80b-a9a507625cb7";
|
private static String TOKEN_ROOT = "d1bd50e2-587b-6e68-d80b-a9a507625cb7";
|
||||||
private static String USER_VALID = "validUser";
|
private static String USER_VALID = "validUser";
|
||||||
@ -135,6 +136,36 @@ public class HTTPVaultConnectorTest {
|
|||||||
assertThat("Vault not unsealed", sealStatus.isSealed(), is(false));
|
assertThat("Vault not unsealed", sealStatus.isSealed(), is(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test health status
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void healthTest() {
|
||||||
|
HealthResponse res = null;
|
||||||
|
try {
|
||||||
|
res = connector.getHealth();
|
||||||
|
} catch (VaultConnectorException e) {
|
||||||
|
fail("Retrieving health status failed: " + e.getMessage());
|
||||||
|
}
|
||||||
|
assertThat("Health response should be set", res, is(notNullValue()));
|
||||||
|
assertThat("Unexpected version", res.getVersion(), is(VAULT_VERISON));
|
||||||
|
assertThat("Unexpected init status", res.isInitialized(), is(true));
|
||||||
|
assertThat("Unexpected seal status", res.isSealed(), is(false));
|
||||||
|
assertThat("Unexpected standby status", res.isStandby(), is(false));
|
||||||
|
|
||||||
|
// No seal vault and verify correct status.
|
||||||
|
authRoot();
|
||||||
|
connector.seal();
|
||||||
|
assumeTrue(connector.sealStatus().isSealed());
|
||||||
|
connector.resetAuth(); // SHould work unauthenticated
|
||||||
|
try {
|
||||||
|
res = connector.getHealth();
|
||||||
|
} catch (VaultConnectorException e) {
|
||||||
|
fail("Retrieving health status failed when sealed: " + e.getMessage());
|
||||||
|
}
|
||||||
|
assertThat("Unexpected seal status", res.isSealed(), is(true));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test listing of authentication backends
|
* Test listing of authentication backends
|
||||||
*/
|
*/
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
package de.stklcode.jvault.connector.model.response;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
|
import static org.hamcrest.Matchers.notNullValue;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JUnit Test for {@link AuthResponse} model.
|
||||||
|
*
|
||||||
|
* @author Stefan Kalscheuer
|
||||||
|
* @since 0.7.0
|
||||||
|
*/
|
||||||
|
public class HealthResponseTest {
|
||||||
|
private static final String CLUSTER_ID = "c9abceea-4f46-4dab-a688-5ce55f89e228";
|
||||||
|
private static final String CLUSTER_NAME = "vault-cluster-5515c810";
|
||||||
|
private static final String VERSION = "0.6.2";
|
||||||
|
private static final Long SERVER_TIME_UTC = 1469555798L;
|
||||||
|
private static final Boolean STANDBY = false;
|
||||||
|
private static final Boolean SEALED = false;
|
||||||
|
private static final Boolean INITIALIZED = true;
|
||||||
|
|
||||||
|
private static final String RES_JSON = "{\n" +
|
||||||
|
" \"cluster_id\": \"" + CLUSTER_ID + "\",\n" +
|
||||||
|
" \"cluster_name\": \"" + CLUSTER_NAME + "\",\n" +
|
||||||
|
" \"version\": \"" + VERSION + "\",\n" +
|
||||||
|
" \"server_time_utc\": " + SERVER_TIME_UTC + ",\n" +
|
||||||
|
" \"standby\": " + STANDBY + ",\n" +
|
||||||
|
" \"sealed\": " + SEALED + ",\n" +
|
||||||
|
" \"initialized\": " + INITIALIZED + "\n" +
|
||||||
|
"}";
|
||||||
|
/**
|
||||||
|
* Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation).
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void jsonRoundtrip() {
|
||||||
|
try {
|
||||||
|
HealthResponse res = new ObjectMapper().readValue(RES_JSON, HealthResponse.class);
|
||||||
|
assertThat("Parsed response is NULL", res, is(notNullValue()));
|
||||||
|
assertThat("Incorrect cluster ID", res.getClusterID(), is(CLUSTER_ID));
|
||||||
|
assertThat("Incorrect cluster name", res.getClusterName(), is(CLUSTER_NAME));
|
||||||
|
assertThat("Incorrect version", res.getVersion(), is(VERSION));
|
||||||
|
assertThat("Incorrect server time", res.getServerTimeUTC(), is(SERVER_TIME_UTC));
|
||||||
|
assertThat("Incorrect standby state", res.isStandby(), is(STANDBY));
|
||||||
|
assertThat("Incorrect seal state", res.isSealed(), is(SEALED));
|
||||||
|
assertThat("Incorrect initialization state", res.isInitialized(), is(INITIALIZED));
|
||||||
|
} catch (IOException e) {
|
||||||
|
fail("Health deserialization failed: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user