cert-manager-webhook-example/.github/workflows/test-kubernetes.yaml
2025-03-12 17:47:49 +01:00

153 lines
5.8 KiB
YAML

name: Run webhook tests in a full environment
on:
workflow_call:
secrets:
DNSIMPLE_API_TOKEN:
required: true
DNSIMPLE_ZONE_NAME:
required: true
jobs:
test:
runs-on: ubuntu-latest
strategy:
max-parallel: 3
matrix:
# Always quote versions to prevent int truncation (1.30 -> 1.3)
# https://kubernetes.io/releases
k8s-version: ["1.30", "1.31", "1.32"]
# https://cert-manager.io/docs/releases/ (Always include path version)
cm-version: ["1.16.0", "1.17.0"]
steps:
- uses: actions/checkout@v4
- name: Start minikube
uses: medyagh/setup-minikube@master
with:
kubernetes-version: ${{ matrix.k8s-version }}
- name: Install cert-manager, patch upstream dns servers, wait for readiness
run: |
echo "Target cert-manager version: ${{ matrix.cm-version }}"
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v${{ matrix.cm-version }}/cert-manager.yaml
# Patch cert-manager to use DNSimple's nameservers for faster propagation-checks
kubectl patch deployment cert-manager -n cert-manager --type='json' -p='[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": "--dns01-recursive-nameservers=ns1.dnsimple.com:53"}]'
kubectl wait --for=condition=available --timeout=600s deployment/cert-manager-webhook -n cert-manager
- name: Install cert-manager-webhook-dnsimple, wait for readiness
env:
DNSIMPLE_API_TOKEN: ${{ secrets.DNSIMPLE_API_TOKEN }}
DNSIMPLE_ZONE_NAME: ${{ secrets.DNSIMPLE_ZONE_NAME}}
run: |
helm install cert-manager-webhook-dnsimple ./charts/cert-manager-webhook-dnsimple \
--namespace cert-manager \
--set dnsimple.token="$DNSIMPLE_API_TOKEN" \
--set groupName="acme.$DNSIMPLE_ZONE_NAME" \
--set image.repository=ghcr.io/${{ github.repository_owner }}/cert-manager-webhook-dnsimple \
--set clusterIssuer.staging.enabled=true \
--set clusterIssuer.email="noreply@$DNSIMPLE_ZONE_NAME" \
--set image.tag=commit-${{ github.sha }}
helm -n cert-manager list
max_wait_time_seconds=800
sleep_between_iterations=10
start=$(date +%s)
end=$(( $start + $max_wait_time_seconds ))
echo ""
echo "Awaiting succesful deployment for max ${max_wait_time_seconds} seconds or until $(date --date="@$end")"
while [ $(date +%s) -le $end ]; do
echo "[i] New iteration at $(date)"
kubectl -n cert-manager get po
if [ $(kubectl -n cert-manager get po | grep Crash | wc -l) -gt 0 ]; then
echo "::error title=Deployment is failing::At least one pod is crashing"
for pod in $(kubectl -n cert-manager get po | grep Crash | awk '{print $1}'); do
echo "Logs for pod '$pod'"
kubectl -n cert-manager logs $pod
done
exit 1
fi
replicas=$(kubectl -n cert-manager get deploy/cert-manager-webhook-dnsimple -o=jsonpath={.status.unavailableReplicas})
if [[ $([ -z $replicas ]) || $replicas -gt 0 ]]; then
sleep $sleep_between_iterations
else
echo "Replicas of deployment cert-manager-webhook-dnsimple have become available."
exit 0
fi
done
echo "::error title=Deployment timed out::Have timed out waiting for good deployment health"
exit 1
- name: Create sample certificate that uses the webhook
env:
DNSIMPLE_ZONE_NAME: ${{ secrets.DNSIMPLE_ZONE_NAME }}
run: |
echo """apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: dnsimple-test
namespace: default
spec:
dnsNames:
- gh-action-test.$DNSIMPLE_ZONE_NAME
issuerRef:
name: cert-manager-webhook-dnsimple-staging
kind: ClusterIssuer
secretName: dnsimple-test-tls
""" > certificate.yaml
kubectl apply -f certificate.yaml
- name: Assert that the DNS record was created
env:
DNSIMPLE_ZONE_NAME: ${{ secrets.DNSIMPLE_ZONE_NAME }}
timeout-minutes: 10
run: |
while true; do
if nslookup -type=TXT _acme-challenge.gh-action-test.$DNSIMPLE_ZONE_NAME ns1.dnsimple.com; then
break
fi
sleep 30
done
# This step can time out, but it timing out doesn't necessarily mean that the webhook is not working.
# Timeouts mainly happen due to the environment of the runner and/or parallelism, thus such occurrences will simply be dismissed as warnings.
- name: Check the certificate status
run: |
max_wait_time_seconds=300
end=$(( $(date +%s) + $max_wait_time_seconds ))
start=$(date +%s)
sleep 5
while [ $(date +%s) -le $end ]; do
OUT_CRT=$(kubectl get certificate/dnsimple-test -o jsonpath='{.status.conditions}')
OUT_CRQ=$(kubectl get CertificateRequest -o json)
echo "Certificate:"
echo "$OUT_CRT"
echo "CertificateRequest:"
echo "$OUT_CRQ" | jq .items[0].status.conditions
if [ $(echo "$OUT_CRT" | grep -iE "Failed|Denied" | wc -l) -gt 0 ]; then
echo "::Error title=Certificate resource errored::The certificate ressource has an error"
exit 1
fi
if [ $(kubectl get certificate dnsimple-test -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}') == "True" ]; then
echo "Certificate is ready after $(( $(date +%s) - $start )) seconds"
exit 0
fi
sleep 20
echo -e "\n[i] New iteration at $(date)"
done
echo "::warning title=Certificate timed out::Have timed out waiting for certificate"