Introduction
On particular occasions, a Vault administrator needs to identify all the child namespaces starting from a specific point or from the root
namespace. This how-to aims to simplify this task by leveraging a shell script.
Prerequisites
- This how-to article is valid only for the Enterprise version of Vault.
- Bash version 5.1 or BusyBox version 1.33.1 onwards.
Overview
If for example there are multiple child namespaces named
ns1
, ns2
, ns3
, ns1/ns11
, ns1/ns12
andns3/ns31/ns32/ns34
, it might be difficult to get all the child namespaces with a single command.
The following script can leverage the effort by parsing recursively, starting from a specific namespace, all the child namespaces within a desired depth. By default, the starting namespace is the
root
namespace and the default depth is 1
.Procedures
-
Step 1 (optional) - For testing purposes, create a namespace child hierarchy like:
ns1
,ns2
andns3
andns1/ns11
,ns1/ns12
andns3/ns31/ns32/ns34
or as visual tree:
root/
├── ns1
│ ├── ns11
│ └── ns12
├── ns2
└── ns3
└── ns31
└── ns32
└── ns34
# Commands for creating the namespaces
$ vault namespace create ns1
$ vault namespace create ns2
$ vault namespace create ns3
$ VAULT_NAMESPACE=ns1 vault namespace create ns11
$ VAULT_NAMESPACE=ns1 vault namespace create ns12
$ VAULT_NAMESPACE=ns3 vault namespace create ns31
$ VAULT_NAMESPACE=ns3/ns31 vault namespace create ns32
$ VAULT_NAMESPACE=ns3/ns31/ns32 vault namespace create ns33
- Step 2 - Create a Bash shell script for parsing the namespaces with name
recursive_namespaces.sh
#!/bin/sh
#
# First passing argument is the depth of searching and the second argument is the
# starting namespace.
# If the first argument is not an integer then this argument is considered the
# starting namespace and depth is set to level=1
export all_namespaces=""
export cosmetic_namespace=""
export level=1
function getnamespaces() {
# Recursive function for collecting all the namespaces in a variable
# First argument is the depth of recursivity
# Second argument is the starting namespace
# If the first argument is not a number than we bail out
case $1 in
'' | *[!0-9]*) return 1 ;;
*) : ;;
esac
# If we reach to the last level then we end the recursive loop
(($1 < 1)) && return 0
for i in $(vault namespace list -ns=$2 2>>/dev/null | sed -e '1,2d'); do
{
export all_namespaces=$(echo $all_namespaces "$2$i")
if [ "X$2" == "X" ]; then
(($1 > 1)) && getnamespaces $(($1 - 1)) "$i"
else
(($1 > 1)) && getnamespaces $(($1 - 1)) "$2$i"
fi
}
done
return 0
}
# Getting all arguments from OS as ARGS. By default we use the level depth 1.
# If the first argument is NOT an integer we consider the string as namespace
# starting and level depth 1.
case $1 in
'' | *[!0-9]*)
(($# >= 1)) && export namespace=$(echo $1)
export level=1
;;
*)
(($# >= 1)) && export level=$(echo $1)
export level=${level:=1}
# Sanitize input level - removes left zeroes to avoid OCTAL conversion
([[ ! -z "${level}" ]] && [[ "${level}" =~ ^[0-9]+$ ]]) &&
export level=${level#${level%%[1-9]*}}
export level=${level:=1}
#
(($# >= 2)) && export namespace=$(echo $2)
;;
esac
export namespace=${namespace:=root}
# If the namespace is default then we empty the namespace starting point.
# Otherwise we only ensure that the last character is '/' .
if [[ "X${namespace}" == "Xroot" ]]; then
export namespace=""
else
[[ $(echo ${namespace: -1}) == '/' ]] || export namespace="${namespace}/"
fi
export cosmetic_namespace=${namespace}
export cosmetic_namespace=${cosmetic_namespace:=root/}
echo "### Searching namespaces starting with ${cosmetic_namespace} and depth ${level} ."
getnamespaces ${level} ${namespace}
echo "$all_namespaces ###" | sed 's/ /\n/g'
# Cleanup the variables for multiple executions
unset all_namespaces namespace level cosmetic_namespace
- Step 3 - Example of how to execute the Bash script for parsing the namespaces with default depth level=2 starting from
root
namespace
sh recursive_namespaces.sh 2
### Searching namespaces starting with root/ and depth 2.
ns1/
ns1/ns11/
ns1/ns12/
ns2/
ns3/
ns3/ns31/
###
- Step 4 - Example of how to execute the Bash script for parsing the namespaces with default depth level=3 starting from
ns3/ns31
namespace:
sh recursive_namespaces.sh 3 ns3/ns31
### Searching namespaces starting with ns3/ns31/ and depth 3.
ns3/ns31/ns32/
ns3/ns31/ns32/ns33/
###
- Step 5 - Example of how to execute the Bash script for parsing the namespaces with default depth level=9999 starting from
root/
namespace:
### Searching namespaces starting with root/ and depth 9999 .
ns1/
ns1/ns11/
ns1/ns12/
ns2/
ns3/
ns3/ns31/
ns3/ns31/ns32/
ns3/ns31/ns32/ns33/
###
- Step 6 - (For HCP) Example of how to execute the Bash script for parsing the namespaces with default depth level=9999 starting from
admin/
namespace:
sh recursive_namespaces.sh 999 admin
### Searching namespaces starting with admin/ and depth 9999 .
admin/ns1/
admin/ns1/ns11/
admin/ns1/ns12/
admin/ns2/
admin/ns3/
admin/ns3/ns31/
admin/ns3/ns31/ns32/
admin/ns3/ns31/ns32/ns33/
###
Additional Information:
- HashiCorp Learn: Vault Namespaces