@@ -29,6 +29,8 @@ import (
2929 "sigs.k8s.io/controller-runtime/pkg/webhook"
3030
3131 "github.com/project-codeflare/codeflare-operator/pkg/config"
32+ "k8s.io/apimachinery/pkg/util/validation/field"
33+ "sigs.k8s.io/controller-runtime/pkg/webhook/admission"
3234)
3335
3436// log is for logging in this package.
@@ -40,16 +42,21 @@ func SetupRayClusterWebhookWithManager(mgr ctrl.Manager, cfg *config.KubeRayConf
4042 WithDefaulter (& rayClusterDefaulter {
4143 Config : cfg ,
4244 }).
45+ WithValidator (& rayClusterValidator {}).
4346 Complete ()
4447}
4548
4649// +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
50+ //+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
4751
4852type rayClusterDefaulter struct {
4953 Config * config.KubeRayConfiguration
5054}
55+ type rayClusterValidator struct {}
5156
5257var _ webhook.CustomDefaulter = & rayClusterDefaulter {}
58+ var _ webhook.CustomValidator = & rayClusterValidator {}
59+
5360
5461// Default implements webhook.Defaulter so a webhook will be registered for the type
5562func (r * rayClusterDefaulter ) Default (ctx context.Context , obj runtime.Object ) error {
@@ -132,3 +139,32 @@ func (r *rayClusterDefaulter) Default(ctx context.Context, obj runtime.Object) e
132139
133140 return nil
134141}
142+
143+ func (v * rayClusterValidator ) ValidateCreate (ctx context.Context , obj runtime.Object ) (admission.Warnings , error ) {
144+ raycluster := obj .(* rayv1.RayCluster )
145+ var warnings admission.Warnings
146+ var allErrors field.ErrorList
147+ specPath := field .NewPath ("spec" )
148+
149+ if raycluster .Spec .HeadGroupSpec .EnableIngress == nil || * raycluster .Spec .HeadGroupSpec .EnableIngress {
150+ rayclusterlog .Info ("Creating RayCluster resources with EnableIngress set to true or unspecified is not allowed" )
151+ 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" ))
152+ }
153+
154+ return warnings , allErrors .ToAggregate ()
155+ }
156+
157+ func (v * rayClusterValidator ) ValidateUpdate (ctx context.Context , oldObj , newObj runtime.Object ) (admission.Warnings , error ) {
158+ newRayCluster := newObj .(* rayv1.RayCluster )
159+ if ! newRayCluster .DeletionTimestamp .IsZero () {
160+ // Object is being deleted, skip validations
161+ return nil , nil
162+ }
163+ warnings , err := v .ValidateCreate (ctx , newRayCluster )
164+ return warnings , err
165+ }
166+
167+ func (v * rayClusterValidator ) ValidateDelete (ctx context.Context , obj runtime.Object ) (admission.Warnings , error ) {
168+ // Optional: Add delete validation logic here
169+ return nil , nil
170+ }
0 commit comments