Skip to content
This repository has been archived by the owner on Jan 12, 2024. It is now read-only.

Commit

Permalink
Merge pull request #34 from Nike-Inc/highlander
Browse files Browse the repository at this point in the history
Remove Vault Client dependency
  • Loading branch information
sdford authored Apr 24, 2018
2 parents 864ea0b + d79c58e commit 95646f4
Show file tree
Hide file tree
Showing 52 changed files with 2,546 additions and 466 deletions.
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
[![Coverage Status](https://coveralls.io/repos/github/Nike-Inc/cerberus-java-client/badge.svg?branch=master)](https://coveralls.io/github/Nike-Inc/cerberus-java-client)
[![][license img]][license]

A java based client library for Cerberus that's built on top of Nike's Vault client.
A java based client library for Cerberus that's built on top of Nike's Cerberus client.

This library acts as a wrapper around the Nike developed Vault client by configuring the client to be Cerberus compatible.
This library acts as a wrapper around the Nike developed Cerberus client by configuring the client to be Cerberus compatible.

To learn more about Cerberus, please see the [Cerberus website](http://engineering.nike.com/cerberus/).

Expand All @@ -17,14 +17,14 @@ To learn more about Cerberus, please see the [Cerberus website](http://engineeri
2. Add the [Cerberus client dependency](https://bintray.com/nike/maven/cerberus-client) to your build (e.g. Maven, Gradle)
3. Provide an authentication mechanism.
- For local development it is easiest to export a `CERBERUS_TOKEN` that you copied from the Cerberus dashboard.
When running in AWS, your application will not need this environmetal variable, instead it will automatically
When running in AWS, your application will not need this environment variable, instead it will automatically
authenticate using its IAM role. Alternatively, set a `cerberus.token` System property.
- If you would like to test IAM authentication locally, you can do that by [assuming a role](http://docs.aws.amazon.com/cli/latest/userguide/cli-roles.html).
4. Access secrets from Cerberus using Java
``` java
String cerberusUrl = "https://cerberus.example.com";
VaultClient vaultClient = DefaultCerberusClientFactory.getClient(cerberusUrl);
Map<String,String> secrets = vaultClient.read("/app/my-sdb-name").getData();
CerberusClient cerberusClient = DefaultCerberusClientFactory.getClient(cerberusUrl);
Map<String,String> secrets = cerberusClient.read("/app/my-sdb-name").getData();
```

## Lambdas
Expand Down Expand Up @@ -68,8 +68,8 @@ Setup the CERBERUS_ADDR environmental variable and access Cerberus using Java:

``` java
String invokedFunctionArn = context.getInvokedFunctionArn();
VaultClient vaultClient = DefaultCerberusClientFactory.getClientForLambda(invokedFunctionArn);
Map<String,String> secrets = vaultClient.read("/app/my-sdb-name").getData();
CerberusClient cerberusClient = DefaultCerberusClientFactory.getClientForLambda(invokedFunctionArn);
Map<String,String> secrets = cerberusClient.read("/app/my-sdb-name").getData();
```

## More Configuration Options
Expand All @@ -83,8 +83,8 @@ Provide the URL directly using the factory method `DefaultCerberusClientFactory.
and then use the factory method that does not require a URL:

``` java
final VaultClient vaultClient = DefaultCerberusClientFactory.getClient();
Map<String,String> secrets = vaultClient.read("/app/my-sdb-name").getData();
final CerberusClient cerberusClient = DefaultCerberusClientFactory.getClient();
Map<String,String> secrets = cerberusClient.read("/app/my-sdb-name").getData();
```

### Configuring Credentials
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
version=4.3.0
version=5.0.0
groupId=com.nike
artifactId=cerberus-client
10 changes: 7 additions & 3 deletions gradle/dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ repositories {
}

def AWS_SDK_VERSION = '1.11.123'
def VAULT_CLIENT_COORDINATES = "com.nike:vault-client:2.1.0"

//noinspection GroovyAssignabilityCheck
dependencies {
Expand All @@ -35,13 +34,17 @@ dependencies {
***********************************************************************************************************************/

// these will be added to the POM and excluded from the shadow jar
shadow VAULT_CLIENT_COORDINATES
compile VAULT_CLIENT_COORDINATES
shadow "joda-time:joda-time:2.8.1"
shadow "org.apache.commons:commons-lang3:3.4"
shadow "org.slf4j:slf4j-api:1.7.25"
shadow "com.google.code.gson:gson:2.5"
shadow "com.google.code.findbugs:jsr305:3.0.1"

compile "com.squareup.okhttp3:okhttp:3.9.0"
compile "org.apache.commons:commons-lang3:3.4"
compile "com.google.code.gson:gson:2.5"
compile "com.google.code.findbugs:jsr305:3.0.1"
compile "org.slf4j:slf4j-api:1.7.25"

compile "com.amazonaws:aws-java-sdk-core:${AWS_SDK_VERSION}"
compile "com.amazonaws:aws-java-sdk-kms:${AWS_SDK_VERSION}"
Expand All @@ -60,6 +63,7 @@ dependencies {
}
testCompile "org.assertj:assertj-core:2.3.0"
testCompile "com.squareup.okhttp3:mockwebserver:3.7.0"
testCompile "commons-io:commons-io:2.4"
}

shadowJar {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
/*
* Copyright (c) 2018 Nike, Inc.
*
* 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 com.nike.cerberus.client.auth.aws;

import com.fieldju.commons.EnvUtils;
import com.nike.cerberus.client.CerberusClient;
import com.nike.cerberus.client.CerberusServerException;
import com.nike.cerberus.client.DefaultCerberusUrlResolver;
import com.nike.cerberus.client.model.CerberusListResponse;
import com.nike.cerberus.client.model.CerberusResponse;
import okhttp3.OkHttpClient;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.BeforeClass;
import org.junit.Test;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

/**
* Tests StaticIamRoleCerberusCredentialsProvider class
*/
public class CerberusClientTest {

private static final String ROOT_SDB_PATH = "app/cerberus-integration-tests-sdb/";

private static String iam_principal_arn;
private static String region;

private static String secretPath;
private static String sdbFullSecretPath;
private static Map<String, String> secretData;

private static CerberusClient cerberusClient;

private static StaticIamRoleCerberusCredentialsProvider staticIamRoleCerberusCredentialsProvider;

@BeforeClass
public static void setUp() {
iam_principal_arn = EnvUtils.getRequiredEnv("TEST_IAM_PRINCIPAL_ARN", "The role to be assume by the integration test");
region = EnvUtils.getRequiredEnv("TEST_REGION");

EnvUtils.getRequiredEnv("CERBERUS_ADDR");

secretPath = UUID.randomUUID().toString();
sdbFullSecretPath = ROOT_SDB_PATH + secretPath;

String key = RandomStringUtils.randomAlphabetic(15);
String value = RandomStringUtils.randomAlphabetic(25);
secretData = new HashMap<>();
secretData.put(key, value);
}

private Map<String, String> generateNewSecretData() {
String key = RandomStringUtils.randomAlphabetic(20);
String value = RandomStringUtils.randomAlphabetic(30);
Map<String, String> newSecretData = new HashMap<>();
newSecretData.put(key, value);

return newSecretData;
}

@Test
public void test_cerberus_client_crud_after_auth_with_account_id_and_role_name() {
Pattern arn_pattern = Pattern.compile("arn:aws:iam::(?<accountId>[0-9].*):role\\/(?<roleName>.*)");
Matcher matcher = arn_pattern.matcher(iam_principal_arn);
if (! matcher.matches()) {
throw new AssertionError("IAM Principal ARN does not match expected format");
}
String account_id = matcher.group("accountId");
String role_name = matcher.group("roleName");

staticIamRoleCerberusCredentialsProvider = new StaticIamRoleCerberusCredentialsProvider(
new DefaultCerberusUrlResolver(),
account_id,
role_name,
region);

cerberusClient = new CerberusClient(new DefaultCerberusUrlResolver(),
staticIamRoleCerberusCredentialsProvider, new OkHttpClient());

// create secret
cerberusClient.write(sdbFullSecretPath, secretData);

// read secret
CerberusResponse cerberusReadResponse = cerberusClient.read(sdbFullSecretPath);
assertEquals(secretData, cerberusReadResponse.getData());

// list secrets
CerberusListResponse cerberusListResponse = cerberusClient.list(ROOT_SDB_PATH);
assertTrue(cerberusListResponse.getKeys().contains(secretPath));

// update secret
Map<String, String> newSecretData = generateNewSecretData();
cerberusClient.write(sdbFullSecretPath, newSecretData);
secretData = newSecretData;

// confirm updated secret data
CerberusResponse cerberusReadResponseUpdated = cerberusClient.read(sdbFullSecretPath);
assertEquals(newSecretData, cerberusReadResponseUpdated.getData());

// delete secret
cerberusClient.delete(sdbFullSecretPath);

// confirm secret is deleted
try {
cerberusClient.read(sdbFullSecretPath);
} catch (CerberusServerException cse) {
assertEquals(404, cse.getCode());
}
}

@Test
public void test_secret_is_deleted_after_auth_with_iam_principal_name() {

staticIamRoleCerberusCredentialsProvider = new StaticIamRoleCerberusCredentialsProvider(
new DefaultCerberusUrlResolver(),
iam_principal_arn,
region);

cerberusClient = new CerberusClient(new DefaultCerberusUrlResolver(),
staticIamRoleCerberusCredentialsProvider, new OkHttpClient());

// create secret
cerberusClient.write(sdbFullSecretPath, secretData);

// read secret
CerberusResponse cerberusReadResponse = cerberusClient.read(sdbFullSecretPath);
assertEquals(secretData, cerberusReadResponse.getData());

// list secrets
CerberusListResponse cerberusListResponse = cerberusClient.list(ROOT_SDB_PATH);
assertTrue(cerberusListResponse.getKeys().contains(secretPath));

// update secret
Map<String, String> newSecretData = generateNewSecretData();
cerberusClient.write(sdbFullSecretPath, newSecretData);
secretData = newSecretData;

// confirm updated secret data
CerberusResponse cerberusReadResponseUpdated = cerberusClient.read(sdbFullSecretPath);
assertEquals(newSecretData, cerberusReadResponseUpdated.getData());

// delete secret
cerberusClient.delete(sdbFullSecretPath);

// confirm secret is deleted
try {
cerberusClient.read(sdbFullSecretPath);
} catch (CerberusServerException cse) {
assertEquals(404, cse.getCode());
}
}

}
Loading

0 comments on commit 95646f4

Please sign in to comment.