diff --git a/enos/enos-descriptions.hcl b/enos/enos-descriptions.hcl index c9902314a3..c78dbeacf7 100644 --- a/enos/enos-descriptions.hcl +++ b/enos/enos-descriptions.hcl @@ -180,7 +180,8 @@ globals { EOF verify_vault_version = <<-EOF - Verify that the Vault cluster has the correct embedded version metadata. This metadata includes + Verify that the Vault CLI has the correct embedded version metadata and that the Vault Cluster + verision history includes our expected version. The CLI metadata that is validated includes the Vault version, edition, build date, and any special prerelease metadata. EOF diff --git a/enos/enos-qualities.hcl b/enos/enos-qualities.hcl index 841e2a9995..639cf027cd 100644 --- a/enos/enos-qualities.hcl +++ b/enos/enos-qualities.hcl @@ -250,6 +250,21 @@ quality "vault_api_sys_storage_raft_remove_peer_write_removes_peer" { EOF } +quality "vault_api_sys_version_history_keys" { + description = <<-EOF + The v1/sys/version-history Vault API returns the cluster version history and the 'keys' data + includes our target version + EOF +} + +quality "vault_api_sys_version_history_key_info" { + description = <<-EOF + The v1/sys/version-history Vault API returns the cluster version history and the + 'key_info["$expected_version]' data is present for the expected version and the 'build_date' + matches the expected build_date. + EOF +} + quality "vault_artifact_bundle" { description = "The candidate binary packaged as a zip bundle is used for testing" } diff --git a/enos/enos-scenario-agent.hcl b/enos/enos-scenario-agent.hcl index 23f0d857d8..884dc912ba 100644 --- a/enos/enos-scenario-agent.hcl +++ b/enos/enos-scenario-agent.hcl @@ -411,33 +411,6 @@ scenario "agent" { } } - step "verify_vault_version" { - description = global.description.verify_vault_version - module = module.vault_verify_version - depends_on = [step.wait_for_leader] - - providers = { - enos = local.enos_provider[matrix.distro] - } - - verifies = [ - quality.vault_version_build_date, - quality.vault_version_edition, - quality.vault_version_release, - ] - - variables { - hosts = step.create_vault_cluster_targets.hosts - vault_addr = step.create_vault_cluster.api_addr_localhost - vault_edition = matrix.edition - vault_install_dir = global.vault_install_dir[matrix.artifact_type] - vault_product_version = matrix.artifact_source == "local" ? step.get_local_metadata.version : var.vault_product_version - vault_revision = matrix.artifact_source == "local" ? step.get_local_metadata.revision : var.vault_revision - vault_build_date = matrix.artifact_source == "local" ? step.get_local_metadata.build_date : var.vault_build_date - vault_root_token = step.create_vault_cluster.root_token - } - } - step "verify_vault_unsealed" { description = global.description.verify_vault_unsealed module = module.vault_verify_unsealed @@ -460,13 +433,39 @@ scenario "agent" { } } + step "verify_vault_version" { + description = global.description.verify_vault_version + module = module.vault_verify_version + depends_on = [step.verify_vault_unsealed] + + providers = { + enos = local.enos_provider[matrix.distro] + } + + verifies = [ + quality.vault_api_sys_version_history_keys, + quality.vault_api_sys_version_history_key_info, + quality.vault_version_build_date, + quality.vault_version_edition, + quality.vault_version_release, + ] + + variables { + hosts = step.create_vault_cluster_targets.hosts + vault_addr = step.create_vault_cluster.api_addr_localhost + vault_edition = matrix.edition + vault_install_dir = global.vault_install_dir[matrix.artifact_type] + vault_product_version = matrix.artifact_source == "local" ? step.get_local_metadata.version : var.vault_product_version + vault_revision = matrix.artifact_source == "local" ? step.get_local_metadata.revision : var.vault_revision + vault_build_date = matrix.artifact_source == "local" ? step.get_local_metadata.build_date : var.vault_build_date + vault_root_token = step.create_vault_cluster.root_token + } + } + step "verify_write_test_data" { description = global.description.verify_write_test_data module = module.vault_verify_write_data - depends_on = [ - step.create_vault_cluster, - step.get_vault_cluster_ips - ] + depends_on = [step.verify_vault_unsealed] providers = { enos = local.enos_provider[matrix.distro] @@ -492,10 +491,7 @@ scenario "agent" { description = global.description.verify_raft_cluster_all_nodes_are_voters skip_step = matrix.backend != "raft" module = module.vault_verify_raft_auto_join_voter - depends_on = [ - step.create_vault_cluster, - step.get_vault_cluster_ips - ] + depends_on = [step.verify_vault_unsealed] providers = { enos = local.enos_provider[matrix.distro] @@ -515,10 +511,7 @@ scenario "agent" { step "verify_replication" { description = global.description.verify_replication_status module = module.vault_verify_replication - depends_on = [ - step.create_vault_cluster, - step.get_vault_cluster_ips - ] + depends_on = [step.verify_vault_unsealed] providers = { enos = local.enos_provider[matrix.distro] @@ -561,7 +554,7 @@ scenario "agent" { step "verify_ui" { description = global.description.verify_ui module = module.vault_verify_ui - depends_on = [step.create_vault_cluster] + depends_on = [step.verify_vault_unsealed] providers = { enos = local.enos_provider[matrix.distro] diff --git a/enos/enos-scenario-autopilot.hcl b/enos/enos-scenario-autopilot.hcl index 0671c3d74e..abaad263dd 100644 --- a/enos/enos-scenario-autopilot.hcl +++ b/enos/enos-scenario-autopilot.hcl @@ -685,6 +685,8 @@ scenario "autopilot" { } verifies = [ + quality.vault_api_sys_version_history_keys, + quality.vault_api_sys_version_history_key_info, quality.vault_version_build_date, quality.vault_version_edition, quality.vault_version_release, diff --git a/enos/enos-scenario-proxy.hcl b/enos/enos-scenario-proxy.hcl index 8db5d8d5b7..a47abaedf1 100644 --- a/enos/enos-scenario-proxy.hcl +++ b/enos/enos-scenario-proxy.hcl @@ -388,33 +388,6 @@ scenario "proxy" { } } - step "verify_vault_version" { - description = global.description.verify_vault_version - module = module.vault_verify_version - depends_on = [step.create_vault_cluster] - - providers = { - enos = local.enos_provider[matrix.distro] - } - - verifies = [ - quality.vault_version_build_date, - quality.vault_version_edition, - quality.vault_version_release, - ] - - variables { - hosts = step.create_vault_cluster_targets.hosts - vault_addr = step.create_vault_cluster.api_addr_localhost - vault_edition = matrix.edition - vault_install_dir = global.vault_install_dir[matrix.artifact_type] - vault_product_version = matrix.artifact_source == "local" ? step.get_local_metadata.version : var.vault_product_version - vault_revision = matrix.artifact_source == "local" ? step.get_local_metadata.revision : var.vault_revision - vault_build_date = matrix.artifact_source == "local" ? step.get_local_metadata.build_date : var.vault_build_date - vault_root_token = step.create_vault_cluster.root_token - } - } - step "verify_vault_unsealed" { description = global.description.verify_vault_unsealed module = module.vault_verify_unsealed @@ -437,13 +410,39 @@ scenario "proxy" { } } + step "verify_vault_version" { + description = global.description.verify_vault_version + module = module.vault_verify_version + depends_on = [step.verify_vault_unsealed] + + providers = { + enos = local.enos_provider[matrix.distro] + } + + verifies = [ + quality.vault_api_sys_version_history_keys, + quality.vault_api_sys_version_history_key_info, + quality.vault_version_build_date, + quality.vault_version_edition, + quality.vault_version_release, + ] + + variables { + hosts = step.create_vault_cluster_targets.hosts + vault_addr = step.create_vault_cluster.api_addr_localhost + vault_edition = matrix.edition + vault_install_dir = global.vault_install_dir[matrix.artifact_type] + vault_product_version = matrix.artifact_source == "local" ? step.get_local_metadata.version : var.vault_product_version + vault_revision = matrix.artifact_source == "local" ? step.get_local_metadata.revision : var.vault_revision + vault_build_date = matrix.artifact_source == "local" ? step.get_local_metadata.build_date : var.vault_build_date + vault_root_token = step.create_vault_cluster.root_token + } + } + step "verify_write_test_data" { description = global.description.verify_write_test_data module = module.vault_verify_write_data - depends_on = [ - step.create_vault_cluster, - step.get_vault_cluster_ips - ] + depends_on = [step.verify_vault_unsealed] providers = { enos = local.enos_provider[matrix.distro] @@ -469,7 +468,7 @@ scenario "proxy" { description = global.description.verify_raft_cluster_all_nodes_are_voters skip_step = matrix.backend != "raft" module = module.vault_verify_raft_auto_join_voter - depends_on = [step.create_vault_cluster] + depends_on = [step.verify_vault_unsealed] providers = { enos = local.enos_provider[matrix.distro] @@ -489,7 +488,7 @@ scenario "proxy" { step "verify_replication" { description = global.description.verify_replication_status module = module.vault_verify_replication - depends_on = [step.create_vault_cluster] + depends_on = [step.verify_vault_unsealed] providers = { enos = local.enos_provider[matrix.distro] @@ -532,7 +531,7 @@ scenario "proxy" { step "verify_ui" { description = global.description.verify_ui module = module.vault_verify_ui - depends_on = [step.create_vault_cluster] + depends_on = [step.verify_vault_unsealed] providers = { enos = local.enos_provider[matrix.distro] diff --git a/enos/enos-scenario-replication.hcl b/enos/enos-scenario-replication.hcl index 239c784592..d828f9ab9c 100644 --- a/enos/enos-scenario-replication.hcl +++ b/enos/enos-scenario-replication.hcl @@ -603,6 +603,8 @@ scenario "replication" { } verifies = [ + quality.vault_api_sys_version_history_keys, + quality.vault_api_sys_version_history_key_info, quality.vault_version_build_date, quality.vault_version_edition, quality.vault_version_release, diff --git a/enos/enos-scenario-seal-ha.hcl b/enos/enos-scenario-seal-ha.hcl index e72f2b1b2a..8aecd57ef8 100644 --- a/enos/enos-scenario-seal-ha.hcl +++ b/enos/enos-scenario-seal-ha.hcl @@ -700,6 +700,8 @@ scenario "seal_ha" { } verifies = [ + quality.vault_api_sys_version_history_keys, + quality.vault_api_sys_version_history_key_info, quality.vault_version_build_date, quality.vault_version_edition, quality.vault_version_release, diff --git a/enos/enos-scenario-smoke.hcl b/enos/enos-scenario-smoke.hcl index 69e166a5df..1fb2c0f300 100644 --- a/enos/enos-scenario-smoke.hcl +++ b/enos/enos-scenario-smoke.hcl @@ -430,33 +430,6 @@ scenario "smoke" { } } - step "verify_vault_version" { - description = global.description.verify_vault_version - module = module.vault_verify_version - depends_on = [step.create_vault_cluster] - - providers = { - enos = local.enos_provider[matrix.distro] - } - - verifies = [ - quality.vault_version_build_date, - quality.vault_version_edition, - quality.vault_version_release, - ] - - variables { - hosts = step.create_vault_cluster_targets.hosts - vault_addr = step.create_vault_cluster.api_addr_localhost - vault_edition = matrix.edition - vault_install_dir = global.vault_install_dir[matrix.artifact_type] - vault_product_version = matrix.artifact_source == "local" ? step.get_local_metadata.version : var.vault_product_version - vault_revision = matrix.artifact_source == "local" ? step.get_local_metadata.revision : var.vault_revision - vault_build_date = matrix.artifact_source == "local" ? step.get_local_metadata.build_date : var.vault_build_date - vault_root_token = step.create_vault_cluster.root_token - } - } - step "verify_vault_unsealed" { description = global.description.verify_vault_unsealed module = module.vault_verify_unsealed @@ -479,13 +452,39 @@ scenario "smoke" { } } + step "verify_vault_version" { + description = global.description.verify_vault_version + module = module.vault_verify_version + depends_on = [step.verify_vault_unsealed] + + providers = { + enos = local.enos_provider[matrix.distro] + } + + verifies = [ + quality.vault_api_sys_version_history_keys, + quality.vault_api_sys_version_history_key_info, + quality.vault_version_build_date, + quality.vault_version_edition, + quality.vault_version_release, + ] + + variables { + hosts = step.create_vault_cluster_targets.hosts + vault_addr = step.create_vault_cluster.api_addr_localhost + vault_edition = matrix.edition + vault_install_dir = global.vault_install_dir[matrix.artifact_type] + vault_product_version = matrix.artifact_source == "local" ? step.get_local_metadata.version : var.vault_product_version + vault_revision = matrix.artifact_source == "local" ? step.get_local_metadata.revision : var.vault_revision + vault_build_date = matrix.artifact_source == "local" ? step.get_local_metadata.build_date : var.vault_build_date + vault_root_token = step.create_vault_cluster.root_token + } + } + step "verify_write_test_data" { description = global.description.verify_write_test_data module = module.vault_verify_write_data - depends_on = [ - step.create_vault_cluster, - step.get_vault_cluster_ips - ] + depends_on = [step.verify_vault_unsealed] providers = { enos = local.enos_provider[matrix.distro] @@ -511,10 +510,7 @@ scenario "smoke" { description = global.description.verify_raft_cluster_all_nodes_are_voters skip_step = matrix.backend != "raft" module = module.vault_verify_raft_auto_join_voter - depends_on = [ - step.create_vault_cluster, - step.get_vault_cluster_ips - ] + depends_on = [step.verify_vault_unsealed] providers = { enos = local.enos_provider[matrix.distro] @@ -534,10 +530,7 @@ scenario "smoke" { step "verify_replication" { description = global.description.verify_replication_status module = module.vault_verify_replication - depends_on = [ - step.create_vault_cluster, - step.get_vault_cluster_ips - ] + depends_on = [step.verify_vault_unsealed] providers = { enos = local.enos_provider[matrix.distro] @@ -580,10 +573,7 @@ scenario "smoke" { step "verify_ui" { description = global.description.verify_ui module = module.vault_verify_ui - depends_on = [ - step.create_vault_cluster, - step.get_vault_cluster_ips - ] + depends_on = [step.verify_vault_unsealed] providers = { enos = local.enos_provider[matrix.distro] diff --git a/enos/enos-scenario-upgrade.hcl b/enos/enos-scenario-upgrade.hcl index 015840ac9a..8f190b5926 100644 --- a/enos/enos-scenario-upgrade.hcl +++ b/enos/enos-scenario-upgrade.hcl @@ -576,35 +576,6 @@ scenario "upgrade" { } } - step "verify_vault_version" { - description = global.description.verify_vault_version - module = module.vault_verify_version - depends_on = [ - step.get_updated_vault_cluster_ips, - ] - - providers = { - enos = local.enos_provider[matrix.distro] - } - - verifies = [ - quality.vault_version_build_date, - quality.vault_version_edition, - quality.vault_version_release, - ] - - variables { - hosts = step.create_vault_cluster_targets.hosts - vault_addr = step.create_vault_cluster.api_addr_localhost - vault_edition = matrix.edition - vault_install_dir = global.vault_install_dir[matrix.artifact_type] - vault_product_version = matrix.artifact_source == "local" ? step.get_local_metadata.version : var.vault_product_version - vault_revision = matrix.artifact_source == "local" ? step.get_local_metadata.revision : var.vault_revision - vault_build_date = matrix.artifact_source == "local" ? step.get_local_metadata.build_date : var.vault_build_date - vault_root_token = step.create_vault_cluster.root_token - } - } - step "verify_vault_unsealed" { description = global.description.verify_vault_unsealed module = module.vault_verify_unsealed @@ -629,11 +600,39 @@ scenario "upgrade" { } } + step "verify_vault_version" { + description = global.description.verify_vault_version + module = module.vault_verify_version + depends_on = [step.verify_vault_unsealed] + + providers = { + enos = local.enos_provider[matrix.distro] + } + + verifies = [ + quality.vault_api_sys_version_history_keys, + quality.vault_api_sys_version_history_key_info, + quality.vault_version_build_date, + quality.vault_version_edition, + quality.vault_version_release, + ] + + variables { + hosts = step.create_vault_cluster_targets.hosts + vault_addr = step.create_vault_cluster.api_addr_localhost + vault_edition = matrix.edition + vault_install_dir = global.vault_install_dir[matrix.artifact_type] + vault_product_version = matrix.artifact_source == "local" ? step.get_local_metadata.version : var.vault_product_version + vault_revision = matrix.artifact_source == "local" ? step.get_local_metadata.revision : var.vault_revision + vault_build_date = matrix.artifact_source == "local" ? step.get_local_metadata.build_date : var.vault_build_date + vault_root_token = step.create_vault_cluster.root_token + } + } + step "verify_read_test_data" { description = global.description.verify_write_test_data module = module.vault_verify_read_data depends_on = [ - step.get_updated_vault_cluster_ips, step.verify_write_test_data, step.verify_vault_unsealed ] @@ -660,9 +659,7 @@ scenario "upgrade" { description = global.description.verify_raft_cluster_all_nodes_are_voters skip_step = matrix.backend != "raft" module = module.vault_verify_raft_auto_join_voter - depends_on = [ - step.get_updated_vault_cluster_ips, - ] + depends_on = [step.verify_vault_unsealed] providers = { enos = local.enos_provider[matrix.distro] @@ -682,9 +679,7 @@ scenario "upgrade" { step "verify_replication" { description = global.description.verify_replication_status module = module.vault_verify_replication - depends_on = [ - step.get_updated_vault_cluster_ips, - ] + depends_on = [step.verify_vault_unsealed] providers = { enos = local.enos_provider[matrix.distro] @@ -706,9 +701,7 @@ scenario "upgrade" { step "verify_ui" { description = global.description.verify_ui module = module.vault_verify_ui - depends_on = [ - step.get_updated_vault_cluster_ips, - ] + depends_on = [step.verify_vault_unsealed] providers = { enos = local.enos_provider[matrix.distro] diff --git a/enos/modules/vault_upgrade/main.tf b/enos/modules/vault_upgrade/main.tf index 2ee8d113b6..6e8b0deeee 100644 --- a/enos/modules/vault_upgrade/main.tf +++ b/enos/modules/vault_upgrade/main.tf @@ -7,7 +7,8 @@ terraform { source = "hashicorp/aws" } enos = { - source = "registry.terraform.io/hashicorp-forge/enos" + source = "registry.terraform.io/hashicorp-forge/enos" + version = ">= 0.5.4" } } } @@ -79,6 +80,10 @@ locals { vault_bin_path = "${var.vault_install_dir}/vault" } +// Upgrade the Vault artifact in-place. With zip bundles we must use the same path of the original +// installation so that we can re-use the systemd unit that enos_vault_start created at +// /etc/systemd/system/vault.service. The path does not matter for package types as the systemd +// unit for the bianry is included and will be installed. resource "enos_bundle_install" "upgrade_vault_binary" { for_each = var.hosts @@ -93,10 +98,32 @@ resource "enos_bundle_install" "upgrade_vault_binary" { } } +// We assume that our original Vault cluster used a zip bundle from releases.hashicorp.com and as +// such enos_vault_start will have created a systemd unit for it at /etc/systemd/systemd/vault.service. +// If we're upgrading to a package that contains its own systemd unit we'll need to remove the +// old unit file so that when we restart vault we pick up the new unit that points to the updated +// binary. +resource "enos_remote_exec" "maybe_remove_old_unit_file" { + for_each = var.hosts + depends_on = [enos_bundle_install.upgrade_vault_binary] + + environment = { + ARTIFACT_NAME = enos_bundle_install.upgrade_vault_binary[each.key].name + } + + scripts = [abspath("${path.module}/scripts/maybe-remove-old-unit-file.sh")] + + transport = { + ssh = { + host = each.value.public_ip + } + } +} + module "get_ip_addresses" { source = "../vault_get_cluster_ips" - depends_on = [enos_bundle_install.upgrade_vault_binary] + depends_on = [enos_remote_exec.maybe_remove_old_unit_file] hosts = var.hosts ip_version = var.ip_version diff --git a/enos/modules/vault_upgrade/scripts/maybe-remove-old-unit-file.sh b/enos/modules/vault_upgrade/scripts/maybe-remove-old-unit-file.sh new file mode 100644 index 0000000000..cb56bdd3fa --- /dev/null +++ b/enos/modules/vault_upgrade/scripts/maybe-remove-old-unit-file.sh @@ -0,0 +1,37 @@ +#!/bin/bash +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: BUSL-1.1 + +set -e + +fail() { + echo "$1" 1>&2 + exit 1 +} + +[[ -z "$ARTIFACT_NAME" ]] && fail "ARTIFACT_NAME env variable has not been set" + +if [ "${ARTIFACT_NAME##*.}" == "zip" ]; then + echo "Skipped removing unit file because new artifact is a zip bundle" + exit 0 +fi + +# Get the unit file for the vault.service that is running. If it's not in /etc/systemd then it +# should be a package provided unit file so we don't need to delete anything. +if ! unit_path=$(systemctl show -P FragmentPath vault 2>&1); then + echo "Skipped removing unit file because and existing path could not be found: $unit_path" + exit 0 +fi + +if [[ "$unit_path" == *"/etc/systemd"* ]]; then + if [ -f "$unit_path" ]; then + echo "Removing old systemd unit file: $unit_path" + if ! out=$(sudo rm "$unit_path" 2>&1); then + fail "Failed to remove old unit file: $unit_path: $out" + fi + else + echo "Skipped removing old systemd unit file because it no longer exists: $unit_path" + fi +else + echo "Skipped removing old systemd unit file because it was not created in /etc/systemd/: $unit_path" +fi diff --git a/enos/modules/vault_upgrade/scripts/restart-vault.sh b/enos/modules/vault_upgrade/scripts/restart-vault.sh index 3c20cd7f22..ba067fc88c 100644 --- a/enos/modules/vault_upgrade/scripts/restart-vault.sh +++ b/enos/modules/vault_upgrade/scripts/restart-vault.sh @@ -12,11 +12,15 @@ binpath=${VAULT_INSTALL_DIR}/vault test -x "$binpath" || fail "unable to locate vault binary at $binpath" if ! out=$(sudo systemctl stop vault 2>&1); then - echo "failed to stop vault: $out: $(sudo systemctl status vault)" 1>&2 + fail "failed to stop vault: $out: $(sudo systemctl status vault)" +fi + +if ! out=$(sudo systemctl daemon-reload 2>&1); then + fail "failed to daemon-reload systemd: $out" 1>&2 fi if ! out=$(sudo systemctl start vault 2>&1); then - echo "failed to start vault: $out: $(sudo systemctl status vault)" 1>&2 + fail "failed to start vault: $out: $(sudo systemctl status vault)" fi count=0 diff --git a/enos/modules/vault_verify_version/main.tf b/enos/modules/vault_verify_version/main.tf index 3ea979ed3f..9c992bb0a0 100644 --- a/enos/modules/vault_verify_version/main.tf +++ b/enos/modules/vault_verify_version/main.tf @@ -58,7 +58,7 @@ variable "vault_root_token" { default = null } -resource "enos_remote_exec" "verify_all_nodes_have_updated_version" { +resource "enos_remote_exec" "verify_cli_version" { for_each = var.hosts environment = { @@ -71,6 +71,25 @@ resource "enos_remote_exec" "verify_all_nodes_have_updated_version" { VAULT_VERSION = var.vault_product_version, } + scripts = [abspath("${path.module}/scripts/verify-cli-version.sh")] + + transport = { + ssh = { + host = each.value.public_ip + } + } +} + +resource "enos_remote_exec" "verify_cluster_version" { + for_each = var.hosts + + environment = { + VAULT_ADDR = var.vault_addr, + VAULT_BUILD_DATE = var.vault_build_date, + VAULT_TOKEN = var.vault_root_token, + VAULT_VERSION = var.vault_product_version, + } + scripts = [abspath("${path.module}/scripts/verify-cluster-version.sh")] transport = { diff --git a/enos/modules/vault_verify_version/scripts/verify-cli-version.sh b/enos/modules/vault_verify_version/scripts/verify-cli-version.sh new file mode 100644 index 0000000000..5c9bbe5106 --- /dev/null +++ b/enos/modules/vault_verify_version/scripts/verify-cli-version.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: BUSL-1.1 + +# Verify the Vault "version" includes the correct base version, build date, +# revision SHA, and edition metadata. +set -e + +fail() { + echo "$1" 1>&2 + exit 1 +} + +[[ -z "$VAULT_ADDR" ]] && fail "VAULT_ADDR env variable has not been set" +[[ -z "$VAULT_BUILD_DATE" ]] && fail "VAULT_BUILD_DATE env variable has not been set" +[[ -z "$VAULT_EDITION" ]] && fail "VAULT_EDITION env variable has not been set" +[[ -z "$VAULT_INSTALL_DIR" ]] && fail "VAULT_INSTALL_DIR env variable has not been set" +[[ -z "$VAULT_REVISION" ]] && fail "VAULT_REVISION env variable has not been set" +[[ -z "$VAULT_TOKEN" ]] && fail "VAULT_TOKEN env variable has not been set" +[[ -z "$VAULT_VERSION" ]] && fail "VAULT_VERSION env variable has not been set" + +binpath=${VAULT_INSTALL_DIR}/vault +edition=${VAULT_EDITION} +version=${VAULT_VERSION} +sha=${VAULT_REVISION} +build_date=${VAULT_BUILD_DATE} + +test -x "$binpath" || fail "unable to locate vault binary at $binpath" +version_expected="Vault v$version ($sha), built $build_date" + +case "$edition" in + *ce) ;; + *ent) ;; + *ent.hsm) version_expected="$version_expected (cgo)";; + *ent.fips1402) version_expected="$version_expected (cgo)" ;; + *ent.hsm.fips1402) version_expected="$version_expected (cgo)" ;; + *) fail "Unknown Vault edition: ($edition)" ;; +esac + +version_expected_nosha=$(echo "$version_expected" | awk '!($3="")' | sed 's/ / /' | sed -e 's/[[:space:]]*$//') +version_output=$("$binpath" version) + +if [[ "$version_output" == "$version_expected_nosha" ]] || [[ "$version_output" == "$version_expected" ]]; then + echo "Version verification succeeded!" +else + fail "expected Version=$version_expected or $version_expected_nosha, got: $version_output" +fi diff --git a/enos/modules/vault_verify_version/scripts/verify-cluster-version.sh b/enos/modules/vault_verify_version/scripts/verify-cluster-version.sh index 38c242fc3a..91cee7ca2d 100644 --- a/enos/modules/vault_verify_version/scripts/verify-cluster-version.sh +++ b/enos/modules/vault_verify_version/scripts/verify-cluster-version.sh @@ -12,36 +12,26 @@ fail() { } [[ -z "$VAULT_ADDR" ]] && fail "VAULT_ADDR env variable has not been set" -[[ -z "$VAULT_BUILD_DATE" ]] && fail "VAULT_TOKEN env variable has not been set" -[[ -z "$VAULT_EDITION" ]] && fail "VAULT_TOKEN env variable has not been set" -[[ -z "$VAULT_INSTALL_DIR" ]] && fail "VAULT_TOKEN env variable has not been set" -[[ -z "$VAULT_REVISION" ]] && fail "VAULT_TOKEN env variable has not been set" +[[ -z "$VAULT_BUILD_DATE" ]] && fail "VAULT_BUILD_DATE env variable has not been set" [[ -z "$VAULT_TOKEN" ]] && fail "VAULT_TOKEN env variable has not been set" -[[ -z "$VAULT_VERSION" ]] && fail "VAULT_TOKEN env variable has not been set" +[[ -z "$VAULT_VERSION" ]] && fail "VAULT_VERSION env variable has not been set" -binpath=${VAULT_INSTALL_DIR}/vault -edition=${VAULT_EDITION} -version=${VAULT_VERSION} -sha=${VAULT_REVISION} -build_date=${VAULT_BUILD_DATE} - -test -x "$binpath" || fail "unable to locate vault binary at $binpath" -version_expected="Vault v$version ($sha), built $build_date" - -case "$edition" in - *ce) ;; - *ent) ;; - *ent.hsm) version_expected="$version_expected (cgo)";; - *ent.fips1402) version_expected="$version_expected (cgo)" ;; - *ent.hsm.fips1402) version_expected="$version_expected (cgo)" ;; - *) fail "Unknown Vault edition: ($edition)" ;; -esac - -version_expected_nosha=$(echo "$version_expected" | awk '!($3="")' | sed 's/ / /' | sed -e 's/[[:space:]]*$//') -version_output=$("$binpath" version) - -if [[ "$version_output" == "$version_expected_nosha" ]] || [[ "$version_output" == "$version_expected" ]]; then - echo "Version verification succeeded!" -else - fail "expected Version=$version_expected or $version_expected_nosha, got: $version_output" +# The sys/version-history endpoint only includes major.minor.patch, any other semver fields need to +# be stripped out. +if ! version=$(cut -d + -f1 <<< "$VAULT_VERSION" | cut -d - -f1); then + fail "failed to parse the expected version: $version" fi + +if ! vh=$(curl -s -X LIST -H "X-Vault-Token: $VAULT_TOKEN" http://127.0.0.1:8200/v1/sys/version-history | jq -eMc '.data'); then + fail "failed to Vault cluster version history: $vh" +fi + +if ! out=$(jq -eMc --arg version "$version" '.keys | contains([$version])' <<< "$vh"); then + fail "cluster version history does not include our expected version: expected: $version, versions: $(jq -eMc '.keys' <<< "$vh"): output: $out" +fi + +if ! out=$(jq -eMc --arg version "$version" --arg bd "$VAULT_BUILD_DATE" '.key_info[$version].build_date == $bd' <<< "$vh"); then + fail "cluster version history build date is not the expected date: expected: $VAULT_BUILD_DATE, output: $out" +fi + +printf "Cluster version information is valid!: %s\n" "$vh"