Skip to content

Commit 03a9ef6

Browse files
authored
Merge pull request #162 from kubernetes-sigs/revert-142-allow-upgrades
Revert "api: Allow changes to CloudstackMachineTemplate"
2 parents a5fc9af + f0c20ec commit 03a9ef6

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

api/v1beta2/cloudstackmachinetemplate_webhook.go

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@ limitations under the License.
1717
package v1beta2
1818

1919
import (
20+
"fmt"
21+
"reflect"
2022
"strings"
2123

24+
"k8s.io/apimachinery/pkg/api/errors"
2225
"k8s.io/apimachinery/pkg/runtime"
2326
"k8s.io/apimachinery/pkg/util/validation/field"
2427
"sigs.k8s.io/cluster-api-provider-cloudstack/pkg/webhookutil"
@@ -76,7 +79,30 @@ func (r *CloudStackMachineTemplate) ValidateCreate() error {
7679

7780
// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type
7881
func (r *CloudStackMachineTemplate) ValidateUpdate(old runtime.Object) error {
79-
return r.ValidateCreate()
82+
cloudstackmachinetemplatelog.V(1).Info("entered validate update webhook", "api resource name", r.Name)
83+
84+
oldMachineTemplate, ok := old.(*CloudStackMachineTemplate)
85+
if !ok {
86+
return errors.NewBadRequest(fmt.Sprintf("expected a CloudStackMachineTemplate but got a %T", old))
87+
}
88+
89+
// CloudStackMachineTemplateSpec.CloudStackMachineTemplateResource.CloudStackMachineSpec
90+
spec := r.Spec.Spec.Spec
91+
oldSpec := oldMachineTemplate.Spec.Spec.Spec
92+
93+
errorList := field.ErrorList(nil)
94+
errorList = webhookutil.EnsureBothFieldsAreEqual(spec.Offering.ID, spec.Offering.Name, oldSpec.Offering.ID, oldSpec.Offering.Name, "offering", errorList)
95+
errorList = webhookutil.EnsureBothFieldsAreEqual(spec.DiskOffering.ID, spec.DiskOffering.Name, oldSpec.DiskOffering.ID, oldSpec.DiskOffering.Name, "diskOffering", errorList)
96+
errorList = webhookutil.EnsureStringFieldsAreEqual(spec.SSHKey, oldSpec.SSHKey, "sshkey", errorList)
97+
errorList = webhookutil.EnsureBothFieldsAreEqual(spec.Template.ID, spec.Template.Name, oldSpec.Template.ID, oldSpec.Template.Name, "template", errorList)
98+
errorList = webhookutil.EnsureStringStringMapFieldsAreEqual(&spec.Details, &oldSpec.Details, "details", errorList)
99+
errorList = webhookutil.EnsureStringFieldsAreEqual(spec.Affinity, oldSpec.Affinity, "affinity", errorList)
100+
101+
if !reflect.DeepEqual(spec.AffinityGroupIDs, oldSpec.AffinityGroupIDs) { // Equivalent to other Ensure funcs.
102+
errorList = append(errorList, field.Forbidden(field.NewPath("spec", "AffinityGroupIDs"), "AffinityGroupIDs"))
103+
}
104+
105+
return webhookutil.AggregateObjErrors(r.GroupVersionKind().GroupKind(), r.Name, errorList)
80106
}
81107

82108
// ValidateDelete implements webhook.Validator so a webhook will be registered for the type

api/v1beta2/cloudstackmachinetemplate_webhook_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828

2929
var _ = Describe("CloudStackMachineTemplate webhook", func() {
3030
var ctx context.Context
31+
forbiddenRegex := "admission webhook.*denied the request.*Forbidden\\: %s"
3132
requiredRegex := "admission webhook.*denied the request.*Required value\\: %s"
3233

3334
BeforeEach(func() { // Reset test vars to initial state.
@@ -61,4 +62,39 @@ var _ = Describe("CloudStackMachineTemplate webhook", func() {
6162
})
6263
})
6364

65+
Context("When updating a CloudStackMachineTemplate", func() {
66+
BeforeEach(func() { // Reset test vars to initial state.
67+
Ω(k8sClient.Create(ctx, dummies.CSMachineTemplate1)).Should(Succeed())
68+
})
69+
70+
It("should reject VM template updates to the CloudStackMachineTemplate", func() {
71+
dummies.CSMachineTemplate1.Spec.Spec.Spec.Template = infrav1.CloudStackResourceIdentifier{Name: "ArbitraryUpdateTemplate"}
72+
Ω(k8sClient.Update(ctx, dummies.CSMachineTemplate1)).
73+
Should(MatchError(MatchRegexp(forbiddenRegex, "template")))
74+
})
75+
76+
It("should reject VM disk offering updates to the CloudStackMachineTemplate", func() {
77+
dummies.CSMachineTemplate1.Spec.Spec.Spec.DiskOffering = infrav1.CloudStackResourceDiskOffering{
78+
CloudStackResourceIdentifier: infrav1.CloudStackResourceIdentifier{Name: "DiskOffering2"}}
79+
Ω(k8sClient.Update(ctx, dummies.CSMachineTemplate1)).
80+
Should(MatchError(MatchRegexp(forbiddenRegex, "diskOffering")))
81+
})
82+
83+
It("should reject VM offering updates to the CloudStackMachineTemplate", func() {
84+
dummies.CSMachineTemplate1.Spec.Spec.Spec.Offering = infrav1.CloudStackResourceIdentifier{Name: "Offering2"}
85+
Ω(k8sClient.Update(ctx, dummies.CSMachineTemplate1)).
86+
Should(MatchError(MatchRegexp(forbiddenRegex, "offering")))
87+
})
88+
89+
It("should reject updates to VM details of the CloudStackMachineTemplate", func() {
90+
dummies.CSMachineTemplate1.Spec.Spec.Spec.Details = map[string]string{"memoryOvercommitRatio": "1.5"}
91+
Ω(k8sClient.Update(ctx, dummies.CSMachineTemplate1)).
92+
Should(MatchError(MatchRegexp(forbiddenRegex, "details")))
93+
})
94+
95+
It("should reject updates to the list of AffinityGroupIDs of the CloudStackMachineTemplate", func() {
96+
dummies.CSMachineTemplate1.Spec.Spec.Spec.AffinityGroupIDs = []string{"28b907b8-75a7-4214-bd3d-6c61961fc2ag"}
97+
Ω(k8sClient.Update(ctx, dummies.CSMachineTemplate1)).ShouldNot(Succeed())
98+
})
99+
})
64100
})

0 commit comments

Comments
 (0)