Skip to content

Commit 0873fc4

Browse files
Create RayCluster ValidatingWebhook
1 parent 9f5bde6 commit 0873fc4

File tree

7 files changed

+78
-2
lines changed

7 files changed

+78
-2
lines changed

PROJECT

+1
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,6 @@ resources:
1919
version: v1
2020
webhooks:
2121
defaulting: true
22+
validation: true
2223
webhookVersion: v1
2324
version: "3"

config/openshift/kustomization.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ namespace: openshift-operators
66
# "wordpress" becomes "alices-wordpress".
77
# Note that it should also match with the prefix (text before '-') of the namespace
88
# field above.
9-
namePrefix: codeflare-operator-
109

1110
# Labels to add to all resources and selectors.
1211
commonLabels:
@@ -19,4 +18,5 @@ bases:
1918

2019
patches:
2120
- path: manager_webhook_patch.yaml
22-
- path: webhookcainjection_patch.yaml
21+
- path: webhookcainjection_mpatch.yaml
22+
- path: webhookcainjection_vpatch.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# This patch add annotation to admission webhook config
2+
apiVersion: admissionregistration.k8s.io/v1
3+
kind: ValidatingWebhookConfiguration
4+
metadata:
5+
name: validating-webhook-configuration
6+
annotations:
7+
service.beta.openshift.io/inject-cabundle: "true"

config/webhook/kustomization.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
namePrefix: codeflare-operator-
2+
13
resources:
24
- manifests.yaml
35
- service.yaml

config/webhook/manifests.yaml

+27
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,30 @@ webhooks:
2525
resources:
2626
- rayclusters
2727
sideEffects: None
28+
---
29+
apiVersion: admissionregistration.k8s.io/v1
30+
kind: ValidatingWebhookConfiguration
31+
metadata:
32+
creationTimestamp: null
33+
name: validating-webhook-configuration
34+
webhooks:
35+
- admissionReviewVersions:
36+
- v1
37+
clientConfig:
38+
service:
39+
name: webhook-service
40+
namespace: system
41+
path: /validate-ray-io-v1-raycluster
42+
failurePolicy: Fail
43+
name: vraycluster.kb.io
44+
rules:
45+
- apiGroups:
46+
- ray.io
47+
apiVersions:
48+
- v1
49+
operations:
50+
- CREATE
51+
- UPDATE
52+
resources:
53+
- rayclusters
54+
sideEffects: None

pkg/controllers/raycluster_webhook.go

+39
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,12 @@ import (
2323

2424
corev1 "k8s.io/api/core/v1"
2525
"k8s.io/apimachinery/pkg/runtime"
26+
"k8s.io/apimachinery/pkg/util/validation/field"
2627
"k8s.io/utils/pointer"
2728
ctrl "sigs.k8s.io/controller-runtime"
2829
logf "sigs.k8s.io/controller-runtime/pkg/log"
2930
"sigs.k8s.io/controller-runtime/pkg/webhook"
31+
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
3032

3133
"github.com/project-codeflare/codeflare-operator/pkg/config"
3234
)
@@ -40,16 +42,24 @@ func SetupRayClusterWebhookWithManager(mgr ctrl.Manager, cfg *config.KubeRayConf
4042
WithDefaulter(&rayClusterDefaulter{
4143
Config: cfg,
4244
}).
45+
WithValidator(&rayClusterWebhook{
46+
Config: cfg,
47+
}).
4348
Complete()
4449
}
4550

4651
// +kubebuilder:webhook:path=/mutate-ray-io-v1-raycluster,mutating=true,failurePolicy=fail,sideEffects=None,groups=ray.io,resources=rayclusters,verbs=create;update,versions=v1,name=mraycluster.kb.io,admissionReviewVersions=v1
52+
// +kubebuilder:webhook:path=/validate-ray-io-v1-raycluster,mutating=false,failurePolicy=fail,sideEffects=None,groups=ray.io,resources=rayclusters,verbs=create;update,versions=v1,name=vraycluster.kb.io,admissionReviewVersions=v1
4753

4854
type rayClusterDefaulter struct {
4955
Config *config.KubeRayConfiguration
5056
}
57+
type rayClusterWebhook struct {
58+
Config *config.KubeRayConfiguration
59+
}
5160

5261
var _ webhook.CustomDefaulter = &rayClusterDefaulter{}
62+
var _ webhook.CustomValidator = &rayClusterWebhook{}
5363

5464
// Default implements webhook.Defaulter so a webhook will be registered for the type
5565
func (r *rayClusterDefaulter) Default(ctx context.Context, obj runtime.Object) error {
@@ -132,3 +142,32 @@ func (r *rayClusterDefaulter) Default(ctx context.Context, obj runtime.Object) e
132142

133143
return nil
134144
}
145+
146+
func (v *rayClusterWebhook) ValidateCreate(ctx context.Context, obj runtime.Object) (admission.Warnings, error) {
147+
raycluster := obj.(*rayv1.RayCluster)
148+
var warnings admission.Warnings
149+
var allErrors field.ErrorList
150+
specPath := field.NewPath("spec")
151+
152+
if pointer.BoolDeref(raycluster.Spec.HeadGroupSpec.EnableIngress, false) {
153+
rayclusterlog.Info("Creating RayCluster resources with EnableIngress set to true or unspecified is not allowed")
154+
allErrors = append(allErrors, field.Invalid(specPath.Child("headGroupSpec").Child("enableIngress"), raycluster.Spec.HeadGroupSpec.EnableIngress, "creating RayCluster resources with EnableIngress set to true or unspecified is not allowed"))
155+
}
156+
157+
return warnings, allErrors.ToAggregate()
158+
}
159+
160+
func (v *rayClusterWebhook) ValidateUpdate(ctx context.Context, oldObj, newObj runtime.Object) (admission.Warnings, error) {
161+
newRayCluster := newObj.(*rayv1.RayCluster)
162+
if !newRayCluster.DeletionTimestamp.IsZero() {
163+
// Object is being deleted, skip validations
164+
return nil, nil
165+
}
166+
warnings, err := v.ValidateCreate(ctx, newRayCluster)
167+
return warnings, err
168+
}
169+
170+
func (v *rayClusterWebhook) ValidateDelete(ctx context.Context, obj runtime.Object) (admission.Warnings, error) {
171+
// Optional: Add delete validation logic here
172+
return nil, nil
173+
}

0 commit comments

Comments
 (0)