From 3935fd70e743931e6322bf088cd3e1c866f2e2cd Mon Sep 17 00:00:00 2001
From: James Munnelly <james@munnelly.eu>
Date: Mon, 29 Apr 2019 17:55:26 +0100
Subject: [PATCH] Update Helm chart and Dockerfile

Signed-off-by: James Munnelly <james@munnelly.eu>
---
 .gitignore                                    |  3 +
 Dockerfile                                    | 24 ++++-
 .../example-webhook/templates/apiservice.yaml | 18 ++++
 .../example-webhook/templates/deployment.yaml | 18 ++--
 deploy/example-webhook/templates/ingress.yaml | 38 --------
 deploy/example-webhook/templates/rbac.yaml    | 90 +++++++++++++++++++
 deploy/example-webhook/templates/service.yaml |  4 +-
 deploy/example-webhook/values.yaml            |  6 +-
 main.go                                       |  9 +-
 9 files changed, 155 insertions(+), 55 deletions(-)
 create mode 100644 deploy/example-webhook/templates/apiservice.yaml
 delete mode 100644 deploy/example-webhook/templates/ingress.yaml
 create mode 100644 deploy/example-webhook/templates/rbac.yaml

diff --git a/.gitignore b/.gitignore
index f1c181e..7dcb1e9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,6 @@
 
 # Output of the go coverage tool, specifically when used with LiteIDE
 *.out
+
+# Ignore the built binary
+cert-manager-webhook-example
diff --git a/Dockerfile b/Dockerfile
index 14a64d8..70ce631 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,7 +1,25 @@
-FROM golang:1.12.1
+FROM golang:1.12.4-alpine AS build_deps
 
-COPY . /workspace
+RUN apk add --no-cache git
 
 WORKDIR /workspace
-RUN go build
+ENV GO111MODULE=on
 
+COPY go.mod .
+COPY go.sum .
+
+RUN go mod download
+
+FROM build_deps AS build
+
+COPY . .
+
+RUN CGO_ENABLED=0 go build -o webhook -ldflags '-w -extldflags "-static"' .
+
+FROM alpine:3.9
+
+RUN apk add --no-cache ca-certificates
+
+COPY --from=build /workspace/webhook /usr/local/bin/webhook
+
+ENTRYPOINT ["webhook"]
diff --git a/deploy/example-webhook/templates/apiservice.yaml b/deploy/example-webhook/templates/apiservice.yaml
new file mode 100644
index 0000000..ddd7c75
--- /dev/null
+++ b/deploy/example-webhook/templates/apiservice.yaml
@@ -0,0 +1,18 @@
+apiVersion: apiregistration.k8s.io/v1beta1
+kind: APIService
+metadata:
+  name: v1alpha1.{{ .Values.groupName }}
+  labels:
+    app: {{ include "example-webhook.name" . }}
+    chart: {{ include "example-webhook.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+spec:
+  group: {{ .Values.groupName }}
+  groupPriorityMinimum: 1000
+  versionPriority: 15
+  insecureSkipTLSVerify: true
+  service:
+    name: {{ include "example-webhook.fullname" . }}
+    namespace: {{ .Release.Namespace }}
+  version: v1alpha1
diff --git a/deploy/example-webhook/templates/deployment.yaml b/deploy/example-webhook/templates/deployment.yaml
index 4ae5220..fc0acbd 100644
--- a/deploy/example-webhook/templates/deployment.yaml
+++ b/deploy/example-webhook/templates/deployment.yaml
@@ -19,22 +19,28 @@ spec:
         app: {{ include "example-webhook.name" . }}
         release: {{ .Release.Name }}
     spec:
+      serviceAccountName: {{ include "example-webhook.fullname" . }}
       containers:
         - name: {{ .Chart.Name }}
           image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
           imagePullPolicy: {{ .Values.image.pullPolicy }}
+          env:
+            - name: GROUP_NAME
+              value: {{ .Values.groupName | quote }}
           ports:
-            - name: http
-              containerPort: 80
+            - name: https
+              containerPort: 443
               protocol: TCP
           livenessProbe:
             httpGet:
-              path: /
-              port: http
+              scheme: HTTPS
+              path: /healthz
+              port: https
           readinessProbe:
             httpGet:
-              path: /
-              port: http
+              scheme: HTTPS
+              path: /healthz
+              port: https
           resources:
 {{ toYaml .Values.resources | indent 12 }}
     {{- with .Values.nodeSelector }}
diff --git a/deploy/example-webhook/templates/ingress.yaml b/deploy/example-webhook/templates/ingress.yaml
deleted file mode 100644
index 37d8b61..0000000
--- a/deploy/example-webhook/templates/ingress.yaml
+++ /dev/null
@@ -1,38 +0,0 @@
-{{- if .Values.ingress.enabled -}}
-{{- $fullName := include "example-webhook.fullname" . -}}
-{{- $ingressPath := .Values.ingress.path -}}
-apiVersion: extensions/v1beta1
-kind: Ingress
-metadata:
-  name: {{ $fullName }}
-  labels:
-    app: {{ include "example-webhook.name" . }}
-    chart: {{ include "example-webhook.chart" . }}
-    release: {{ .Release.Name }}
-    heritage: {{ .Release.Service }}
-{{- with .Values.ingress.annotations }}
-  annotations:
-{{ toYaml . | indent 4 }}
-{{- end }}
-spec:
-{{- if .Values.ingress.tls }}
-  tls:
-  {{- range .Values.ingress.tls }}
-    - hosts:
-      {{- range .hosts }}
-        - {{ . | quote }}
-      {{- end }}
-      secretName: {{ .secretName }}
-  {{- end }}
-{{- end }}
-  rules:
-  {{- range .Values.ingress.hosts }}
-    - host: {{ . | quote }}
-      http:
-        paths:
-          - path: {{ $ingressPath }}
-            backend:
-              serviceName: {{ $fullName }}
-              servicePort: http
-  {{- end }}
-{{- end }}
diff --git a/deploy/example-webhook/templates/rbac.yaml b/deploy/example-webhook/templates/rbac.yaml
new file mode 100644
index 0000000..3e51ef0
--- /dev/null
+++ b/deploy/example-webhook/templates/rbac.yaml
@@ -0,0 +1,90 @@
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ include "example-webhook.fullname" . }}
+  labels:
+    app: {{ include "example-webhook.name" . }}
+    chart: {{ include "example-webhook.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+---
+# 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.
+apiVersion: rbac.authorization.k8s.io/v1beta1
+kind: RoleBinding
+metadata:
+  name: {{ include "example-webhook.fullname" . }}:webhook-authentication-reader
+  namespace: kube-system
+  labels:
+    app: {{ include "example-webhook.name" . }}
+    chart: {{ include "example-webhook.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: extension-apiserver-authentication-reader
+subjects:
+  - apiGroup: ""
+    kind: ServiceAccount
+    name: {{ include "example-webhook.fullname" . }}
+    namespace: {{ .Release.Namespace }}
+---
+# apiserver gets the auth-delegator role to delegate auth decisions to
+# the core apiserver
+apiVersion: rbac.authorization.k8s.io/v1beta1
+kind: ClusterRoleBinding
+metadata:
+  name: {{ include "example-webhook.fullname" . }}:auth-delegator
+  labels:
+    app: {{ include "example-webhook.name" . }}
+    chart: {{ include "example-webhook.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: system:auth-delegator
+subjects:
+  - apiGroup: ""
+    kind: ServiceAccount
+    name: {{ include "example-webhook.fullname" . }}
+    namespace: {{ .Release.Namespace }}
+---
+# Grant cert-manager permission to validate using our apiserver
+apiVersion: rbac.authorization.k8s.io/v1beta1
+kind: ClusterRole
+metadata:
+  name: {{ include "example-webhook.fullname" . }}:domain-solver
+  labels:
+    app: {{ include "example-webhook.name" . }}
+    chart: {{ include "example-webhook.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+rules:
+  - apiGroups:
+      - {{ .Values.groupName }}
+    resources:
+      - '*'
+    verbs:
+      - 'create'
+---
+apiVersion: rbac.authorization.k8s.io/v1beta1
+kind: ClusterRoleBinding
+metadata:
+  name: {{ include "example-webhook.fullname" . }}:domain-solver
+  labels:
+    app: {{ include "example-webhook.name" . }}
+    chart: {{ include "example-webhook.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: cert-manager:domain-solver
+subjects:
+  - apiGroup: ""
+    kind: ServiceAccount
+    name: {{ .Values.certManager.serviceAccountName }}
+    namespace: {{ .Values.certManager.namespace }}
diff --git a/deploy/example-webhook/templates/service.yaml b/deploy/example-webhook/templates/service.yaml
index 1c76555..572089e 100644
--- a/deploy/example-webhook/templates/service.yaml
+++ b/deploy/example-webhook/templates/service.yaml
@@ -11,9 +11,9 @@ spec:
   type: {{ .Values.service.type }}
   ports:
     - port: {{ .Values.service.port }}
-      targetPort: http
+      targetPort: https
       protocol: TCP
-      name: http
+      name: https
   selector:
     app: {{ include "example-webhook.name" . }}
     release: {{ .Release.Name }}
diff --git a/deploy/example-webhook/values.yaml b/deploy/example-webhook/values.yaml
index 6d974f9..da3f9eb 100644
--- a/deploy/example-webhook/values.yaml
+++ b/deploy/example-webhook/values.yaml
@@ -8,6 +8,10 @@
 # here is recommended.
 groupName: acme.mycompany.com
 
+certManager:
+  namespace: cert-manager
+  serviceAccountName: cert-manager
+
 image:
   repository: mycompany/webhook-image
   tag: stable
@@ -18,7 +22,7 @@ fullnameOverride: ""
 
 service:
   type: ClusterIP
-  port: 80
+  port: 443
 
 ingress:
   enabled: false
diff --git a/main.go b/main.go
index 2ba407f..8a4c78b 100644
--- a/main.go
+++ b/main.go
@@ -8,8 +8,8 @@ import (
 	//"k8s.io/client-go/kubernetes"
 	"k8s.io/client-go/rest"
 
-	"github.com/jetstack/cert-manager/pkg/acme/webhook/cmd"
 	"github.com/jetstack/cert-manager/pkg/acme/webhook/apis/acme/v1alpha1"
+	"github.com/jetstack/cert-manager/pkg/acme/webhook/cmd"
 )
 
 const GroupName = "acme.mycompany.com"
@@ -88,7 +88,7 @@ func (c *customDNSProviderSolver) Present(ch *v1alpha1.ChallengeRequest) error {
 	fmt.Printf("Decoded configuration %v", cfg)
 
 	// TODO: add code that sets a record in the DNS provider's console
-	panic("implement me")
+	return nil
 }
 
 // CleanUp should delete the relevant TXT record from the DNS provider console.
@@ -99,7 +99,7 @@ func (c *customDNSProviderSolver) Present(ch *v1alpha1.ChallengeRequest) error {
 // concurrently.
 func (c *customDNSProviderSolver) CleanUp(ch *v1alpha1.ChallengeRequest) error {
 	// TODO: add code that deletes a record from the DNS provider's console
-	panic("implement me")
+	return nil
 }
 
 // Initialize will be called when the webhook first starts.
@@ -123,8 +123,7 @@ func (c *customDNSProviderSolver) Initialize(kubeClientConfig *rest.Config, stop
 	//c.client = cl
 
 	///// END OF CODE TO MAKE KUBERNETES CLIENTSET AVAILABLE
-
-	panic("implement me")
+	return nil
 }
 
 // loadConfig is a small helper function that decodes JSON configuration into