version: '3' env: MINIKUBE_KUBE_VERSION: 1.31.0 ARGO_CHART_RELEASE_NAME: argo-cd ARGO_NAMESPACE: "argocd" CHART_DIR_PATH_INIT: "charts/init" CHART_DIR_PATH_ARGOCD: "charts/argocd" CHART_DIR_PATH_CNI: "charts/cilium" KUBESEAL_PRIVATE_KEY: "./private.key" KUBESEAL_PUBLIC_CERT: "./public.cert" CHARTS_DIR: "./charts" tasks: minikube: desc: "(Re-)Create minikube instance." cmds: - helm repo add cilium https://helm.cilium.io/ - helm repo update cilium - minikube delete #- minikube start --cni=false --kubernetes-version=${MINIKUBE_KUBE_VERSION} - minikube start --kubernetes-version=${MINIKUBE_KUBE_VERSION} # copy all supplied configs into minikube #- | # for file in $(ls ./configs/minikube/**); do # minikube cp $file /$file # done # - minikube cp ./configs/minikube/containerd/certs.d/* /etc/containerd/certs.d/. # - helm upgrade --install --create-namespace --namespace kube-system cilium cilium/cilium --set operator.replicas=1 #- helm upgrade --install --create-namespace --namespace traefik traefik traefik/traefik --set service.externalIPs={192.168.49.2} minikube-copy-system-configs: desc: "Copy system configs into minikube instance." cmds: - | for file in $(ls ./configs/minikube/**); do echo "Copying $file to minikube" # minikube cp $file /$file done argocd: desc: "(Re-)Install ArgoCD." cmds: - helm repo add argocd https://argoproj.github.io/argo-helm/ - helm repo update argocd - helm dependency update ${CHART_DIR_PATH_ARGOCD} - helm dependency build ${CHART_DIR_PATH_ARGOCD} - helm upgrade --install --create-namespace --namespace ${ARGO_NAMESPACE} ${ARGO_CHART_RELEASE_NAME} ${CHART_DIR_PATH_ARGOCD} argocd-late: desc: "(Re-)Install late stage ArgoCD resources like encrypted secrets from local chart." cmds: - helm upgrade --install --namespace ${ARGO_NAMESPACE} argocd-late charts/argocd-late argocd-forward: desc: "Kubectl port forward ArgoCD" cmds: - kubectl wait --timeout=600s --for=condition=Available=True -n ${ARGO_NAMESPACE} deployment ${ARGO_CHART_RELEASE_NAME}-argocd-server - echo Credentials user=${ARGO_USER} password=${ARGO_PASSWORD} - kubectl port-forward svc/${ARGO_CHART_RELEASE_NAME}-argocd-server -n ${ARGO_NAMESPACE} ${FORWARD_PORT}:443 vars: ARGO_USER: admin ARGO_PASSWORD: sh: kubectl get -n ${ARGO_NAMESPACE} secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d cni: desc: "(Re-)Install CNI helm chart to cluster" cmds: - helm dependency build ${CHART_DIR_PATH_CNI} - helm upgrade --install --create-namespace --namespace ${CNI_NAMESPACE} ${CNI_NAME} ${CHART_DIR_PATH_CNI} get-gpu-nodes: desc: "List GPU enabled nodes" cmds: - kubectl get nodes -o jsonpath='{.items[?(@.metadata.annotations.nfd\.node\.kubernetes\.io/extended-resources=="nvidia.com/gpu")].metadata.name}' rook-tools: desc: "Exec rook-tools container" cmds: - kubectl -n rook-ceph exec -it {{ .PODS }} -- ceph status - kubectl -n rook-ceph exec -it {{ .PODS }} -- bash vars: PODS: sh: kubectl -n rook-ceph get pod -l "app=rook-ceph-tools" -o jsonpath='{.items[*].metadata.name}' sealed-secrets: desc: "(Re-)Install sealed-secrets controller." cmds: - helm repo add bitnami https://charts.bitnami.com/bitnami - helm repo update bitnami - helm dependency update charts/sealed-secrets - helm dependency build charts/sealed-secrets - helm upgrade --install --create-namespace --namespace sealed-secrets sealed-secrets charts/sealed-secrets init: desc: "(Re-)Install GitOps initialisation chart to make ArgoCD watch infrastructure." cmds: - helm upgrade --install --create-namespace --namespace ${ARGO_NAMESPACE} --set="environment.revision=${REVISION}" init ${CHART_DIR_PATH_INIT} vars: REVISION: sh: git rev-parse --abbrev-ref HEAD seal: desc: "Kubeseal all *.unsealed.yaml secrets into and over adjacent *.sealed.yaml files." cmds: - task: generic-seal - task: env-specific-seal vars: ENV: "dev" - task: env-specific-seal vars: ENV: "stg" - task: env-specific-seal vars: ENV: "prd" env-specific-seal: desc: "Kubeseal environment specific secrets into and over adjacent *.sealed.yaml files." silent: true requires: vars: - ENV sources: - "{{ .CHARTS_DIR }}/**/*.{{ .ENV }}.unsealed.yaml" generates: - "{{ .CHARTS_DIR }}/**/*.{{ .ENV }}.sealed.yaml" cmds: - for: sources cmd: | echo "Sealing - {{ .ITEM }} with {{ .KUBESEAL_PUBLIC_CERT }}" condition='\{\{- if eq .Values.environment.mode "{{ .ENV }}" \}\}' outfile=$(sed -e 's/.unsealed.yaml/.sealed.yaml/' <<< "{{ .ITEM }}") if [ -s "{{ .ITEM }}" ]; then echo $condition > $outfile cat {{ .ITEM }} | kubeseal --cert {{ .KUBESEAL_PUBLIC_CERT }} -o yaml >> $outfile echo "\{\{- end \}\}" >> $outfile sed -i 's/\\{/{/g' $outfile sed -i 's/\\}/}/g' $outfile echo "Sealed - $outfile" else echo "WARNING: no content in {{ .ITEM }}. Skipping." fi method: none generic-seal: desc: "Kubeseal all *.unsealed.yaml secrets into and over adjacent *.sealed.yaml files." silent: true sources: - "{{ .CHARTS_DIR }}/**/*.unsealed.yaml" generates: - "{{ .CHARTS_DIR }}/**/*.sealed.yaml" cmds: - for: sources cmd: | echo "Sealing - {{ .ITEM }} with {{ .KUBESEAL_PUBLIC_CERT }}" OUTFILE=$(sed -e 's/.unsealed.yaml/.sealed.yaml/' <<< "{{ .ITEM }}") CONTENT=$(cat {{ .ITEM }} | sed '{{ "s/.*{{.*//" }}' | sed '{{ "s/---//" }}' ) if [ -s "{{ .ITEM }}" ]; then cat {{ .ITEM }} | kubeseal --cert {{ .KUBESEAL_PUBLIC_CERT }} -o yaml > $OUTFILE echo "Sealed - $OUTFILE" else echo "WARNING: no content in {{ .ITEM }}. Skipping." fi method: none unseal: desc: "Un-Kubeseal all *.sealed.yaml secrets into and over adjacent *.unsealed.yaml files." silent: true sources: - "{{ .CHARTS_DIR }}/**/*.sealed.yaml" generates: - "{{ .CHARTS_DIR }}/**/*.unsealed.yaml" cmds: - for: sources cmd: | echo "Unsealing - {{ .ITEM }} with {{ .KUBESEAL_PRIVATE_KEY }}" OUTFILE=$(sed -e 's/.sealed.yaml/.unsealed.yaml/' <<< "{{ .ITEM }}") CONTENT=$(cat {{ .ITEM }} | sed '{{ "s/.*{{.*//" }}' | sed '{{ "s/---//" }}' ) if [[ ! $( echo "${CONTENT}" | yq ' .spec.template.metadata.labels."secret.deepcypher.me/bas64only"') = 'true' ]]; then echo "Unsealing and base64 decoding - ${{ .ITEM }}" echo "${CONTENT}" | kubeseal --recovery-unseal --recovery-private-key {{ .KUBESEAL_PRIVATE_KEY }} -o yaml | yq '.data |= map_values(@base64d) | .stringData = .data | del(.data) | del(.metadata.ownerReferences)' > $OUTFILE else echo "Unsealing - ${{ .ITEM }}" echo "${CONTENT}" | kubeseal --recovery-unseal --recovery-private-key {{ .KUBESEAL_PRIVATE_KEY }} -o yaml > $OUTFILE echo "WARNING: secret is binary. Skipping base64 decode." fi echo "Unsealed - $OUTFILE" method: none crossplane-keycloak-reset: desc: "Remove crossplane keycloak-provider resources to reset the instance." silent: true cmds: - | for crd in $(kubectl get crds -o name | grep "keycloak\.crossplane\.io"); do kind=$(kubectl get "$crd" -o jsonpath='{.spec.names.plural}') group=$(kubectl get "$crd" -o jsonpath='{.spec.group}') # Skip specific kinds if [[ "$kind" =~ ^(providerconfigs|providerconfigusages|storeconfigs)$ ]]; then echo "Avoiding $group $kind..." continue fi echo "Selecting $group $kind ..." kubectl get "$kind.$group" -A --ignore-not-found echo "Removing $group $kind resources ..." kubectl delete "$kind.$group" --all -A --wait=false --ignore-not-found done rook-osds: desc: "Show OSD node drive information." silent: true cmds: - | # This uses the example/default cluster name "rook" OSD_PODS=$(kubectl get pods --all-namespaces -l \ app=rook-ceph-osd,rook_cluster=rook-ceph -o jsonpath='{.items[*].metadata.name}') # Find node and drive associations from OSD pods for pod in $(echo ${OSD_PODS}) do echo "Pod: ${pod}" echo "Node: $(kubectl -n rook-ceph get pod ${pod} -o jsonpath='{.spec.nodeName}')" kubectl -n rook-ceph exec ${pod} -c osd -- sh -c '\ for i in /var/lib/ceph/osd/ceph-*; do [ -f ${i}/ready ] || continue echo -ne "-$(basename ${i}) " echo $(lsblk -n -o NAME,SIZE ${i}/block 2> /dev/null || \ findmnt -n -v -o SOURCE,SIZE -T ${i}) $(cat ${i}/type) done | sort -V echo' done list-gpu-pods: desc: "List all pods requesting GPU resources." silent: true cmds: - | kubectl get pods --all-namespaces -o json | jq -r '.items[] | select(.spec.containers[].resources.requests."nvidia.com/gpu" != null) | "\(.metadata.namespace)/\(.metadata.name): \(.spec.containers[].resources.requests."nvidia.com/gpu") GPU"'