Skip to content

Commit f12e837

Browse files
committed
Change AWSMachineTemplate webhook for SSA apply
1 parent 03c068a commit f12e837

File tree

9 files changed

+53
-49
lines changed

9 files changed

+53
-49
lines changed

api/v1beta2/awsmachinetemplate_webhook.go

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,34 @@ limitations under the License.
1717
package v1beta2
1818

1919
import (
20+
"context"
21+
"fmt"
22+
2023
"github.com/google/go-cmp/cmp"
2124
apierrors "k8s.io/apimachinery/pkg/api/errors"
2225
"k8s.io/apimachinery/pkg/runtime"
2326
"k8s.io/apimachinery/pkg/util/validation/field"
2427
ctrl "sigs.k8s.io/controller-runtime"
2528
"sigs.k8s.io/controller-runtime/pkg/webhook"
29+
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
2630

2731
"sigs.k8s.io/cluster-api-provider-aws/feature"
32+
"sigs.k8s.io/cluster-api/util/topology"
2833
)
2934

30-
func (r *AWSMachineTemplate) SetupWebhookWithManager(mgr ctrl.Manager) error {
35+
func (r *AWSMachineTemplateWebhook) SetupWebhookWithManager(mgr ctrl.Manager) error {
3136
return ctrl.NewWebhookManagedBy(mgr).
32-
For(r).
37+
For(&AWSMachineTemplate{}).
38+
WithValidator(r).
3339
Complete()
3440
}
3541

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{}
3745

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{}
4148

4249
func (r *AWSMachineTemplate) validateRootVolume() field.ErrorList {
4350
var allErrs field.ErrorList
@@ -95,9 +102,14 @@ func (r *AWSMachineTemplate) validateNonRootVolumes() field.ErrorList {
95102
}
96103

97104
// 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 {
99106
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
101113

102114
if spec.CloudInit.SecretPrefix != "" {
103115
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 {
111123
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "template", "spec", "providerID"), "cannot be set in templates"))
112124
}
113125

114-
allErrs = append(allErrs, r.validateRootVolume()...)
115-
allErrs = append(allErrs, r.validateNonRootVolumes()...)
126+
allErrs = append(allErrs, obj.validateRootVolume()...)
127+
allErrs = append(allErrs, obj.validateNonRootVolumes()...)
116128

117129
// Feature gate is not enabled but ignition is enabled then send a forbidden error.
118130
if !feature.Gates.Enabled(feature.BootstrapFormatIgnition) && spec.Ignition != nil {
@@ -126,26 +138,40 @@ func (r *AWSMachineTemplate) ValidateCreate() error {
126138
"cannot be set if spec.template.spec.ignition is set"))
127139
}
128140

129-
return aggregateObjErrors(r.GroupVersionKind().GroupKind(), r.Name, allErrs)
141+
return aggregateObjErrors(obj.GroupVersionKind().GroupKind(), obj.Name, allErrs)
130142
}
131143

132144
// 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
135161

136162
// 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 = ""
139165
}
140166

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"))
143169
}
144170

145-
return nil
171+
return aggregateObjErrors(newAWSMachineTemplate.GroupVersionKind().GroupKind(), newAWSMachineTemplate.Name, allErrs)
146172
}
147173

148174
// 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 {
150176
return nil
151177
}

api/v1beta2/awsmachinetemplate_webhook_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ func TestAWSMachineTemplateValidateUpdate(t *testing.T) {
9797
},
9898
},
9999
},
100-
wantError: true,
100+
wantError: false,
101101
},
102102
{
103103
name: "allow secrets manager",

api/v1beta2/suite_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ func setup() {
6767
if err := (&AWSMachine{}).SetupWebhookWithManager(testEnv); err != nil {
6868
panic(fmt.Sprintf("Unable to setup AWSMachine webhook: %v", err))
6969
}
70-
if err := (&AWSMachineTemplate{}).SetupWebhookWithManager(testEnv); err != nil {
70+
if err := (&AWSMachineTemplateWebhook{}).SetupWebhookWithManager(testEnv); err != nil {
7171
panic(fmt.Sprintf("Unable to setup AWSMachineTemplate webhook: %v", err))
7272
}
7373
if err := (&AWSClusterControllerIdentity{}).SetupWebhookWithManager(testEnv); err != nil {

config/webhook/manifests.yaml

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -407,28 +407,6 @@ webhooks:
407407
resources:
408408
- awsmachines
409409
sideEffects: None
410-
- admissionReviewVersions:
411-
- v1
412-
- v1beta1
413-
clientConfig:
414-
service:
415-
name: webhook-service
416-
namespace: system
417-
path: /validate-infrastructure-cluster-x-k8s-io-v1beta2-awsmachinetemplate
418-
failurePolicy: Fail
419-
matchPolicy: Equivalent
420-
name: validation.awsmachinetemplate.infrastructure.x-k8s.io
421-
rules:
422-
- apiGroups:
423-
- infrastructure.cluster.x-k8s.io
424-
apiVersions:
425-
- v1beta2
426-
operations:
427-
- CREATE
428-
- UPDATE
429-
resources:
430-
- awsmachinetemplates
431-
sideEffects: None
432410
- admissionReviewVersions:
433411
- v1
434412
- v1beta1

controllers/suite_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ func setup() {
6060
if err := (&infrav1.AWSMachine{}).SetupWebhookWithManager(testEnv); err != nil {
6161
panic(fmt.Sprintf("Unable to setup AWSMachine webhook: %v", err))
6262
}
63-
if err := (&infrav1.AWSMachineTemplate{}).SetupWebhookWithManager(testEnv); err != nil {
63+
if err := (&infrav1.AWSMachineTemplateWebhook{}).SetupWebhookWithManager(testEnv); err != nil {
6464
panic(fmt.Sprintf("Unable to setup AWSMachineTemplate webhook: %v", err))
6565
}
6666
if err := (&infrav1.AWSClusterControllerIdentity{}).SetupWebhookWithManager(testEnv); err != nil {

exp/controllers/suite_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ func setup() {
6767
if err := (&infrav1.AWSMachine{}).SetupWebhookWithManager(testEnv); err != nil {
6868
panic(fmt.Sprintf("Unable to setup AWSMachine webhook: %v", err))
6969
}
70-
if err := (&infrav1.AWSMachineTemplate{}).SetupWebhookWithManager(testEnv); err != nil {
70+
if err := (&infrav1.AWSMachineTemplateWebhook{}).SetupWebhookWithManager(testEnv); err != nil {
7171
panic(fmt.Sprintf("Unable to setup AWSMachineTemplate webhook: %v", err))
7272
}
7373
if err := (&expinfrav1.AWSMachinePool{}).SetupWebhookWithManager(testEnv); err != nil {

exp/instancestate/suite_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ func setup() {
7171
if err := (&infrav1.AWSMachine{}).SetupWebhookWithManager(testEnv); err != nil {
7272
panic(fmt.Sprintf("Unable to setup AWSMachine webhook: %v", err))
7373
}
74-
if err := (&infrav1.AWSMachineTemplate{}).SetupWebhookWithManager(testEnv); err != nil {
74+
if err := (&infrav1.AWSMachineTemplateWebhook{}).SetupWebhookWithManager(testEnv); err != nil {
7575
panic(fmt.Sprintf("Unable to setup AWSMachineTemplate webhook: %v", err))
7676
}
7777
if err := (&expinfrav1.AWSMachinePool{}).SetupWebhookWithManager(testEnv); err != nil {

main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ func setupReconcilersAndWebhooks(ctx context.Context, mgr ctrl.Manager, awsServi
276276
}
277277
}
278278

279-
if err := (&infrav1.AWSMachineTemplate{}).SetupWebhookWithManager(mgr); err != nil {
279+
if err := (&infrav1.AWSMachineTemplateWebhook{}).SetupWebhookWithManager(mgr); err != nil {
280280
setupLog.Error(err, "unable to create webhook", "webhook", "AWSMachineTemplate")
281281
os.Exit(1)
282282
}

test/e2e/data/e2e_eks_conf.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,12 @@ providers:
8080
- name: aws
8181
type: InfrastructureProvider
8282
versions:
83-
- name: v1.4.99
83+
- name: v1.6.99
8484
# Use manifest from source files
8585
value: ../../../config/default
8686
contract: v1beta1
8787
files:
88-
- sourcePath: "./shared/v1beta1_provider/metadata.yaml"
88+
- sourcePath: "./shared/v1beta2_provider/metadata.yaml"
8989
replacements:
9090
- old: "imagePullPolicy: Always"
9191
new: "imagePullPolicy: IfNotPresent"

0 commit comments

Comments
 (0)