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"