-
Notifications
You must be signed in to change notification settings - Fork 9
Vault 37086 plugin quality configure plugin and test dynamic role api crud with enos #181
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: VAULT-37081-Plugin-Quality-Add-bootstrap-environment-setup-to-plugin-repo
Are you sure you want to change the base?
Changes from all commits
c0c89ba
1cce6b5
f7da7fa
cf9afe3
f513f34
f581de7
34d9149
7b35481
3028bff
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
dn: uid={{.Username}},ou=users,dc=example,dc=com | ||
objectClass: inetOrgPerson | ||
uid: {{.Username}} | ||
cn: {{.Username}} | ||
sn: {{.Password | utf16le | base64}} | ||
memberOf: cn=dev,ou=groups,dc=example,dc=com | ||
userPassword: {{.Password}} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
dn: uid={{.Username}},ou=users,dc=example,dc=com | ||
changetype: delete |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
dn: uid={{.Username}},ou=users,dc=example,dc=com | ||
changetype: delete |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
# Copyright (c) HashiCorp, Inc. | ||
# SPDX-License-Identifier: BUSL-1.1 | ||
|
||
terraform { | ||
required_providers { | ||
enos = { | ||
source = "registry.terraform.io/hashicorp-forge/enos" | ||
} | ||
} | ||
} | ||
|
||
locals { | ||
ldif_files = fileset("${path.module}/ldif", "*") | ||
file_host_pairs = flatten([ | ||
for i in range(length(var.hosts)) : [ | ||
for file in local.ldif_files : { | ||
host_index = i | ||
public_ip = var.hosts[i].public_ip | ||
file = file | ||
} | ||
] | ||
]) | ||
file_host_map = { | ||
for item in local.file_host_pairs : | ||
"${item["host_index"]}_${item["file"]}" => item | ||
} | ||
} | ||
|
||
# Copy LDIF files to the hosts | ||
resource "enos_file" "ldif_files" { | ||
for_each = local.file_host_map | ||
source = abspath("${path.module}/ldif/${each.value["file"]}") | ||
destination = "${var.ldif_path}/${each.value["file"]}" | ||
transport = { | ||
ssh = { | ||
host = each.value["public_ip"] | ||
} | ||
} | ||
} | ||
|
||
# Execute the dynamic role CRUD API test script on the Vault leader | ||
resource "enos_remote_exec" "dynamic_role_crud_api_test" { | ||
depends_on = [enos_file.ldif_files] | ||
scripts = ["${path.module}/scripts/dynamic-role.sh"] | ||
|
||
environment = { | ||
VAULT_ADDR = var.vault_addr | ||
VAULT_TOKEN = var.vault_root_token | ||
PLUGIN_PATH = var.plugin_mount_path | ||
LDAP_HOST = var.ldap_host | ||
LDAP_PORT = var.ldap_port | ||
|
||
ROLE_NAME = var.ldap_role_name | ||
LDAP_USER_DN_TPL = var.ldap_user_dn_tpl | ||
LDIF_PATH = var.ldif_path | ||
} | ||
|
||
transport = { | ||
ssh = { | ||
host = var.vault_leader_ip | ||
} | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
#!/usr/bin/env bash | ||
# Copyright (c) HashiCorp, Inc. | ||
# SPDX-License-Identifier: BUSL-1.1 | ||
set -e | ||
|
||
# Test Vault LDAP Dynamic Role CRUD and credential lifecycle using provided LDIFs. | ||
# Assumptions: | ||
# - You have uploaded creation.ldif, deletion.ldif, and rollback.ldif to the server. | ||
# - Vault CLI is authenticated and VAULT_ADDR and VAULT_TOKEN are set. | ||
# - Required ENV vars: | ||
# PLUGIN_PATH (e.g., local-secrets-ldap) | ||
# ROLE_NAME (e.g., adam) | ||
# LDAP_HOST | ||
# LDAP_PORT | ||
# LDAP_USER_DN_TPL (e.g., uid={{username}},ou=users,dc=example,dc=com) | ||
# LDIF_PATH (path to directory containing creation.ldif, deletion.ldif, rollback.ldif) | ||
|
||
fail() { | ||
echo "$1" 1>&2 | ||
exit 1 | ||
} | ||
|
||
[[ -z "$ROLE_NAME" ]] && fail "ROLE_NAME env variable has not been set" | ||
[[ -z "$LDAP_HOST" ]] && fail "LDAP_HOST env variable has not been set" | ||
[[ -z "$LDAP_PORT" ]] && fail "LDAP_PORT env variable has not been set" | ||
[[ -z "$LDAP_USER_DN_TPL" ]] && fail "LDAP_USER_DN_TPL env variable has not been set" | ||
[[ -z "$LDIF_PATH" ]] && fail "LDIF_PATH env variable has not been set" | ||
|
||
export VAULT_ADDR | ||
export VAULT_TOKEN | ||
|
||
ROLE_PATH="${PLUGIN_PATH}/role/${ROLE_NAME}" | ||
|
||
echo "==> Creating dynamic role: ${ROLE_NAME}" | ||
vault write "${ROLE_PATH}" \ | ||
creation_ldif=@${LDIF_PATH}/creation.ldif \ | ||
deletion_ldif=@${LDIF_PATH}/deletion.ldif \ | ||
rollback_ldif=@${LDIF_PATH}/rollback.ldif \ | ||
default_ttl="2m" \ | ||
max_ttl="10m" | ||
|
||
echo "==> Reading dynamic role" | ||
vault read "${ROLE_PATH}" | ||
|
||
echo "==> Listing dynamic roles" | ||
vault list "${PLUGIN_PATH}/role" | ||
|
||
echo "==> Requesting dynamic credentials" | ||
CRED_PATH="${PLUGIN_PATH}/creds/${ROLE_NAME}" | ||
DYNAMIC_CREDS="$(vault read -format=json "${CRED_PATH}")" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe this line won't error out even if the |
||
DYN_USERNAME=$(echo "${DYNAMIC_CREDS}" | jq -r .data.username) | ||
DYN_PASSWORD=$(echo "${DYNAMIC_CREDS}" | jq -r .data.password) | ||
LEASE_ID=$(echo "${DYNAMIC_CREDS}" | jq -r .lease_id) | ||
|
||
echo "==> Got dynamic username: ${DYN_USERNAME}" | ||
echo "==> Got dynamic password: ${DYN_PASSWORD}" | ||
echo "==> Lease ID: ${LEASE_ID}" | ||
Comment on lines
+55
to
+57
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What happens if we don't get these values? |
||
|
||
# Build the DN for the dynamic user | ||
DYN_DN=${LDAP_USER_DN_TPL/\{\{username\}\}/$DYN_USERNAME} | ||
|
||
echo "==> Verifying login with dynamic credentials" | ||
if ldapwhoami -h "${LDAP_HOST}:${LDAP_PORT}" -x -w "${DYN_PASSWORD}" -D "${DYN_DN}"; then | ||
echo "[OK] Dynamic user login succeeded." | ||
else | ||
echo "[ERROR] Dynamic user login failed!" | ||
exit 1 | ||
fi | ||
|
||
echo "==> Revoking dynamic credentials (deletes LDAP user)" | ||
vault lease revoke "${LEASE_ID}" | ||
|
||
sleep 2 | ||
|
||
echo "==> Verifying dynamic user is deleted" | ||
if ldapwhoami -h "${LDAP_HOST}:${LDAP_PORT}" -x -w "${DYN_PASSWORD}" -D "${DYN_DN}"; then | ||
echo "[ERROR] Dynamic user still exists after lease revoke!" | ||
exit 1 | ||
else | ||
echo "[OK] Dynamic user deleted as expected." | ||
fi | ||
|
||
echo "==> Deleting dynamic role" | ||
vault delete "${ROLE_PATH}" | ||
|
||
echo "==> Confirming dynamic role deletion" | ||
if vault read "${ROLE_PATH}"; then | ||
echo "[ERROR] Dynamic role still exists after deletion!" | ||
exit 1 | ||
else | ||
echo "[OK] Dynamic role deleted successfully." | ||
fi | ||
|
||
echo "==> Dynamic role CRUD and credential lifecycle test: SUCCESS" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we test these crud APIs after a seal/unseal or leadership change? |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
variable "hosts" { | ||
description = "The target machines host addresses to use for the Vault cluster" | ||
type = map(object({ | ||
ipv6 = string | ||
private_ip = string | ||
public_ip = string | ||
})) | ||
} | ||
|
||
variable "vault_leader_ip" { | ||
type = string | ||
description = "Public IP of the Vault leader node" | ||
} | ||
|
||
variable "plugin_mount_path" { | ||
type = string | ||
description = "Mount path for the plugin" | ||
} | ||
|
||
# LDAP variables for configuration | ||
variable "ldap_host" { | ||
type = string | ||
description = "LDAP IP or hostname" | ||
} | ||
|
||
variable "ldap_port" { | ||
type = string | ||
description = "LDAP port" | ||
} | ||
|
||
variable "ldap_user_dn_tpl" { | ||
type = string | ||
description = "LDAP user DN template" | ||
} | ||
|
||
variable "ldap_role_name" { | ||
type = string | ||
description = "LDAP role name to be created" | ||
} | ||
|
||
variable "ldif_path" { | ||
type = string | ||
description = "LDIF files path" | ||
} | ||
|
||
variable "vault_addr" { | ||
type = string | ||
description = "The Vault API address" | ||
} | ||
|
||
variable "vault_root_token" { | ||
type = string | ||
description = "The Vault cluster root token" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think all files in this repo need to be MPL