Skip to content

Commit

Permalink
Support prefixPath field (#67)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcoreni authored and jetersen committed Jan 20, 2020
1 parent e102726 commit 3736158
Show file tree
Hide file tree
Showing 10 changed files with 67 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ The secret source for JCasC is configured via environment variables as way to ge
- The environment variable `CASC_VAULT_AGENT_ADDR` is optional. It takes precedence over `CASC_VAULT_URL` and is used for connecting to a Vault Agent. [See this section](#vault-agent)
- The environment variable `CASC_VAULT_MOUNT` is optional. (Vault auth mount. For example, `ldap` or another username & password authentication type, defaults to `userpass`.)
- The environment variable `CASC_VAULT_NAMESPACE` is optional. If used, sets the Vault namespace for Enterprise Vaults.
- The environment variable `CASC_VAULT_PREFIX_PATH` is optional. If used, allows to use complex prefix paths (for example with KV secrets available at `my/long/data/prefix/kv/secret1` set this to `my/long/data/prefix/kv`).
- The environment variable `CASC_VAULT_FILE` is optional, provides a way for the other variables to be read from a file instead of environment variables.
- The environment variable `CASC_VAULT_ENGINE_VERSION` is optional. If unset, your vault path is assumed to be using kv version 2. If your vault path uses engine version 1, set this variable to `1`.
- The issued token should have read access to vault path `auth/token/lookup-self` in order to determine its expiration time. JCasC will re-issue a token if its expiration is reached (except for `CASC_VAULT_TOKEN`).
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@
<dependency>
<groupId>com.bettercloud</groupId>
<artifactId>vault-java-driver</artifactId>
<version>5.0.0</version>
<version>5.1.0</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ public class VaultConfiguration

private String vaultNamespace;

private String prefixPath;

private Integer timeout = DEFAULT_TIMEOUT;

@DataBoundConstructor
Expand All @@ -68,6 +70,7 @@ public VaultConfiguration(VaultConfiguration toCopy) {
this.skipSslVerification = toCopy.skipSslVerification;
this.engineVersion = toCopy.engineVersion;
this.vaultNamespace = toCopy.vaultNamespace;
this.prefixPath = toCopy.prefixPath;
this.timeout = toCopy.timeout;
}

Expand All @@ -88,6 +91,9 @@ public VaultConfiguration mergeWithParent(VaultConfiguration parent) {
if (StringUtils.isBlank(result.getVaultNamespace())) {
result.setVaultNamespace(parent.getVaultNamespace());
}
if (StringUtils.isBlank(result.getPrefixPath())) {
result.setPrefixPath(parent.getPrefixPath());
}
if (result.timeout == null) {
result.setTimeout(parent.getTimeout());
}
Expand Down Expand Up @@ -149,6 +155,15 @@ public void setVaultNamespace(String vaultNamespace) {
this.vaultNamespace = fixEmptyAndTrim(vaultNamespace);
}

public String getPrefixPath() {
return prefixPath;
}

@DataBoundSetter
public void setPrefixPath(String prefixPath) {
this.prefixPath = fixEmptyAndTrim(prefixPath);
}

public Integer getTimeout() {
return timeout;
}
Expand Down Expand Up @@ -221,6 +236,10 @@ public VaultConfig getVaultConfig() {
if (StringUtils.isNotEmpty(this.getVaultNamespace())) {
vaultConfig.nameSpace(this.getVaultNamespace());
}

if (StringUtils.isNotEmpty(this.getPrefixPath())) {
vaultConfig.prefixPath(this.getPrefixPath());
}
} catch (VaultException e) {
throw new VaultPluginException("Could not set up VaultConfig.", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@ private static String getVaultSecret(String secretPath, String secretKey,
vaultConfig.nameSpace(globalConfig.getConfiguration().getVaultNamespace());
}

if (StringUtils.isNotEmpty(globalConfig.getConfiguration().getPrefixPath())) {
vaultConfig.prefixPath(globalConfig.getConfiguration().getPrefixPath());
}

VaultCredential vaultCredential = retrieveVaultCredentials(
globalConfig.getConfiguration().getVaultCredentialId());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public class VaultSecretSource extends SecretSource {
private static final String CASC_VAULT_APPROLE = "CASC_VAULT_APPROLE";
private static final String CASC_VAULT_APPROLE_SECRET = "CASC_VAULT_APPROLE_SECRET";
private static final String CASC_VAULT_NAMESPACE = "CASC_VAULT_NAMESPACE";
private static final String CASC_VAULT_PREFIX_PATH = "CASC_VAULT_PREFIX_PATH";
private static final String CASC_VAULT_ENGINE_VERSION = "CASC_VAULT_ENGINE_VERSION";
private static final String CASC_VAULT_PATHS = "CASC_VAULT_PATHS";
private static final String CASC_VAULT_PATH = "CASC_VAULT_PATH"; // TODO: deprecate!
Expand Down Expand Up @@ -63,6 +64,7 @@ private void configureVault() {
.map(Optional::of)
.orElseGet(() -> getVariable(CASC_VAULT_URL));
Optional<String> vaultNamespace = getVariable(CASC_VAULT_NAMESPACE);
Optional<String> vaultPrefixPath = getVariable(CASC_VAULT_PREFIX_PATH);
Optional<String[]> vaultPaths = getCommaSeparatedVariables(CASC_VAULT_PATHS);
getVariable(CASC_VAULT_PATH).ifPresent(s -> LOGGER
.log(Level.SEVERE, "{0} is deprecated, please switch to {1}",
Expand All @@ -88,6 +90,11 @@ private void configureVault() {

vaultConfig.engineVersion(Integer.parseInt(vaultEngineVersion));
LOGGER.log(Level.FINE, "Using engine version: {0}", vaultEngineVersion);

if (vaultPrefixPath.isPresent()) {
vaultConfig.prefixPath(vaultPrefixPath.get());
LOGGER.log(Level.FINE, "Using prefixPath with Vault: {0}", vaultPrefixPath);
}
} catch (VaultException e) {
LOGGER.log(Level.WARNING, "Could not configure vault connection", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,14 @@ public void shouldStoreFailureHandling() {
parent.setTimeout(20);
assertThat(parent.isFailIfNotFound(), is(false));
}

@Test
public void shouldStorePrefixPath() {
VaultConfiguration parent = new VaultConfiguration();
parent.setVaultUrl("http://vault-url.com/");
parent.setFailIfNotFound(false);
parent.setPrefixPath("my/custom/prefixpath");
parent.setTimeout(20);
assertThat(parent.getPrefixPath(), is("my/custom/prefixpath"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,19 @@ public void kv2WithUser() {
assertThat(SecretSourceResolver.resolve(context, "${key1}"), equalTo("123"));
}

@Test
@ConfiguredWithCode("vault.yml")
@Envs({
@Env(name = "CASC_VAULT_USER", value = VAULT_USER),
@Env(name = "CASC_VAULT_PW", value = VAULT_PW),
@Env(name = "CASC_VAULT_PATHS", value = VAULT_PATH_LONG_KV2_1 + "," + VAULT_PATH_LONG_KV2_2),
@Env(name = "CASC_VAULT_PREFIX_PATH", value = VAULT_PATH_LONG_KV2_PREFIX_PATH),
@Env(name = "CASC_VAULT_ENGINE_VERSION", value = "2")
})
public void kv2WithLongPathAndUser() {
assertThat(SecretSourceResolver.resolve(context, "${key1}"), equalTo("123"));
}

@Test
@ConfiguredWithCode("vault.yml")
@Envs({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ public interface TestConstants {
String VAULT_PATH_KV2_2 = "kv-v2/dev";
String VAULT_PATH_KV2_3 = "kv-v2/qa";
String VAULT_PATH_KV2_AUTH_TEST = "kv-v2/auth-test";
String VAULT_PATH_LONG_KV2_1 = "long/path/kv-v2/admin";
String VAULT_PATH_LONG_KV2_2 = "long/path/kv-v2/dev";
String VAULT_PATH_LONG_KV2_PREFIX_PATH = "long/path/kv-v2";
String VAULT_APPROLE_FILE = "JCasC_temp_approle_secret.prop";
String VAULT_AGENT_FILE = "JCasC_temp_vault_agent.prop";
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ public static void configureVaultContainer(VaultContainer container) {
// Create Secret Backends
runCommand(container, "vault", "secrets", "enable", "-path=kv-v2",
"-version=2", "kv");
runCommand(container, "vault", "secrets", "enable", "-path=long/path/kv-v2",
"-version=2", "kv");
runCommand(container, "vault", "secrets", "enable", "-path=kv-v1",
"-version=1", "kv");

Expand Down Expand Up @@ -137,6 +139,9 @@ public static void configureVaultContainer(VaultContainer container) {
runCommand(container, "vault", "kv", "put", VAULT_PATH_KV2_3, "key2=321");
runCommand(container, "vault", "kv", "put", VAULT_PATH_KV2_AUTH_TEST,
"key1=auth-test");
runCommand(container, "vault", "kv", "put", VAULT_PATH_LONG_KV2_1, "key1=123",
"key2=456");
runCommand(container, "vault", "kv", "put", VAULT_PATH_LONG_KV2_2, "key3=789");
VaultContainer vaultAgentContainer = createVaultAgentContainer(roleIDPath,
secretIDPath);
assert vaultAgentContainer != null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ path "kv-v2/*" {
capabilities = ["create", "read", "list"]
}

path "long/path/kv-v2/*" {
capabilities = ["create", "read", "list"]
}

path "auth/token/lookup-self" {
capabilities = ["read"]
}

0 comments on commit 3736158

Please sign in to comment.