KubeZero/charts/kubezero/bootstrap.sh

205 lines
5.8 KiB
Bash
Raw Normal View History

2020-11-03 12:51:57 +00:00
#!/bin/bash
set -ex
ACTION=$1
2020-12-01 15:46:04 +00:00
ARTIFACTS=($(echo $2 | tr "," "\n"))
2020-11-26 17:37:10 +00:00
CLUSTER=$3
2020-11-26 13:21:10 +00:00
LOCATION=${4:-""}
which yq || { echo "yq not found!"; exit 1; }
2020-12-03 10:04:08 +00:00
which helm || { echo "helm not found!"; exit 1; }
helm_version=$(helm version --short)
echo $helm_version | grep -qe "^v3.[5-9]" || { echo "Helm version >= 3.5 required!"; exit 1; }
# Simulate well-known CRDs being available
2021-09-28 14:12:23 +00:00
API_VERSIONS="-a monitoring.coreos.com/v1 -a snapshot.storage.k8s.io/v1"
KUBE_VERSION="--kube-version $(kubectl version -o json | jq -r .serverVersion.gitVersion)"
TMPDIR=$(mktemp -d kubezero.XXX)
[ -z "$DEBUG" ] && trap 'rm -rf $TMPDIR' ERR EXIT
2020-11-03 12:51:57 +00:00
# Waits for max 300s and retries
function wait_for() {
local TRIES=0
while true; do
eval " $@" && break
[ $TRIES -eq 100 ] && return 1
2020-11-03 12:51:57 +00:00
let TRIES=$TRIES+1
sleep 3
done
}
function chart_location() {
if [ -z "$LOCATION" ]; then
echo "$1 --repo https://cdn.zero-downtime.net/charts"
else
echo "$LOCATION/$1"
fi
}
# make sure namespace exists prior to calling helm as the create-namespace options doesn't work
function create_ns() {
local namespace=$1
if [ "$namespace" != "kube-system" ]; then
kubectl get ns $namespace || kubectl create ns $namespace
fi
}
2020-11-03 12:51:57 +00:00
# delete non kube-system ns
function delete_ns() {
local namespace=$1
[ "$namespace" != "kube-system" ] && kubectl delete ns $namespace
}
# Extract crds via helm calls and apply delta=crds only
function _crds() {
2021-11-11 13:53:23 +00:00
helm template $(chart_location $chart) -n $namespace --name-template $module $targetRevision --skip-crds --set ${module}.installCRDs=false -f $TMPDIR/values.yaml $API_VERSIONS $KUBE_VERSION > $TMPDIR/helm-no-crds.yaml
helm template $(chart_location $chart) -n $namespace --name-template $module $targetRevision --include-crds --set ${module}.installCRDs=true -f $TMPDIR/values.yaml $API_VERSIONS $KUBE_VERSION > $TMPDIR/helm-crds.yaml
diff -e $TMPDIR/helm-no-crds.yaml $TMPDIR/helm-crds.yaml | head -n-1 | tail -n+2 > $TMPDIR/crds.yaml
2021-11-11 13:53:23 +00:00
# Only apply if there are actually any crds
if [ -s $TMPDIR/crds.yaml ]; then
kubectl apply -f $TMPDIR/crds.yaml --server-side
2021-11-11 13:53:23 +00:00
fi
}
# helm template | kubectl apply -f -
# confine to one namespace if possible
function apply(){
helm template $(chart_location $chart) -n $namespace --name-template $module $targetRevision --skip-crds -f $TMPDIR/values.yaml $API_VERSIONS $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 > $TMPDIR/helm.yaml
kubectl $action -f $TMPDIR/helm.yaml && rc=$? || rc=$?
2020-11-03 12:51:57 +00:00
}
function _helm() {
local action=$1
2021-11-11 13:53:23 +00:00
local module=$2
local chart="kubezero-${module}"
2021-12-15 22:19:52 +00:00
local namespace="$(yq eval '.spec.destination.namespace' $TMPDIR/kubezero/templates/${module}.yaml)"
targetRevision=""
2021-12-15 22:19:52 +00:00
_version="$(yq eval '.spec.source.targetRevision' $TMPDIR/kubezero/templates/${module}.yaml)"
[ -n "$_version" ] && targetRevision="--version $_version"
2021-11-11 13:53:23 +00:00
2021-12-15 22:19:52 +00:00
yq eval '.spec.source.helm.values' $TMPDIR/kubezero/templates/${module}.yaml > $TMPDIR/values.yaml
if [ $action == "crds" ]; then
2021-11-11 13:53:23 +00:00
# Allow custom CRD handling
declare -F ${module}-crds && ${module}-crds || _crds
2020-12-01 15:46:04 +00:00
elif [ $action == "apply" ]; then
# namespace must exist prior to apply
2020-12-01 15:46:04 +00:00
create_ns $namespace
# Optional pre hook
2021-11-11 13:53:23 +00:00
declare -F ${module}-pre && ${module}-pre
apply
2020-11-03 12:51:57 +00:00
# Optional post hook
2021-11-11 13:53:23 +00:00
declare -F ${module}-post && ${module}-post
2020-12-01 15:46:04 +00:00
elif [ $action == "delete" ]; then
apply
# Delete dedicated namespace if not kube-system
2020-12-01 15:46:04 +00:00
delete_ns $namespace
fi
return 0
2020-11-03 12:51:57 +00:00
}
2020-11-03 12:51:57 +00:00
################
# cert-manager #
################
function cert-manager-post() {
# If any error occurs, wait for initial webhook deployment and try again
# see: https://cert-manager.io/docs/concepts/webhook/#webhook-connection-problems-shortly-after-cert-manager-installation
if [ $rc -ne 0 ]; then
wait_for "kubectl get deployment -n $namespace cert-manager-webhook"
kubectl rollout status deployment -n $namespace cert-manager-webhook
wait_for 'kubectl get validatingwebhookconfigurations -o yaml | grep "caBundle: LS0"'
apply
fi
wait_for "kubectl get ClusterIssuer -n $namespace kubezero-local-ca-issuer"
kubectl wait --timeout=180s --for=condition=Ready -n $namespace ClusterIssuer/kubezero-local-ca-issuer
}
2020-11-03 12:51:57 +00:00
###########
# ArgoCD #
###########
function argocd-pre() {
for f in $CLUSTER/secrets/argocd-*.yaml; do
kubectl apply -f $f
done
}
###########
# Metrics #
###########
# Cleanup patch jobs from previous runs , ArgoCD does this automatically
function metrics-pre() {
kubectl delete jobs --field-selector status.successful=1 -n monitoring
}
2021-11-11 13:53:23 +00:00
##########
## MAIN ##
2021-11-11 13:53:23 +00:00
##########
if [ ! -f $CLUSTER/kubezero/application.yaml ]; then
echo "Cannot find cluster config!"
exit 1
fi
2021-12-15 22:19:52 +00:00
KUBEZERO_VERSION=$(yq eval '.spec.source.targetRevision' $CLUSTER/kubezero/application.yaml)
2021-11-11 13:53:23 +00:00
# Extract all kubezero values from argo app
2021-12-15 22:19:52 +00:00
yq eval '.spec.source.helm.values' $CLUSTER/kubezero/application.yaml > $TMPDIR/values.yaml
2021-11-11 13:53:23 +00:00
# Render all enabled Kubezero modules
helm template $(chart_location kubezero) -f $TMPDIR/values.yaml --version $KUBEZERO_VERSION --devel --output-dir $TMPDIR
# Resolve all the all enabled artifacts
if [ ${ARTIFACTS[0]} == "all" ]; then
2021-11-11 13:53:23 +00:00
ARTIFACTS=($(ls $TMPDIR/kubezero/templates | sed -e 's/.yaml//g'))
fi
echo "Artifacts: ${ARTIFACTS[@]}"
2021-11-11 13:53:23 +00:00
if [ $1 == "apply" -o $1 == "crds" ]; then
for t in ${ARTIFACTS[@]}; do
2021-11-11 13:53:23 +00:00
_helm $1 $t || true
done
# Delete in reverse order, continue even if errors
elif [ $1 == "delete" ]; then
set +e
for (( idx=${#ARTIFACTS[@]}-1 ; idx>=0 ; idx-- )) ; do
2021-11-11 13:53:23 +00:00
_helm delete ${ARTIFACTS[idx]} || true
done
2020-11-03 12:51:57 +00:00
fi