Skip to content

Commit

Permalink
Remove VaultClient in favor of RestOperations.
Browse files Browse the repository at this point in the history
Remove VaultClient from VaultTemplate and switch implementations to use RestOperations directly. VaultClient provided an additional abstraction level over RestTemplate with a large API surface adding only little value.

Implementations work directly with RestOperations. Relative URI expansion is handled by DefaultUriTemplateHandler configured with the VaultEndpoint base URI.

Closes gh-49.

Original pull request: gh-57.
  • Loading branch information
mp911de committed Feb 16, 2017
1 parent b1e28c4 commit 5078a4c
Show file tree
Hide file tree
Showing 50 changed files with 1,243 additions and 1,961 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2016-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.
Expand All @@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.vault.client;
package org.springframework.vault;

import org.springframework.core.NestedRuntimeException;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2016-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.
Expand All @@ -22,11 +22,12 @@
import org.apache.commons.logging.LogFactory;

import org.springframework.util.Assert;
import org.springframework.vault.client.VaultClient;
import org.springframework.vault.client.VaultException;
import org.springframework.vault.client.VaultResponseEntity;
import org.springframework.vault.VaultException;
import org.springframework.vault.client.VaultResponses;
import org.springframework.vault.support.VaultResponse;
import org.springframework.vault.support.VaultToken;
import org.springframework.web.client.HttpStatusCodeException;
import org.springframework.web.client.RestOperations;

/**
* AppId implementation of {@link ClientAuthentication}. {@link AppIdAuthentication} uses
Expand All @@ -35,7 +36,7 @@
*
* @author Mark Paluch
* @see AppIdAuthenticationOptions
* @see VaultClient
* @see RestOperations
* @see <a href="https://www.vaultproject.io/docs/auth/app-id.html">Auth Backend: App
* ID</a>
*/
Expand All @@ -45,22 +46,23 @@ public class AppIdAuthentication implements ClientAuthentication {

private final AppIdAuthenticationOptions options;

private final VaultClient vaultClient;
private final RestOperations restOperations;

/**
* Creates a {@link AppIdAuthentication} using {@link AppIdAuthenticationOptions} and
* {@link VaultClient}.
* {@link RestOperations}.
*
* @param options must not be {@literal null}.
* @param vaultClient must not be {@literal null}.
* @param restOperations must not be {@literal null}.
*/
public AppIdAuthentication(AppIdAuthenticationOptions options, VaultClient vaultClient) {
public AppIdAuthentication(AppIdAuthenticationOptions options,
RestOperations restOperations) {

Assert.notNull(options, "AppIdAuthenticationOptions must not be null");
Assert.notNull(vaultClient, "VaultClient must not be null");
Assert.notNull(restOperations, "RestOperations must not be null");

this.options = options;
this.vaultClient = vaultClient;
this.restOperations = restOperations;
}

@Override
Expand All @@ -73,18 +75,18 @@ private VaultToken createTokenUsingAppId() {
Map<String, String> login = getAppIdLogin(options.getAppId(), options
.getUserIdMechanism().createUserId());

VaultResponseEntity<VaultResponse> entity = vaultClient.postForEntity(
String.format("auth/%s/login", options.getPath()), login,
VaultResponse.class);
try {
VaultResponse response = restOperations.postForObject("/auth/{mount}/login",
login, VaultResponse.class, options.getPath());

if (!entity.isSuccessful()) {
logger.debug("Login successful using AppId authentication");

return LoginTokenUtil.from(response.getAuth());
}
catch (HttpStatusCodeException e) {
throw new VaultException(String.format("Cannot login using app-id: %s",
entity.getMessage()));
VaultResponses.getError(e.getResponseBodyAsString())));
}

logger.debug("Login successful using AppId authentication");

return LoginTokenUtil.from(entity.getBody().getAuth());
}

private Map<String, String> getAppIdLogin(String appId, String userId) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2016-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.
Expand All @@ -22,11 +22,12 @@
import org.apache.commons.logging.LogFactory;

import org.springframework.util.Assert;
import org.springframework.vault.client.VaultClient;
import org.springframework.vault.client.VaultException;
import org.springframework.vault.client.VaultResponseEntity;
import org.springframework.vault.VaultException;
import org.springframework.vault.client.VaultResponses;
import org.springframework.vault.support.VaultResponse;
import org.springframework.vault.support.VaultToken;
import org.springframework.web.client.HttpStatusCodeException;
import org.springframework.web.client.RestOperations;

/**
* AppRole implementation of {@link ClientAuthentication}. RoleId and SecretId (optional)
Expand All @@ -37,7 +38,7 @@
*
* @author Mark Paluch
* @see AppRoleAuthenticationOptions
* @see VaultClient
* @see RestOperations
* @see <a href="https://www.vaultproject.io/docs/auth/approle.html">Auth Backend:
* AppRole</a>
*/
Expand All @@ -47,23 +48,23 @@ public class AppRoleAuthentication implements ClientAuthentication {

private final AppRoleAuthenticationOptions options;

private final VaultClient vaultClient;
private final RestOperations restOperations;

/**
* Creates a {@link AppRoleAuthentication} using {@link AppRoleAuthenticationOptions}
* and {@link VaultClient}.
* and {@link RestOperations}.
*
* @param options must not be {@literal null}.
* @param vaultClient must not be {@literal null}.
* @param restOperations must not be {@literal null}.
*/
public AppRoleAuthentication(AppRoleAuthenticationOptions options,
VaultClient vaultClient) {
RestOperations restOperations) {

Assert.notNull(options, "AppRoleAuthenticationOptions must not be null");
Assert.notNull(vaultClient, "VaultClient must not be null");
Assert.notNull(restOperations, "RestOperations must not be null");

this.options = options;
this.vaultClient = vaultClient;
this.restOperations = restOperations;
}

@Override
Expand All @@ -76,18 +77,18 @@ private VaultToken createTokenUsingAppRole() {
Map<String, String> login = getAppRoleLogin(options.getRoleId(),
options.getSecretId());

VaultResponseEntity<VaultResponse> entity = vaultClient.postForEntity(
String.format("auth/%s/login", options.getPath()), login,
VaultResponse.class);
try {
VaultResponse response = restOperations.postForObject("/auth/{mount}/login",
login, VaultResponse.class, options.getPath());

if (!entity.isSuccessful()) {
logger.debug("Login successful using AppRole authentication");

return LoginTokenUtil.from(response.getAuth());
}
catch (HttpStatusCodeException e) {
throw new VaultException(String.format("Cannot login using AppRole: %s",
entity.getMessage()));
VaultResponses.getError(e.getResponseBodyAsString())));
}

logger.debug("Login successful using AppRole authentication");

return LoginTokenUtil.from(entity.getBody().getAuth());
}

private Map<String, String> getAppRoleLogin(String roleId, String secretId) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2016-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.
Expand All @@ -25,13 +25,13 @@

import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.vault.client.VaultClient;
import org.springframework.vault.client.VaultException;
import org.springframework.vault.client.VaultResponseEntity;
import org.springframework.vault.VaultException;
import org.springframework.vault.client.VaultResponses;
import org.springframework.vault.support.VaultResponse;
import org.springframework.vault.support.VaultToken;
import org.springframework.web.client.HttpStatusCodeException;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.RestOperations;

/**
* AWS-EC2 login implementation.
Expand All @@ -42,6 +42,7 @@
*
* @author Mark Paluch
* @see AwsEc2AuthenticationOptions
* @see RestOperations
* @see <a href="https://www.vaultproject.io/docs/auth/aws-ec2.html">Auth Backend:
* aws-ec2</a>
*/
Expand All @@ -51,41 +52,42 @@ public class AwsEc2Authentication implements ClientAuthentication {

private final AwsEc2AuthenticationOptions options;

private final VaultClient vaultClient;
private final RestOperations vaultRestOperations;

private final RestTemplate restTemplate;
private final RestOperations awsMetadataRestOperations;

private final AtomicReference<char[]> nonce = new AtomicReference<char[]>();

/**
* Creates a new {@link AwsEc2Authentication}.
*
* @param vaultClient must not be {@literal null}.
*
* @param vaultRestOperations must not be {@literal null}.
*/
public AwsEc2Authentication(VaultClient vaultClient) {
this(AwsEc2AuthenticationOptions.DEFAULT, vaultClient, vaultClient
.getRestTemplate());
public AwsEc2Authentication(RestOperations vaultRestOperations) {
this(AwsEc2AuthenticationOptions.DEFAULT, vaultRestOperations,
vaultRestOperations);
}

/**
* Creates a new {@link AwsEc2Authentication} specifying
* {@link AwsEc2AuthenticationOptions}, {@link VaultClient} and a {@link RestTemplate}
* .
*
* {@link AwsEc2AuthenticationOptions}, a Vault and an AWS-Metadata-specific
* {@link RestOperations} .
*
* @param options must not be {@literal null}.
* @param vaultClient must not be {@literal null}.
* @param restTemplate must not be {@literal null}.
* @param vaultRestOperations must not be {@literal null}.
* @param awsMetadataRestOperations must not be {@literal null}.
*/
public AwsEc2Authentication(AwsEc2AuthenticationOptions options,
VaultClient vaultClient, RestTemplate restTemplate) {
RestOperations vaultRestOperations, RestOperations awsMetadataRestOperations) {

Assert.notNull(options, "AwsEc2AuthenticationOptions must not be null");
Assert.notNull(vaultClient, "VaultEndpoint must not be null");
Assert.notNull(restTemplate, "RestTemplate must not be null");
Assert.notNull(vaultRestOperations, "Vault RestOperations must not be null");
Assert.notNull(awsMetadataRestOperations,
"AWS Metadata RestOperations must not be null");

this.options = options;
this.vaultClient = vaultClient;
this.restTemplate = restTemplate;
this.vaultRestOperations = vaultRestOperations;
this.awsMetadataRestOperations = awsMetadataRestOperations;
}

@Override
Expand All @@ -96,35 +98,34 @@ public VaultToken login() throws VaultException {
@SuppressWarnings("unchecked")
private VaultToken createTokenUsingAwsEc2() {

String path = String.format("auth/%s/login", options.getPath());

Map<String, String> login = getEc2Login();

VaultResponseEntity<VaultResponse> entity = this.vaultClient.postForEntity(path,
login, VaultResponse.class);

if (!entity.isSuccessful()) {
throw new VaultException(String.format("Cannot login using AWS-EC2: %s",
entity.getMessage()));
}

VaultResponse body = entity.getBody();

if (logger.isDebugEnabled()) {
try {

if (body.getAuth().get("metadata") instanceof Map) {
Map<Object, Object> metadata = (Map<Object, Object>) body.getAuth().get(
"metadata");
logger.debug(String
.format("Login successful using AWS-EC2 authentication for instance %s, AMI %s",
metadata.get("instance_id"), metadata.get("instance_id")));
}
else {
logger.debug("Login successful using AWS-EC2 authentication");
VaultResponse response = this.vaultRestOperations.postForObject(
"/auth/{mount}/login", login, VaultResponse.class, options.getPath());

if (logger.isDebugEnabled()) {

if (response.getAuth().get("metadata") instanceof Map) {
Map<Object, Object> metadata = (Map<Object, Object>) response
.getAuth().get("metadata");
logger.debug(String
.format("Login successful using AWS-EC2 authentication for instance %s, AMI %s",
metadata.get("instance_id"),
metadata.get("instance_id")));
}
else {
logger.debug("Login successful using AWS-EC2 authentication");
}
}
}

return LoginTokenUtil.from(entity.getBody().getAuth());
return LoginTokenUtil.from(response.getAuth());
}
catch (HttpStatusCodeException e) {
throw new VaultException(String.format("Cannot login using AWS-EC2: %s",
VaultResponses.getError(e.getResponseBodyAsString())));
}
}

protected Map<String, String> getEc2Login() {
Expand All @@ -142,8 +143,8 @@ protected Map<String, String> getEc2Login() {
login.put("nonce", new String(this.nonce.get()));

try {
String pkcs7 = restTemplate.getForObject(options.getIdentityDocumentUri(),
String.class);
String pkcs7 = awsMetadataRestOperations.getForObject(
options.getIdentityDocumentUri(), String.class);
if (StringUtils.hasText(pkcs7)) {
login.put("pkcs7", pkcs7.replaceAll("\\r", "").replace("\\n", ""));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2016-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.
Expand All @@ -15,7 +15,7 @@
*/
package org.springframework.vault.authentication;

import org.springframework.vault.client.VaultException;
import org.springframework.vault.VaultException;
import org.springframework.vault.support.VaultToken;

/**
Expand All @@ -33,5 +33,5 @@ public interface ClientAuthentication {
*
* @return a {@link VaultToken}.
*/
public VaultToken login() throws VaultException;
VaultToken login() throws VaultException;
}
Loading

0 comments on commit 5078a4c

Please sign in to comment.