#!/usr/bin/env bash set -e help-table() { local -a rows local max_cmd=7 max_opt=6 max_desc=11 rows+=("Command|Option|Description") rows+=("===ENV===| | ") rows+=("version||Show version of required tools.") rows+=("info||Show info about env.") rows+=("template-dotenv||Generate .env from .env.template.") rows+=("export-kubeconfig|[user][path]|Export kubeconfig file for service account.") rows+=("generate-kubconfig|[name]|Generate kubeconfig for deploymentUpdater.") rows+=("load-kubeconfig-from-keepass|[ctx]|Load kubeconfig file from KeePass.") rows+=("save-kubeconfig-to-keepass|[ctx]|Save kubeconfig file in KeePass.") rows+=("===DOCS===| | ") rows+=("install-vitepress||Install Node dependencies.") rows+=("docs||Generate Helm chart readmes.") rows+=("lint||Lint Helm charts.") rows+=("dev-vitepress||Start VitePress dev server.") rows+=("build-vitepress||Build site with VitePress.") rows+=("serve-vitepress||Serve VitePress build.") rows+=("===HOST===| | ") rows+=("start||Start kind Kubernetes cluster.") rows+=("start-and-prepare||Start and prepare Kubernetes cluster.") rows+=("load-image|[tag]|Load Docker image into kind cluster.") rows+=("delete-kind||Delete kind Kubernetes cluster.") rows+=("setup-hosts||Update hosts file.") rows+=("forward|[chart]|Forward port.") rows+=("===CHART===| | ") rows+=("list-charts||List local Helm charts.") rows+=("list-external-charts||List external Helm charts.") rows+=("list-cluster||List clusters.") rows+=("list-deployment||List deployments.") rows+=("list-context||List kubeconfig files.") rows+=("switch-context||Switch kubeconfig file.") rows+=("get-context||Show active kubeconfig.") rows+=("get-cluster||Show active cluster.") rows+=("update-dependencies|[chart]|Update dependencies for a chart.") rows+=("install-chart|[chart][values]|Install Helm chart.") rows+=("upgrade-release|[chart][values]|Upgrade Helm release.") rows+=("uninstall-release|[release]|Uninstall Helm release.") rows+=("===KUBECTL===| | ") rows+=("show-secrets|[chart]|Show secrets for chart.") rows+=("exec-bash|[chart]|Open bash shell in container.") rows+=("logs|[grep]|Select pods with grep and show logs.") rows+=("list||List Helm deployments.") rows+=("get-pods||List all pods.") rows+=("get-namespace||Show active namespace.") rows+=("login-oc||Refresh the auth token for OpenShift.") rows+=("run-job|[name]|Make a copy of job.") rows+=("===HELM===| | ") rows+=("add-repos||Add the required Helm repos.") rows+=("template-manifest|[chart][values]|Template all charts with Helm.") rows+=("package-repo|[chart]|Package Helm charts.") rows+=("index-repo||Index Helm chart.") rows+=("remove-repo||Remove the kubernetes-build repo.") rows+=("commit||Commit .tgz files.") rows+=("===LLM===| | ") rows+=("commit-with-llm||Commit with llm generated commit message.") rows+=("update-with-llm|[glob][prompt]|Feed files matching glob to LLM and apply changes.") rows+=("===TEST===| | ") rows+=("test-chart-clusterIssuer||Test cluster issuer.") rows+=("test-chart-odoo|[cleanup]|Setup Odoo chart and dependencies.") rows+=("test-chart-nextcloud|[cleanup]|Setup Nextcloud chart and dependencies.") for row in "${rows[@]}"; do IFS='|' read -r cmd opt desc <<< "$row" (( ${#cmd} > max_cmd )) && max_cmd=${#cmd} (( ${#opt} > max_opt )) && max_opt=${#opt} (( ${#desc} > max_desc )) && max_desc=${#desc} done printf '| %-*s | %-*s | %-*s |\n' \ "$max_cmd" "Command" \ "$max_opt" "Option" \ "$max_desc" "Description" printf '|-%*s-|-%*s-|-%*s-|\n' \ "$max_cmd" "$(printf '%*s' "$max_cmd" '' | tr ' ' '-')" \ "$max_opt" "$(printf '%*s' "$max_opt" '' | tr ' ' '-')" \ "$max_desc" "$(printf '%*s' "$max_desc" '' | tr ' ' '-')" local first_row=true for row in "${rows[@]:1}"; do IFS='|' read -r cmd opt desc <<< "$row" if [[ "$cmd" =~ ^===.*===$ ]]; then group_name="${cmd/===/}" group_name="${group_name/===/}" if [ "$first_row" = true ]; then first_row=false else printf '|-%*s-|-%*s-|-%*s-|\n' \ "$max_cmd" "$(printf '%*s' "$max_cmd" '' | tr ' ' '-')" \ "$max_opt" "$(printf '%*s' "$max_opt" '' | tr ' ' '-')" \ "$max_desc" "$(printf '%*s' "$max_desc" '' | tr ' ' '-')" fi local left_pad=$(( (max_cmd - ${#group_name}) / 2 )) local right_pad=$(( max_cmd - left_pad - ${#group_name} )) printf '| %*s%s%*s | %*s | %*s |\n' \ "$left_pad" "" \ "$group_name" \ "$right_pad" "" \ "$max_opt" "" \ "$max_desc" "" printf '|-%*s-|-%*s-|-%*s-|\n' \ "$max_cmd" "$(printf '%*s' "$max_cmd" '' | tr ' ' '-')" \ "$max_opt" "$(printf '%*s' "$max_opt" '' | tr ' ' '-')" \ "$max_desc" "$(printf '%*s' "$max_desc" '' | tr ' ' '-')" else first_row=false printf '| %-*s | %-*s | %-*s |\n' \ "$max_cmd" "$cmd" \ "$max_opt" "$opt" \ "$max_desc" "$desc" fi done } help() { echo if [[ -n "$1" ]]; then help-table | grep -i "$1" | column -t -s'|' else echo 'task [options]' echo echo 'commands:' echo help-table fi echo } # Default vars OC_PROJECT=${OC_PROJECT:="odoo"} CONTAINER_REGISTRY=${CONTAINER_REGISTRY:="mintsystem/"} CONTAINER_CONFIG="$HOME/.docker/$CONTAINER_REGISTRY" # Dynamic vars pass_entry=$(echo "env/${PWD##*/}" | tr '[:upper:]' '[:lower:]') keepass_entry=$(echo "env/${PWD##*/}" | tr '[:upper:]' '[:lower:]') get-namespace() { if kubectl-ctx &> /dev/null; then echo $(kubectl-ns -c 2> /dev/null) fi } namespace="$(get-namespace)" get-context() { local alias="$(basename "$(readlink "$HOME/.kube/config" 2>/dev/null)" 2>/dev/null | cut -d '.' -f 2)" echo "${alias:-loc}" } context_alias="$(get-context)" # Import commands clone-taskfile(){ if [[ ! -d "$HOME/taskfile.build" ]]; then echo -e "\033[38;5;214mGit\033[0m: Clone taskfile repo" git clone https://git.taskfile.build "$HOME/taskfile.build" else echo -e "\033[38;5;214mGit\033[0m: Pull taskfile repo" git -C "$HOME/taskfile.build" pull fi } if [[ -d "$HOME/taskfile.build/bin" ]]; then for file in "$HOME/taskfile.build/bin/"*; do if [[ -f "$file" ]]; then source "$file" fi done fi # Env Commands version() { kind version helm version } info() { echo "OpenShift-Project: $OC_PROJECT" echo "Context-Alias: $(get-context)" echo "Namespace: $namespace" } install-vitepress() { pnpm install } setup-hosts() { echo 'Adding entries to /etc/hosts ...' # Cluster grep -qxF '127.0.0.1 knd.local' /etc/hosts || echo '127.0.0.1 knd.local' | sudo tee -a /etc/hosts > /dev/null # Odoo grep -qxF '127.0.0.1 odoo.local' /etc/hosts || echo '127.0.0.1 odoo.local' | sudo tee -a /etc/hosts > /dev/null grep -qxF '127.0.0.1 odoo.knd.local' /etc/hosts || echo '127.0.0.1 odoo.knd.local' | sudo tee -a /etc/hosts > /dev/null grep -qxF '127.0.0.1 staging.odoo.knd.local' /etc/hosts || echo '127.0.0.1 staging.odoo.knd.local' | sudo tee -a /etc/hosts > /dev/null # Odoo with different namespace grep -qxF '127.0.0.1 restic.local' /etc/hosts || echo '127.0.0.1 restic.local' | sudo tee -a /etc/hosts > /dev/null grep -qxF '127.0.0.1 restic.knd.local' /etc/hosts || echo '127.0.0.1 restic.knd.local' | sudo tee -a /etc/hosts > /dev/null grep -qxF '127.0.0.1 staging.restic.knd.local' /etc/hosts || echo '127.0.0.1 staging.restic.knd.local' | sudo tee -a /etc/hosts > /dev/null # Nextcloud grep -qxF '127.0.0.1 nextcloud.local' /etc/hosts || echo '127.0.0.1 nextcloud.local' | sudo tee -a /etc/hosts > /dev/null grep -qxF '127.0.0.1 nextcloud.knd.local' /etc/hosts || echo '127.0.0.1 nextcloud.knd.local' | sudo tee -a /etc/hosts > /dev/null # Collabora grep -qxF '127.0.0.1 doc.nextcloud.knd.local' /etc/hosts || echo '127.0.0.1 doc.nextcloud.knd.local' | sudo tee -a /etc/hosts > /dev/null # Hugo grep -qxF '127.0.0.1 hugo.knd.local' /etc/hosts || echo '127.0.0.1 hugo.knd.local' | sudo tee -a /etc/hosts > /dev/null # Vuepress grep -qxF '127.0.0.1 vuepress.knd.local' /etc/hosts || echo '127.0.0.1 vuepress.knd.local' | sudo tee -a /etc/hosts > /dev/null } test-chart-odoo() { if [[ "$1" = 'cleanup' ]]; then echo 'Cleanup environment' delete-kind else start-and-prepare update-dependencies odoo install-chart odoo test_values/odoo.knd.local.yaml kubectl wait --for=condition=Available --timeout=300s deployments/odoo-odoo fi } test-chart-nextcloud() { if [[ "$1" = 'cleanup' ]]; then echo 'Cleanup environment' delete-kind else start add-repos info # install-chart haproxy-ingress # kubectl wait --namespace haproxy-ingress --for=condition=Available --timeout=60s deployments/haproxy-ingress install-chart traefik kubectl wait --namespace traefik --for=condition=Available --timeout=60s deployments/traefik install-chart cnpg kubectl wait --namespace cnpg-system --for=condition=Available --timeout=60s deployments/cnpg-cloudnative-pg kubectl create secret generic nextcloud-creds --from-literal=NEXTCLOUD_ADMIN_USER="test" --from-literal=NEXTCLOUD_ADMIN_PASSWORD="test" install-chart nextcloud test_values/nextcloud.knd.local.yaml fi } export-kubeconfig() { if test -z "$1"; then echo '\$1 is empty.'; exit; fi if test -z "$2"; then echo '\$2 is empty.'; exit; fi local kube_user=$1 local kube_output_file=$2 kubectl config set-cluster default --server=https://k3s.raspberrypi.build --kubeconfig=$kube_output_file kubectl config set-context default --cluster=default --user=$kube_user --kubeconfig=$kube_output_file kubectl config set-credentials "$kube_user" --token=$(kubectl create token $kube_user --duration=87600h) --kubeconfig=$kube_output_file kubectl config use-context default --kubeconfig=$kube_output_file echo "Kubeconfig exported for user $kube_user to file $kube_output_file" } generate-kubconfig() { if test -z "$1"; then echo '\$1 is empty.'; exit; fi local name="$1" local cluster=$(get-cluster) local kubeconfig_file="values/.kube/config.${cluster}-${name}" local secret_name="${name}-sa-token" local server=$(kubectl config view --minify --output 'jsonpath={.clusters[0].cluster.server}') local ca=$(kubectl get secret/$secret_name -o jsonpath='{.data.ca\.crt}') local token=$(kubectl get secret/$secret_name -o jsonpath='{.data.token}' | base64 --decode) local namespace=$(kubectl get secret/$secret_name -o jsonpath='{.data.namespace}' | base64 --decode) echo "apiVersion: v1 kind: Config clusters: - name: default-cluster cluster: certificate-authority-data: ${ca} server: ${server} contexts: - name: default-context context: cluster: default-cluster namespace: ${namespace} user: default-user current-context: default-context users: - name: default-user user: token: ${token}" > "$kubeconfig_file" echo "Kubeconfig generated for $name at $kubeconfig_file" } # Host Commands start() { if [[ "$context_alias" != "loc" ]]; then echo "Current context alias is '$context_alias' and not 'loc'." exit 1 fi echo 'Start kind.' kind create cluster } start-and-prepare() { start add-repos info # install-chart haproxy-ingress # kubectl wait --namespace haproxy-ingress --for=condition=Available --timeout=60s deployments/haproxy-ingress echo "Install traefik." install-chart traefik kubectl wait --namespace traefik --for=condition=Available --timeout=60s deployments/traefik echo "Install the CloudNativePG." install-chart cnpg kubectl wait --namespace cnpg-system --for=condition=Available --timeout=60s deployments/cnpg-cloudnative-pg echo "Install k8up." install-chart k8up #FIXME: This does not work in GitHub runner env. echo "Load Odoo image." docker pull mintsystem/odoo:19.0.20260630 load-image mintsystem/odoo:19.0.20260630 } load-image() { if test -z "$1"; then echo '\$1 is empty.'; exit; fi if kind &> /dev/null && kind get clusters | grep -q 'kind'; then echo 'Kind cluster is available. Checking for local Docker images...' if docker images -q "$1" > /dev/null; then echo 'Loading local Odoo image into Kind cluster...' kind load docker-image "$1" fi fi } delete-kind() { echo 'Delete kind.' kind delete cluster } forward() { if test -z "$1"; then echo '\$1 is empty.'; exit; fi "forward-$1" } forward-postgres() { local port=5432 echo "Connect to http://localhost:$port url in your browser." kubectl port-forward service/postgres $port:5432 } forward-odoo() { local port=8080 echo "Open http://localhost:$port url in your browser." kubectl port-forward service/odoo $port:8069 } forward-odoo-staging() { local port=8080 echo "Open http://localhost:$port url in your browser." kubectl port-forward service/odoo-staging $port:8069 } forward-nextcloud() { local port=8080 echo "Open http://localhost:$port url in your browser." kubectl port-forward service/nextcloud $port:8080 } forward-haproxy-ingress() { local port=8080 kubectl get ingresses echo "Open http://\$namespace.knd.local:$port url in your browser." kubectl port-forward -n haproxy-ingress svc/haproxy-ingress $port:80 } forward-ingress-nginx() { local port=8080 kubectl get ingresses echo "Open http://\$namespace.knd.local:$port url in your browser." kubectl port-forward -n ingress-nginx svc/ingress-nginx $port:80 } forward-prometheusagent() { local port=9090 echo "Connect to http://localhost:$port to access the Prometheus agent." kubectl port-forward -n prometheus deployment/prometheus-agent $port:9090 } forward-traefik() { local port=8080 kubectl get ingresses echo "Open http://\$namespace.knd.local:$port url in your browser." kubectl port-forward -n traefik svc/traefik $port:80 } # Chart Commands list-charts() { for dir in */; do dir_name="${dir%/}" if [ -f "$dir/Chart.yaml" ]; then echo "$dir_name" fi done } list-external-charts() { echo 'cert-manager' echo 'cnpg' echo 'haproxy-ingress' echo 'k8up' echo 'traefik' } list-cluster() { local -a rows local max_name=4 max_alias=5 max_base=4 for file in $(grep -l "^kind: cluster$" values/*.yaml 2>/dev/null); do local name=$(yq eval '.name' "$file" 2>/dev/null) local alias=$(yq eval '.alias' "$file" 2>/dev/null) local base=$(basename "$file" .yaml) [[ -z "$name" ]] && name="(not set)" [[ -z "$alias" ]] && alias="(not set)" rows+=("$name|$alias|$base") (( ${#name} > max_name )) && max_name=${#name} (( ${#alias} > max_alias )) && max_alias=${#alias} (( ${#base} > max_base )) && max_base=${#base} done [[ ${#rows[@]} -eq 0 ]] && { echo "No cluster files found." return } printf '| %-*s | %-*s | %-*s |\n' \ "$max_name" "Name" \ "$max_alias" "Alias" \ "$max_base" "Cname" printf '|-%*s-|-%*s-|-%*s-|\n' \ "$max_name" "$(printf '%*s' "$max_name" '' | tr ' ' '-')" \ "$max_alias" "$(printf '%*s' "$max_alias" '' | tr ' ' '-')" \ "$max_base" "$(printf '%*s' "$max_base" '' | tr ' ' '-')" printf '%s\n' "${rows[@]}" | sort | while IFS='|' read -r name alias base; do printf '| %-*s | %-*s | %-*s |\n' \ "$max_name" "$name" \ "$max_alias" "$alias" \ "$max_base" "$base" done } list-deployment() { local -a rows local max_namespace=9 max_cluster=7 max_chart=5 for file in $(grep -l "^kind: deployment$" values/*.yaml 2>/dev/null); do local base=$(basename "$file" .yaml) local namespace="${base%%.*}" local cluster="${base#*.}" local chart=$(yq eval '.chart' "$file" 2>/dev/null) [[ "${chart}" == "null" ]] && chart="" rows+=("$namespace|$cluster|$chart") (( ${#namespace} > max_namespace )) && max_namespace=${#namespace} (( ${#cluster} > max_cluster )) && max_cluster=${#cluster} (( ${#chart} > max_chart )) && max_chart=${#chart} done [[ ${#rows[@]} -eq 0 ]] && { echo "No deployment files found." return } printf '| %-*s | %-*s | %-*s |\n' \ "$max_namespace" "Namespace" \ "$max_cluster" "Cluster" \ "$max_chart" "Chart" printf '|-%*s-|-%*s-|-%*s-|\n' \ "$max_namespace" "$(printf '%*s' "$max_namespace" '' | tr ' ' '-')" \ "$max_cluster" "$(printf '%*s' "$max_cluster" '' | tr ' ' '-')" \ "$max_chart" "$(printf '%*s' "$max_chart" '' | tr ' ' '-')" printf '%s\n' "${rows[@]}" | sort | while IFS='|' read -r namespace cluster chart; do printf '| %-*s | %-*s | %-*s |\n' \ "$max_namespace" "$namespace" \ "$max_cluster" "$cluster" \ "$max_chart" "$chart" done } list-context() { local -a rows local max_name=4 max_path=4 for file in values/.kube/config.*; do [[ ! -f "$file" ]] && continue local name=$(basename "$file" | sed 's/^config\.//') rows+=("$name|$file") (( ${#name} > max_name )) && max_name=${#name} (( ${#file} > max_path )) && max_path=${#file} done [[ ${#rows[@]} -eq 0 ]] && { echo "No context files found in values/.kube/config.*" return } printf '| %-*s | %-*s |\n' \ "$max_name" "Name" \ "$max_path" "Path" printf '|-%*s-|-%*s-|\n' \ "$max_name" "$(printf '%*s' "$max_name" '' | tr ' ' '-')" \ "$max_path" "$(printf '%*s' "$max_path" '' | tr ' ' '-')" printf '%s\n' "${rows[@]}" | sort | while IFS='|' read -r name path; do printf '| %-*s | %-*s |\n' \ "$max_name" "$name" \ "$max_path" "$path" done } switch-context() { if test -z "$1"; then echo '\$1 is empty.'; exit; fi local link_name="$HOME/.kube/config" local target="$PWD/values/.kube/config.$1" if [[ ! -f "$target" ]]; then echo "Error: Target config file '$target' does not exist." >&2 return 1 fi echo "Remove $link_name" rm "$link_name" || true echo "Setup symlink from $link_name to $target" touch "$target" ln -s "$target" "$link_name" chmod 0644 "$target" echo 'Select namespace' kubectl-ns } get-cluster() { basename "$(readlink "$HOME/.kube/config")" | cut -d. -f2 | cut -d- -f1 } update-dependencies() { if test -z "$1"; then echo '\$1 is empty.'; exit; fi helm dependency update "$1" } install-chart() { if test -z "$1"; then echo '\$1 is empty.'; exit; fi if [[ "$(get-context)" = 'axo' ]]; then echo "Set oc project to $OC_PROJECT." oc project "$OC_PROJECT" fi local release_name="$(echo "$1" | tr '[:upper:]' '[:lower:]')" if [[ "$1" = 'clusterIssuer' ]]; then "install-$1" "$2" elif list-charts | grep -q "$1"; then echo "Install chart $1 as release $release_name:" helm install "$release_name" "$1" \ --values "$2" else "install-$1" "$2" fi } install-cnpg() { echo 'Install cnpg/cloudnative-pg.' helm upgrade --install cnpg \ --namespace cnpg-system \ --create-namespace \ cnpg/cloudnative-pg } install-k8up() { echo 'Install k8up-io/k8up.' helm install k8up k8up-io/k8up \ --create-namespace --namespace k8up } install-cert-manager() { echo 'Install jetstack/cert-manager.' helm install \ cert-manager jetstack/cert-manager \ --namespace cert-manager \ --create-namespace \ --version v1.18.2 \ --set crds.enabled=true \ --set config.featureGates.ACMEHTTP01IngressPathTypeExact=false # https://github.com/Infomaniak/cert-manager-webhook-infomaniak echo 'Apply Infomaniak webhook' kubectl apply -f https://github.com/Infomaniak/cert-manager-webhook-infomaniak/releases/download/v0.3.1/rendered-manifest.yaml } install-clusterIssuer() { echo 'Install clusterissuer.' helm install clusterissuer clusterIssuer \ --namespace cert-manager \ --values "$1" } install-haproxy-ingress() { echo 'Install haproxy-ingress/haproxy-ingress.' helm install haproxy-ingress haproxy-ingress/haproxy-ingress \ --create-namespace --namespace haproxy-ingress } install-ingress-nginx() { echo 'Install ingress-nginx/ingress-nginx.' helm install ingress-nginx ingress-nginx/ingress-nginx \ --create-namespace --namespace ingress-nginx } install-traefik() { echo 'Install traefik/traefik.' helm install traefik traefik/traefik \ --create-namespace --namespace traefik } upgrade-release() { if test -z "$1"; then echo '\$1 is empty.'; exit; fi local release_name="$(echo "$1" | tr '[:upper:]' '[:lower:]')" if list-charts | grep -q "$1"; then echo "Upgrade $1 chart for release $release_name:" helm upgrade "$release_name" "$1" \ --values "$2" else "upgrade-$1" "$2" fi } upgrade-cert-manager() { echo 'Upgrade jetstack/cert-manager.' helm upgrade \ cert-manager jetstack/cert-manager \ --namespace cert-manager \ --version v1.18.2 \ --set crds.enabled=true \ --set config.featureGates.ACMEHTTP01IngressPathTypeExact=false # https://github.com/Infomaniak/cert-manager-webhook-infomaniak echo 'Apply Infomaniak webhook' kubectl apply -f https://github.com/Infomaniak/cert-manager-webhook-infomaniak/releases/download/v0.3.1/rendered-manifest.yaml } upgrade-clusterIssuer() { echo 'Upgrade clusterIssuer.' helm upgrade \ clusterissuer clusterIssuer \ --namespace cert-manager \ --values "$2" } uninstall-release() { if test -z "$1"; then echo '\$1 is empty.'; exit; fi local release_name="$(echo "$1" | tr '[:upper:]' '[:lower:]')" echo "Uninstall release $release_name:" case "$release_name" in "ingress-nginx") uninstall-ingress-nginx ;; *) helm uninstall "$release_name" ;; esac } uninstall-ingress-nginx() { echo 'Uninstall ingress-nginx release.' helm uninstall ingress-nginx --namespace ingress-nginx } run-job() { if test -z "$1"; then echo '\$1 is empty.'; exit 1; fi local job_name="$1" echo "Run job: $job_name" kubectl delete job ${job_name}-run --ignore-not-found kubectl create job --from=cronjob/${job_name} ${job_name}-run } # kubectl Commands show-secrets() { if test -z "$1"; then echo '\$1/chart is empty.'; exit; fi if [[ "$1" = 'postgres' ]]; then echo 'postgres/user:' kubectl get secret postgres -o jsonpath="{.data.user}" | base64 --decode && echo echo 'postgres/password:' kubectl get secret postgres -o jsonpath="{.data.password}" | base64 --decode && echo elif [[ "$1" = 'clusterIssuer' ]]; then echo 'cert-manager/infomaniak-api-credentials:' kubectl get secret -n cert-manager infomaniak-api-token -o jsonpath="{.data.access-token}" | base64 --decode && echo elif [[ "$1" = 'forgejoRunner' ]]; then echo 'forgejo-runner/forgejoInstanceToken:' kubectl get secret forgejo-runner -o jsonpath="{.data.forgejoInstanceToken}" | base64 --decode && echo elif [[ "$1" = 'nextcloud' ]]; then echo 'nextcloud/creds:' kubectl get secret nextcloud-creds -o jsonpath="{.data.nextcloud-username}" | base64 --decode && echo echo 'nextcloud/password:' kubectl get secret nextcloud-creds -o jsonpath="{.data.nextcloud-password}" | base64 --decode && echo echo 'nextcloud-postgresql-app:username:' kubectl get secret nextcloud-postgresql-app -o jsonpath="{.data.username}" | base64 --decode && echo echo 'nextcloud-postgresql-app:password:' kubectl get secret nextcloud-postgresql-app -o jsonpath="{.data.password}" | base64 --decode && echo fi } exec-bash() { if test -z "$1"; then echo '\$1 is empty.'; exit; fi kubectl exec -it "$1" -- bash } logs() { local pod_id=$(kubectl get pods -o=name --all-namespaces | grep "$1") kubectl logs "$pod_id" } get-pods() { kubectl get pods } logs-haproxy-ingress() { local pod_id=$(kubectl get pods -o=name -n haproxy-ingress | grep 'haproxy-ingress') kubectl logs "$pod_id" -n haproxy-ingress } # Helm Commands template-manifest() { if test -z "$1"; then echo '\$1 is empty.'; exit; fi if test -z "$2"; then echo '\$2 is empty.'; exit; fi local release_name="$(echo "$1" | tr '[:upper:]' '[:lower:]')" # echo "Template chart $1 as release ${release_name}..." if [[ "$1" = 'clusterIssuer' ]]; then helm --debug template "$release_name" clusterIssuer \ --namespace cert-manager \ --values "$2" > manifest.yaml elif list-charts | grep -q "$1"; then helm --debug template "$release_name" "$1" \ --values "$2" fi } list() { helm list } package-repo() { if [[ -n "$1" ]]; then echo "Package $1 Helm chart." helm package "$1" else echo 'Package all Helm charts.' update-dependencies odoo update-dependencies prometheusAgent index-repo for chart in $(list-charts); do helm package "$chart" done fi } commit() { git config user.name 'Mint Bot' git config user.email 'bot@mint-system.ch' git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@github.com/Mint-System/Kubernetes-Build" git add *.tgz git commit -m 'feat(helm): package revision update' git push || echo 'No changes to commit' } index-repo() { echo 'Update index.yaml' helm repo index . } add-repos(){ echo 'Add kubernetes-build.' helm repo add kubernetes-build https://kubernetes.build echo 'Add haproxy-ingress.' helm repo add haproxy-ingress https://haproxy-ingress.github.io/charts echo 'Add jetstack.' helm repo add jetstack https://charts.jetstack.io echo 'Add cnpg.' helm repo add cnpg https://cloudnative-pg.github.io/charts echo 'Add k8up.' helm repo add k8up-io https://k8up-io.github.io/k8up echo 'Add traefik.' helm repo add traefik https://helm.traefik.io/traefik } remove-repo(){ echo 'Remove the kubernetes-build repo.' helm repo remove kubernetes-build } # Docs Commands docs() { for repo in $(list-charts | grep -v '^deploymentUpdater$'); do pnpm run generate-readme --values "$repo/values.yaml" -r "$repo/README.md" done } lint() { for chart in $(list-charts); do helm lint "$chart" done } dev-vitepress() { cp README.md index.md pnpm run docs:dev } build-vitepress() { cp README.md index.md pnpm run docs:build cp *.tgz .vitepress/dist cp index.yaml .vitepress/dist } serve-vitepress() { pnpm run docs:preview } if [[ "$1" == *","* ]]; then # Split comma-separated commands IFS=',' read -ra COMMANDS <<< "$1" for cmd in "${COMMANDS[@]}"; do # Trim whitespace cmd=$(echo "$cmd" | xargs) if declare -f "$cmd" > /dev/null; then "$cmd" else echo "Unknown command: $1" help "$@" exit 1 fi done elif declare -f "$1" > /dev/null; then "$1" "${@:2}" else case "$1" in *) echo "Unknown command: $1" help exit 1 ;; esac fi