From d217f117fcdfddfb311d4db00ef534c3d01560d7 Mon Sep 17 00:00:00 2001 From: 0xFEEDC0DE64 Date: Mon, 19 Oct 2026 08:05:52 +0200 Subject: [PATCH] Retire cert-manager direct deployment repository --- .gitea/workflows/deploy.yml | 51 --------------------- README.md | 20 ++++----- certificates.yaml | 60 ------------------------- ci-deployer.yaml | 46 ------------------- cloudflare-api-credentials.yaml.example | 8 ---- cloudflare.yaml | 17 ------- create-ci-kubeconfig.sh | 26 ----------- http-issuer.yaml | 14 ------ install.sh | 45 ------------------- test.sh | 14 ------ values.yaml | 6 --- 11 files changed, 10 insertions(+), 297 deletions(-) delete mode 100644 .gitea/workflows/deploy.yml delete mode 100644 certificates.yaml delete mode 100644 ci-deployer.yaml delete mode 100644 cloudflare-api-credentials.yaml.example delete mode 100644 cloudflare.yaml delete mode 100755 create-ci-kubeconfig.sh delete mode 100644 http-issuer.yaml delete mode 100755 install.sh delete mode 100755 test.sh delete mode 100644 values.yaml diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml deleted file mode 100644 index 3b3a194..0000000 --- a/.gitea/workflows/deploy.yml +++ /dev/null @@ -1,51 +0,0 @@ -name: Validate and deploy cert-manager configuration -on: [push, pull_request] -env: - KUBECTL_VERSION: v1.36.3 - KUBERNETES_API: https://host.containers.internal:6443 - KUBERNETES_TLS_SERVER_NAME: 192.168.0.2 -jobs: - validate: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - run: bash test.sh - deploy: - if: gitea.ref == 'refs/heads/main' - needs: validate - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Install kubectl - run: | - curl -fsSL -o "${RUNNER_TEMP}/kubectl" "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/amd64/kubectl" - chmod 0700 "${RUNNER_TEMP}/kubectl" - - name: Configure Kubernetes access - env: - KUBE_CONFIG_BASE64: ${{ secrets.KUBE_CONFIG_BASE64 }} - run: | - test -n "${KUBE_CONFIG_BASE64}" - printf '%s' "${KUBE_CONFIG_BASE64}" | base64 -d > "${RUNNER_TEMP}/kubeconfig" - chmod 0600 "${RUNNER_TEMP}/kubeconfig" - export KUBECONFIG="${RUNNER_TEMP}/kubeconfig" - "${RUNNER_TEMP}/kubectl" config set-cluster cluster --server="${KUBERNETES_API}" --tls-server-name="${KUBERNETES_TLS_SERVER_NAME}" - - name: Apply and verify - run: | - export KUBECONFIG="${RUNNER_TEMP}/kubeconfig" - for file in cloudflare.yaml http-issuer.yaml certificates.yaml; do - "${RUNNER_TEMP}/kubectl" apply --server-side --force-conflicts --dry-run=server -f "$file" - done - for file in cloudflare.yaml http-issuer.yaml certificates.yaml; do - "${RUNNER_TEMP}/kubectl" apply --server-side --force-conflicts -f "$file" - done - for issuer in letsencrypt-dns letsencrypt-http; do - for attempt in {1..60}; do - ready=$("${RUNNER_TEMP}/kubectl" get clusterissuer "$issuer" -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}') - [[ "$ready" == True ]] && break - [[ "$attempt" != 60 ]] || exit 1 - sleep 5 - done - done - for certificate in brunner-ninja watschn-studio brgkepler-com gschissenes-equipment; do - test "$("${RUNNER_TEMP}/kubectl" -n default get certificate "$certificate" -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}')" = True - done diff --git a/README.md b/README.md index d2c08fe..4cf3420 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ -# cert-manager on Kubernetes +# Archived cert-manager deployment repository -The operator is pinned to chart/app `v1.21.1` and remains an administrator -upgrade because it owns CRDs, admission webhooks, and cluster-wide RBAC. Gitea -Actions validates and deploys only the two exact ClusterIssuers and four exact -Certificates; it cannot read Secrets, create/delete resources, or modify the -operator. +This legacy repository is archived and is no longer a deployment source. Argo +CD in [`homelab-gitops`](https://code.brunner.ninja/feedc0de/homelab-gitops/src/branch/main/apps/cert-manager) +is the sole owner of the Jetstack cert-manager chart, homelab ClusterIssuers, +and centrally managed Certificates. -`cloudflare-api-credentials.yaml` is intentionally ignored. Copy the `.example`, -insert the existing token, and run `./install.sh`; when the file is absent the -installer preserves the existing live Secret. Run `./create-ci-kubeconfig.sh` -once and save only its final line as repository secret `KUBE_CONFIG_BASE64`. +The former direct Gitea Actions deploy workflow and its Kubernetes deployer +credentials/RBAC have been retired. Do not use historical manifests or scripts +from this repository to change the live cluster. Make normal changes in +`homelab-gitops`; use the documented Argo CD bootstrap/recovery procedure only +if Argo itself is unavailable. diff --git a/certificates.yaml b/certificates.yaml deleted file mode 100644 index 0c6516c..0000000 --- a/certificates.yaml +++ /dev/null @@ -1,60 +0,0 @@ -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - name: brunner-ninja - namespace: default -spec: - secretName: brunner-ninja-tls - issuerRef: - name: letsencrypt-dns - kind: ClusterIssuer - dnsNames: - - brunner.ninja - - "*.brunner.ninja" - privateKey: - rotationPolicy: Always ---- -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - name: watschn-studio - namespace: default -spec: - secretName: watschn-studio-tls - issuerRef: - name: letsencrypt-dns - kind: ClusterIssuer - dnsNames: - - watschn.studio - privateKey: - rotationPolicy: Always ---- -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - name: brgkepler-com - namespace: default -spec: - secretName: brgkepler-com-tls - issuerRef: - name: letsencrypt-http - kind: ClusterIssuer - dnsNames: - - brgkepler.com - privateKey: - rotationPolicy: Always ---- -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - name: gschissenes-equipment - namespace: default -spec: - secretName: gschissenes-equipment-tls - issuerRef: - name: letsencrypt-http - kind: ClusterIssuer - dnsNames: - - gschissenes.equipment - privateKey: - rotationPolicy: Always diff --git a/ci-deployer.yaml b/ci-deployer.yaml deleted file mode 100644 index 47ad756..0000000 --- a/ci-deployer.yaml +++ /dev/null @@ -1,46 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - name: cert-manager-config-deployer - namespace: cert-manager -automountServiceAccountToken: false ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: cert-manager-config-deployer -rules: - - apiGroups: [cert-manager.io] - resources: [clusterissuers] - resourceNames: [letsencrypt-dns, letsencrypt-http] - verbs: [get, patch, update] - - apiGroups: [cert-manager.io] - resources: [certificates] - resourceNames: [brunner-ninja, watschn-studio, brgkepler-com, gschissenes-equipment] - verbs: [get, patch, update] - - apiGroups: [apps] - resources: [deployments] - resourceNames: [cert-manager, cert-manager-cainjector, cert-manager-webhook] - verbs: [get] ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: cert-manager-config-deployer -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: cert-manager-config-deployer -subjects: - - kind: ServiceAccount - name: cert-manager-config-deployer - namespace: cert-manager ---- -apiVersion: v1 -kind: Secret -metadata: - name: cert-manager-config-deployer-token - namespace: cert-manager - annotations: - kubernetes.io/service-account.name: cert-manager-config-deployer -type: kubernetes.io/service-account-token diff --git a/cloudflare-api-credentials.yaml.example b/cloudflare-api-credentials.yaml.example deleted file mode 100644 index 78a8ac8..0000000 --- a/cloudflare-api-credentials.yaml.example +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: cloudflare-api-token-secret - namespace: cert-manager -type: Opaque -stringData: - api-token: REPLACE_WITH_CLOUDFLARE_API_TOKEN diff --git a/cloudflare.yaml b/cloudflare.yaml deleted file mode 100644 index 9360fd6..0000000 --- a/cloudflare.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: cert-manager.io/v1 -kind: ClusterIssuer -metadata: - name: letsencrypt-dns -spec: - acme: - email: daniel@brunner.ninja - server: https://acme-v02.api.letsencrypt.org/directory - privateKeySecretRef: - name: letsencrypt-dns-account-key - solvers: - - dns01: - cloudflare: - email: daniel@brunner.ninja - apiKeySecretRef: - name: cloudflare-api-credentials - key: apiKey diff --git a/create-ci-kubeconfig.sh b/create-ci-kubeconfig.sh deleted file mode 100755 index 583f456..0000000 --- a/create-ci-kubeconfig.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail -project_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd) -namespace=cert-manager -service_account=cert-manager-config-deployer -secret=cert-manager-config-deployer-token -ssh_host=${KUBECTL_SSH_HOST:-} -ssh_config=${SSH_CONFIG:-} -cluster_kubectl() { if [[ -n "$ssh_host" ]]; then if [[ -n "$ssh_config" ]]; then ssh -F "$ssh_config" "$ssh_host" kubectl "$@"; else ssh "$ssh_host" kubectl "$@"; fi; else kubectl "$@"; fi; } -if [[ -n "$ssh_host" ]]; then cluster_kubectl apply -f - < "$project_dir/ci-deployer.yaml" >&2; else cluster_kubectl apply -f "$project_dir/ci-deployer.yaml" >&2; fi -for attempt in {1..30}; do - if cluster_kubectl -n "$namespace" get secret "$secret" -o jsonpath='{.data.token}' 2>/dev/null | grep -q .; then break; fi - [[ "$attempt" != 30 ]] || { echo 'Timed out waiting for service-account token' >&2; exit 1; } - sleep 1 -done -work=$(mktemp -d); trap 'rm -rf "$work"' EXIT -server=$(cluster_kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}') -cluster_kubectl -n "$namespace" get secret "$secret" -o jsonpath='{.data.ca\.crt}' | base64 -d > "$work/ca.crt" -token=$(cluster_kubectl -n "$namespace" get secret "$secret" -o jsonpath='{.data.token}' | base64 -d) -export KUBECONFIG="$work/config" -kubectl config set-cluster cluster --server="$server" --certificate-authority="$work/ca.crt" --embed-certs=true >/dev/null -kubectl config set-credentials "$service_account" --token="$token" >/dev/null -kubectl config set-context cert-manager --cluster=cluster --user="$service_account" --namespace="$namespace" >/dev/null -kubectl config use-context cert-manager >/dev/null -echo 'Store this line as Gitea Actions secret KUBE_CONFIG_BASE64; do not commit it.' >&2 -base64 -w0 "$KUBECONFIG"; printf '\n' diff --git a/http-issuer.yaml b/http-issuer.yaml deleted file mode 100644 index 7704dfc..0000000 --- a/http-issuer.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: cert-manager.io/v1 -kind: ClusterIssuer -metadata: - name: letsencrypt-http -spec: - acme: - email: daniel@brunner.ninja - server: https://acme-v02.api.letsencrypt.org/directory - privateKeySecretRef: - name: letsencrypt-http-account-key - solvers: - - http01: - ingress: - ingressClassName: traefik diff --git a/install.sh b/install.sh deleted file mode 100755 index 5d67eef..0000000 --- a/install.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/sh - -set -eu - -CERT_MANAGER_VERSION=v1.21.1 -CERT_MANAGER_CHART=oci://quay.io/jetstack/charts/cert-manager -PROJECT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) -CREDENTIALS_FILE=${CLOUDFLARE_CREDENTIALS_FILE:-$PROJECT_DIR/cloudflare-api-credentials.yaml} - -kubectl create namespace cert-manager --dry-run=client -o yaml | kubectl apply -f - - -if [ -f "$CREDENTIALS_FILE" ]; then - if grep -q 'REPLACE_WITH_' "$CREDENTIALS_FILE"; then - echo "Refusing placeholder credentials in $CREDENTIALS_FILE" >&2 - exit 1 - fi - kubectl apply -f "$CREDENTIALS_FILE" -elif kubectl -n cert-manager get secret cloudflare-api-token-secret >/dev/null 2>&1; then - echo "Keeping existing cert-manager/cloudflare-api-token-secret Secret." -else - echo "Missing $CREDENTIALS_FILE and the live Cloudflare Secret." >&2 - exit 1 -fi - -helm upgrade --install cert-manager "$CERT_MANAGER_CHART" \ - --version "$CERT_MANAGER_VERSION" \ - --namespace cert-manager \ - --create-namespace \ - --take-ownership \ - --force-conflicts \ - --rollback-on-failure \ - --wait \ - --timeout 10m \ - -f "$PROJECT_DIR/values.yaml" - -kubectl apply -f "$PROJECT_DIR/cloudflare.yaml" -kubectl apply -f "$PROJECT_DIR/http-issuer.yaml" -kubectl wait --for=condition=Ready clusterissuer/letsencrypt-dns --timeout=120s -kubectl wait --for=condition=Ready clusterissuer/letsencrypt-http --timeout=120s - -kubectl apply -f "$PROJECT_DIR/certificates.yaml" -kubectl wait --for=condition=Ready certificate/brunner-ninja --namespace default --timeout=10m -kubectl wait --for=condition=Ready certificate/watschn-studio --namespace default --timeout=10m -kubectl wait --for=condition=Ready certificate/brgkepler-com --namespace default --timeout=10m -kubectl wait --for=condition=Ready certificate/gschissenes-equipment --namespace default --timeout=10m diff --git a/test.sh b/test.sh deleted file mode 100755 index a12de0b..0000000 --- a/test.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail -dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd) -sh -n "$dir/install.sh" -bash -n "$dir/create-ci-kubeconfig.sh" "$dir/test.sh" -grep -Fxq 'cloudflare-api-credentials.yaml' "$dir/.gitignore" -if grep -R -q 'cloudflare-api-credentials' "$dir/.gitea/workflows"; then - echo 'CI must never read or apply the ignored credential manifest.' >&2 - exit 1 -fi -image=ghcr.io/yannh/kubeconform:v0.7.0 -for file in cloudflare.yaml http-issuer.yaml certificates.yaml; do docker run --rm -i "$image" -strict -exit-on-error -ignore-missing-schemas -summary < "$dir/$file"; done -docker run --rm -i "$image" -strict -exit-on-error -summary < "$dir/ci-deployer.yaml" -echo 'cert-manager configuration is valid; no credential file is tracked by CI.' diff --git a/values.yaml b/values.yaml deleted file mode 100644 index f5c537f..0000000 --- a/values.yaml +++ /dev/null @@ -1,6 +0,0 @@ -crds: - enabled: true - -extraArgs: - - --dns01-recursive-nameservers-only - - --dns01-recursive-nameservers=1.1.1.1:53,8.8.8.8:53