@@ -17,27 +17,34 @@ limitations under the License.
17
17
package v1beta2
18
18
19
19
import (
20
+ "context"
21
+ "fmt"
22
+
20
23
"github.com/google/go-cmp/cmp"
21
24
apierrors "k8s.io/apimachinery/pkg/api/errors"
22
25
"k8s.io/apimachinery/pkg/runtime"
23
26
"k8s.io/apimachinery/pkg/util/validation/field"
24
27
ctrl "sigs.k8s.io/controller-runtime"
25
28
"sigs.k8s.io/controller-runtime/pkg/webhook"
29
+ "sigs.k8s.io/controller-runtime/pkg/webhook/admission"
26
30
27
31
"sigs.k8s.io/cluster-api-provider-aws/feature"
32
+ "sigs.k8s.io/cluster-api/util/topology"
28
33
)
29
34
30
- func (r * AWSMachineTemplate ) SetupWebhookWithManager (mgr ctrl.Manager ) error {
35
+ func (r * AWSMachineTemplateWebhook ) SetupWebhookWithManager (mgr ctrl.Manager ) error {
31
36
return ctrl .NewWebhookManagedBy (mgr ).
32
- For (r ).
37
+ For (& AWSMachineTemplate {}).
38
+ WithValidator (r ).
33
39
Complete ()
34
40
}
35
41
36
- // +kubebuilder:webhook:verbs=create;update,path=/validate-infrastructure-cluster-x-k8s-io-v1beta2-awsmachinetemplate,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=awsmachinetemplates,versions=v1beta2,name=validation.awsmachinetemplate.infrastructure.x-k8s.io,sideEffects=None,admissionReviewVersions=v1;v1beta1
42
+ // AWSMachineTemplateWebhook implements a custom validation webhook for AWSMachineTemplate.
43
+ // +kubebuilder:object:generate=false
44
+ type AWSMachineTemplateWebhook struct {}
37
45
38
- var (
39
- _ webhook.Validator = & AWSMachineTemplate {}
40
- )
46
+ // +kubebuilder:webhook:verbs=create;update,path=/validate-infrastructure-cluster-x-k8s-io-v1beta2-awsmachinetemplate,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=awsmachinetemplates,versions=v1beta2,name=validation.awsmachinetemplate.infrastructure.x-k8s.io,sideEffects=None,admissionReviewVersions=v1;v1beta1
47
+ var _ webhook.CustomValidator = & AWSMachineTemplateWebhook {}
41
48
42
49
func (r * AWSMachineTemplate ) validateRootVolume () field.ErrorList {
43
50
var allErrs field.ErrorList
@@ -95,9 +102,14 @@ func (r *AWSMachineTemplate) validateNonRootVolumes() field.ErrorList {
95
102
}
96
103
97
104
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type.
98
- func (r * AWSMachineTemplate ) ValidateCreate () error {
105
+ func (r * AWSMachineTemplateWebhook ) ValidateCreate (_ context. Context , raw runtime. Object ) error {
99
106
var allErrs field.ErrorList
100
- spec := r .Spec .Template .Spec
107
+ obj , ok := raw .(* AWSMachineTemplate )
108
+ if ! ok {
109
+ return apierrors .NewBadRequest (fmt .Sprintf ("expected a VSphereMachineTemplate but got a %T" , raw ))
110
+ }
111
+
112
+ spec := obj .Spec .Template .Spec
101
113
102
114
if spec .CloudInit .SecretPrefix != "" {
103
115
allErrs = append (allErrs , field .Forbidden (field .NewPath ("spec" , "template" , "spec" , "cloudInit" , "secretPrefix" ), "cannot be set in templates" ))
@@ -111,8 +123,8 @@ func (r *AWSMachineTemplate) ValidateCreate() error {
111
123
allErrs = append (allErrs , field .Forbidden (field .NewPath ("spec" , "template" , "spec" , "providerID" ), "cannot be set in templates" ))
112
124
}
113
125
114
- allErrs = append (allErrs , r .validateRootVolume ()... )
115
- allErrs = append (allErrs , r .validateNonRootVolumes ()... )
126
+ allErrs = append (allErrs , obj .validateRootVolume ()... )
127
+ allErrs = append (allErrs , obj .validateNonRootVolumes ()... )
116
128
117
129
// Feature gate is not enabled but ignition is enabled then send a forbidden error.
118
130
if ! feature .Gates .Enabled (feature .BootstrapFormatIgnition ) && spec .Ignition != nil {
@@ -126,26 +138,40 @@ func (r *AWSMachineTemplate) ValidateCreate() error {
126
138
"cannot be set if spec.template.spec.ignition is set" ))
127
139
}
128
140
129
- return aggregateObjErrors (r .GroupVersionKind ().GroupKind (), r .Name , allErrs )
141
+ return aggregateObjErrors (obj .GroupVersionKind ().GroupKind (), obj .Name , allErrs )
130
142
}
131
143
132
144
// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type.
133
- func (r * AWSMachineTemplate ) ValidateUpdate (old runtime.Object ) error {
134
- oldAWSMachineTemplate := old .(* AWSMachineTemplate )
145
+ func (r * AWSMachineTemplateWebhook ) ValidateUpdate (ctx context.Context , oldRaw runtime.Object , newRaw runtime.Object ) error {
146
+ newAWSMachineTemplate , ok := newRaw .(* AWSMachineTemplate )
147
+ if ! ok {
148
+ return apierrors .NewBadRequest (fmt .Sprintf ("expected a AWSMachineTemplate but got a %T" , newRaw ))
149
+ }
150
+ oldAWSMachineTemplate , ok := oldRaw .(* AWSMachineTemplate )
151
+ if ! ok {
152
+ return apierrors .NewBadRequest (fmt .Sprintf ("expected a AWSMachineTemplate but got a %T" , oldRaw ))
153
+ }
154
+
155
+ req , err := admission .RequestFromContext (ctx )
156
+ if err != nil {
157
+ return apierrors .NewBadRequest (fmt .Sprintf ("expected a admission.Request inside context: %v" , err ))
158
+ }
159
+
160
+ var allErrs field.ErrorList
135
161
136
162
// Allow setting of cloudInit.secureSecretsBackend to "secrets-manager" only to handle v1beta2 upgrade
137
- if oldAWSMachineTemplate .Spec .Template .Spec .CloudInit .SecureSecretsBackend == "" && r .Spec .Template .Spec .CloudInit .SecureSecretsBackend == SecretBackendSecretsManager {
138
- r .Spec .Template .Spec .CloudInit .SecureSecretsBackend = ""
163
+ if oldAWSMachineTemplate .Spec .Template .Spec .CloudInit .SecureSecretsBackend == "" && newAWSMachineTemplate .Spec .Template .Spec .CloudInit .SecureSecretsBackend == SecretBackendSSMParameterStore {
164
+ newAWSMachineTemplate .Spec .Template .Spec .CloudInit .SecureSecretsBackend = ""
139
165
}
140
166
141
- if ! cmp .Equal (r .Spec , oldAWSMachineTemplate .Spec ) {
142
- return apierrors . NewBadRequest ( " AWSMachineTemplate.Spec is immutable" )
167
+ if ! topology . ShouldSkipImmutabilityChecks ( req , newAWSMachineTemplate ) && ! cmp .Equal (newAWSMachineTemplate .Spec , oldAWSMachineTemplate .Spec ) {
168
+ allErrs = append ( allErrs , field . Invalid ( field . NewPath ( "spec" ), newAWSMachineTemplate , " AWSMachineTemplate.Spec is immutable") )
143
169
}
144
170
145
- return nil
171
+ return aggregateObjErrors ( newAWSMachineTemplate . GroupVersionKind (). GroupKind (), newAWSMachineTemplate . Name , allErrs )
146
172
}
147
173
148
174
// ValidateDelete implements webhook.Validator so a webhook will be registered for the type.
149
- func (r * AWSMachineTemplate ) ValidateDelete () error {
175
+ func (r * AWSMachineTemplateWebhook ) ValidateDelete (_ context. Context , _ runtime. Object ) error {
150
176
return nil
151
177
}
0 commit comments