penguin/webhook-freedns

freedns webhook for cert-manager

commit c7e83ca6cc450ede0f45820a1b2eabca3700b6d5

author斟酌 鵬兄 <tgckpg@gmail.com>
date2022-03-12T23:35:44Z
subjectI don't know what I'm doing
commit c7e83ca6cc450ede0f45820a1b2eabca3700b6d5
Author: 斟酌 鵬兄 <tgckpg@gmail.com>
Date:   2022-03-12T23:35:44Z

    I don't know what I'm doing
---
 .gitignore                                         |  2 +-
 Makefile                                           |  4 +-
 .../.helmignore                                    |  0
 .../Chart.yaml                                     |  2 +-
 .../templates/NOTES.txt                            |  0
 .../templates/_helpers.tpl                         | 22 ++---
 .../templates/apiservice.yaml                      |  8 +-
 .../templates/deployment.yaml                      | 14 ++--
 .../templates/pki.yaml                             | 42 +++++-----
 .../templates/rbac.yaml                            | 36 ++++----
 .../templates/service.yaml                         |  8 +-
 .../values.yaml                                    |  2 +-
 example/dns.go                                     | 69 ----------------
 example/example.go                                 | 68 ---------------
 example/example_test.go                            | 96 ----------------------
 go.mod                                             |  2 +-
 main.go                                            | 21 ++---
 main_test.go                                       | 23 ++----
 testdata/freedns-solver/config.json                |  4 +
 testdata/freedns-solver/freedns-auth.yaml          |  7 ++
 testdata/my-custom-solver/README.md                |  3 -
 testdata/my-custom-solver/config.json              |  1 -
 22 files changed, 98 insertions(+), 336 deletions(-)

diff --git a/.gitignore b/.gitignore
index a4be81c..a41ba7b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,7 +12,7 @@
 *.out
 
 # Ignore the built binary
-cert-manager-webhook-example
+cert-manager-webhook-freedns
 
 # Make artifacts
 _out
diff --git a/Makefile b/Makefile
index 9c243ad..c308489 100644
--- a/Makefile
+++ b/Makefile
@@ -35,7 +35,7 @@ build:
 .PHONY: rendered-manifest.yaml
 rendered-manifest.yaml:
 	helm template \
-	    --name example-webhook \
+	    --name freedns-webhook \
         --set image.repository=$(IMAGE_NAME) \
         --set image.tag=$(IMAGE_TAG) \
-        deploy/example-webhook > "$(OUT)/rendered-manifest.yaml"
+        deploy/freedns-webhook > "$(OUT)/rendered-manifest.yaml"
diff --git a/deploy/example-webhook/.helmignore b/deploy/freedns-webhook/.helmignore
similarity index 100%
rename from deploy/example-webhook/.helmignore
rename to deploy/freedns-webhook/.helmignore
diff --git a/deploy/example-webhook/Chart.yaml b/deploy/freedns-webhook/Chart.yaml
similarity index 80%
rename from deploy/example-webhook/Chart.yaml
rename to deploy/freedns-webhook/Chart.yaml
index 77c6ead..429a888 100644
--- a/deploy/example-webhook/Chart.yaml
+++ b/deploy/freedns-webhook/Chart.yaml
@@ -1,5 +1,5 @@
 apiVersion: v1
 appVersion: "1.0"
 description: A Helm chart for Kubernetes
-name: example-webhook
+name: freedns-webhook
 version: 0.1.0
diff --git a/deploy/example-webhook/templates/NOTES.txt b/deploy/freedns-webhook/templates/NOTES.txt
similarity index 100%
rename from deploy/example-webhook/templates/NOTES.txt
rename to deploy/freedns-webhook/templates/NOTES.txt
diff --git a/deploy/example-webhook/templates/_helpers.tpl b/deploy/freedns-webhook/templates/_helpers.tpl
similarity index 64%
rename from deploy/example-webhook/templates/_helpers.tpl
rename to deploy/freedns-webhook/templates/_helpers.tpl
index d3c474b..a16b9ca 100644
--- a/deploy/example-webhook/templates/_helpers.tpl
+++ b/deploy/freedns-webhook/templates/_helpers.tpl
@@ -2,7 +2,7 @@
 {{/*
 Expand the name of the chart.
 */}}
-{{- define "example-webhook.name" -}}
+{{- define "freedns-webhook.name" -}}
 {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
 {{- end -}}
 
@@ -11,7 +11,7 @@ Create a default fully qualified app name.
 We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
 If release name contains chart name it will be used as a full name.
 */}}
-{{- define "example-webhook.fullname" -}}
+{{- define "freedns-webhook.fullname" -}}
 {{- if .Values.fullnameOverride -}}
 {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
 {{- else -}}
@@ -27,22 +27,22 @@ If release name contains chart name it will be used as a full name.
 {{/*
 Create chart name and version as used by the chart label.
 */}}
-{{- define "example-webhook.chart" -}}
+{{- define "freedns-webhook.chart" -}}
 {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
 {{- end -}}
 
-{{- define "example-webhook.selfSignedIssuer" -}}
-{{ printf "%s-selfsign" (include "example-webhook.fullname" .) }}
+{{- define "freedns-webhook.selfSignedIssuer" -}}
+{{ printf "%s-selfsign" (include "freedns-webhook.fullname" .) }}
 {{- end -}}
 
-{{- define "example-webhook.rootCAIssuer" -}}
-{{ printf "%s-ca" (include "example-webhook.fullname" .) }}
+{{- define "freedns-webhook.rootCAIssuer" -}}
+{{ printf "%s-ca" (include "freedns-webhook.fullname" .) }}
 {{- end -}}
 
-{{- define "example-webhook.rootCACertificate" -}}
-{{ printf "%s-ca" (include "example-webhook.fullname" .) }}
+{{- define "freedns-webhook.rootCACertificate" -}}
+{{ printf "%s-ca" (include "freedns-webhook.fullname" .) }}
 {{- end -}}
 
-{{- define "example-webhook.servingCertificate" -}}
-{{ printf "%s-webhook-tls" (include "example-webhook.fullname" .) }}
+{{- define "freedns-webhook.servingCertificate" -}}
+{{ printf "%s-webhook-tls" (include "freedns-webhook.fullname" .) }}
 {{- end -}}
diff --git a/deploy/example-webhook/templates/apiservice.yaml b/deploy/freedns-webhook/templates/apiservice.yaml
similarity index 67%
rename from deploy/example-webhook/templates/apiservice.yaml
rename to deploy/freedns-webhook/templates/apiservice.yaml
index 4f6d5ce..cccc75d 100644
--- a/deploy/example-webhook/templates/apiservice.yaml
+++ b/deploy/freedns-webhook/templates/apiservice.yaml
@@ -3,17 +3,17 @@ kind: APIService
 metadata:
   name: v1alpha1.{{ .Values.groupName }}
   labels:
-    app: {{ include "example-webhook.name" . }}
-    chart: {{ include "example-webhook.chart" . }}
+    app: {{ include "freedns-webhook.name" . }}
+    chart: {{ include "freedns-webhook.chart" . }}
     release: {{ .Release.Name }}
     heritage: {{ .Release.Service }}
   annotations:
-    cert-manager.io/inject-ca-from: "{{ .Release.Namespace }}/{{ include "example-webhook.servingCertificate" . }}"
+    cert-manager.io/inject-ca-from: "{{ .Release.Namespace }}/{{ include "freedns-webhook.servingCertificate" . }}"
 spec:
   group: {{ .Values.groupName }}
   groupPriorityMinimum: 1000
   versionPriority: 15
   service:
-    name: {{ include "example-webhook.fullname" . }}
+    name: {{ include "freedns-webhook.fullname" . }}
     namespace: {{ .Release.Namespace }}
   version: v1alpha1
diff --git a/deploy/example-webhook/templates/deployment.yaml b/deploy/freedns-webhook/templates/deployment.yaml
similarity index 80%
rename from deploy/example-webhook/templates/deployment.yaml
rename to deploy/freedns-webhook/templates/deployment.yaml
index ed49463..c2de51f 100644
--- a/deploy/example-webhook/templates/deployment.yaml
+++ b/deploy/freedns-webhook/templates/deployment.yaml
@@ -1,25 +1,25 @@
 apiVersion: apps/v1
 kind: Deployment
 metadata:
-  name: {{ include "example-webhook.fullname" . }}
+  name: {{ include "freedns-webhook.fullname" . }}
   labels:
-    app: {{ include "example-webhook.name" . }}
-    chart: {{ include "example-webhook.chart" . }}
+    app: {{ include "freedns-webhook.name" . }}
+    chart: {{ include "freedns-webhook.chart" . }}
     release: {{ .Release.Name }}
     heritage: {{ .Release.Service }}
 spec:
   replicas: {{ .Values.replicaCount }}
   selector:
     matchLabels:
-      app: {{ include "example-webhook.name" . }}
+      app: {{ include "freedns-webhook.name" . }}
       release: {{ .Release.Name }}
   template:
     metadata:
       labels:
-        app: {{ include "example-webhook.name" . }}
+        app: {{ include "freedns-webhook.name" . }}
         release: {{ .Release.Name }}
     spec:
-      serviceAccountName: {{ include "example-webhook.fullname" . }}
+      serviceAccountName: {{ include "freedns-webhook.fullname" . }}
       containers:
         - name: {{ .Chart.Name }}
           image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
@@ -53,7 +53,7 @@ spec:
       volumes:
         - name: certs
           secret:
-            secretName: {{ include "example-webhook.servingCertificate" . }}
+            secretName: {{ include "freedns-webhook.servingCertificate" . }}
     {{- with .Values.nodeSelector }}
       nodeSelector:
 {{ toYaml . | indent 8 }}
diff --git a/deploy/example-webhook/templates/pki.yaml b/deploy/freedns-webhook/templates/pki.yaml
similarity index 51%
rename from deploy/example-webhook/templates/pki.yaml
rename to deploy/freedns-webhook/templates/pki.yaml
index b4b4c23..2cdc378 100644
--- a/deploy/example-webhook/templates/pki.yaml
+++ b/deploy/freedns-webhook/templates/pki.yaml
@@ -4,11 +4,11 @@
 apiVersion: cert-manager.io/v1
 kind: Issuer
 metadata:
-  name: {{ include "example-webhook.selfSignedIssuer" . }}
+  name: {{ include "freedns-webhook.selfSignedIssuer" . }}
   namespace: {{ .Release.Namespace | quote }}
   labels:
-    app: {{ include "example-webhook.name" . }}
-    chart: {{ include "example-webhook.chart" . }}
+    app: {{ include "freedns-webhook.name" . }}
+    chart: {{ include "freedns-webhook.chart" . }}
     release: {{ .Release.Name }}
     heritage: {{ .Release.Service }}
 spec:
@@ -20,19 +20,19 @@ spec:
 apiVersion: cert-manager.io/v1
 kind: Certificate
 metadata:
-  name: {{ include "example-webhook.rootCACertificate" . }}
+  name: {{ include "freedns-webhook.rootCACertificate" . }}
   namespace: {{ .Release.Namespace | quote }}
   labels:
-    app: {{ include "example-webhook.name" . }}
-    chart: {{ include "example-webhook.chart" . }}
+    app: {{ include "freedns-webhook.name" . }}
+    chart: {{ include "freedns-webhook.chart" . }}
     release: {{ .Release.Name }}
     heritage: {{ .Release.Service }}
 spec:
-  secretName: {{ include "example-webhook.rootCACertificate" . }}
+  secretName: {{ include "freedns-webhook.rootCACertificate" . }}
   duration: 43800h # 5y
   issuerRef:
-    name: {{ include "example-webhook.selfSignedIssuer" . }}
-  commonName: "ca.example-webhook.cert-manager"
+    name: {{ include "freedns-webhook.selfSignedIssuer" . }}
+  commonName: "ca.freedns-webhook.cert-manager"
   isCA: true
 
 ---
@@ -41,16 +41,16 @@ spec:
 apiVersion: cert-manager.io/v1
 kind: Issuer
 metadata:
-  name: {{ include "example-webhook.rootCAIssuer" . }}
+  name: {{ include "freedns-webhook.rootCAIssuer" . }}
   namespace: {{ .Release.Namespace | quote }}
   labels:
-    app: {{ include "example-webhook.name" . }}
-    chart: {{ include "example-webhook.chart" . }}
+    app: {{ include "freedns-webhook.name" . }}
+    chart: {{ include "freedns-webhook.chart" . }}
     release: {{ .Release.Name }}
     heritage: {{ .Release.Service }}
 spec:
   ca:
-    secretName: {{ include "example-webhook.rootCACertificate" . }}
+    secretName: {{ include "freedns-webhook.rootCACertificate" . }}
 
 ---
 
@@ -58,19 +58,19 @@ spec:
 apiVersion: cert-manager.io/v1
 kind: Certificate
 metadata:
-  name: {{ include "example-webhook.servingCertificate" . }}
+  name: {{ include "freedns-webhook.servingCertificate" . }}
   namespace: {{ .Release.Namespace | quote }}
   labels:
-    app: {{ include "example-webhook.name" . }}
-    chart: {{ include "example-webhook.chart" . }}
+    app: {{ include "freedns-webhook.name" . }}
+    chart: {{ include "freedns-webhook.chart" . }}
     release: {{ .Release.Name }}
     heritage: {{ .Release.Service }}
 spec:
-  secretName: {{ include "example-webhook.servingCertificate" . }}
+  secretName: {{ include "freedns-webhook.servingCertificate" . }}
   duration: 8760h # 1y
   issuerRef:
-    name: {{ include "example-webhook.rootCAIssuer" . }}
+    name: {{ include "freedns-webhook.rootCAIssuer" . }}
   dnsNames:
-  - {{ include "example-webhook.fullname" . }}
-  - {{ include "example-webhook.fullname" . }}.{{ .Release.Namespace }}
-  - {{ include "example-webhook.fullname" . }}.{{ .Release.Namespace }}.svc
+  - {{ include "freedns-webhook.fullname" . }}
+  - {{ include "freedns-webhook.fullname" . }}.{{ .Release.Namespace }}
+  - {{ include "freedns-webhook.fullname" . }}.{{ .Release.Namespace }}.svc
diff --git a/deploy/example-webhook/templates/rbac.yaml b/deploy/freedns-webhook/templates/rbac.yaml
similarity index 65%
rename from deploy/example-webhook/templates/rbac.yaml
rename to deploy/freedns-webhook/templates/rbac.yaml
index d386362..5ba2e74 100644
--- a/deploy/example-webhook/templates/rbac.yaml
+++ b/deploy/freedns-webhook/templates/rbac.yaml
@@ -1,10 +1,10 @@
 apiVersion: v1
 kind: ServiceAccount
 metadata:
-  name: {{ include "example-webhook.fullname" . }}
+  name: {{ include "freedns-webhook.fullname" . }}
   labels:
-    app: {{ include "example-webhook.name" . }}
-    chart: {{ include "example-webhook.chart" . }}
+    app: {{ include "freedns-webhook.name" . }}
+    chart: {{ include "freedns-webhook.chart" . }}
     release: {{ .Release.Name }}
     heritage: {{ .Release.Service }}
 ---
@@ -14,11 +14,11 @@ metadata:
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
 metadata:
-  name: {{ include "example-webhook.fullname" . }}:webhook-authentication-reader
+  name: {{ include "freedns-webhook.fullname" . }}:webhook-authentication-reader
   namespace: kube-system
   labels:
-    app: {{ include "example-webhook.name" . }}
-    chart: {{ include "example-webhook.chart" . }}
+    app: {{ include "freedns-webhook.name" . }}
+    chart: {{ include "freedns-webhook.chart" . }}
     release: {{ .Release.Name }}
     heritage: {{ .Release.Service }}
 roleRef:
@@ -28,7 +28,7 @@ roleRef:
 subjects:
   - apiGroup: ""
     kind: ServiceAccount
-    name: {{ include "example-webhook.fullname" . }}
+    name: {{ include "freedns-webhook.fullname" . }}
     namespace: {{ .Release.Namespace }}
 ---
 # apiserver gets the auth-delegator role to delegate auth decisions to
@@ -36,10 +36,10 @@ subjects:
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
 metadata:
-  name: {{ include "example-webhook.fullname" . }}:auth-delegator
+  name: {{ include "freedns-webhook.fullname" . }}:auth-delegator
   labels:
-    app: {{ include "example-webhook.name" . }}
-    chart: {{ include "example-webhook.chart" . }}
+    app: {{ include "freedns-webhook.name" . }}
+    chart: {{ include "freedns-webhook.chart" . }}
     release: {{ .Release.Name }}
     heritage: {{ .Release.Service }}
 roleRef:
@@ -49,17 +49,17 @@ roleRef:
 subjects:
   - apiGroup: ""
     kind: ServiceAccount
-    name: {{ include "example-webhook.fullname" . }}
+    name: {{ include "freedns-webhook.fullname" . }}
     namespace: {{ .Release.Namespace }}
 ---
 # Grant cert-manager permission to validate using our apiserver
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRole
 metadata:
-  name: {{ include "example-webhook.fullname" . }}:domain-solver
+  name: {{ include "freedns-webhook.fullname" . }}:domain-solver
   labels:
-    app: {{ include "example-webhook.name" . }}
-    chart: {{ include "example-webhook.chart" . }}
+    app: {{ include "freedns-webhook.name" . }}
+    chart: {{ include "freedns-webhook.chart" . }}
     release: {{ .Release.Name }}
     heritage: {{ .Release.Service }}
 rules:
@@ -73,16 +73,16 @@ rules:
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
 metadata:
-  name: {{ include "example-webhook.fullname" . }}:domain-solver
+  name: {{ include "freedns-webhook.fullname" . }}:domain-solver
   labels:
-    app: {{ include "example-webhook.name" . }}
-    chart: {{ include "example-webhook.chart" . }}
+    app: {{ include "freedns-webhook.name" . }}
+    chart: {{ include "freedns-webhook.chart" . }}
     release: {{ .Release.Name }}
     heritage: {{ .Release.Service }}
 roleRef:
   apiGroup: rbac.authorization.k8s.io
   kind: ClusterRole
-  name: {{ include "example-webhook.fullname" . }}:domain-solver
+  name: {{ include "freedns-webhook.fullname" . }}:domain-solver
 subjects:
   - apiGroup: ""
     kind: ServiceAccount
diff --git a/deploy/example-webhook/templates/service.yaml b/deploy/freedns-webhook/templates/service.yaml
similarity index 61%
rename from deploy/example-webhook/templates/service.yaml
rename to deploy/freedns-webhook/templates/service.yaml
index 572089e..844933b 100644
--- a/deploy/example-webhook/templates/service.yaml
+++ b/deploy/freedns-webhook/templates/service.yaml
@@ -1,10 +1,10 @@
 apiVersion: v1
 kind: Service
 metadata:
-  name: {{ include "example-webhook.fullname" . }}
+  name: {{ include "freedns-webhook.fullname" . }}
   labels:
-    app: {{ include "example-webhook.name" . }}
-    chart: {{ include "example-webhook.chart" . }}
+    app: {{ include "freedns-webhook.name" . }}
+    chart: {{ include "freedns-webhook.chart" . }}
     release: {{ .Release.Name }}
     heritage: {{ .Release.Service }}
 spec:
@@ -15,5 +15,5 @@ spec:
       protocol: TCP
       name: https
   selector:
-    app: {{ include "example-webhook.name" . }}
+    app: {{ include "freedns-webhook.name" . }}
     release: {{ .Release.Name }}
diff --git a/deploy/example-webhook/values.yaml b/deploy/freedns-webhook/values.yaml
similarity index 95%
rename from deploy/example-webhook/values.yaml
rename to deploy/freedns-webhook/values.yaml
index 31eb151..239aa2a 100644
--- a/deploy/example-webhook/values.yaml
+++ b/deploy/freedns-webhook/values.yaml
@@ -1,6 +1,6 @@
 # The GroupName here is used to identify your company or business unit that
 # created this webhook.
-# For example, this may be "acme.mycompany.com".
+# For freedns, this may be "acme.mycompany.com".
 # This name will need to be referenced in each Issuer's `webhook` stanza to
 # inform cert-manager of where to send ChallengePayload resources in order to
 # solve the DNS01 challenge.
diff --git a/example/dns.go b/example/dns.go
deleted file mode 100644
index e29597e..0000000
--- a/example/dns.go
+++ /dev/null
@@ -1,69 +0,0 @@
-package example
-
-import (
-	"fmt"
-
-	"github.com/miekg/dns"
-)
-
-func (e *exampleSolver) handleDNSRequest(w dns.ResponseWriter, req *dns.Msg) {
-	msg := new(dns.Msg)
-	msg.SetReply(req)
-	switch req.Opcode {
-	case dns.OpcodeQuery:
-		for _, q := range msg.Question {
-			if err := e.addDNSAnswer(q, msg, req); err != nil {
-				msg.SetRcode(req, dns.RcodeServerFailure)
-				break
-			}
-		}
-	}
-	w.WriteMsg(msg)
-}
-
-func (e *exampleSolver) addDNSAnswer(q dns.Question, msg *dns.Msg, req *dns.Msg) error {
-	switch q.Qtype {
-	// Always return loopback for any A query
-	case dns.TypeA:
-		rr, err := dns.NewRR(fmt.Sprintf("%s 5 IN A 127.0.0.1", q.Name))
-		if err != nil {
-			return err
-		}
-		msg.Answer = append(msg.Answer, rr)
-		return nil
-
-	// TXT records are the only important record for ACME dns-01 challenges
-	case dns.TypeTXT:
-		e.RLock()
-		record, found := e.txtRecords[q.Name]
-		e.RUnlock()
-		if !found {
-			msg.SetRcode(req, dns.RcodeNameError)
-			return nil
-		}
-		rr, err := dns.NewRR(fmt.Sprintf("%s 5 IN TXT %s", q.Name, record))
-		if err != nil {
-			return err
-		}
-		msg.Answer = append(msg.Answer, rr)
-		return nil
-
-	// NS and SOA are for authoritative lookups, return obviously invalid data
-	case dns.TypeNS:
-		rr, err := dns.NewRR(fmt.Sprintf("%s 5 IN NS ns.example-acme-webook.invalid.", q.Name))
-		if err != nil {
-			return err
-		}
-		msg.Answer = append(msg.Answer, rr)
-		return nil
-	case dns.TypeSOA:
-		rr, err := dns.NewRR(fmt.Sprintf("%s 5 IN SOA %s 20 5 5 5 5", "ns.example-acme-webook.invalid.", "ns.example-acme-webook.invalid."))
-		if err != nil {
-			return err
-		}
-		msg.Answer = append(msg.Answer, rr)
-		return nil
-	default:
-		return fmt.Errorf("unimplemented record type %v", q.Qtype)
-	}
-}
diff --git a/example/example.go b/example/example.go
deleted file mode 100644
index d31b42d..0000000
--- a/example/example.go
+++ /dev/null
@@ -1,68 +0,0 @@
-// package example contains a self-contained example of a webhook that passes the cert-manager
-// DNS conformance tests
-package example
-
-import (
-	"fmt"
-	"os"
-	"sync"
-
-	"github.com/jetstack/cert-manager/pkg/acme/webhook"
-	acme "github.com/jetstack/cert-manager/pkg/acme/webhook/apis/acme/v1alpha1"
-	"github.com/miekg/dns"
-	"k8s.io/client-go/rest"
-)
-
-type exampleSolver struct {
-	name       string
-	server     *dns.Server
-	txtRecords map[string]string
-	sync.RWMutex
-}
-
-func (e *exampleSolver) Name() string {
-	return e.name
-}
-
-func (e *exampleSolver) Present(ch *acme.ChallengeRequest) error {
-	e.Lock()
-	e.txtRecords[ch.ResolvedFQDN] = ch.Key
-	e.Unlock()
-	return nil
-}
-
-func (e *exampleSolver) CleanUp(ch *acme.ChallengeRequest) error {
-	e.Lock()
-	delete(e.txtRecords, ch.ResolvedFQDN)
-	e.Unlock()
-	return nil
-}
-
-func (e *exampleSolver) Initialize(kubeClientConfig *rest.Config, stopCh <-chan struct{}) error {
-	go func(done <-chan struct{}) {
-		<-done
-		if err := e.server.Shutdown(); err != nil {
-			fmt.Fprintf(os.Stderr, "%s\n", err.Error())
-		}
-	}(stopCh)
-	go func() {
-		if err := e.server.ListenAndServe(); err != nil {
-			fmt.Fprintf(os.Stderr, "%s\n", err.Error())
-			os.Exit(1)
-		}
-	}()
-	return nil
-}
-
-func New(port string) webhook.Solver {
-	e := &exampleSolver{
-		name:       "example",
-		txtRecords: make(map[string]string),
-	}
-	e.server = &dns.Server{
-		Addr:    ":" + port,
-		Net:     "udp",
-		Handler: dns.HandlerFunc(e.handleDNSRequest),
-	}
-	return e
-}
diff --git a/example/example_test.go b/example/example_test.go
deleted file mode 100644
index 8c40df2..0000000
--- a/example/example_test.go
+++ /dev/null
@@ -1,96 +0,0 @@
-package example
-
-import (
-	"crypto/rand"
-	"math/big"
-	"testing"
-
-	acme "github.com/jetstack/cert-manager/pkg/acme/webhook/apis/acme/v1alpha1"
-	"github.com/miekg/dns"
-	"github.com/stretchr/testify/assert"
-)
-
-func TestExampleSolver_Name(t *testing.T) {
-	port, _ := rand.Int(rand.Reader, big.NewInt(50000))
-	port = port.Add(port, big.NewInt(15534))
-	solver := New(port.String())
-	assert.Equal(t, "example", solver.Name())
-}
-
-func TestExampleSolver_Initialize(t *testing.T) {
-	port, _ := rand.Int(rand.Reader, big.NewInt(50000))
-	port = port.Add(port, big.NewInt(15534))
-	solver := New(port.String())
-	done := make(chan struct{})
-	err := solver.Initialize(nil, done)
-	assert.NoError(t, err, "Expected Initialize not to error")
-	close(done)
-}
-
-func TestExampleSolver_Present_Cleanup(t *testing.T) {
-	port, _ := rand.Int(rand.Reader, big.NewInt(50000))
-	port = port.Add(port, big.NewInt(15534))
-	solver := New(port.String())
-	done := make(chan struct{})
-	err := solver.Initialize(nil, done)
-	assert.NoError(t, err, "Expected Initialize not to error")
-
-	validTestData := []struct {
-		hostname string
-		record   string
-	}{
-		{"test1.example.com.", "testkey1"},
-		{"test2.example.com.", "testkey2"},
-		{"test3.example.com.", "testkey3"},
-	}
-	for _, test := range validTestData {
-		err := solver.Present(&acme.ChallengeRequest{
-			Action:       acme.ChallengeActionPresent,
-			Type:         "dns-01",
-			ResolvedFQDN: test.hostname,
-			Key:          test.record,
-		})
-		assert.NoError(t, err, "Unexpected error while presenting %v", t)
-	}
-
-	// Resolve test data
-	for _, test := range validTestData {
-		msg := new(dns.Msg)
-		msg.Id = dns.Id()
-		msg.RecursionDesired = true
-		msg.Question = make([]dns.Question, 1)
-		msg.Question[0] = dns.Question{dns.Fqdn(test.hostname), dns.TypeTXT, dns.ClassINET}
-		in, err := dns.Exchange(msg, "127.0.0.1:"+port.String())
-
-		assert.NoError(t, err, "Presented record %s not resolvable", test.hostname)
-		assert.Len(t, in.Answer, 1, "RR response is of incorrect length")
-		assert.Equal(t, []string{test.record}, in.Answer[0].(*dns.TXT).Txt, "TXT record returned did not match presented record")
-	}
-
-	// Cleanup test data
-	for _, test := range validTestData {
-		err := solver.CleanUp(&acme.ChallengeRequest{
-			Action:       acme.ChallengeActionCleanUp,
-			Type:         "dns-01",
-			ResolvedFQDN: test.hostname,
-			Key:          test.record,
-		})
-		assert.NoError(t, err, "Unexpected error while cleaning up %v", t)
-	}
-
-	// Resolve test data
-	for _, test := range validTestData {
-		msg := new(dns.Msg)
-		msg.Id = dns.Id()
-		msg.RecursionDesired = true
-		msg.Question = make([]dns.Question, 1)
-		msg.Question[0] = dns.Question{dns.Fqdn(test.hostname), dns.TypeTXT, dns.ClassINET}
-		in, err := dns.Exchange(msg, "127.0.0.1:"+port.String())
-
-		assert.NoError(t, err, "Presented record %s not resolvable", test.hostname)
-		assert.Len(t, in.Answer, 0, "RR response is of incorrect length")
-		assert.Equal(t, dns.RcodeNameError, in.Rcode, "Expexted NXDOMAIN")
-	}
-
-	close(done)
-}
diff --git a/go.mod b/go.mod
index 8ad2f46..efd84bd 100644
--- a/go.mod
+++ b/go.mod
@@ -1,4 +1,4 @@
-module github.com/cert-manager/webhook-example
+module github.com/cert-manager/webhook-freedns
 
 go 1.17
 
diff --git a/main.go b/main.go
index 33937cb..8368df4 100644
--- a/main.go
+++ b/main.go
@@ -6,7 +6,7 @@ import (
 	"os"
 
 	extapi "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
-	//"k8s.io/client-go/kubernetes"
+	"k8s.io/client-go/kubernetes"
 	"k8s.io/client-go/rest"
 
 	"github.com/jetstack/cert-manager/pkg/acme/webhook/apis/acme/v1alpha1"
@@ -41,7 +41,7 @@ type customDNSProviderSolver struct {
 	// 3. uncomment the relevant code in the Initialize method below
 	// 4. ensure your webhook's service account has the required RBAC role
 	//    assigned to it for interacting with the Kubernetes APIs you need.
-	//client kubernetes.Clientset
+	client *kubernetes.Clientset
 }
 
 // customDNSProviderConfig is a structure that is used to decode into when
@@ -65,7 +65,9 @@ type customDNSProviderConfig struct {
 	// `issuer.spec.acme.dns01.providers.webhook.config` field.
 
 	//Email           string `json:"email"`
-	//APIKeySecretRef v1alpha1.SecretKeySelector `json:"apiKeySecretRef"`
+	SecretRef string `json:"secretName"`
+	Domain string `json:"domain"`
+	//APIKeySecretRef v1.SecretKeySelector `json:"apiKeySecretRef"`
 }
 
 // Name is used as the name for this DNS solver when referencing it on the ACME
@@ -75,7 +77,7 @@ type customDNSProviderConfig struct {
 // within a single webhook deployment**.
 // For example, `cloudflare` may be used as the name of a solver.
 func (c *customDNSProviderSolver) Name() string {
-	return "my-custom-solver"
+	return "freedns-solver"
 }
 
 // Present is responsible for actually presenting the DNS record with the
@@ -120,12 +122,11 @@ func (c *customDNSProviderSolver) Initialize(kubeClientConfig *rest.Config, stop
 	///// UNCOMMENT THE BELOW CODE TO MAKE A KUBERNETES CLIENTSET AVAILABLE TO
 	///// YOUR CUSTOM DNS PROVIDER
 
-	//cl, err := kubernetes.NewForConfig(kubeClientConfig)
-	//if err != nil {
-	//	return err
-	//}
-	//
-	//c.client = cl
+	cl, err := kubernetes.NewForConfig(kubeClientConfig)
+	if err != nil {
+		return err
+	}
+	c.client = cl
 
 	///// END OF CODE TO MAKE KUBERNETES CLIENTSET AVAILABLE
 	return nil
diff --git a/main_test.go b/main_test.go
index f81a15e..a9df41b 100644
--- a/main_test.go
+++ b/main_test.go
@@ -5,8 +5,6 @@ import (
 	"testing"
 
 	"github.com/jetstack/cert-manager/test/acme/dns"
-
-	"github.com/cert-manager/webhook-example/example"
 )
 
 var (
@@ -20,22 +18,11 @@ func TestRunsSuite(t *testing.T) {
 	//
 
 	// Uncomment the below fixture when implementing your custom DNS provider
-	//fixture := dns.NewFixture(&customDNSProviderSolver{},
-	//	dns.SetResolvedZone(zone),
-	//	dns.SetAllowAmbientCredentials(false),
-	//	dns.SetManifestPath("testdata/my-custom-solver"),
-	//	dns.SetBinariesPath("_test/kubebuilder/bin"),
-	//)
-	solver := example.New("59351")
-	fixture := dns.NewFixture(solver,
-		dns.SetResolvedZone("example.com."),
-		dns.SetManifestPath("testdata/my-custom-solver"),
-		dns.SetDNSServer("127.0.0.1:59351"),
-		dns.SetUseAuthoritative(false),
+	fixture := dns.NewFixture(&customDNSProviderSolver{},
+		dns.SetResolvedZone(zone),
+		dns.SetAllowAmbientCredentials(false),
+		dns.SetManifestPath("testdata/freedns-solver"),
 	)
-	//need to uncomment and  RunConformance delete runBasic and runExtended once https://github.com/cert-manager/cert-manager/pull/4835 is merged
-	//fixture.RunConformance(t)
-	fixture.RunBasic(t)
-	fixture.RunExtended(t)
+	fixture.RunConformance(t)
 
 }
diff --git a/testdata/freedns-solver/config.json b/testdata/freedns-solver/config.json
new file mode 100644
index 0000000..f1723e9
--- /dev/null
+++ b/testdata/freedns-solver/config.json
@@ -0,0 +1,4 @@
+{
+	"secretName": "freedns-auth"
+	, "domain": "example.com"
+}
diff --git a/testdata/freedns-solver/freedns-auth.yaml b/testdata/freedns-solver/freedns-auth.yaml
new file mode 100644
index 0000000..239740d
--- /dev/null
+++ b/testdata/freedns-solver/freedns-auth.yaml
@@ -0,0 +1,7 @@
+apiVersion: v1
+kind: Secret
+metadata:
+  name: freedns-auth
+data:
+  username: ZXhhbXBsZQ==
+  password: MTIzNA==
diff --git a/testdata/my-custom-solver/README.md b/testdata/my-custom-solver/README.md
deleted file mode 100644
index feb4cbd..0000000
--- a/testdata/my-custom-solver/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Solver testdata directory
-
-TODO
diff --git a/testdata/my-custom-solver/config.json b/testdata/my-custom-solver/config.json
deleted file mode 100644
index 0967ef4..0000000
--- a/testdata/my-custom-solver/config.json
+++ /dev/null
@@ -1 +0,0 @@
-{}