@@ -17,9 +17,13 @@ limitations under the License.
1717package v1alpha1
1818
1919import (
20+ "context"
2021 "fmt"
22+ "reflect"
2123
24+ apierrors "k8s.io/apimachinery/pkg/api/errors"
2225 "k8s.io/apimachinery/pkg/runtime"
26+ "k8s.io/apimachinery/pkg/util/validation/field"
2327 ctrl "sigs.k8s.io/controller-runtime"
2428 logf "sigs.k8s.io/controller-runtime/pkg/log"
2529 "sigs.k8s.io/controller-runtime/pkg/webhook"
@@ -30,74 +34,110 @@ import (
3034var cdk8sappproxylog = logf .Log .WithName ("cdk8sappproxy-resource" )
3135
3236func (c * Cdk8sAppProxy ) SetupWebhookWithManager (mgr ctrl.Manager ) error {
37+ w := new (cdk8sAppProxyWebhook )
38+
3339 return ctrl .NewWebhookManagedBy (mgr ).
3440 For (c ).
41+ WithDefaulter (w ).
42+ WithValidator (w ).
3543 Complete ()
3644}
3745
3846// +kubebuilder:webhook:path=/mutate-addons-cluster-x-k8s-io-v1alpha1-cdk8sappproxy,mutating=true,failurePolicy=fail,sideEffects=None,groups=addons.cluster.x-k8s.io,resources=cdk8sappproxies,verbs=create;update,versions=v1alpha1,name=cdk8sappproxy.kb.io,admissionReviewVersions=v1
3947
40- // var _ webhook.CustomDefaulter = &Cdk8sAppProxy{}.
41- var _ webhook.Defaulter = & Cdk8sAppProxy {}
48+ type cdk8sAppProxyWebhook struct {}
49+
50+ var (
51+ _ webhook.CustomValidator = & cdk8sAppProxyWebhook {}
52+ _ webhook.CustomDefaulter = & cdk8sAppProxyWebhook {}
53+ )
4254
4355// Default implements webhook.CustomDefaulter so a webhook will be registered for the type.
44- func (c * Cdk8sAppProxy ) Default () {
45- cdk8sappproxylog .Info ("default" , "name" , c .Name )
56+ func (* cdk8sAppProxyWebhook ) Default (_ context.Context , objRaw runtime.Object ) error {
57+ obj , ok := objRaw .(* Cdk8sAppProxy )
58+ if ! ok {
59+ return apierrors .NewBadRequest (fmt .Sprintf ("expected a Cdk8sAppProxy but got a %T" , objRaw ))
60+ }
61+ cdk8sappproxylog .Info ("default" , "name" , obj .Name )
4662
47- // Set the default git reference if not specified
48- if c . Spec . GitRepository != nil && c .Spec .GitRepository .Reference == "" {
49- c .Spec .GitRepository .Reference = "main"
63+ // Defining the Reference is optional, so we set a default value.
64+ if obj .Spec .GitRepository .Reference == "" {
65+ obj .Spec .GitRepository .Reference = "main"
5066 }
5167
52- // Set the default path if not specified
53- if c . Spec . GitRepository != nil && c .Spec .GitRepository .Path == "" {
54- c .Spec .GitRepository .Path = "."
68+ // Defining the Path is optional, so we set a default value.
69+ if obj .Spec .GitRepository .Path == "" {
70+ obj .Spec .GitRepository .Path = "."
5571 }
72+
73+ return nil
5674}
5775
76+ // TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation.
5877// +kubebuilder:webhook:path=/validate-addons-cluster-x-k8s-io-v1alpha1-cdk8sappproxy,mutating=false,failurePolicy=fail,sideEffects=None,groups=addons.cluster.x-k8s.io,resources=cdk8sappproxies,verbs=create;update,versions=v1alpha1,name=cdk8sappproxy.kb.io,admissionReviewVersions=v1
5978
60- var _ webhook.Validator = & Cdk8sAppProxy {}
79+ // ValidateCreate implements webhook.Validator so a webhook will be registered for the type.
80+ func (* cdk8sAppProxyWebhook ) ValidateCreate (_ context.Context , objRaw runtime.Object ) (admission.Warnings , error ) {
81+ var allErrs field.ErrorList
6182
62- // ValidateCreate implements webhook.CustomValidator so a webhook will be registered for the type.
63- func (c * Cdk8sAppProxy ) ValidateCreate () (admission.Warnings , error ) {
64- cdk8sappproxylog .Info ("validate create" , "name" , c .Name )
65-
66- return c .validateCdk8sAppProxy ()
67- }
83+ newObj , ok := objRaw .(* Cdk8sAppProxy )
84+ if ! ok {
85+ return nil , apierrors .NewBadRequest (fmt .Sprintf ("expected a Cdk8sAppProxy but got a %T" , objRaw ))
86+ }
6887
69- // ValidateUpdate implement webhook.CustomValidator so a webhook will be registered for the type.
70- func (c * Cdk8sAppProxy ) ValidateUpdate (oldRaw runtime.Object ) (admission.Warnings , error ) {
71- cdk8sappproxylog .Info ("validate update" , "name" , c .Name )
88+ cdk8sappproxylog .Info ("validate create" , "name" , newObj .Name )
7289
73- return c .validateCdk8sAppProxy ()
74- }
90+ if newObj .Spec .GitRepository .URL == "" {
91+ allErrs = append (allErrs ,
92+ field .Invalid (field .NewPath ("spec" , "GitRepository" , "URL" ),
93+ newObj .Spec .GitRepository .URL , "GitRepository.URL must be specified" ))
94+ }
7595
76- // ValidateDelete implements webhook.CustomValidator so a webhook will be registered for the type.
77- func ( c * Cdk8sAppProxy ) ValidateDelete () (admission. Warnings , error ) {
78- cdk8sappproxylog . Info ( "validate delete" , "name" , c . Name )
96+ if len ( allErrs ) > 0 {
97+ return nil , apierrors . NewInvalid ( GroupVersion . WithKind ( " Cdk8sAppProxy" ). GroupKind (), newObj . Name , allErrs )
98+ }
7999
80- // No validation needed for delete
81100 return nil , nil
82101}
83102
84- func (c * Cdk8sAppProxy ) validateCdk8sAppProxy () (admission.Warnings , error ) {
85- var allErrs []error
103+ // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type.
104+ func (* cdk8sAppProxyWebhook ) ValidateUpdate (_ context.Context , oldRaw , newRaw runtime.Object ) (admission.Warnings , error ) {
105+ var allErrs field.ErrorList
86106
87- if c .Spec .GitRepository == nil {
88- allErrs = append (allErrs , fmt .Errorf ("gitRepository must be specified" ))
107+ oldObj , ok := oldRaw .(* Cdk8sAppProxy )
108+ if ! ok {
109+ return nil , apierrors .NewBadRequest (fmt .Sprintf ("expected a Cdk8sAppProxy but got a %T" , oldRaw ))
110+ }
111+ newObj , ok := newRaw .(* Cdk8sAppProxy )
112+ if ! ok {
113+ return nil , apierrors .NewBadRequest (fmt .Sprintf ("expected a Cdk8sAppProxy but got a %T" , newRaw ))
89114 }
90115
91- // Validate GitRepository fields if specified
92- if c .Spec .GitRepository != nil {
93- if c .Spec .GitRepository .URL == "" {
94- allErrs = append (allErrs , fmt .Errorf ("gitRepository.url is required when gitRepository is specified" ))
95- }
116+ cdk8sappproxylog .Info ("validate update" , "name" , newObj .Name )
117+
118+ if ! reflect .DeepEqual (newObj .Spec .GitRepository .URL , oldObj .Spec .GitRepository .URL ) {
119+ allErrs = append (allErrs ,
120+ field .Invalid (field .NewPath ("spec" , "GitRepository" , "URL" ),
121+ newObj .Spec .GitRepository .URL , "field is immutable" ),
122+ )
96123 }
97124
98125 if len (allErrs ) > 0 {
99- return nil , fmt .Errorf ("validation failed: %v" , allErrs )
126+ return nil , apierrors .NewInvalid (GroupVersion .WithKind ("Cdk8sAppProxy" ).GroupKind (), newObj .Name , allErrs )
127+ }
128+
129+ return nil , nil
130+ }
131+
132+ // ValidateDelete implements webhook.Validator so a webhook will be registered for the type.
133+ func (* cdk8sAppProxyWebhook ) ValidateDelete (_ context.Context , objRaw runtime.Object ) (admission.Warnings , error ) {
134+ obj , ok := objRaw .(* Cdk8sAppProxy )
135+ if ! ok {
136+ return nil , fmt .Errorf ("expected a Cdk8sAppProxy Object but got %T" , objRaw )
100137 }
138+ cdk8sappproxylog .Info ("validate delete" , "name" , obj .Name )
139+
140+ // ToDo: Define delete validation, if we need any. Needs to be decided.
101141
102142 return nil , nil
103143}
0 commit comments