diff --git a/src/main/java/com/bettercloud/vault/api/Auth.java b/src/main/java/com/bettercloud/vault/api/Auth.java index f696f096..87b78b51 100644 --- a/src/main/java/com/bettercloud/vault/api/Auth.java +++ b/src/main/java/com/bettercloud/vault/api/Auth.java @@ -178,6 +178,10 @@ public AuthResponse createToken(final TokenRequest tokenRequest) throws VaultExc * @throws VaultException If any error occurs, or unexpected response received from Vault */ public AuthResponse createToken(final TokenRequest tokenRequest, final String tokenAuthMount) throws VaultException { + return createToken(tokenRequest, tokenAuthMount, tokenAuthMount, config.getToken()); + } + + public AuthResponse createToken(final TokenRequest tokenRequest, final String tokenAuthMount, final String token) throws VaultException { int retryCount = 0; final String mount = tokenAuthMount != null ? tokenAuthMount : "token"; @@ -213,7 +217,7 @@ public AuthResponse createToken(final TokenRequest tokenRequest, final String to // HTTP request to Vault final RestResponse restResponse = new Rest()//NOPMD .url(url) - .header("X-Vault-Token", config.getToken()) + .header("X-Vault-Token", token) .body(requestJson.getBytes("UTF-8")) .connectTimeoutSeconds(config.getOpenTimeout()) .readTimeoutSeconds(config.getReadTimeout()) @@ -1037,6 +1041,10 @@ public AuthResponse renewSelf(final long increment) throws VaultException { * @throws VaultException If any error occurs, or unexpected response received from Vault */ public AuthResponse renewSelf(final long increment, final String tokenAuthMount) throws VaultException { + return renewSelf(increment, tokenAuthMount, config.getToken()); + } + + public AuthResponse renewSelf(final long increment, final String tokenAuthMount, final String token) throws VaultException { int retryCount = 0; final String mount = tokenAuthMount != null ? tokenAuthMount : "token"; @@ -1046,7 +1054,7 @@ public AuthResponse renewSelf(final long increment, final String tokenAuthMount) final String requestJson = Json.object().add("increment", increment).toString(); final RestResponse restResponse = new Rest()//NOPMD .url(config.getAddress() + "/v1/auth/" + mount + "/renew-self") - .header("X-Vault-Token", config.getToken()) + .header("X-Vault-Token", token) .body(increment < 0 ? null : requestJson.getBytes("UTF-8")) .connectTimeoutSeconds(config.getOpenTimeout()) .readTimeoutSeconds(config.getReadTimeout()) @@ -1100,6 +1108,10 @@ public LookupResponse lookupSelf() throws VaultException { * @throws VaultException If any error occurs, or unexpected response received from Vault */ public LookupResponse lookupSelf(final String tokenAuthMount) throws VaultException { + return lookupSelf(tokenAuthMount, config.getToken()) + } + + public LookupResponse lookupSelf(final String tokenAuthMount, final String token) throws VaultException { int retryCount = 0; final String mount = tokenAuthMount != null ? tokenAuthMount : "token"; while (true) { @@ -1107,7 +1119,7 @@ public LookupResponse lookupSelf(final String tokenAuthMount) throws VaultExcept // HTTP request to Vault final RestResponse restResponse = new Rest()//NOPMD .url(config.getAddress() + "/v1/auth/" + mount + "/lookup-self") - .header("X-Vault-Token", config.getToken()) + .header("X-Vault-Token", token) .connectTimeoutSeconds(config.getOpenTimeout()) .readTimeoutSeconds(config.getReadTimeout()) .sslVerification(config.getSslConfig().isVerify()) @@ -1158,6 +1170,10 @@ public void revokeSelf() throws VaultException { * @throws VaultException If any error occurs, or unexpected response received from Vault */ public void revokeSelf(final String tokenAuthMount) throws VaultException { + revokeSelf(tokenAuthMount, config.getToken()); + } + + public void revokeSelf(final String tokenAuthMount, final String token) throws VaultException { int retryCount = 0; final String mount = tokenAuthMount != null ? tokenAuthMount : "token"; while (true) { @@ -1165,7 +1181,7 @@ public void revokeSelf(final String tokenAuthMount) throws VaultException { // HTTP request to Vault final RestResponse restResponse = new Rest()//NOPMD .url(config.getAddress() + "/v1/auth/" + mount + "/revoke-self") - .header("X-Vault-Token", config.getToken()) + .header("X-Vault-Token", token) .connectTimeoutSeconds(config.getOpenTimeout()) .readTimeoutSeconds(config.getReadTimeout()) .sslVerification(config.getSslConfig().isVerify()) diff --git a/src/main/java/com/bettercloud/vault/api/Debug.java b/src/main/java/com/bettercloud/vault/api/Debug.java index 9be1eb2b..d8c89419 100644 --- a/src/main/java/com/bettercloud/vault/api/Debug.java +++ b/src/main/java/com/bettercloud/vault/api/Debug.java @@ -72,6 +72,16 @@ public HealthResponse health( final Integer activeCode, final Integer standbyCode, final Integer sealedCode + ) throws VaultException { + return health(standbyOk, activeCode, standbyCode, sealedCode, config.getToken()); + } + + public HealthResponse health( + final Boolean standbyOk, + final Integer activeCode, + final Integer standbyCode, + final Integer sealedCode, + final String token ) throws VaultException { final String path = "sys/health"; int retryCount = 0; @@ -85,8 +95,8 @@ public HealthResponse health( .sslVerification(config.getSslConfig().isVerify()) .sslContext(config.getSslConfig().getSslContext()); // Add token if present - if (config.getToken() != null) { - rest.header("X-Vault-Token", config.getToken()); + if (token != null) { + rest.header("X-Vault-Token", token); } // Add params if present if (standbyOk != null) rest.parameter("standbyok", standbyOk.toString()); diff --git a/src/main/java/com/bettercloud/vault/api/Leases.java b/src/main/java/com/bettercloud/vault/api/Leases.java index 29bbd79a..df66265f 100644 --- a/src/main/java/com/bettercloud/vault/api/Leases.java +++ b/src/main/java/com/bettercloud/vault/api/Leases.java @@ -38,12 +38,16 @@ public Leases(final VaultConfig config) { * @throws VaultException If an error occurs, or unexpected reponse received from Vault */ public VaultResponse revoke(final String leaseId) throws VaultException { + return revoke(leaseId, config.getToken()); + } + + public VaultResponse revoke(final String leaseId, final String token) throws VaultException { int retryCount = 0; while (true) { try { final RestResponse restResponse = new Rest()//NOPMD .url(config.getAddress() + "/v1/sys/revoke/" + leaseId) - .header("X-Vault-Token", config.getToken()) + .header("X-Vault-Token", token) .connectTimeoutSeconds(config.getOpenTimeout()) .readTimeoutSeconds(config.getReadTimeout()) .sslVerification(config.getSslConfig().isVerify()) @@ -92,12 +96,16 @@ public VaultResponse revoke(final String leaseId) throws VaultException { * @throws VaultException If an error occurs, or unexpected reponse received from Vault */ public VaultResponse revokePrefix(final String prefix) throws VaultException { + return revokePrefix(prefix, config.getToken()); + } + + public VaultResponse revokePrefix(final String prefix, final String token) throws VaultException { int retryCount = 0; while (true) { try { final RestResponse restResponse = new Rest()//NOPMD .url(config.getAddress() + "/v1/sys/revoke-prefix/" + prefix) - .header("X-Vault-Token", config.getToken()) + .header("X-Vault-Token", token) .connectTimeoutSeconds(config.getOpenTimeout()) .readTimeoutSeconds(config.getReadTimeout()) .sslVerification(config.getSslConfig().isVerify()) @@ -149,12 +157,16 @@ public VaultResponse revokePrefix(final String prefix) throws VaultException { * @throws VaultException If an error occurs, or unexpected reponse received from Vault */ public VaultResponse revokeForce(final String prefix) throws VaultException { + return revokeForce(prefix, config.getToken()); + } + + public VaultResponse revokeForce(final String prefix, final String token) throws VaultException { int retryCount = 0; while (true) { try { final RestResponse restResponse = new Rest()//NOPMD .url(config.getAddress() + "/v1/sys/revoke-force/" + prefix) - .header("X-Vault-Token", config.getToken()) + .header("X-Vault-Token", token) .connectTimeoutSeconds(config.getOpenTimeout()) .readTimeoutSeconds(config.getReadTimeout()) .sslVerification(config.getSslConfig().isVerify()) @@ -202,6 +214,10 @@ public VaultResponse revokeForce(final String prefix) throws VaultException { * @throws VaultException The response information returned from Vault */ public VaultResponse renew(final String leaseId, final long increment) throws VaultException { + return renew(leaseId, increment, config.getToken()); + } + + public VaultResponse renew(final String leaseId, final long increment, final String token) throws VaultException { // TODO: Update the integration test suite to provide coverate for this // The "generic" backend does not support support lease renewal. The only other backend @@ -216,7 +232,7 @@ public VaultResponse renew(final String leaseId, final long increment) throws Va final String requestJson = Json.object().add("increment", increment).toString(); final RestResponse restResponse = new Rest()//NOPMD .url(config.getAddress() + "/v1/sys/renew/" + leaseId) - .header("X-Vault-Token", config.getToken()) + .header("X-Vault-Token", token) .body(increment < 0 ? null : requestJson.getBytes("UTF-8")) .connectTimeoutSeconds(config.getOpenTimeout()) .readTimeoutSeconds(config.getReadTimeout()) diff --git a/src/main/java/com/bettercloud/vault/api/Logical.java b/src/main/java/com/bettercloud/vault/api/Logical.java index 9c45f4c8..31c64d18 100644 --- a/src/main/java/com/bettercloud/vault/api/Logical.java +++ b/src/main/java/com/bettercloud/vault/api/Logical.java @@ -14,6 +14,7 @@ import com.bettercloud.vault.rest.Rest; import com.bettercloud.vault.rest.RestException; import com.bettercloud.vault.rest.RestResponse; +import java.nio.charset.StandardCharsets; /** *

The implementing class for Vault's core/logical operations (e.g. read, write).

@@ -47,17 +48,17 @@ public Logical(final VaultConfig config) { * @throws VaultException If any errors occurs with the REST request (e.g. non-200 status code, invalid JSON payload, etc), and the maximum number of retries is exceeded. */ public LogicalResponse read(final String path) throws VaultException { - return read(path, true); + return read(path, config.getToken()); } - public LogicalResponse read(final String path, boolean shouldRetry) throws VaultException { + public LogicalResponse read(final String path, String token) throws VaultException { int retryCount = 0; while (true) { try { // Make an HTTP request to Vault final RestResponse restResponse = new Rest()//NOPMD .url(config.getAddress() + "/v1/" + path) - .header("X-Vault-Token", config.getToken()) + .header("X-Vault-Token", token) .connectTimeoutSeconds(config.getOpenTimeout()) .readTimeoutSeconds(config.getReadTimeout()) .sslVerification(config.getSslConfig().isVerify()) @@ -118,6 +119,10 @@ public LogicalResponse read(final String path, boolean shouldRetry) throws Vault * @throws VaultException If any errors occurs with the REST request, and the maximum number of retries is exceeded. */ public LogicalResponse write(final String path, final Map nameValuePairs) throws VaultException { + return write(path, nameValuePairs, config.getToken()); + } + + public LogicalResponse write(final String path, final Map nameValuePairs, String token) throws VaultException { int retryCount = 0; while (true) { try { @@ -146,7 +151,7 @@ public LogicalResponse write(final String path, final Map nameVa final RestResponse restResponse = new Rest()//NOPMD .url(config.getAddress() + "/v1/" + path) .body(requestJson.toString().getBytes("UTF-8")) - .header("X-Vault-Token", config.getToken()) + .header("X-Vault-Token", token) .connectTimeoutSeconds(config.getOpenTimeout()) .readTimeoutSeconds(config.getReadTimeout()) .sslVerification(config.getSslConfig().isVerify()) @@ -195,10 +200,14 @@ public LogicalResponse write(final String path, final Map nameVa * @throws VaultException If any errors occur, or unexpected response received from Vault */ public List list(final String path) throws VaultException { + return list(path, config.getToken()); + } + + public List list(final String path, String token) throws VaultException { final String fullPath = path == null ? "list=true" : path + "?list=true"; LogicalResponse response = null; try { - response = read(fullPath); + response = read(fullPath, token); } catch (final VaultException e) { if (e.getHttpStatusCode() != 404) { throw e; @@ -232,13 +241,17 @@ public List list(final String path) throws VaultException { * @throws VaultException If any error occurs, or unexpected response received from Vault */ public LogicalResponse delete(final String path) throws VaultException { + return delete(path, config.getToken()); + } + + public LogicalResponse delete(final String path, String token) throws VaultException { int retryCount = 0; while (true) { try { // Make an HTTP request to Vault final RestResponse restResponse = new Rest()//NOPMD .url(config.getAddress() + "/v1/" + path) - .header("X-Vault-Token", config.getToken()) + .header("X-Vault-Token", token) .connectTimeoutSeconds(config.getOpenTimeout()) .readTimeoutSeconds(config.getReadTimeout()) .sslVerification(config.getSslConfig().isVerify()) @@ -270,4 +283,72 @@ public LogicalResponse delete(final String path) throws VaultException { } } } + + public List getCapabilitiesSelf(final String path) throws VaultException { + return getCapabilitiesSelf(path, config.getToken()); + } + + public List getCapabilitiesSelf(final String path, String token) throws VaultException { + final List returnValues = new ArrayList<>(); + LogicalResponse response = null; + try { + int retryCount = 0; + while (true) { + try { + final String payload = String.format("{\"path\":\"%s\"}", path); + // Make an HTTP request to Vault + final RestResponse restResponse = new Rest()//NOPMD + .url(config.getAddress() + "/v1/sys/capabilities-self") + .header("X-Vault-Token", token) + .connectTimeoutSeconds(config.getOpenTimeout()) + .readTimeoutSeconds(config.getReadTimeout()) + .sslVerification(config.getSslConfig().isVerify()) + .sslContext(config.getSslConfig().getSslContext()) + .body(payload.getBytes(StandardCharsets.UTF_8)) + .post(); + + // Validate response + if (restResponse.getStatus() != 200) { + throw new VaultException("Vault responded with HTTP status code: " + restResponse.getStatus() + + "\nResponse body: " + new String(restResponse.getBody(), "UTF-8"), restResponse.getStatus()); + } + + response = new LogicalResponse(restResponse, retryCount); + if (response != null + && response.getRestResponse().getStatus() != 404 + && response.getData() != null + && response.getData().get("capabilities") != null) { + + final JsonArray keys = Json.parse(response.getData().get("capabilities")).asArray(); + for (int index = 0; index < keys.size(); index++) { + returnValues.add(keys.get(index).asString()); + } + } + return returnValues; + } catch (RuntimeException | VaultException | RestException | UnsupportedEncodingException e) { + // If there are retries to perform, then pause for the configured interval and then execute the loop again... + if (retryCount < config.getMaxRetries()) { + retryCount++; + try { + final int retryIntervalMilliseconds = config.getRetryIntervalMilliseconds(); + Thread.sleep(retryIntervalMilliseconds); + } catch (InterruptedException e1) { + e1.printStackTrace(); + } + } else if (e instanceof VaultException) { + // ... otherwise, give up. + throw (VaultException) e; + } else { + throw new VaultException(e); + } + } + } + + } catch (final VaultException e) { + if (e.getHttpStatusCode() != 404) { + throw e; + } + } + return returnValues; + } } diff --git a/src/main/java/com/bettercloud/vault/api/Seal.java b/src/main/java/com/bettercloud/vault/api/Seal.java index 67fcee45..a8d5bc4f 100644 --- a/src/main/java/com/bettercloud/vault/api/Seal.java +++ b/src/main/java/com/bettercloud/vault/api/Seal.java @@ -29,13 +29,17 @@ public Seal(final VaultConfig config) { * @throws VaultException If any error occurs, or unexpected response received from Vault */ public void seal() throws VaultException { + seal(config.getToken()); + } + + public void seal(final String token) throws VaultException { int retryCount = 0; while (true) { try { // HTTP request to Vault final RestResponse restResponse = new Rest()//NOPMD .url(config.getAddress() + "/v1/sys/seal") - .header("X-Vault-Token", config.getToken()) + .header("X-Vault-Token", token) .connectTimeoutSeconds(config.getOpenTimeout()) .readTimeoutSeconds(config.getReadTimeout()) .sslVerification(config.getSslConfig().isVerify()) diff --git a/src/main/java/com/bettercloud/vault/api/pki/Pki.java b/src/main/java/com/bettercloud/vault/api/pki/Pki.java index a01e5af3..ad556309 100644 --- a/src/main/java/com/bettercloud/vault/api/pki/Pki.java +++ b/src/main/java/com/bettercloud/vault/api/pki/Pki.java @@ -95,6 +95,10 @@ public PkiResponse createOrUpdateRole(final String roleName) throws VaultExcepti * @throws VaultException If any error occurs or unexpected response is received from Vault */ public PkiResponse createOrUpdateRole(final String roleName, final RoleOptions options) throws VaultException { + return createOrUpdateRole(roleName, options, config.getToken()); + } + + public PkiResponse createOrUpdateRole(final String roleName, final RoleOptions options, final String token) throws VaultException { int retryCount = 0; while (true) { try { @@ -102,7 +106,7 @@ public PkiResponse createOrUpdateRole(final String roleName, final RoleOptions o final RestResponse restResponse = new Rest()//NOPMD .url(String.format("%s/v1/%s/roles/%s", config.getAddress(), this.mountPath, roleName)) - .header("X-Vault-Token", config.getToken()) + .header("X-Vault-Token", token) .body(requestJson.getBytes("UTF-8")) .connectTimeoutSeconds(config.getOpenTimeout()) .readTimeoutSeconds(config.getReadTimeout()) @@ -157,13 +161,17 @@ public PkiResponse createOrUpdateRole(final String roleName, final RoleOptions o * @throws VaultException If any error occurs or unexpected response is received from Vault */ public PkiResponse getRole(final String roleName) throws VaultException { + return getRole(roleName, config.getToken()); + } + + public PkiResponse getRole(final String roleName, final String token) throws VaultException { int retryCount = 0; while (true) { // Make an HTTP request to Vault try { final RestResponse restResponse = new Rest()//NOPMD .url(String.format("%s/v1/%s/roles/%s", config.getAddress(), this.mountPath, roleName)) - .header("X-Vault-Token", config.getToken()) + .header("X-Vault-Token", token) .connectTimeoutSeconds(config.getOpenTimeout()) .readTimeoutSeconds(config.getReadTimeout()) .sslVerification(config.getSslConfig().isVerify()) @@ -217,13 +225,17 @@ public PkiResponse getRole(final String roleName) throws VaultException { * @throws VaultException If any error occurs or unexpected response is received from Vault */ public PkiResponse deleteRole(final String roleName) throws VaultException { + return deleteRole(roleName, config.getToken()); + } + + public PkiResponse deleteRole(final String roleName, final String token) throws VaultException { int retryCount = 0; while (true) { // Make an HTTP request to Vault try { final RestResponse restResponse = new Rest()//NOPMD .url(String.format("%s/v1/%s/roles/%s", config.getAddress(), this.mountPath, roleName)) - .header("X-Vault-Token", config.getToken()) + .header("X-Vault-Token", token) .connectTimeoutSeconds(config.getOpenTimeout()) .readTimeoutSeconds(config.getReadTimeout()) .sslVerification(config.getSslConfig().isVerify()) @@ -333,6 +345,19 @@ public PkiResponse issue( final String ttl, final CredentialFormat format, final String csr + ) throws VaultException { + return issue(roleName, commonName, altNames, ipSans, ttl, format, csr, config.getToken()); + } + + public PkiResponse issue( + final String roleName, + final String commonName, + final List altNames, + final List ipSans, + final String ttl, + final CredentialFormat format, + final String csr, + final String token ) throws VaultException { int retryCount = 0; while (true) { @@ -377,7 +402,7 @@ public PkiResponse issue( String endpoint = (csr == null || csr.isEmpty()) ? "%s/v1/%s/issue/%s" : "%s/v1/%s/sign/%s"; final RestResponse restResponse = new Rest()//NOPMD .url(String.format(endpoint, config.getAddress(), this.mountPath, roleName)) - .header("X-Vault-Token", config.getToken()) + .header("X-Vault-Token", token) .body(requestJson.getBytes("UTF-8")) .connectTimeoutSeconds(config.getOpenTimeout()) .readTimeoutSeconds(config.getReadTimeout())