#!/bin/bash # Simulate well-known CRDs being available API_VERSIONS="-a monitoring.coreos.com/v1 -a snapshot.storage.k8s.io/v1" # Waits for max 300s and retries function wait_for() { local TRIES=0 while true; do eval " $@" && break [ $TRIES -eq 100 ] && return 1 let TRIES=$TRIES+1 sleep 3 done } function chart_location() { echo "$1 --repo https://cdn.zero-downtime.net/charts" } function argo_used() { kubectl get application kubezero -n argocd >/dev/null && rc=$? || rc=$? return $rc } # get kubezero-values from ArgoCD if available or use in-cluster CM without Argo function get_kubezero_values() { argo_used && \ { kubectl get application kubezero -n argocd -o yaml | yq .spec.source.helm.values > ${WORKDIR}/kubezero-values.yaml; } || \ { kubectl get configmap -n kube-system kubezero-values -o yaml | yq '.data."values.yaml"' > ${WORKDIR}/kubezero-values.yaml ;} } function disable_argo() { cat > _argoapp_patch.yaml < $WORKDIR/helm-no-crds.yaml helm template $(chart_location $chart) -n $namespace --name-template $module $targetRevision --include-crds --set ${module}.installCRDs=true -f $WORKDIR/values.yaml $API_VERSIONS --kube-version $KUBE_VERSION > $WORKDIR/helm-crds.yaml diff -e $WORKDIR/helm-no-crds.yaml $WORKDIR/helm-crds.yaml | head -n-1 | tail -n+2 > $WORKDIR/crds.yaml # Only apply if there are actually any crds if [ -s $WORKDIR/crds.yaml ]; then [ -n "$DEBUG" ] && cat $WORKDIR/crds.yaml kubectl apply -f $WORKDIR/crds.yaml --server-side --force-conflicts fi } # helm template | kubectl apply -f - # confine to one namespace if possible function render() { helm template $(chart_location $chart) -n $namespace --name-template $module $targetRevision --skip-crds -f $WORKDIR/values.yaml $API_VERSIONS --kube-version $KUBE_VERSION $@ \ | python3 -c ' #!/usr/bin/python3 import yaml import sys for manifest in yaml.safe_load_all(sys.stdin): if manifest: if "metadata" in manifest and "namespace" not in manifest["metadata"]: manifest["metadata"]["namespace"] = sys.argv[1] print("---") print(yaml.dump(manifest))' $namespace > $WORKDIR/helm.yaml } function _helm() { local action=$1 local module=$2 # check if module is even enabled and return if not [ ! -f $WORKDIR/kubezero/templates/${module}.yaml ] && { echo "Module $module disabled. No-op."; return 0; } local chart="$(yq eval '.spec.source.chart' $WORKDIR/kubezero/templates/${module}.yaml)" local namespace="$(yq eval '.spec.destination.namespace' $WORKDIR/kubezero/templates/${module}.yaml)" targetRevision="" _version="$(yq eval '.spec.source.targetRevision' $WORKDIR/kubezero/templates/${module}.yaml)" [ -n "$_version" ] && targetRevision="--version $_version" yq eval '.spec.source.helm.values' $WORKDIR/kubezero/templates/${module}.yaml > $WORKDIR/values.yaml echo "using values to $action of module $module: " cat $WORKDIR/values.yaml if [ $action == "crds" ]; then # Allow custom CRD handling declare -F ${module}-crds && ${module}-crds || _crds elif [ $action == "apply" ]; then # namespace must exist prior to apply create_ns $namespace # Optional pre hook declare -F ${module}-pre && ${module}-pre render kubectl $action -f $WORKDIR/helm.yaml --server-side --force-conflicts && rc=$? || rc=$? # Optional post hook declare -F ${module}-post && ${module}-post elif [ $action == "delete" ]; then render kubectl $action -f $WORKDIR/helm.yaml && rc=$? || rc=$? # Delete dedicated namespace if not kube-system [ -n "$DELETE_NS" ] && delete_ns $namespace fi return 0 }