penguin/webhook-freedns

freedns webhook for cert-manager

commit 74a7eb382840d8bbbe93d10bcc2974785e2b2924

author斟酌 鵬兄 <tgckpg@gmail.com>
date2024-11-02T11:04:53Z
subjectRemoved secret-read permissions from pod
commit 74a7eb382840d8bbbe93d10bcc2974785e2b2924
Author: 斟酌 鵬兄 <tgckpg@gmail.com>
Date:   2024-11-02T11:04:53Z

    Removed secret-read permissions from pod
---
 README.md                                        | 27 ++++++++--------
 deploy/freedns-webhook/Chart.yaml                |  6 ++--
 deploy/freedns-webhook/templates/deployment.yaml |  3 ++
 deploy/freedns-webhook/templates/rbac.yaml       | 39 ------------------------
 deploy/freedns-webhook/templates/secrets.yaml    | 15 +++++++++
 deploy/freedns-webhook/values.yaml               |  7 ++++-
 main.go                                          | 26 ++++++----------
 7 files changed, 48 insertions(+), 75 deletions(-)

diff --git a/README.md b/README.md
index 56b05d5..ab2b930 100644
--- a/README.md
+++ b/README.md
@@ -5,8 +5,8 @@ Have you read it? If you haven't go read it. Cuz I'll keep everything short.
 
 This is a dns01 solver for [FreeDNS](https://freedns.afraid.org/).
 
-Pull requests welcome. I'm completely unfamiliar with golang. I did it by looking at
-other webhook repos and this is the result.
+Pull requests welcome. I'm now somewhat familiar with golang. You can also look at
+other and choose the one that fits your need.
 
 ## Install
 ```bash
@@ -42,18 +42,15 @@ Normally if you haven't changed anything, the default namespace should be
 `cert-manager`. It should be within the same namespace for the webhook when
 you do `helm install webhook -n cert-manager`.
 
-```yaml
-apiVersion: v1
-kind: Secret
-metadata:
-  name: freedns-auth
-  namespace: cert-manager
-data:
-  username: [YOUR_USERNAME_IN_BASE64]
-  password: [YOUR_PASSWORD_IN_BASE64]
-type: Opaque
-```
-
 Additionally, the following names can be customized
 * acme.freedns.afraid.org
-* freedns-auth
\ No newline at end of file
+
+### UPDATE
+2024-10-30
+- Merged from upstream, now works on 1.31 cluster
+
+2024-11-02
+- Webhook will now properly logs its actions
+- Removed permissions to read secrets from pod for obvious reansons
+  - Authentication details are now requested from Helm
+  - You should remove the old secret `freedns-auth`. It is now handled by Helm.
diff --git a/deploy/freedns-webhook/Chart.yaml b/deploy/freedns-webhook/Chart.yaml
index 429a888..ef995cc 100644
--- a/deploy/freedns-webhook/Chart.yaml
+++ b/deploy/freedns-webhook/Chart.yaml
@@ -1,5 +1,5 @@
 apiVersion: v1
-appVersion: "1.0"
-description: A Helm chart for Kubernetes
+appVersion: "2024.11.02.05"
+description: A FreeDNS webhook dns01 solver for cert-manager
 name: freedns-webhook
-version: 0.1.0
+version: 0.1.1
diff --git a/deploy/freedns-webhook/templates/deployment.yaml b/deploy/freedns-webhook/templates/deployment.yaml
index 43d6f79..44a5a89 100644
--- a/deploy/freedns-webhook/templates/deployment.yaml
+++ b/deploy/freedns-webhook/templates/deployment.yaml
@@ -29,6 +29,9 @@ spec:
             - --v=2
             - --tls-cert-file=/tls/tls.crt
             - --tls-private-key-file=/tls/tls.key
+          envFrom:
+            - secretRef:
+                name: {{ include "freedns-webhook.fullname" . }}-auth
           env:
             - name: GROUP_NAME
               value: {{ .Values.groupName | quote }}
diff --git a/deploy/freedns-webhook/templates/rbac.yaml b/deploy/freedns-webhook/templates/rbac.yaml
index 42cf507..cf0650a 100644
--- a/deploy/freedns-webhook/templates/rbac.yaml
+++ b/deploy/freedns-webhook/templates/rbac.yaml
@@ -8,45 +8,6 @@ metadata:
     release: {{ .Release.Name }}
     heritage: {{ .Release.Service }}
 ---
-apiVersion: rbac.authorization.k8s.io/v1
-kind: Role
-metadata:
-  name: {{ include "freedns-webhook.fullname" . }}:secret-read
-  namespace: {{ .Release.Namespace }}
-  labels:
-    app: {{ include "freedns-webhook.name" . }}
-    chart: {{ include "freedns-webhook.chart" . }}
-    release: {{ .Release.Name }}
-    heritage: {{ .Release.Service }}
-rules:
-  - apiGroups:
-      - ''
-    resources:
-      - 'secrets'
-    verbs:
-      - 'get'
----
-# Grant the webhook permission to read the secret
-apiVersion: rbac.authorization.k8s.io/v1
-kind: RoleBinding
-metadata:
-  name: {{ include "freedns-webhook.fullname" . }}:secret-read
-  namespace: {{ .Release.Namespace }}
-  labels:
-    app: {{ include "freedns-webhook.name" . }}
-    chart: {{ include "freedns-webhook.chart" . }}
-    release: {{ .Release.Name }}
-    heritage: {{ .Release.Service }}
-roleRef:
-  apiGroup: rbac.authorization.k8s.io
-  kind: Role
-  name: {{ include "freedns-webhook.fullname" . }}:secret-read
-subjects:
-  - apiGroup: ""
-    kind: ServiceAccount
-    name: {{ include "freedns-webhook.fullname" . }}
-    namespace: {{ .Release.Namespace }}
----
 # Grant the webhook permission to read the ConfigMap containing the Kubernetes
 # apiserver's requestheader-ca-certificate.
 # This ConfigMap is automatically created by the Kubernetes apiserver.
diff --git a/deploy/freedns-webhook/templates/secrets.yaml b/deploy/freedns-webhook/templates/secrets.yaml
new file mode 100644
index 0000000..cc49b3c
--- /dev/null
+++ b/deploy/freedns-webhook/templates/secrets.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Secret
+type: Opaque
+data:
+  FREEDNS_USERNAME: {{ required "Please provide the value of freedns.auth.FREEDNS_USERNAME" .Values.freedns.auth.FREEDNS_USERNAME | b64enc | quote }}
+  FREEDNS_PASSWORD: {{ required "Please provide the value of freedns.auth.FREEDNS_PASSWORD" .Values.freedns.auth.FREEDNS_PASSWORD | b64enc | quote }}
+metadata:
+  name: {{ include "freedns-webhook.fullname" . }}-auth
+  namespace: {{ .Release.Namespace | quote }}
+  labels:
+    app: {{ include "freedns-webhook.name" . }}
+    chart: {{ include "freedns-webhook.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+type: Opaque
diff --git a/deploy/freedns-webhook/values.yaml b/deploy/freedns-webhook/values.yaml
index a15228f..137c488 100644
--- a/deploy/freedns-webhook/values.yaml
+++ b/deploy/freedns-webhook/values.yaml
@@ -14,7 +14,7 @@ certManager:
 
 image:
   repository: penguinade/cert-manager-webhook-freedns
-  tag: 2024.11.02.04
+  tag: 2024.11.02.05
   pullPolicy: IfNotPresent
 
 nameOverride: ""
@@ -24,6 +24,11 @@ service:
   type: ClusterIP
   port: 443
 
+freedns:
+  auth:
+    FREEDNS_USERNAME:
+    FREEDNS_PASSWORD:
+
 resources: {}
   # We usually recommend not to specify default resources and to leave this as a conscious
   # choice for the user. This also increases chances charts run on environments with little
diff --git a/main.go b/main.go
index da33ecd..7f16f30 100644
--- a/main.go
+++ b/main.go
@@ -1,14 +1,12 @@
 package main
 
 import (
-	"context"
 	"encoding/json"
 	"fmt"
 	"os"
 	"strings"
 
 	extapi "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/client-go/kubernetes"
 	"k8s.io/client-go/rest"
 
@@ -19,11 +17,19 @@ import (
 )
 
 var GroupName = os.Getenv("GROUP_NAME")
+var UserName = os.Getenv("FREEDNS_USERNAME")
+var Password = os.Getenv("FREEDNS_PASSWORD")
 
 func main() {
 	if GroupName == "" {
 		panic("GROUP_NAME must be specified")
 	}
+	if UserName == "" {
+		panic("FREEDNS_USERNAME must be specified")
+	}
+	if Password == "" {
+		panic("FREEDNS_PASSWORD must be specified")
+	}
 
 	// This will register our custom DNS provider with the webhook serving
 	// library, making it available as an API under the provided GroupName.
@@ -91,22 +97,8 @@ func (c *customDNSProviderSolver) Name() string {
 // cert-manager itself will later perform a self check to ensure that the
 // solver has correctly configured the DNS provider.
 func (c *customDNSProviderSolver) Present(ch *v1alpha1.ChallengeRequest) error {
-	cfg, err := loadConfig(ch.Config)
-	if err != nil {
-		return err
-	}
-
-	secretName := cfg.SecretRef
-	secretObj, err := c.client.CoreV1().Secrets(ch.ResourceNamespace).Get(context.Background(), secretName, metav1.GetOptions{})
-	if err != nil {
-		return fmt.Errorf("Unable to get secret `%s/%s`; %v", secretName, ch.ResourceNamespace, err)
-	}
-
-	username := string(secretObj.Data["username"])
-	password := string(secretObj.Data["password"])
-
 	dnsObj := freedns.FreeDNS{}
-	err = dnsObj.Login(username, password)
+	err := dnsObj.Login(UserName, Password)
 	if err != nil {
 		return err
 	}