Skip to content

Instantly share code, notes, and snippets.

@TomerFi
Created November 27, 2022 20:05
Show Gist options
  • Save TomerFi/0d989c976fc127ea876e56158b54f24e to your computer and use it in GitHub Desktop.
Save TomerFi/0d989c976fc127ea876e56158b54f24e to your computer and use it in GitHub Desktop.
Collect multiple K8S resources into YAML files based on a grep expression
#!/bin/bash
set -e
set -u
set -o pipefail
######################################## DESCRIPTION #############################################################
## Use this script to collect multiple resources into YAML files. ##
## ##
## The mandatory '--exp' option takes a grep expression to match against all 'kind.group'. ##
## ##
## i.e. 'collect_k8s_resources_by_expression.sh --exp monitoring.coreos.com' ##
## will result in a 'collected' directory with a bunch of YAML files for every CR in monitoring.coreos.com. ##
## doing '--exp coreos.com' might include a broader wide of YAML files as we grep over `kubectl api-resources`. ##
## the more specific the expression, the last YAML files we'll get, and the less time this script takes to run. ##
## ##
## OVERUSAGE WARNING: will result in a lot of API requests and a lengthy runtime, ##
## think about your expression b4 running it! ##
##################################################################################################################
####################################### USAGE EXAMPLES ############################################
## bash ./collect_k8s_resources_by_expression.sh --exp coreos.com ##
## bash ./collect_k8s_resources_by_expression.sh --exp coreos.com --dir collected ##
## bash ./collect_k8s_resources_by_expression.sh --exp coreos.com --dir collected --nonamespaced ##
## bash ./collect_k8s_resources_by_expression.sh --exp coreos.com --dir collected --noclustered ##
## bash ./collect_k8s_resources_by_expression.sh --exp coreos.com --clean ##
###################################################################################################
# iterate over arguments and create named parameters
while [ $# -gt 0 ]; do
if [[ $1 == *"--"* ]]; then
param="${1/--/}"
if [ -z ${2+x} ] || [[ $2 = --* ]]; then
declare $param="true"
else
declare $param="$2"
fi
fi
shift
done
# set non-required parameters defaults
dir=${dir:-collected}
nonamespaced=${nonamespaced:-false}
noclustered=${noclustered:-false}
clean=${clean:-false}
# verify required parameters
if [ -z ${exp+x} ]; then
echo "ERROR: You must specify a grep expression using the '--exp' option. i.e. a partial resource group."
exit 1
fi
if [ $nonamespaced = "true" ] && [ $noclustered = "true" ] ; then
echo "ERROR: The '--nonamespaced' skips namespace resources, the '--noclustered' skips cluster ones, these cannot be combined."
exit 1
fi
# get kind from 'kind.group'
get_kind() {
IFS='.' kgsplit=($1)
echo ${kgsplit[0]}
}
# get name from kind.group/name
get_name_cluster() {
IFS='/' kgsplit=($1)
echo ${kgsplit[1]}
}
# gather 'kubectl get' commands
commands=()
# use the --nonamespaced option to disable namespace resources fetch
if [ $nonamespaced != "true" ]; then
# grab namespaced api resources
namepsaced=`kubectl api-resources --no-headers --namespaced=true -o name | grep $exp`
if [ -z "$namepsaced" ]; then
echo "WARN: no namespaced resources matching regex expression '$exp' found"
else
records=($namepsaced)
for rec in "${records[@]}"; do
crs=`kubectl get $rec -A -o 'custom-columns=ns:.metadata.namespace,n:.metadata.name' --no-headers`
if [ ! -z "$crs" ]; then
kind=$(get_kind $rec)
IFS=$'\n' resources=($crs)
for res in "${resources[@]}"; do
sanitized=`echo $res | xargs`
target="$dir"/"$kind"_"${sanitized// /_}.yaml"
commands+=("kubectl get $rec -n $sanitized -o yaml > $target")
done
fi
done
fi
fi
# use the --noclustered option to disable cluster resources fetch
if [ $noclustered != "true" ]; then
# grab clustrer api resources
clustered=`kubectl api-resources --namespaced=false -o name | grep $exp`
if [ -z "$clustered" ]; then
echo "WARN: no clustered resources matching regex expression '$exp' found"
else
records=($clustered)
for rec in "${records[@]}"; do
crs=`kubectl get $rec -o name --no-headers`
if [ ! -z "$crs" ]; then
kind=$(get_kind $rec)
IFS=$'\n' resources=($crs)
for res in "${resources[@]}"; do
name=$(get_name_cluster $res)
target="$dir"/"$kind"_"cluster_$name.yaml"
commands+=("kubectl get $rec $name -o yaml > $target")
done
fi
done
fi
fi
# clean target directory
if [ $clean = "true" ]; then
rm -rf $dir
fi
# create target directory if doesn't exists
if [ ! -d "$dir" ]; then
mkdir -p $dir
fi
# remove (if) existing commands file
rm -f $dir/commands
# list and evaluate all commands - will result in a list-file and 0-to-many CR yaml files
for cmd in "${commands[@]}"; do
echo $cmd >> $dir/commands
eval $cmd
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment