199 lines
6.3 KiB
Bash

#!/usr/bin/env bash
# Convert all templated variables to shell variables
VAULT_ADDR=${VAULT_ADDR}
VAULT_TOKEN=${VAULT_TOKEN}
INSTALL_DIR=${INSTALL_DIR}
VAULT_CLI_VERSION=${VAULT_CLI_VERSION}
ENTERPRISE=${ENTERPRISE}
# Fetch URL content to stdout
fetch() {
url="$1"
if command -v curl > /dev/null 2>&1; then
curl -sSL --fail "$${url}"
elif command -v wget > /dev/null 2>&1; then
wget -qO- "$${url}"
elif command -v busybox > /dev/null 2>&1; then
busybox wget -qO- "$${url}"
else
printf "curl, wget, or busybox is not installed. Please install curl or wget in your image.\n"
return 1
fi
}
# Download URL to a file
fetch_to_file() {
dest="$1"
url="$2"
if command -v curl > /dev/null 2>&1; then
curl -sSL --fail "$${url}" -o "$${dest}"
elif command -v wget > /dev/null 2>&1; then
wget -O "$${dest}" "$${url}"
elif command -v busybox > /dev/null 2>&1; then
busybox wget -O "$${dest}" "$${url}"
else
printf "curl, wget, or busybox is not installed. Please install curl or wget in your image.\n"
return 1
fi
}
unzip_safe() {
if command -v unzip > /dev/null 2>&1; then
command unzip "$@"
elif command -v busybox > /dev/null 2>&1; then
busybox unzip "$@"
else
printf "unzip or busybox is not installed. Please install unzip in your image.\n"
return 1
fi
}
install() {
# Get the architecture of the system
ARCH=$(uname -m)
if [ "$${ARCH}" = "x86_64" ]; then
ARCH="amd64"
elif [ "$${ARCH}" = "aarch64" ]; then
ARCH="arm64"
else
printf "Unsupported architecture: %s\n" "$${ARCH}"
return 1
fi
# Determine OS and validate
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
if [ "$${OS}" != "linux" ] && [ "$${OS}" != "darwin" ]; then
printf "Unsupported OS: %s. Only linux and darwin are supported.\n" "$${OS}"
return 1
fi
# Fetch release information from HashiCorp API
if [ "$${VAULT_CLI_VERSION}" = "latest" ]; then
if [ "$${ENTERPRISE}" = "true" ]; then
API_URL="https://api.releases.hashicorp.com/v1/releases/vault/latest?license_class=enterprise"
else
API_URL="https://api.releases.hashicorp.com/v1/releases/vault/latest"
fi
else
# For specific version, append +ent suffix for enterprise
if [ "$${ENTERPRISE}" = "true" ]; then
API_URL="https://api.releases.hashicorp.com/v1/releases/vault/$${VAULT_CLI_VERSION}+ent"
else
API_URL="https://api.releases.hashicorp.com/v1/releases/vault/$${VAULT_CLI_VERSION}"
fi
fi
API_RESPONSE=$(fetch "$${API_URL}")
if [ -z "$${API_RESPONSE}" ]; then
printf "Failed to fetch release information from HashiCorp API.\n"
return 1
fi
# Parse version and download URL from API response
if command -v jq > /dev/null 2>&1; then
VAULT_CLI_VERSION=$(printf '%s' "$${API_RESPONSE}" | jq -r '.version')
DOWNLOAD_URL=$(printf '%s' "$${API_RESPONSE}" | jq -r --arg os "$${OS}" --arg arch "$${ARCH}" '.builds[] | select(.os == $os and .arch == $arch) | .url')
else
VAULT_CLI_VERSION=$(printf '%s' "$${API_RESPONSE}" | sed -n 's/.*"version":"\([^"]*\)".*/\1/p')
# Fallback: construct URL manually if jq not available
DOWNLOAD_URL="https://releases.hashicorp.com/vault/$${VAULT_CLI_VERSION}/vault_$${VAULT_CLI_VERSION}_$${OS}_$${ARCH}.zip"
fi
if [ -z "$${VAULT_CLI_VERSION}" ]; then
printf "Failed to determine Vault version.\n"
return 1
fi
if [ -z "$${DOWNLOAD_URL}" ]; then
printf "Failed to determine download URL for Vault %s (%s/%s).\n" "$${VAULT_CLI_VERSION}" "$${OS}" "$${ARCH}"
return 1
fi
printf "Vault version: %s\n" "$${VAULT_CLI_VERSION}"
# Check if the vault CLI is installed and has the correct version
installation_needed=1
if command -v vault > /dev/null 2>&1; then
CURRENT_VERSION=$(vault version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+')
if [ "$${CURRENT_VERSION}" = "$${VAULT_CLI_VERSION}" ]; then
printf "Vault version %s is already installed and up-to-date.\n\n" "$${CURRENT_VERSION}"
installation_needed=0
fi
fi
if [ "$${installation_needed}" = "1" ]; then
# Download and install Vault
if [ -z "$${CURRENT_VERSION}" ]; then
printf "Installing Vault CLI ...\n\n"
else
printf "Upgrading Vault CLI from version %s to %s ...\n\n" "$${CURRENT_VERSION}" "$${VAULT_CLI_VERSION}"
fi
# Create temporary directory for download
TEMP_DIR=$(mktemp -d)
cd "$${TEMP_DIR}" || return 1
printf "Downloading from %s\n" "$${DOWNLOAD_URL}"
if ! fetch_to_file vault.zip "$${DOWNLOAD_URL}"; then
printf "Failed to download Vault.\n"
rm -rf "$${TEMP_DIR}"
return 1
fi
if ! unzip_safe vault.zip; then
printf "Failed to unzip Vault.\n"
rm -rf "$${TEMP_DIR}"
return 1
fi
# Install to the specified directory
if [ -n "$${INSTALL_DIR}" ] && [ -w "$${INSTALL_DIR}" ]; then
mv vault "$${INSTALL_DIR}/vault"
printf "Vault installed to %s successfully!\n\n" "$${INSTALL_DIR}"
elif [ -n "$${INSTALL_DIR}" ] && [ ! -w "$${INSTALL_DIR}" ]; then
# Try with sudo if install dir specified but not writable
if sudo mv vault "$${INSTALL_DIR}/vault" 2> /dev/null; then
printf "Vault installed to %s successfully!\n\n" "$${INSTALL_DIR}"
else
printf "Warning: Cannot write to %s. " "$${INSTALL_DIR}"
mkdir -p ~/.local/bin
if mv vault ~/.local/bin/vault; then
printf "Installed to ~/.local/bin instead.\n"
printf "Please add ~/.local/bin to your PATH to use vault CLI.\n"
else
printf "Failed to install Vault.\n"
rm -rf "$${TEMP_DIR}"
return 1
fi
fi
elif sudo mv vault /usr/local/bin/vault 2> /dev/null; then
printf "Vault installed successfully!\n\n"
else
mkdir -p ~/.local/bin
if ! mv vault ~/.local/bin/vault; then
printf "Failed to move Vault to local bin.\n"
rm -rf "$${TEMP_DIR}"
return 1
fi
printf "Please add ~/.local/bin to your PATH to use vault CLI.\n"
fi
# Clean up temp directory
rm -rf "$${TEMP_DIR}"
fi
return 0
}
# Run installation
if ! install; then
printf "Failed to install Vault CLI.\n"
exit 1
fi
# Indicate token configuration status
if [ -n "$${VAULT_TOKEN}" ]; then
printf "Vault token has been configured via VAULT_TOKEN environment variable.\n"
else
printf "No Vault token provided. Use 'vault login' or set VAULT_TOKEN to authenticate.\n"
fi