Skip to content

Commit bc4e445

Browse files
feat(ws): add validation webhooks for Workspace and WorkspaceKind (#34)
* add validating webhook Signed-off-by: Adem Baccara <[email protected]> * add tests for workspacekind and workspace webhooks Signed-off-by: Adem Baccara <[email protected]> * re-add cert-manager Signed-off-by: Adem Baccara <[email protected]> * refactor ValidateCreate and ValidateUpdate functions in wokrspaceKind webhook Signed-off-by: Adem Baccara <[email protected]> * add e2e test for webhooks Signed-off-by: Adem Baccara <[email protected]> * mathew refactor 1 Signed-off-by: Mathew Wicks <[email protected]> * mathew refactor 2 Signed-off-by: Mathew Wicks <[email protected]> * mathew refactor 3 Signed-off-by: Mathew Wicks <[email protected]> --------- Signed-off-by: Adem Baccara <[email protected]> Signed-off-by: Mathew Wicks <[email protected]> Co-authored-by: Mathew Wicks <[email protected]>
1 parent 38b8955 commit bc4e445

37 files changed

+3106
-221
lines changed

workspaces/controller/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ endef
199199

200200
define prompt_for_e2e_test_execution
201201
if [ "$$(echo "$(KUBEFLOW_TEST_PROMPT)" | tr '[:upper:]' '[:lower:]')" = "false" ]; then \
202-
echo "Skipping E2E test confirmation prompt (KUBEFLOW_TEST_PROMPT is set to true)"; \
202+
echo "Skipping E2E test confirmation prompt (KUBEFLOW_TEST_PROMPT is set to false)"; \
203203
else \
204204
current_k8s_context=$$(kubectl config current-context); \
205205
echo "================================ WARNING ================================"; \

workspaces/controller/PROJECT

+6
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,17 @@ resources:
1616
kind: Workspace
1717
path: github.com/kubeflow/notebooks/workspaces/controller/api/v1beta1
1818
version: v1beta1
19+
webhooks:
20+
validation: true
21+
webhookVersion: v1
1922
- api:
2023
crdVersion: v1
2124
controller: true
2225
domain: kubeflow.org
2326
kind: WorkspaceKind
2427
path: github.com/kubeflow/notebooks/workspaces/controller/api/v1beta1
2528
version: v1beta1
29+
webhooks:
30+
validation: true
31+
webhookVersion: v1
2632
version: "3"

workspaces/controller/cmd/main.go

+34-4
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ import (
3535
"sigs.k8s.io/controller-runtime/pkg/webhook"
3636

3737
kubefloworgv1beta1 "github.com/kubeflow/notebooks/workspaces/controller/api/v1beta1"
38-
"github.com/kubeflow/notebooks/workspaces/controller/internal/controller"
38+
controllerInternal "github.com/kubeflow/notebooks/workspaces/controller/internal/controller"
39+
"github.com/kubeflow/notebooks/workspaces/controller/internal/helper"
40+
webhookInternal "github.com/kubeflow/notebooks/workspaces/controller/internal/webhook"
3941
//+kubebuilder:scaffold:imports
4042
)
4143

@@ -115,21 +117,30 @@ func main() {
115117
// the manager stops, so would be fine to enable this option. However,
116118
// if you are doing or is intended to do any operation such as perform cleanups
117119
// after the manager stops then its usage might be unsafe.
118-
// LeaderElectionReleaseOnCancel: true,
120+
//
121+
// TODO: check if we are doing anything which would prevent us from using this option.
122+
//LeaderElectionReleaseOnCancel: true,
119123
})
120124
if err != nil {
121125
setupLog.Error(err, "unable to start manager")
122126
os.Exit(1)
123127
}
124128

125-
if err = (&controller.WorkspaceReconciler{
129+
// setup field indexers on the manager cache. we use these indexes to efficiently
130+
// query the cache for things like which Workspaces are using a particular WorkspaceKind
131+
if err := helper.SetupManagerFieldIndexers(mgr); err != nil {
132+
setupLog.Error(err, "unable to setup field indexers")
133+
os.Exit(1)
134+
}
135+
136+
if err = (&controllerInternal.WorkspaceReconciler{
126137
Client: mgr.GetClient(),
127138
Scheme: mgr.GetScheme(),
128139
}).SetupWithManager(mgr); err != nil {
129140
setupLog.Error(err, "unable to create controller", "controller", "Workspace")
130141
os.Exit(1)
131142
}
132-
if err = (&controller.WorkspaceKindReconciler{
143+
if err = (&controllerInternal.WorkspaceKindReconciler{
133144
Client: mgr.GetClient(),
134145
Scheme: mgr.GetScheme(),
135146
}).SetupWithManager(mgr); err != nil {
@@ -138,6 +149,25 @@ func main() {
138149
}
139150
//+kubebuilder:scaffold:builder
140151

152+
if os.Getenv("ENABLE_WEBHOOKS") != "false" {
153+
if err = (&webhookInternal.WorkspaceValidator{
154+
Client: mgr.GetClient(),
155+
Scheme: mgr.GetScheme(),
156+
}).SetupWebhookWithManager(mgr); err != nil {
157+
setupLog.Error(err, "unable to create webhook", "webhook", "Workspace")
158+
os.Exit(1)
159+
}
160+
}
161+
if os.Getenv("ENABLE_WEBHOOKS") != "false" {
162+
if err = (&webhookInternal.WorkspaceKindValidator{
163+
Client: mgr.GetClient(),
164+
Scheme: mgr.GetScheme(),
165+
}).SetupWebhookWithManager(mgr); err != nil {
166+
setupLog.Error(err, "unable to create webhook", "webhook", "WorkspaceKind")
167+
os.Exit(1)
168+
}
169+
}
170+
141171
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
142172
setupLog.Error(err, "unable to set up health check")
143173
os.Exit(1)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# The following manifests contain a self-signed issuer CR and a certificate CR.
2+
# More document can be found at https://docs.cert-manager.io
3+
# WARNING: Targets CertManager v1.0. Check https://cert-manager.io/docs/installation/upgrading/ for breaking changes.
4+
apiVersion: cert-manager.io/v1
5+
kind: Issuer
6+
metadata:
7+
labels:
8+
app.kubernetes.io/name: certificate
9+
app.kubernetes.io/instance: serving-cert
10+
app.kubernetes.io/component: certificate
11+
app.kubernetes.io/created-by: workspace-controller
12+
app.kubernetes.io/part-of: workspace-controller
13+
app.kubernetes.io/managed-by: kustomize
14+
name: selfsigned-issuer
15+
namespace: system
16+
spec:
17+
selfSigned: {}
18+
---
19+
apiVersion: cert-manager.io/v1
20+
kind: Certificate
21+
metadata:
22+
labels:
23+
app.kubernetes.io/name: certificate
24+
app.kubernetes.io/instance: serving-cert
25+
app.kubernetes.io/component: certificate
26+
app.kubernetes.io/created-by: workspace-controller
27+
app.kubernetes.io/part-of: workspace-controller
28+
app.kubernetes.io/managed-by: kustomize
29+
name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml
30+
namespace: system
31+
spec:
32+
# SERVICE_NAME and SERVICE_NAMESPACE will be substituted by kustomize
33+
dnsNames:
34+
- SERVICE_NAME.SERVICE_NAMESPACE.svc
35+
- SERVICE_NAME.SERVICE_NAMESPACE.svc.cluster.local
36+
issuerRef:
37+
kind: Issuer
38+
name: selfsigned-issuer
39+
secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
resources:
2+
- certificate.yaml
3+
4+
configurations:
5+
- kustomizeconfig.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# This configuration is for teaching kustomize how to update name ref substitution
2+
nameReference:
3+
- kind: Issuer
4+
group: cert-manager.io
5+
fieldSpecs:
6+
- kind: Certificate
7+
group: cert-manager.io
8+
path: spec/issuerRef/name

workspaces/controller/config/crd/kustomization.yaml

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ patches:
1313

1414
# [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix.
1515
# patches here are for enabling the CA injection for each CRD
16-
#- path: patches/cainjection_in_workspaces.yaml
17-
#- path: patches/cainjection_in_workspacekinds.yaml
16+
- path: patches/cainjection_in_workspaces.yaml
17+
- path: patches/cainjection_in_workspacekinds.yaml
1818
#+kubebuilder:scaffold:crdkustomizecainjectionpatch
1919

2020
# [WEBHOOK] To enable webhook, uncomment the following section
2121
# the following config is for teaching kustomize how to do kustomization for CRDs.
2222

23-
#configurations:
24-
#- kustomizeconfig.yaml
23+
configurations:
24+
- kustomizeconfig.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# The following patch adds a directive for certmanager to inject CA into the CRD
2+
apiVersion: apiextensions.k8s.io/v1
3+
kind: CustomResourceDefinition
4+
metadata:
5+
annotations:
6+
cert-manager.io/inject-ca-from: CERTIFICATE_NAMESPACE/CERTIFICATE_NAME
7+
name: workspacekinds.kubeflow.org
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# The following patch adds a directive for certmanager to inject CA into the CRD
2+
apiVersion: apiextensions.k8s.io/v1
3+
kind: CustomResourceDefinition
4+
metadata:
5+
annotations:
6+
cert-manager.io/inject-ca-from: CERTIFICATE_NAMESPACE/CERTIFICATE_NAME
7+
name: workspaces.kubeflow.org
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# The following patch enables a conversion webhook for the CRD
2+
apiVersion: apiextensions.k8s.io/v1
3+
kind: CustomResourceDefinition
4+
metadata:
5+
name: workspacekinds.kubeflow.org
6+
spec:
7+
conversion:
8+
strategy: Webhook
9+
webhook:
10+
clientConfig:
11+
service:
12+
namespace: system
13+
name: webhook-service
14+
path: /convert
15+
conversionReviewVersions:
16+
- v1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# The following patch enables a conversion webhook for the CRD
2+
apiVersion: apiextensions.k8s.io/v1
3+
kind: CustomResourceDefinition
4+
metadata:
5+
name: workspaces.kubeflow.org
6+
spec:
7+
conversion:
8+
strategy: Webhook
9+
webhook:
10+
clientConfig:
11+
service:
12+
namespace: system
13+
name: webhook-service
14+
path: /convert
15+
conversionReviewVersions:
16+
- v1

0 commit comments

Comments
 (0)