Skip to content

Commit 32b577f

Browse files
authored
Add validating, conversion, and defaulting webhooks for ManagedCluster (#8)
kubebuilder create webhook --group azure --version v1alpha1 --kind ManagedCluster --programmatic-validation --conversion --defaulting
1 parent 3783834 commit 32b577f

17 files changed

+201
-68
lines changed

README.md

+11-5
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,27 @@ ctrlarm uses [kubebuilder](https://github.com/kubernetes-sigs/kubebuilder) libra
1212

1313
## Quickstart
1414
``` bash
15-
AZURE_SUBSCRIPTION_ID="$(az account show | jq -j -r '.id')"
16-
AZURE_AUTH_LOCATION="${HOME}/creds.json"
15+
export AZURE_SUBSCRIPTION_ID="$(az account show | jq -j -r '.id')"
16+
export AZURE_AUTH_LOCATION="${HOME}/creds.json"
1717

1818
# Create Service Principal used by the ctrlarm controller
1919
az ad sp create-for-rbac --sdk-auth \
2020
--role "Contributor" \
2121
--scope "/subscriptions/${AZURE_SUBSCRIPTION_ID}" > "${AZURE_AUTH_LOCATION}"
2222

23-
AZURE_B64ENCODED_CREDENTIALS="$(cat ${AZURE_AUTH_LOCATION} | base64 -w0)"
24-
AZURE_CLIENT_ID="$(cat ${AZURE_AUTH_LOCATION} | jq -j -r '.clientId' | base64 -w0)"
25-
AZURE_CLIENT_SECRET="$(cat ${AZURE_AUTH_LOCATION} | jq -j -r '.clientSecret' | base64 -w0)"
23+
export AZURE_B64ENCODED_CREDENTIALS="$(cat ${AZURE_AUTH_LOCATION} | base64 -w0)"
24+
export AZURE_CLIENT_ID="$(cat ${AZURE_AUTH_LOCATION} | jq -j -r '.clientId' | base64 -w0)"
25+
export AZURE_CLIENT_SECRET="$(cat ${AZURE_AUTH_LOCATION} | jq -j -r '.clientSecret' | base64 -w0)"
2626

2727
# Replace "your-docker-registry"
2828
IMG=your-docker-registry/ctrlarm-controller:latest
2929

30+
# Create a namespace to run cert-manager in
31+
kubectl create namespace cert-manager
32+
33+
# Install the CustomResourceDefinitions and cert-manager itself
34+
kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v0.11.0/cert-manager.yaml
35+
3036
# Build and Deploy
3137
make docker-build docker-push install deploy
3238

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License.
14+
*/
15+
16+
package v1alpha1
17+
18+
import (
19+
"k8s.io/apimachinery/pkg/runtime"
20+
ctrl "sigs.k8s.io/controller-runtime"
21+
"sigs.k8s.io/controller-runtime/pkg/conversion"
22+
"sigs.k8s.io/controller-runtime/pkg/webhook"
23+
)
24+
25+
func (in *ManagedCluster) SetupWebhookWithManager(mgr ctrl.Manager) error {
26+
return ctrl.NewWebhookManagedBy(mgr).
27+
For(in).
28+
Complete()
29+
}
30+
31+
// nolint:lll
32+
// +kubebuilder:webhook:path=/mutate-azure-jpang-dev-v1alpha1-managedcluster,mutating=true,failurePolicy=fail,groups=azure.jpang.dev,resources=managedclusters,verbs=create;update,versions=v1alpha1,name=mmanagedcluster.kb.io
33+
34+
var _ webhook.Defaulter = &ManagedCluster{}
35+
36+
// Default implements webhook.Defaulter so a webhook will be registered for the type
37+
func (in *ManagedCluster) Default() {
38+
}
39+
40+
// nolint:lll
41+
// +kubebuilder:webhook:verbs=create;update;delete,path=/validate-azure-jpang-dev-v1alpha1-managedcluster,mutating=false,failurePolicy=fail,groups=azure.jpang.dev,resources=managedclusters,versions=v1alpha1,name=vmanagedcluster.kb.io
42+
43+
var _ webhook.Validator = &ManagedCluster{}
44+
45+
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type
46+
func (in *ManagedCluster) ValidateCreate() error {
47+
return nil
48+
}
49+
50+
// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type
51+
func (in *ManagedCluster) ValidateUpdate(old runtime.Object) error {
52+
return nil
53+
}
54+
55+
// ValidateDelete implements webhook.Validator so a webhook will be registered for the type
56+
func (in *ManagedCluster) ValidateDelete() error {
57+
return nil
58+
}
59+
60+
var _ conversion.Hub = &ManagedCluster{}
61+
62+
func (in *ManagedCluster) Hub() {}

api/v1alpha1/zz_generated.deepcopy.go

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/certmanager/certificate.yaml

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
11
# The following manifests contain a self-signed issuer CR and a certificate CR.
22
# More document can be found at https://docs.cert-manager.io
3-
apiVersion: certmanager.k8s.io/v1alpha1
3+
# WARNING: Targets CertManager 0.11 check https://docs.cert-manager.io/en/latest/tasks/upgrading/index.html for breaking changes
4+
apiVersion: cert-manager.io/v1alpha2
45
kind: Issuer
56
metadata:
67
name: selfsigned-issuer
78
namespace: system
89
spec:
910
selfSigned: {}
1011
---
11-
apiVersion: certmanager.k8s.io/v1alpha1
12+
apiVersion: cert-manager.io/v1alpha2
1213
kind: Certificate
1314
metadata:
1415
name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml
1516
namespace: system
1617
spec:
1718
# $(SERVICE_NAME) and $(SERVICE_NAMESPACE) will be substituted by kustomize
18-
commonName: $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc
1919
dnsNames:
20+
- $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc
2021
- $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc.cluster.local
2122
issuerRef:
2223
kind: Issuer
+4-4
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
# This configuration is for teaching kustomize how to update name ref and var substitution
22
nameReference:
33
- kind: Issuer
4-
group: certmanager.k8s.io
4+
group: cert-manager.io
55
fieldSpecs:
66
- kind: Certificate
7-
group: certmanager.k8s.io
7+
group: cert-manager.io
88
path: spec/issuerRef/name
99

1010
varReference:
1111
- kind: Certificate
12-
group: certmanager.k8s.io
12+
group: cert-manager.io
1313
path: spec/commonName
1414
- kind: Certificate
15-
group: certmanager.k8s.io
15+
group: cert-manager.io
1616
path: spec/dnsNames

config/crd/kustomization.yaml

+2-6
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,10 @@ resources:
66
# +kubebuilder:scaffold:crdkustomizeresource
77

88
patchesStrategicMerge:
9-
# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix.
10-
# patches here are for enabling the conversion webhook for each CRD
11-
#- patches/webhook_in_managedclusters.yaml
9+
- patches/webhook_in_managedclusters.yaml
1210
# +kubebuilder:scaffold:crdkustomizewebhookpatch
1311

14-
# [CERTMANAGER] To enable webhook, uncomment all the sections with [CERTMANAGER] prefix.
15-
# patches here are for enabling the CA injection for each CRD
16-
#- patches/cainjection_in_managedclusters.yaml
12+
- patches/cainjection_in_managedclusters.yaml
1713
# +kubebuilder:scaffold:crdkustomizecainjectionpatch
1814

1915
# the following config is for teaching kustomize how to do kustomization for CRDs.

config/crd/patches/cainjection_in_managedclusters.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ apiVersion: apiextensions.k8s.io/v1beta1
44
kind: CustomResourceDefinition
55
metadata:
66
annotations:
7-
certmanager.k8s.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
7+
cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
88
name: managedclusters.azure.jpang.dev

config/crd/patches/webhook_in_managedclusters.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ kind: CustomResourceDefinition
55
metadata:
66
name: managedclusters.azure.jpang.dev
77
spec:
8+
preserveUnknownFields: false
89
conversion:
910
strategy: Webhook
1011
webhookClientConfig:

config/default/kustomization.yaml

+31-39
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@ bases:
1616
- ../crd
1717
- ../rbac
1818
- ../manager
19-
# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in crd/kustomization.yaml
20-
#- ../webhook
21-
# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required.
22-
#- ../certmanager
19+
- ../webhook
20+
- ../certmanager
21+
# - ../prometheus
2322

2423
patchesStrategicMerge:
2524
# Protect the /metrics endpoint by putting it behind auth.
@@ -32,41 +31,34 @@ patchesStrategicMerge:
3231
# Only one of manager_auth_proxy_patch.yaml and
3332
# manager_prometheus_metrics_patch.yaml should be enabled.
3433
#- manager_prometheus_metrics_patch.yaml
35-
36-
# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in crd/kustomization.yaml
37-
#- manager_webhook_patch.yaml
38-
39-
# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'.
40-
# Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks.
41-
# 'CERTMANAGER' needs to be enabled to use ca injection
42-
#- webhookcainjection_patch.yaml
34+
- manager_webhook_patch.yaml
35+
- webhookcainjection_patch.yaml
4336

4437
# the following config is for teaching kustomize how to do var substitution
4538
vars:
46-
# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix.
47-
#- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR
48-
# objref:
49-
# kind: Certificate
50-
# group: certmanager.k8s.io
51-
# version: v1alpha1
52-
# name: serving-cert # this name should match the one in certificate.yaml
53-
# fieldref:
54-
# fieldpath: metadata.namespace
55-
#- name: CERTIFICATE_NAME
56-
# objref:
57-
# kind: Certificate
58-
# group: certmanager.k8s.io
59-
# version: v1alpha1
60-
# name: serving-cert # this name should match the one in certificate.yaml
61-
#- name: SERVICE_NAMESPACE # namespace of the service
62-
# objref:
63-
# kind: Service
64-
# version: v1
65-
# name: webhook-service
66-
# fieldref:
67-
# fieldpath: metadata.namespace
68-
#- name: SERVICE_NAME
69-
# objref:
70-
# kind: Service
71-
# version: v1
72-
# name: webhook-service
39+
- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR
40+
objref:
41+
kind: Certificate
42+
group: cert-manager.io
43+
version: v1alpha2
44+
name: serving-cert # this name should match the one in certificate.yaml
45+
fieldref:
46+
fieldpath: metadata.namespace
47+
- name: CERTIFICATE_NAME
48+
objref:
49+
kind: Certificate
50+
group: cert-manager.io
51+
version: v1alpha2
52+
name: serving-cert # this name should match the one in certificate.yaml
53+
- name: SERVICE_NAMESPACE # namespace of the service
54+
objref:
55+
kind: Service
56+
version: v1
57+
name: webhook-service
58+
fieldref:
59+
fieldpath: metadata.namespace
60+
- name: SERVICE_NAME
61+
objref:
62+
kind: Service
63+
version: v1
64+
name: webhook-service

config/default/manager_auth_proxy_patch.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ spec:
1010
spec:
1111
containers:
1212
- name: kube-rbac-proxy
13-
image: gcr.io/kubebuilder/kube-rbac-proxy:v0.4.0
13+
image: gcr.io/kubebuilder/kube-rbac-proxy:v0.4.1
1414
args:
1515
- "--secure-listen-address=0.0.0.0:8443"
1616
- "--upstream=http://127.0.0.1:8080/"

config/default/webhookcainjection_patch.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ kind: MutatingWebhookConfiguration
55
metadata:
66
name: mutating-webhook-configuration
77
annotations:
8-
certmanager.k8s.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
8+
cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
99
---
1010
apiVersion: admissionregistration.k8s.io/v1beta1
1111
kind: ValidatingWebhookConfiguration
1212
metadata:
1313
name: validating-webhook-configuration
1414
annotations:
15-
certmanager.k8s.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
15+
cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)

config/prometheus/kustomization.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
resources:
2+
- monitor.yaml

config/prometheus/monitor.yaml

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
2+
# Prometheus Monitor Service (Metrics)
3+
apiVersion: monitoring.coreos.com/v1
4+
kind: ServiceMonitor
5+
metadata:
6+
labels:
7+
control-plane: controller-manager
8+
name: controller-manager-metrics-monitor
9+
namespace: system
10+
spec:
11+
endpoints:
12+
- path: /metrics
13+
port: https
14+
selector:
15+
control-plane: controller-manager

config/rbac/auth_proxy_service.yaml

-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
apiVersion: v1
22
kind: Service
33
metadata:
4-
annotations:
5-
prometheus.io/port: "8443"
6-
prometheus.io/scheme: https
7-
prometheus.io/scrape: "true"
84
labels:
95
control-plane: controller-manager
106
name: controller-manager-metrics-service

config/webhook/manifests.yaml

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
2+
---
3+
apiVersion: admissionregistration.k8s.io/v1beta1
4+
kind: MutatingWebhookConfiguration
5+
metadata:
6+
creationTimestamp: null
7+
name: mutating-webhook-configuration
8+
webhooks:
9+
- clientConfig:
10+
caBundle: Cg==
11+
service:
12+
name: webhook-service
13+
namespace: system
14+
path: /mutate-azure-jpang-dev-v1alpha1-managedcluster
15+
failurePolicy: Fail
16+
name: mmanagedcluster.kb.io
17+
rules:
18+
- apiGroups:
19+
- azure.jpang.dev
20+
apiVersions:
21+
- v1alpha1
22+
operations:
23+
- CREATE
24+
- UPDATE
25+
resources:
26+
- managedclusters
27+
28+
---
29+
apiVersion: admissionregistration.k8s.io/v1beta1
30+
kind: ValidatingWebhookConfiguration
31+
metadata:
32+
creationTimestamp: null
33+
name: validating-webhook-configuration
34+
webhooks:
35+
- clientConfig:
36+
caBundle: Cg==
37+
service:
38+
name: webhook-service
39+
namespace: system
40+
path: /validate-azure-jpang-dev-v1alpha1-managedcluster
41+
failurePolicy: Fail
42+
name: vmanagedcluster.kb.io
43+
rules:
44+
- apiGroups:
45+
- azure.jpang.dev
46+
apiVersions:
47+
- v1alpha1
48+
operations:
49+
- CREATE
50+
- UPDATE
51+
- DELETE
52+
resources:
53+
- managedclusters

controllers/managedcluster_controller.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"github.com/go-logr/logr"
2929
corev1 "k8s.io/api/core/v1"
3030
apierrors "k8s.io/apimachinery/pkg/api/errors"
31+
"k8s.io/apimachinery/pkg/runtime"
3132
"k8s.io/apimachinery/pkg/types"
3233
"sigs.k8s.io/cluster-api/util/patch"
3334
ctrl "sigs.k8s.io/controller-runtime"
@@ -51,7 +52,8 @@ const (
5152
// ManagedClusterReconciler reconciles a ManagedCluster object
5253
type ManagedClusterReconciler struct {
5354
client.Client
54-
Log logr.Logger
55+
Log logr.Logger
56+
Scheme *runtime.Scheme
5557
}
5658

5759
type managedCluster struct {

0 commit comments

Comments
 (0)