Skip to content

Commit

Permalink
feat: add validation webhook (#239)
Browse files Browse the repository at this point in the history
Signed-off-by: Charles-Edouard Brétéché <[email protected]>
  • Loading branch information
eddycharly authored Nov 25, 2024
1 parent 68105dc commit b2ff6a3
Show file tree
Hide file tree
Showing 35 changed files with 701 additions and 81 deletions.
67 changes: 61 additions & 6 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ jobs:
retention-days: 1
if-no-files-found: error

e2e-tests-chainsaw:
e2e-sidecar-injector:
runs-on: ubuntu-latest
needs: [ prepare-images ]
steps:
Expand Down Expand Up @@ -110,13 +110,68 @@ jobs:
with:
node_image: kindest/node:v1.29.2
cluster_name: kind
- name: Setup test environment
- name: Load image archive
run: |
set -e
make kind-load-archive
- name: Setup cert-manager
run: |
set -e
export HELM=${{ steps.helm.outputs.helm-path }}
make install-cert-manager install-cluster-issuer
- name: Install chart
run: |
set -e
export HELM=${{ steps.helm.outputs.helm-path }}
make docker-load-image
make install-cert-manager
make install-cluster-issuer
make install-kyverno-sidecar-injector
- name: Run Chainsaw Tests
run: chainsaw test tests/e2e-test
run: chainsaw test tests/e2e/sidecar-injector


e2e-authz-server:
runs-on: ubuntu-latest
needs: [ prepare-images ]
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup go
uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0
with:
go-version-file: go.mod
cache-dependency-path: go.sum
- name: Install helm
id: helm
uses: azure/setup-helm@fe7b79cd5ee1e45176fcad797de68ecaf3ca4814 # v4.2.0
- name: Install cosign
uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da # v3.7.0
- name: Install chainsaw
uses: kyverno/action-install-chainsaw@d311eacde764f806c9658574ff64c9c3b21f8397 # v0.2.11
with:
verify: true
- name: Download image archive
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: image.tar
- name: Create kind cluster
uses: helm/kind-action@0025e74a8c7512023d06dc019c617aa3cf561fde # v1.10.0
with:
node_image: kindest/node:v1.29.2
cluster_name: kind
- name: Load image archive
run: |
set -e
make kind-load-archive
- name: Setup cert-manager
run: |
set -e
export HELM=${{ steps.helm.outputs.helm-path }}
make install-cert-manager install-cluster-issuer
- name: Install chart
run: |
set -e
export HELM=${{ steps.helm.outputs.helm-path }}
make deploy-kyverno-authz-server
- name: Run Chainsaw Tests
run: chainsaw test tests/e2e/validation-webhook
# - name: Run Chainsaw Tests
# run: chainsaw test tests/e2e/authz-server
50 changes: 38 additions & 12 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ codegen: codegen-schemas-json

.PHONY: verify-codegen
verify-codegen: ## Verify all generated code and docs are up to date
verify-codegen: go-mod-tidy
verify-codegen: codegen
@echo Checking codegen is up to date... >&2
@git --no-pager diff -- .
Expand All @@ -203,9 +204,11 @@ vet: ## Run go vet
@echo Go vet... >&2
@go vet ./...

#########
# BUILD #
#########
.PHONY: go-mod-tidy
go-mod-tidy: ## Run go mod tidy
go-mod-tidy:
@echo Run go mod tidy... >&2
@go mod tidy

.PHONY: build
build: ## Build
Expand Down Expand Up @@ -284,10 +287,17 @@ kind-create-cluster: $(KIND)

.PHONY: kind-load-image
kind-load-image: ## Build image and load it in kind cluster
kind-load-image: ko-build
kind-load-image: $(KIND)
@echo Load image in kind... >&2
@$(KIND) load docker-image $(KO_REGISTRY)/$(PACKAGE):$(GIT_SHA)

.PHONY: kind-load-archive
kind-load-archive: ## Load image archive in kind cluster
kind-load-archive: $(KIND)
@echo Load image archive in kind... >&2
@$(KIND) load image-archive image.tar

################
# CERTIFICATES #
################
Expand Down Expand Up @@ -316,6 +326,7 @@ install-cert-manager: $(HELM)

.PHONY: install-cluster-issuer
install-cluster-issuer: ## Install cert-manager cluster issuer
install-cluster-issuer: install-cert-manager
install-cluster-issuer:
@echo Install cert-manager cluster issuer... >&2
@kubectl apply -f .manifests/cert-manager/cluster-issuer.yaml
Expand All @@ -335,10 +346,9 @@ install-istio: $(HELM)
# HELM #
########

.PHONY: install-kyverno-sidecar-injector
install-kyverno-sidecar-injector: ## Install kyverno-sidecar-injector chart
install-kyverno-sidecar-injector: kind-load-image
install-kyverno-sidecar-injector: $(HELM)
.PHONY: deploy-kyverno-sidecar-injector
deploy-kyverno-sidecar-injector: ## Deploy kyverno-sidecar-injector chart
deploy-kyverno-sidecar-injector: $(HELM)
@echo Build kyverno-sidecar-injector dependecy... >&2
@$(HELM) dependency build --skip-refresh ./charts/kyverno-sidecar-injector
@echo Install kyverno-sidecar-injector chart... >&2
Expand All @@ -350,17 +360,33 @@ install-kyverno-sidecar-injector: $(HELM)
--set certificates.certManager.issuerRef.kind=ClusterIssuer \
--set certificates.certManager.issuerRef.group=cert-manager.io

.PHONY: install-kyverno-authz-server
install-kyverno-authz-server: ## Install kyverno-authz-server chart
install-kyverno-authz-server: kind-load-image
install-kyverno-authz-server: $(HELM)
.PHONY: install-kyverno-sidecar-injector
install-kyverno-sidecar-injector: ## Install kyverno-sidecar-injector chart
install-kyverno-sidecar-injector: kind-load-image
install-kyverno-authz-server: install-cluster-issuer
install-kyverno-sidecar-injector: $(HELM)
@$(MAKE) deploy-kyverno-sidecar-injector

.PHONY: deploy-kyverno-authz-server
deploy-kyverno-authz-server: ## Deploy kyverno-authz-server chart
deploy-kyverno-authz-server: $(HELM)
@echo Build kyverno-authz-server dependecy... >&2
@$(HELM) dependency build --skip-refresh ./charts/kyverno-authz-server
@echo Install kyverno-authz-server chart... >&2
@$(HELM) upgrade --install kyverno-authz-server --namespace kyverno --create-namespace --wait ./charts/kyverno-authz-server \
--set containers.server.image.registry=$(KO_REGISTRY) \
--set containers.server.image.repository=$(PACKAGE) \
--set containers.server.image.tag=$(GIT_SHA)
--set containers.server.image.tag=$(GIT_SHA) \
--set certificates.certManager.issuerRef.group=cert-manager.io \
--set certificates.certManager.issuerRef.kind=ClusterIssuer \
--set certificates.certManager.issuerRef.name=selfsigned-issuer

.PHONY: install-kyverno-authz-server
install-kyverno-authz-server: ## Install kyverno-authz-server chart
install-kyverno-authz-server: kind-load-image
install-kyverno-authz-server: install-cluster-issuer
install-kyverno-authz-server: $(HELM)
@$(MAKE) deploy-kyverno-authz-server

########
# HELP #
Expand Down
8 changes: 7 additions & 1 deletion charts/kyverno-authz-server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ helm install kyverno-authz-server --namespace kyverno --create-namespace kyverno
| rbac.create | bool | `true` | Create RBAC resources |
| rbac.serviceAccount.name | string | `nil` | The ServiceAccount name |
| rbac.serviceAccount.annotations | object | `{}` | Annotations for the ServiceAccount |
| certificates.static | object | `{}` | Static data to set in certificate secret |
| certificates.certManager | object | `{}` | Infos for creating certificate with cert manager |
| deployment.replicas | int | `nil` | Desired number of pods |
| deployment.revisionHistoryLimit | int | `10` | The number of revisions to keep |
| deployment.annotations | object | `{}` | Deployment annotations. |
Expand Down Expand Up @@ -64,11 +66,15 @@ helm install kyverno-authz-server --namespace kyverno --create-namespace kyverno
| containers.server.livenessProbe | object | See [values.yaml](values.yaml) | Liveness probe. The block is directly forwarded into the deployment, so you can use whatever livenessProbe configuration you want. ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/ |
| containers.server.readinessProbe | object | See [values.yaml](values.yaml) | Readiness Probe. The block is directly forwarded into the deployment, so you can use whatever readinessProbe configuration you want. ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/ |
| containers.server.ports | list | `[{"containerPort":9080,"name":"http","protocol":"TCP"},{"containerPort":9081,"name":"grpc","protocol":"TCP"}]` | Container ports. |
| containers.server.args | list | `["serve","authz-server","--http-address=:9080","--grpc-address=:9081"]` | Container args. |
| containers.server.args | list | `["serve","authz-server","--probes-address=:9080","--grpc-address=:9081"]` | Container args. |
| service.port | int | `9081` | Service port. |
| service.type | string | `"ClusterIP"` | Service type. |
| service.nodePort | string | `nil` | Service node port. Only used if `type` is `NodePort`. |
| service.annotations | object | `{}` | Service annotations. |
| webhook.annotations | object | `{}` | Webhook annotations |
| webhook.failurePolicy | string | `"Fail"` | Webhook failure policy |
| webhook.objectSelector | string | `nil` | Webhook object selector |
| webhook.namespaceSelector | object | `{"matchExpressions":[{"key":"kyverno-injection","operator":"In","values":["enabled"]}]}` | Webhook namespace selector |
| pdb | string | `nil` | |

## Source Code
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{{/* vim: set filetype=mustache: */}}

{{- define "validation-webhook.name" -}}
{{ template "kyverno.lib.names.name" . }}-validation
{{- end -}}

{{- define "validation-webhook.labels" -}}
{{- template "kyverno.lib.labels.merge" (list
(include "kyverno.lib.labels.common" .)
(include "validation-webhook.labels.selector" .)
) -}}
{{- end -}}

{{- define "validation-webhook.labels.selector" -}}
{{- template "kyverno.lib.labels.merge" (list
(include "kyverno.lib.labels.common.selector" .)
(include "kyverno.lib.labels.component" "validation-webhook")
) -}}
{{- end -}}

{{- define "validation-webhook.service-account.name" -}}
{{- if .Values.rbac.create -}}
{{- default (include "validation-webhook.name" .) .Values.rbac.serviceAccount.name -}}
{{- else -}}
{{- required "A service account name is required when `rbac.create` is set to `false`" .Values.rbac.serviceAccount.name -}}
{{- end -}}
{{- end -}}

{{- define "validation-webhook.image" -}}
{{- printf "%s/%s:%s" .registry .repository (default "latest" .tag) -}}
{{- end -}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{{- if .Values.certificates.certManager -}}
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: {{ template "validation-webhook.name" . }}
namespace: {{ template "kyverno.lib.namespace" . }}
labels:
{{- include "validation-webhook.labels" . | nindent 4 }}
spec:
secretName: {{ template "validation-webhook.name" . }}
dnsNames:
- {{ printf "%s.%s.svc" (include "validation-webhook.name" .) (include "kyverno.lib.namespace" .) }}
{{- with .Values.certificates.certManager.issuerRef }}
issuerRef:
{{- tpl (toYaml .) $ | nindent 4 }}
{{- end }}
{{- end }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{{- if .Values.certificates.static -}}
apiVersion: v1
kind: Secret
metadata:
name: {{ template "validation-webhook.name" . }}
namespace: {{ template "kyverno.lib.namespace" . }}
labels:
{{- include "validation-webhook.labels" . | nindent 4 }}
type: kubernetes.io/tls
data:
tls.crt: {{ .Values.certificates.static.crt | b64enc }}
tls.key: {{ .Values.certificates.static.key | b64enc }}
{{- end }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ template "validation-webhook.name" . }}
namespace: {{ template "kyverno.lib.namespace" . }}
labels:
{{- include "validation-webhook.labels" . | nindent 4 }}
{{- with .Values.deployment.annotations }}
annotations:
{{- tpl (toYaml .) $ | nindent 4 }}
{{- end }}
spec:
{{- with .Values.deployment.replicas }}
replicas: {{ . }}
{{- end }}
revisionHistoryLimit: {{ .Values.deployment.revisionHistoryLimit }}
{{- with .Values.deployment.updateStrategy }}
strategy:
{{- toYaml . | nindent 4 }}
{{- end }}
selector:
matchLabels:
{{- include "validation-webhook.labels.selector" . | nindent 6 }}
template:
metadata:
labels:
{{- include "validation-webhook.labels" . | nindent 8 }}
{{- with .Values.pod.labels }}
{{- tpl (toYaml .) $ | nindent 8 }}
{{- end }}
{{- with .Values.pod.annotations }}
annotations: {{ tpl (toYaml .) $ | nindent 8 }}
{{- end }}
spec:
{{- with .Values.pod.imagePullSecrets }}
imagePullSecrets:
{{- tpl (toYaml .) $ | nindent 8 }}
{{- end }}
{{- with .Values.pod.securityContext }}
securityContext:
{{- tpl (toYaml .) $ | nindent 8 }}
{{- end }}
{{- with .Values.pod.nodeSelector }}
nodeSelector:
{{- tpl (toYaml .) $ | nindent 8 }}
{{- end }}
{{- with .Values.pod.tolerations }}
tolerations:
{{- tpl (toYaml .) $ | nindent 8 }}
{{- end }}
{{- with .Values.pod.topologySpreadConstraints }}
topologySpreadConstraints:
{{- tpl (toYaml .) $ | nindent 8 }}
{{- end }}
{{- with .Values.pod.priorityClassName }}
priorityClassName: {{ . | quote }}
{{- end }}
{{- with .Values.pod.hostNetwork }}
hostNetwork: {{ . }}
{{- end }}
{{- with .Values.pod.dnsPolicy }}
dnsPolicy: {{ . }}
{{- end }}
affinity:
{{- with .Values.pod.antiAffinity }}
podAntiAffinity:
{{- tpl (toYaml .) $ | nindent 10 }}
{{- end }}
{{- with .Values.pod.affinity }}
podAffinity:
{{- tpl (toYaml .) $ | nindent 10 }}
{{- end }}
{{- with .Values.pod.nodeAffinity }}
nodeAffinity:
{{- tpl (toYaml .) $ | nindent 10 }}
{{- end }}
serviceAccountName: {{ template "validation-webhook.service-account.name" . }}
volumes:
- name: certs
secret:
secretName: {{ template "validation-webhook.name" . }}
containers:
{{- with .Values.containers.server }}
- name: server
image: {{ include "validation-webhook.image" (mustMerge .image (dict "tag" (default $.Chart.Version $.Chart.AppVersion))) }}
imagePullPolicy: {{ .image.pullPolicy }}
{{- with .resources }}
resources:
{{- tpl (toYaml .) $ | nindent 12 }}
{{- end }}
{{- with .securityContext }}
securityContext:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .startupProbe }}
startupProbe:
{{- tpl (toYaml .) $ | nindent 12 }}
{{- end }}
{{- with .livenessProbe }}
livenessProbe:
{{- tpl (toYaml .) $ | nindent 12 }}
{{- end }}
{{- with .readinessProbe }}
readinessProbe:
{{- tpl (toYaml .) $ | nindent 12 }}
{{- end }}
{{- with .ports }}
ports:
{{- tpl (toYaml .) $ | nindent 12 }}
{{- end }}
args:
- serve
- validation-webhook
- --probes-address=:9080
volumeMounts:
- name: certs
mountPath: /tmp/k8s-webhook-server/serving-certs
readOnly: true
{{- end }}
Loading

0 comments on commit b2ff6a3

Please sign in to comment.