Skip to content

Commit

Permalink
Updated dependencies, updated KubernetesVaultTokenSupplier, added Vau…
Browse files Browse the repository at this point in the history
…ltClientTokenSupplier
  • Loading branch information
artem-v committed Sep 22, 2024
1 parent 6581952 commit 94fbe42
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,38 +15,23 @@ public class KubernetesVaultTokenSupplier implements VaultTokenSupplier {

private static final EnvironmentLoader ENVIRONMENT_LOADER = new EnvironmentLoader();

private String vaultRole = ENVIRONMENT_LOADER.loadVariable("VAULT_ROLE");
private final String vaultRole;
private final String vaultJwtProvider;
private final String serviceAccountTokenPath;

private String vaultJwtProvider =
Optional.ofNullable(
Optional.ofNullable(ENVIRONMENT_LOADER.loadVariable("VAULT_JWT_PROVIDER"))
.orElse(ENVIRONMENT_LOADER.loadVariable("VAULT_MOUNT_POINT")))
.orElse("kubernetes");

private String serviceAccountTokenPath =
Optional.ofNullable(ENVIRONMENT_LOADER.loadVariable("SERVICE_ACCOUNT_TOKEN_PATH"))
.orElse("/var/run/secrets/kubernetes.io/serviceaccount/token");

public KubernetesVaultTokenSupplier vaultRole(String vaultRole) {
this.vaultRole = vaultRole;
return this;
private KubernetesVaultTokenSupplier(Builder builder) {
this.vaultRole = Objects.requireNonNull(builder.vaultRole, "vault role");
this.vaultJwtProvider = Objects.requireNonNull(builder.vaultJwtProvider, "jwt provider");
this.serviceAccountTokenPath =
Objects.requireNonNull(builder.serviceAccountTokenPath, "k8s service account token path");
}

public KubernetesVaultTokenSupplier vaultJwtProvider(String vaultJwtProvider) {
this.vaultJwtProvider = vaultJwtProvider;
return this;
}

public KubernetesVaultTokenSupplier serviceAccountTokenPath(String serviceAccountTokenPath) {
this.serviceAccountTokenPath = serviceAccountTokenPath;
return this;
public static Builder builder() {
return new Builder();
}

@Override
public String getToken(VaultConfig config) {
Objects.requireNonNull(vaultRole, "vault role");
Objects.requireNonNull(vaultJwtProvider, "jwt provider");
Objects.requireNonNull(serviceAccountTokenPath, "k8s service account token path");
try (Stream<String> stream = Files.lines(Paths.get(serviceAccountTokenPath))) {
String jwt = stream.collect(Collectors.joining());
return Objects.requireNonNull(
Expand All @@ -59,4 +44,40 @@ public String getToken(VaultConfig config) {
throw ThrowableUtil.propagate(e);
}
}

public static class Builder {

private String vaultRole = ENVIRONMENT_LOADER.loadVariable("VAULT_ROLE");

private String vaultJwtProvider =
Optional.ofNullable(
Optional.ofNullable(ENVIRONMENT_LOADER.loadVariable("VAULT_JWT_PROVIDER"))
.orElse(ENVIRONMENT_LOADER.loadVariable("VAULT_MOUNT_POINT")))
.orElse("kubernetes");

private String serviceAccountTokenPath =
Optional.ofNullable(ENVIRONMENT_LOADER.loadVariable("SERVICE_ACCOUNT_TOKEN_PATH"))
.orElse("/var/run/secrets/kubernetes.io/serviceaccount/token");

private Builder() {}

public Builder vaultRole(String vaultRole) {
this.vaultRole = vaultRole;
return this;
}

public Builder vaultJwtProvider(String vaultJwtProvider) {
this.vaultJwtProvider = vaultJwtProvider;
return this;
}

public Builder serviceAccountTokenPath(String serviceAccountTokenPath) {
this.serviceAccountTokenPath = serviceAccountTokenPath;
return this;
}

public KubernetesVaultTokenSupplier build() {
return new KubernetesVaultTokenSupplier(this);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package io.scalecube.config.vault;

import com.bettercloud.vault.VaultConfig;
import com.bettercloud.vault.VaultException;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class VaultClientTokenSupplier {

private static final Logger LOGGER = LoggerFactory.getLogger(VaultClientTokenSupplier.class);

private final String vaultAddress;
private final String vaultToken;
private final String vaultRole;

/**
* Constructor.
*
* @param vaultAddress vaultAddress
* @param vaultToken vaultToken (must not set be together with vaultRole)
* @param vaultRole vaultRole (must not set be together with vaultToken)
*/
public VaultClientTokenSupplier(String vaultAddress, String vaultToken, String vaultRole) {
this.vaultAddress = vaultAddress;
this.vaultToken = vaultToken;
this.vaultRole = vaultRole;
if (isNullOrNoneOrEmpty(vaultAddress)) {
throw new IllegalArgumentException("Vault address is required");
}
if (isNullOrNoneOrEmpty(vaultToken) && isNullOrNoneOrEmpty(vaultRole)) {
throw new IllegalArgumentException(
"Vault auth scheme is required (specify either vaultToken or vaultRole)");
}
}

/**
* Returns new instance of {@link VaultClientTokenSupplier}.
*
* @param vaultAddress vaultAddress
* @param vaultToken vaultToken
* @return new instance of {@link VaultClientTokenSupplier}
*/
public static VaultClientTokenSupplier supplierByToken(String vaultAddress, String vaultToken) {
return new VaultClientTokenSupplier(vaultAddress, vaultToken, null);
}

/**
* Returns new instance of {@link VaultClientTokenSupplier}.
*
* @param vaultAddress vaultAddress
* @param vaultRole vaultRole
* @return new instance of {@link VaultClientTokenSupplier}
*/
public static VaultClientTokenSupplier supplierByRole(String vaultAddress, String vaultRole) {
return new VaultClientTokenSupplier(vaultAddress, null, vaultRole);
}

/**
* Obtains vault client token.
*
* @return future result
*/
public Future<String> getToken() {
return CompletableFuture.supplyAsync(this::getToken0);
}

private String getToken0() {
try {
VaultTokenSupplier vaultTokenSupplier;
VaultConfig vaultConfig;

if (!isNullOrNoneOrEmpty(vaultRole)) {
if (!isNullOrNoneOrEmpty(vaultToken)) {
LOGGER.warn(
"Taking KubernetesVaultTokenSupplier by precedence rule, "
+ "ignoring EnvironmentVaultTokenSupplier "
+ "(specify either vaultToken or vaultRole, not both)");
}
vaultTokenSupplier = KubernetesVaultTokenSupplier.builder().vaultRole(vaultRole).build();
vaultConfig = new VaultConfig().address(vaultAddress).build();
} else {
vaultTokenSupplier = new EnvironmentVaultTokenSupplier();
vaultConfig = new VaultConfig().address(vaultAddress).token(vaultToken).build();
}

return vaultTokenSupplier.getToken(vaultConfig);
} catch (VaultException e) {
throw new RuntimeException(e);
}
}

private static boolean isNullOrNoneOrEmpty(String value) {
return Objects.isNull(value)
|| "none".equalsIgnoreCase(value)
|| "null".equals(value)
|| value.isEmpty();
}
}
12 changes: 7 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
Expand Down Expand Up @@ -38,15 +40,15 @@
</scm>

<properties>
<vault-java-driver.version>5.1.0</vault-java-driver.version>
<slf4j.version>2.0.7</slf4j.version>
<log4j.version>2.20.0</log4j.version>

<log4j.version>2.20.0</log4j.version>
<mockito-junit.version>2.27.0</mockito-junit.version>
<junit-jupiter.version>5.1.1</junit-jupiter.version>
<hamcrest.version>1.3</hamcrest.version>
<vault-java-driver.version>5.1.0</vault-java-driver.version>
<testcontainers.version>1.17.4</testcontainers.version>
<guava.version>32.0.0-jre</guava.version>
<testcontainers.version>1.20.1</testcontainers.version>
<guava.version>33.3.0-jre</guava.version>

<distributionManagement.url>https://maven.pkg.github.com/scalecube/scalecube-config
</distributionManagement.url>
Expand Down

0 comments on commit 94fbe42

Please sign in to comment.