diff --git a/hack/velero-restore.sh b/hack/velero-restore.sh new file mode 100755 index 00000000..8cf3843a --- /dev/null +++ b/hack/velero-restore.sh @@ -0,0 +1,181 @@ +#!/usr/bin/env bash + +# This script was made to ensure the right cluster +# restoration using Velero backup technology having Capsule installed. +# It requires cluster admin permission. + +# let script exit if a command fails +#set -o errexit + +# let script exit if an unsed variable is used +#set -o nounset + +KUBECFGFILE="~/.kube/config" +KUBEOPTIONS="--kubeconfig=$KUBECFGFILE" +TMPDIR=/tmp + +usage () { + printf "Usage: $0 [flags] commands\n" + printf "Flags:\n" + printf "\t-c, --kubeconfig\tPath to the kubeconfig file to use for CLI requests.\n" + printf "Commands:\n" + printf "\trestore\t\t\tPerform the restore on the cluster, patching the right object fields.\n" + printf "\n" + printf "E.g. [restore]:\t$0 -c /path/to/kubeconfig restore\n" +} + +# Update KUBEOPTIONS global var. +# Arguments: +# None +# Outputs: +# None +update_kube_options () { + KUBEOPTIONS="--kubeconfig=$KUBECFGFILE" +} + +# Check if the give command is present on the system. +# Arguments: +# $1 - command name +# Outputs: +# Notice that the command is not present. +# Examples: +# check_prerequisite "kubectl" +check_prerequisite () { + cmd=$1 + if ! command -v "$cmd" &> /dev/null; then + printf "Please, install kubectl first.\n" + exit 1 + fi +} + +# Retrive tenant list. +# Arguments: +# None +# Outputs: +# list of the tenants. +get_tenant_list () { + tenants=$(kubectl "$KUBEOPTIONS" get tnt \ + --no-headers -o custom-columns=":.metadata.name") + echo $tenants +} + +# Retrive namespace list. +# Arguments: +# $1 - tenant to retrieve namespaces. +# Outputs: +# list of the namespaces. +# Examples: +# get_namespace_list "oil" +get_namespace_list () { + tnt="$1" + namespaces=$(kubectl "$KUBEOPTIONS" get ns -l capsule.clastix.io/tenant="$tnt" \ + --no-headers -o custom-columns=":metadata.name") + echo $namespaces +} + +# Perform cluster backup listing the namespaces +# for each tenant and retrieving their ownerReference. +# Arguments: +# None +# Outputs: +# Tenants backup status. +cluster_backup () { + # Retrieve tenant names and uids. + owner_reference=$(kubectl "$KUBEOPTIONS" get tenants.capsule.clastix.io --no-headers \ + -o custom-columns=":.metadata.name,:.metadata.uid") + + # Store information inside /tmp/tenant_$(tenant_name). + while IFS= read -r line; do + tnt=$(echo "$line" | awk '{ print $1 }') + uid=$(echo "$line" | awk '{ print $2 }') + + cat < "$TMPDIR/tenant_$tnt" +{ + "op": "add", + "path": "/metadata/ownerReferences", + "value": [ + { + "apiVersion": "capsule.clastix.io/v1alpha1", + "blockOwnerDeletion": true, + "controller": true, + "kind": "Tenant", + "name": "${tnt}", + "uid": "${uid}" + } + ] +} +EOF + done <<< "$owner_reference" +} + +# Perform cluster restore listing the namespaces +# for each tenant and adding their ownerReference. +# Arguments: +# None +# Outputs: +# Tenants restore status. +cluster_restore () { + tenants=($(get_tenant_list)) + + for tnt in ${tenants[@]}; do + + # Ensure backup file exists for the current tenant. + if [ ! -f "$TMPDIR/tenant_$tnt" ]; then + printf "Error: No backup were found for %s tenant.\n" "$tnt" + continue + fi + printf "tenant(restore): %s\n" "$tnt" + namespaces=($(get_namespace_list "$tnt")) + + for ns in ${namespaces[@]}; do + # Read patch content from file. + patch=$(<"$TMPDIR/tenant_$tnt") + kubectl "$KUBEOPTIONS" patch namespaces "$ns" --type=json -p "[$patch]" &>/dev/null + + if [ $? -ne 0 ]; then + printf "\tnamespace: %s\t[KO]\n" "$ns" + continue + fi + printf "\tnamespace: %s\t[OK]\n" "$ns" + done + done +} + +# Check presequisites: +check_prerequisite kubectl + +# Print usage in case of empty arguments. +if [ $# -eq 0 ]; then + usage + exit +fi + +# Flags parsing. +while :; do + case "$1" in + -h|--help) + usage + exit + ;; + -c|--kubeconfig) + KUBECFGFILE="${2}" + printf "Using config file: %s\n" "$KUBECFGFILE" + update_kube_options + shift + ;; + *) + break + esac + shift +done + +# Commands parsing. +case "${@: -1}" in + restore) + cluster_backup + cluster_restore + ;; + *) + break +esac +