Skip to content

Commit

Permalink
Fixup mounts & plugins apis & fix outstanding integration test failures
Browse files Browse the repository at this point in the history
  • Loading branch information
kdubb committed Jan 6, 2024
1 parent 530ed21 commit 55b2972
Show file tree
Hide file tree
Showing 13 changed files with 160 additions and 99 deletions.
6 changes: 3 additions & 3 deletions client/src/main/specs/sys/mounts.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ operations:
method: POST
status: NO_CONTENT
path: mounts/:path
bodyFrom: [type, description, config]
bodyFrom: [type, description, config, options]
parameters:
- name: path
type: String
Expand Down Expand Up @@ -60,8 +60,8 @@ operations:
type: String
- name: allowedManagedKeys
type: java.util.List<String>
- name: options
type: java.util.Map<String, Object>
- name: options
type: java.util.Map<String, Object>


- name: disable
Expand Down
2 changes: 2 additions & 0 deletions client/src/main/specs/sys/plugins.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -200,3 +200,5 @@ types:
type: String
- name: builtin
type: Boolean
- name: deprecationStatus
type: String
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import org.junit.jupiter.api.Test;

import io.quarkus.vault.client.api.secrets.kv2.VaultSecretsKV2SecretMetadataParams;
import io.quarkus.vault.client.api.sys.mounts.VaultSysMountsEnableConfig;
import io.quarkus.vault.client.test.Random;
import io.quarkus.vault.client.test.VaultClientTest;
import io.quarkus.vault.client.test.VaultClientTest.Mount;
Expand All @@ -34,8 +33,7 @@ void testReadConfig(VaultClient client) {
@Test
void testUpdateConfig(VaultClient client, @Random String path) {
// Mount specific engine for testing CAS configuration
client.sys().mounts().enable(path, "kv", "KV with CAS enabled", new VaultSysMountsEnableConfig()
.setOptions(Map.of("version", "2")))
client.sys().mounts().enable(path, "kv", "KV with CAS enabled", null, Map.of("version", "2"))
.await().indefinitely();

var kvApi = client.secrets().kv2(path);
Expand Down
120 changes: 60 additions & 60 deletions client/src/test/java/io/quarkus/vault/client/VaultSecretsPKITest.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ public void testList(VaultClient client) {
assertThat(kvMountInfo.isLocal())
.isFalse();
assertThat(kvMountInfo.getOptions())
.isNotNull()
.containsEntry("version", "2");
assertThat(kvMountInfo.getPluginVersion())
.isEmpty();
Expand Down Expand Up @@ -79,8 +78,8 @@ public void testRead(VaultClient client, @Random String mount) {
.setListingVisibility(VaultSysMountsListingVisibility.HIDDEN)
.setPassthroughRequestHeaders(List.of("header1", "header2"))
.setAllowedResponseHeaders(List.of("header3", "header4"))
.setAllowedManagedKeys(List.of("key5", "key6"))
.setOptions(Map.of("version", "2")))
.setAllowedManagedKeys(List.of("key5", "key6")),
Map.of("version", "2"))
.await().indefinitely();

var kvMountInfo = mountApi.read(mount)
Expand Down Expand Up @@ -117,7 +116,7 @@ public void testRead(VaultClient client, @Random String mount) {
assertThat(kvMountInfo.isLocal())
.isFalse();
assertThat(kvMountInfo.getOptions())
.isEmpty();
.containsEntry("version", "2");
assertThat(kvMountInfo.getPluginVersion())
.isEmpty();
assertThat(kvMountInfo.getRunningPluginVersion())
Expand All @@ -139,7 +138,7 @@ public void testEnable(VaultClient client, @Random String path) {

var mountPath = path + "/";

mountApi.enable(path, "kv", null, null)
mountApi.enable(path, "kv", null, null, null)
.await().indefinitely();

var mounts = mountApi.list()
Expand All @@ -155,7 +154,7 @@ public void testDisable(VaultClient client, @Random String path) {

var mountPath = path + "/";

mountApi.enable(path, "kv", null, null)
mountApi.enable(path, "kv", null, null, null)
.await().indefinitely();

var mounts = mountApi.list()
Expand Down Expand Up @@ -207,8 +206,7 @@ public void testReadTune(VaultClient client) {
public void testTune(VaultClient client, @Random String path) {
var mountApi = client.sys().mounts();

mountApi.enable(path, "kv", null, new VaultSysMountsEnableConfig()
.setOptions(Map.of("version", "1")))
mountApi.enable(path, "kv", null, null, Map.of("version", "1"))
.await().indefinitely();

mountApi.tune(path, new VaultSysMountsTuneParams()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,31 @@ public void testRegister(VaultClient client, @Random String pluginName) throws E
.isEmpty();
assertThat(pluginInfo.getArgs())
.contains("--arg1", "--arg2");
assertThat(pluginInfo.getDeprecationStatus())
.isNull();
}

@Test
public void testReadBuiltin(VaultClient client) {
var pluginsApi = client.sys().plugins();

var pluginInfo = pluginsApi.read("secret", "kv")
.await().indefinitely();

assertThat(pluginInfo)
.isNotNull();
assertThat(pluginInfo.getName())
.isEqualTo("kv");
assertThat(pluginInfo.getCommand())
.isEmpty();
assertThat(pluginInfo.getSha256())
.isEmpty();
assertThat(pluginInfo.getVersion())
.endsWith("builtin");
assertThat(pluginInfo.getArgs())
.isNull();
assertThat(pluginInfo.getDeprecationStatus())
.isEqualTo("supported");
}

@Test
Expand Down Expand Up @@ -252,7 +277,7 @@ public void testReloadMounts(VaultClient client, @Random String pluginName, @Ran
.setVersion("v1.0.0"))
.await().indefinitely();

client.sys().mounts().enable(mount, pluginName, null, null)
client.sys().mounts().enable(mount, pluginName, null, null, null)
.await().indefinitely();

pluginsApi.reloadPlugin(pluginName, "global")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class VaultSysRemountTest {
public void testRemountAndStatus(VaultClient client, @Random String path, @Random String newPath) {
var remountApi = client.sys().remount();

client.sys().mounts().enable(path, "kv", null, null)
client.sys().mounts().enable(path, "kv", null, null, null)
.await().indefinitely();

var remount = remountApi.remount(path, newPath)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
import io.quarkus.vault.client.api.common.VaultFormat;
import io.quarkus.vault.client.api.common.VaultHashAlgorithm;
import io.quarkus.vault.client.api.common.VaultLeasedResult;
import io.quarkus.vault.client.api.secrets.kv2.VaultSecretsKV2ReadSecretResult;
import io.quarkus.vault.client.api.secrets.kv2.VaultSecretsKV2ReadSecretData;
import io.quarkus.vault.client.api.secrets.transit.*;
import io.quarkus.vault.runtime.config.VaultAuthenticationType;
import io.quarkus.vault.runtime.config.VaultConfigSource;
Expand Down Expand Up @@ -156,11 +156,11 @@ public void httpclient() {
var anotherWrappingToken = ConfigProviderResolver.instance().getConfig()
.getValue("vault-test.another-password-kv-v2-wrapping-token", String.class);
var unwrap = vaultClient.sys().wrapping()
.unwrapAs(anotherWrappingToken, VaultSecretsKV2ReadSecretResult.class)
.unwrapAs(anotherWrappingToken, VaultSecretsKV2ReadSecretData.class)
.await().indefinitely();
assertEquals(VAULT_AUTH_USERPASS_PASSWORD, unwrap.getData().getData().get("password"));
assertEquals(VAULT_AUTH_USERPASS_PASSWORD, unwrap.getData().get("password"));
try {
vaultClient.sys().wrapping().unwrapAs(anotherWrappingToken, VaultSecretsKV2ReadSecretResult.class)
vaultClient.sys().wrapping().unwrapAs(anotherWrappingToken, VaultSecretsKV2ReadSecretData.class)
.await().indefinitely();
fail("expected error 400: wrapping token is not valid or does not exist");
} catch (VaultClientException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public static String toVaultDuration(Duration duration) {
if (value.startsWith("PT")) {
value = value.substring(2);
}
return value;
return value.toLowerCase();
}

public static Integer toDurationSeconds(Duration duration) {
Expand Down
48 changes: 36 additions & 12 deletions runtime/src/main/java/io/quarkus/vault/runtime/VaultPKIManager.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package io.quarkus.vault.runtime;

import static io.quarkus.vault.runtime.DurationHelper.fromVaultDuration;
import static io.quarkus.vault.runtime.DurationHelper.toVaultDuration;
import static io.quarkus.vault.runtime.DurationHelper.*;
import static io.quarkus.vault.runtime.VaultPKIManagerFactory.PKI_ENGINE_NAME;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
Expand Down Expand Up @@ -262,9 +261,8 @@ public Uni<Void> updateRole(String role, RoleOptions options) {
options.keyType != null ? VaultSecretsPKIKeyType.from(options.keyType.name().toLowerCase(Locale.ROOT))
: null)
.setKeyBits(options.keyBits != null ? VaultSecretsPKIKeyBits.fromBits(options.keyBits) : null)
.setKeyUsage(options.keyUsages.stream().map(e -> VaultSecretsPKIKeyUsage.from(e.name())).collect(toList()))
.setExtKeyUsage(options.extendedKeyUsages.stream().map(e -> VaultSecretsPKIExtKeyUsage.from(e.name()))
.collect(toList()))
.setKeyUsage(mapKeyUsagesToClient(options.keyUsages))
.setExtKeyUsage(mapExtKeyUsagesToClient(options.extendedKeyUsages))
.setExtKeyUsageOids(options.extendedKeyUsageOIDs)
.setUseCsrCommonName(options.useCSRCommonName)
.setUseCsrSans(options.useCSRSubjectAlternativeNames)
Expand All @@ -291,8 +289,8 @@ public Uni<RoleOptions> getRole(String role) {
return pki.readRole(role)
.map(info -> {
RoleOptions result = new RoleOptions();
result.timeToLive = toVaultDuration(info.getTtl());
result.maxTimeToLive = toVaultDuration(info.getMaxTtl());
result.timeToLive = toStringDurationSeconds(info.getTtl());
result.maxTimeToLive = toStringDurationSeconds(info.getMaxTtl());
result.allowLocalhost = info.isAllowLocalhost();
result.allowedDomains = info.getAllowedDomains();
result.allowTemplatesInAllowedDomains = info.isAllowedDomainsTemplate();
Expand All @@ -310,10 +308,8 @@ public Uni<RoleOptions> getRole(String role) {
result.emailProtectionFlag = info.isEmailProtectionFlag();
result.keyType = stringToCertificateKeyType(info.getKeyType());
result.keyBits = info.getKeyBits().getBits();
result.keyUsages = info.getKeyUsage() != null ? info.getKeyUsage().stream()
.map(e -> CertificateKeyUsage.valueOf(e.name())).collect(toList()) : null;
result.extendedKeyUsages = info.getExtKeyUsage() != null ? info.getExtKeyUsage().stream()
.map(e -> CertificateExtendedKeyUsage.valueOf(e.name())).collect(toList()) : null;
result.keyUsages = mapKeyUsagesFromClient(info.getKeyUsage());
result.extendedKeyUsages = mapExtKeyUsagesFromClient(info.getExtKeyUsage());
result.extendedKeyUsageOIDs = info.getExtKeyUsageOids();
result.useCSRCommonName = info.isUseCsrCommonName();
result.useCSRSubjectAlternativeNames = info.isUseCsrSans();
Expand All @@ -331,7 +327,7 @@ public Uni<RoleOptions> getRole(String role) {
result.requireCommonName = info.isRequireCn();
result.policyOIDs = info.getPolicyIdentifiers();
result.basicConstraintsValidForNonCA = info.isBasicConstraintsValidForNonCa();
result.notBeforeDuration = toVaultDuration(info.getNotBefore());
result.notBeforeDuration = toStringDurationSeconds(info.getNotBefore());
return result;
});
}
Expand Down Expand Up @@ -590,4 +586,32 @@ private PrivateKeyData createPrivateKeyData(String data, VaultSecretsPKIFormat f
throw new VaultException("Unsupported private key format");
}
}

private static List<VaultSecretsPKIKeyUsage> mapKeyUsagesToClient(List<CertificateKeyUsage> keyUsages) {
if (keyUsages == null) {
return null;
}
return keyUsages.stream().map(e -> VaultSecretsPKIKeyUsage.from(e.name())).collect(toList());
}

private static List<CertificateKeyUsage> mapKeyUsagesFromClient(List<VaultSecretsPKIKeyUsage> keyUsages) {
if (keyUsages == null) {
return null;
}
return keyUsages.stream().map(e -> CertificateKeyUsage.valueOf(e.getValue())).collect(toList());
}

private static List<VaultSecretsPKIExtKeyUsage> mapExtKeyUsagesToClient(List<CertificateExtendedKeyUsage> keyUsages) {
if (keyUsages == null) {
return null;
}
return keyUsages.stream().map(e -> VaultSecretsPKIExtKeyUsage.from(e.name())).collect(toList());
}

private static List<CertificateExtendedKeyUsage> mapExtKeyUsagesFromClient(List<VaultSecretsPKIExtKeyUsage> keyUsages) {
if (keyUsages == null) {
return null;
}
return keyUsages.stream().map(e -> CertificateExtendedKeyUsage.valueOf(e.getValue())).collect(toList());
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package io.quarkus.vault.runtime;

import static io.quarkus.vault.runtime.DurationHelper.*;
import static java.util.stream.Collectors.toMap;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import jakarta.annotation.Nullable;
Expand Down Expand Up @@ -233,7 +235,9 @@ public Uni<Void> enable(String engineType, String mount, String description, Ena
.setAllowedResponseHeaders(options.allowedResponseHeaders)
.setAllowedManagedKeys(options.allowedManagedKeys)
.setPluginVersion(options.pluginVersion);
return vaultClient.sys().mounts().enable(mount, engineType, description, config);
return vaultClient.sys().mounts().enable(mount, engineType, description, config, options.options != null
? options.options.entrySet().stream().collect(toMap(Map.Entry::getKey, Map.Entry::getValue))
: null);
}

@Override
Expand Down Expand Up @@ -276,11 +280,11 @@ public Uni<VaultPluginDetails> getPluginDetails(String type, String name, @Nulla
.map(r -> new VaultPluginDetails()
.setBuiltin(r.isBuiltin())
.setName(r.getName())
.setType(type)
.setVersion(r.getVersion())
.setSha256(r.getSha256())
.setCommand(r.getCommand())
.setArgs(r.getArgs()))
.setArgs(r.getArgs())
.setDeprecationStatus(r.getDeprecationStatus()))
.onFailure(VaultClientException.class).recoverWithUni(x -> {
VaultClientException vx = (VaultClientException) x;
if (vx.getStatus() == 404) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ private Uni<List<EncryptionResult>> encryptBatch(String keyName, List<Encryption
String configKeyName;
if (config != null) {
configKeyName = config.name().orElse(keyName);
params.setType(config.type().map(VaultSecretsTransitKeyType::valueOf).orElse(null));
params.setType(config.type().map(VaultSecretsTransitKeyType::from).orElse(null));
params.setConvergentEncryption(config.convergentEncryption().map(Boolean::valueOf).orElse(null));
} else {
configKeyName = keyName;
Expand Down Expand Up @@ -429,7 +429,13 @@ private Uni<List<VerificationResult>> verifyBatch(String keyName, List<Verificat

return transit.verifyBatch(configKeyName, params)
.map(result -> result.stream()
.map(r -> new VerificationResult(r.isValid(), r.getError()))
.map(r -> {
if (r.getError() != null) {
return new VerificationResult(r.isValid(), r.getError());
} else {
return new VerificationResult(r.isValid(), !r.isValid() ? INVALID_SIGNATURE : null);
}
})
.collect(toList()));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import io.quarkus.vault.client.api.sys.init.VaultSysInitParams;
import io.quarkus.vault.client.http.vertx.VertxVaultHttpClient;
import io.quarkus.vault.runtime.VaultVersions;
import io.vertx.ext.web.client.WebClientOptions;
import io.vertx.mutiny.core.Vertx;
import io.vertx.mutiny.ext.web.client.WebClient;

Expand Down Expand Up @@ -163,7 +164,10 @@ private static String readSecretAsString(VaultKVSecretEngine kvSecretEngine, Str
}

private VaultClient createVaultClient() {
VertxVaultHttpClient httpClient = new VertxVaultHttpClient(WebClient.create(Vertx.vertx()));
var webClient = WebClient.create(Vertx.vertx(), new WebClientOptions()
.setTrustAll(true)
.setVerifyHost(false));
VertxVaultHttpClient httpClient = new VertxVaultHttpClient(webClient);
return VaultClient.builder()
.executor(httpClient)
.baseUrl(getVaultUrl().orElseThrow())
Expand Down

0 comments on commit 55b2972

Please sign in to comment.