Skip to content

Instantly share code, notes, and snippets.

@JasonGiedymin
Last active October 11, 2023 19:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JasonGiedymin/fb93be0f171d43c4f6d760046d9eac54 to your computer and use it in GitHub Desktop.
Save JasonGiedymin/fb93be0f171d43c4f6d760046d9eac54 to your computer and use it in GitHub Desktop.
Azure Vault CLI Helper script
#!/usr/bin/env zsh
# Script: azv
# Author: Jason Giedymin <jason.giedymin@gmail.com>
# Name: azv
# Version: 1.0.4
# Description: Azure Vault Helper Script
# License: MIT
#
# Exit Codes:
# 1 - user canceled operation
# 2 - exit due to invalid options provided, such as providing both '--all' and '--vaults'
# 3 - exit due to no default vault set
set -e
AZV_VERSION="1.0.4"
DEFAULT_VAULT="$HOME/.default_azv_vault"
SUPPRESS_BANNER="false"
spinner_pid=
# colors
autoload colors; colors
function start_spinner {
set +m
echo -n "$1 "
{ while : ; do for X in ' • ' ' • ' ' • ' ' • ' ' • ' ' • ' ' • ' ' • ' ' • ' ' • ' ; do echo -en "\b\b\b\b\b\b\b\b$X" ; sleep 0.1 ; done ; done & } 2>/dev/null
spinner_pid=$!
}
function stop_spinner {
{ kill -9 $spinner_pid && wait; } 2>/dev/null
set -m
echo -en "\033[2K\r"
}
function ctrl_c() {
echo "Ctrl-C pressed. Exiting script."
stop_spinner
exit 1
}
trap ctrl_c INT
trap stop_spinner EXIT
setup() {
if [ ! -e $DEFAULT_VAULT ]; then
touch $DEFAULT_VAULT
echo "INFO: Empty Default vault file created at [$DEFAULT_VAULT] ..."
fi;
}
usage() {
cat << EOF
$fg[yellow]Usage: $reset_color
[command] <options>
$fg[yellow]options:$reset_color
--all-vaults : search all vaults in the current subscription
--all : search all vaults across $fg[blue]all subscriptions$reset_color
$fg[red]Warning: $fg[blue]<options> only applies to the following commands:$reset_color
[ls|list-secrets]
[find]
$fg[yellow]Info:$reset_color
[info] : shows info about current subscription and default vault
$fg[yellow]List:$reset_color
[ls-subs|list-subscriptions] : shows all subscriptions
[ls-vaults|list-vaults] : shows all vaults in current subscription
[ls|list-secrets] <wildcard-text> <options> : list all secrets in vault, wildcard acts like find
: ls <wildcard> is equivalent to find <wildcard>
$fg[yellow]Set:$reset_color
[set-sub] : sets the current subscription
[set-vault] : set the current vault
$fg[yellow]Secrets:$reset_color
[find] <wildcard-text> : find a specific secret by wildcard-text
[show|get] <name> : get or show a specific secret by name
EOF
}
get_current_sub() {
az account show | jq '.name'
}
get_current_vault() {
_default_vault=$(cat $DEFAULT_VAULT)
if [ -z $_default_vault ]; then
echo "NONE - run 'azv set-vault <vault-name>'"
else
echo "$_default_vault"
fi;
}
get_all_subs() {
az account list | jq '.[].name'
}
get_sub_id() {
_query=".[] | select(.name == \"$@\") | .id"
az account list | jq "$_query" | tr -d '"'
}
# only works based on currently set
get_all_vaults() {
az keyvault list | jq '.[].name' | tr -d '"'
}
banner() {
cat << EOF
---------------------$fg[blue]INFO$reset_color------------------------
$fg[green]Current Subscription: $fg[yellow]$(get_current_sub) $reset_color
$fg[green]Cached Vault: $fg[yellow]$(get_current_vault) $reset_color (cached vault)
-------------------------------------------------
EOF
}
info() {
if [[ "$SUPPRESS_BANNER" == "false" ]]; then
banner
fi;
}
subs() {
curr_sub=$(get_current_sub)
all_subs=$(get_all_subs)
cat << EOF
$fg[yellow]Subscriptions available:$reset_color
========================
$(echo "$all_subs" | sed "s/$curr_sub/$fg[green]$curr_sub <--** current $reset_color/g")
EOF
}
set_sub() {
_subs="$(get_all_subs)"
if [[ "$_subs" =~ "$@" ]]; then
_sub_id=$(get_sub_id $@)
echo "Found id: [$_sub_id] --for--> [\"$@\"]"
echo "Setting new subscription ... verification to follow ..."
az account set --subscription $_sub_id
subs
else
echo
echo "Could not find \"$@\""
echo
subs
fi;
}
vaults() {
info
_all_vaults="$(get_all_vaults)"
_default_vault=$(cat $DEFAULT_VAULT)
if [ ! -z $_default_vault ]; then
cat << EOF
$fg[yellow]Vaults available: $reset_color
==================
$(echo "$_all_vaults" | sed "s/$_default_vault/$fg[green]$_default_vault <--** current $reset_color/g")
EOF
else
cat << EOF
$fg[yellow]Vaults available: $reset_color
==================
$_all_vaults
EOF
fi;
}
set_vault() {
_vaults="$(get_all_vaults)"
echo "Setting vault to \"$@\""
if [[ "$_vaults" =~ "$@" ]]; then
echo "Found valid vault \"$@\", from the vault list."
echo "$@" > $DEFAULT_VAULT
echo
info
else
echo
echo "!! Did not find \"$@\" !!"
echo
vaults
fi;
}
find_secret_from_vault() {
if [ -z "$2" ]; then
_vault_to_use=$(get_current_vault)
else
_vault_to_use=$2
fi;
info
start_spinner "processing ... please wait ..."
_secrets="$(az keyvault secret list --vault-name $_vault_to_use | jq '.[] | .name' | grep --color=always $1 | tr -d '"')"
stop_spinner
if [ -z "$_secrets" ]; then
_secrets="$fg[red]None Found or no access to look$reset_color"
fi;
cat << EOF
Secrets found from vault $fg[yellow]$_vault_to_use: $reset_color
==============================================
$_secrets
EOF
}
find_secrets() {
if [ $o_all ] && [ $o_all_vaults ]; then
echo
echo "$fg[red] Must choose either '--all' or '--vaults', not both.$reset_color See usage below."
echo
usage
exit 2;
fi;
if [ $o_all ]; then
find_from_all_subs $@
elif [ $o_all_vaults ]; then
find_from_all_vaults $@
else
find_secret_from_vault $@
fi;
}
list_secrets() {
info
start_spinner "processing ... please wait ..."
_secrets="$(az keyvault secret list --vault-name $(get_current_vault) | jq '.[] | .name' | tr -d '"')"
stop_spinner
cat << EOF
$fg[yellow]Secrets:$reset_color
========================================
$_secrets
EOF
}
show_secret() {
info
start_spinner "processing ... please wait ..."
_secret="$(az keyvault secret show --vault-name $(get_current_vault) --name $@ | jq '.value')"
stop_spinner
cat << EOF
$fg[yellow]Secret Value: (will be surrounded by quotes)$reset_color
============================================
$fg[white]$_secret $reset_color
EOF
}
list() {
_default_vault=$(cat $DEFAULT_VAULT)
if [ -z $_default_vault ]; then
echo "Pleae run 'azv set-vault <vault-name>' to set a default vault first."
exit 3;
fi;
_search=$@
if [ -z $_search ]; then
list_secrets $@
else # ls can work like find
find_secrets $@
fi;
}
find_from_all_vaults() {
SUPPRESS_BANNER=true
info
_all_vaults="$(get_all_vaults)"
if [ -z "$_all_vaults" ]; then
echo
echo "$fg[red]No vaults found for the selected subscription.$reset_color"
echo
SUPPRESS_BANNER=false
info
fi;
IFS=$'\n'
for _vault in $(echo "${_all_vaults[@]}" | sed -e 's/\r//g');
do
find_secret_from_vault "$1" "$_vault"
done
}
find_from_all_subs() {
SUPPRESS_BANNER=true
info
_all_subs="$(get_all_subs)"
_original_sub="$(get_current_sub)"
echo "$fg[red]WARNING:$reset_color Script will attempt to switch subscriptions to search all key vaults."
IFS=$'\n'
for _sub in $(echo "${_all_subs[@]}" | sed -e 's/\"//g');
do
set_sub "$_sub"
find_from_all_vaults $1
done
echo "$fg[yellow]Now setting default subscription to what was set prior to cascade '--all' search.$reset_color"
set_sub "$(echo "$_original_sub" | sed -e 's/\"//g')"
}
version() {
echo "Version: $AZV_VERSION"
}
azurevault() {
case $1 in
show|get)
shift
show_secret $@
;;
ls-vaults|list-vaults)
vaults
;;
ls-subs|list-subscriptions)
subs
;;
ls|list-secrets)
shift;
list $@
;;
find)
shift;
find_secrets $@
;;
set-sub)
shift;
set_sub $@
;;
set-vault)
shift;
set_vault $@
;;
info)
info
;;
version)
version
;;
*)
echo
echo " $fg[red]Please choose an command.$reset_color Usage below."
echo
usage
;;
esac
}
main() {
zparseopts -E -D -- \
-all=o_all \
-all-vaults=o_all_vaults
setup
azurevault $@
}
main $@
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment