Skip to content

Commit

Permalink
add more generic validation funcs
Browse files Browse the repository at this point in the history
  • Loading branch information
jackfrancis committed Oct 17, 2022
1 parent f9a6449 commit 31e5ac8
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 117 deletions.
144 changes: 27 additions & 117 deletions exp/api/v1beta1/azuremanagedmachinepool_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,31 +98,18 @@ func (m *AzureManagedMachinePool) ValidateUpdate(oldRaw runtime.Object, client c
allErrs = append(allErrs, err)
}

if m.Spec.SKU != old.Spec.SKU {
allErrs = append(allErrs,
field.Invalid(
field.NewPath("Spec", "SKU"),
m.Spec.SKU,
"field is immutable"))
if err := validateStringImmutable(
field.NewPath("Spec", "SKU"),
old.Spec.SKU,
m.Spec.SKU); err != nil {
allErrs = append(allErrs, err)
}

if old.Spec.OSDiskSizeGB != nil {
// Prevent OSDiskSizeGB modification if it was already set to some value
if m.Spec.OSDiskSizeGB == nil {
// unsetting the field is not allowed
allErrs = append(allErrs,
field.Invalid(
field.NewPath("Spec", "OSDiskSizeGB"),
m.Spec.OSDiskSizeGB,
"field is immutable, unsetting is not allowed"))
} else if *m.Spec.OSDiskSizeGB != *old.Spec.OSDiskSizeGB {
// changing the field is not allowed
allErrs = append(allErrs,
field.Invalid(
field.NewPath("Spec", "OSDiskSizeGB"),
*m.Spec.OSDiskSizeGB,
"field is immutable"))
}
if err := validateInt32PtrImmutable(
field.NewPath("Spec", "OSDiskSizeGB"),
old.Spec.OSDiskSizeGB,
m.Spec.OSDiskSizeGB); err != nil {
allErrs = append(allErrs, err)
}

// custom headers are immutable
Expand Down Expand Up @@ -153,49 +140,25 @@ func (m *AzureManagedMachinePool) ValidateUpdate(oldRaw runtime.Object, client c
}
}

if old.Spec.MaxPods != nil {
// Prevent MaxPods modification if it was already set to some value
if m.Spec.MaxPods == nil {
// unsetting the field is not allowed
allErrs = append(allErrs,
field.Invalid(
field.NewPath("Spec", "MaxPods"),
m.Spec.MaxPods,
"field is immutable, unsetting is not allowed"))
} else if *m.Spec.MaxPods != *old.Spec.MaxPods {
// changing the field is not allowed
allErrs = append(allErrs,
field.Invalid(
field.NewPath("Spec", "MaxPods"),
*m.Spec.MaxPods,
"field is immutable"))
}
if err := validateInt32PtrImmutable(
field.NewPath("Spec", "MaxPods"),
old.Spec.MaxPods,
m.Spec.MaxPods); err != nil {
allErrs = append(allErrs, err)
}

if old.Spec.OsDiskType != nil {
// Prevent OSDiskType modification if it was already set to some value
if m.Spec.OsDiskType == nil || to.String(m.Spec.OsDiskType) == "" {
// unsetting the field is not allowed
allErrs = append(allErrs,
field.Invalid(
field.NewPath("Spec", "OsDiskType"),
m.Spec.OsDiskType,
"field is immutable, unsetting is not allowed"))
} else if *m.Spec.OsDiskType != *old.Spec.OsDiskType {
// changing the field is not allowed
allErrs = append(allErrs,
field.Invalid(
field.NewPath("Spec", "OsDiskType"),
m.Spec.OsDiskType,
"field is immutable"))
}
if err := validateStringPtrImmutable(
field.NewPath("Spec", "OsDiskType"),
old.Spec.OsDiskType,
m.Spec.OsDiskType); err != nil {
allErrs = append(allErrs, err)
}

if !reflect.DeepEqual(m.Spec.ScaleSetPriority, old.Spec.ScaleSetPriority) {
allErrs = append(allErrs,
field.Invalid(field.NewPath("Spec", "ScaleSetPriority"),
m.Spec.ScaleSetPriority, "field is immutable"),
)
if err := validateStringPtrImmutable(
field.NewPath("Spec", "ScaleSetPriority"),
old.Spec.ScaleSetPriority,
m.Spec.ScaleSetPriority); err != nil {
allErrs = append(allErrs, err)
}

if err := validateBoolPtrImmutable(
Expand All @@ -204,6 +167,7 @@ func (m *AzureManagedMachinePool) ValidateUpdate(oldRaw runtime.Object, client c
m.Spec.EnableUltraSSD); err != nil {
allErrs = append(allErrs, err)
}

if err := validateBoolPtrImmutable(
field.NewPath("Spec", "EnableNodePublicIP"),
old.Spec.EnableNodePublicIP,
Expand Down Expand Up @@ -269,7 +233,7 @@ func (m *AzureManagedMachinePool) validateLastSystemNodePool(cli client.Client)
return err
}

if len(ammpList.Items) <= 1 {
if len(ammpList.Items) < 1 {
return errors.New("AKS Cluster must have at least one system pool")
}
return nil
Expand Down Expand Up @@ -346,57 +310,3 @@ func (m *AzureManagedMachinePool) validateEnableNodePublicIP() error {
}
return nil
}

func ensureStringSlicesAreEqual(a []string, b []string) bool {
if len(a) != len(b) {
return false
}

m := map[string]bool{}
for _, v := range a {
m[v] = true
}

for _, v := range b {
if _, ok := m[v]; !ok {
return false
}
}
return true
}

func validateBoolPtrImmutable(path *field.Path, oldVal, newVal *bool) *field.Error {
if oldVal != nil {
// Prevent modification if it was already set to some value
if newVal == nil {
// unsetting the field is not allowed
return field.Invalid(path, newVal, "field is immutable, unsetting is not allowed")
}
if *newVal != *oldVal {
// changing the field is not allowed
return field.Invalid(path, newVal, "field is immutable")
}
} else if newVal != nil {
return field.Invalid(path, newVal, "field is immutable, setting is not allowed")
}

return nil
}

func validateStringPtrImmutable(path *field.Path, oldVal, newVal *string) *field.Error {
if oldVal != nil {
// Prevent modification if it was already set to some value
if newVal == nil {
// unsetting the field is not allowed
return field.Invalid(path, newVal, "field is immutable, unsetting is not allowed")
}
if *newVal != *oldVal {
// changing the field is not allowed
return field.Invalid(path, newVal, "field is immutable")
}
} else if newVal != nil {
return field.Invalid(path, newVal, "field is immutable, setting is not allowed")
}

return nil
}
117 changes: 117 additions & 0 deletions exp/api/v1beta1/webhook.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*
Copyright 2022 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1beta1

import (
"k8s.io/apimachinery/pkg/util/validation/field"
)

const (
unsetMessage = "field is immutable, unsetting is not allowed"
setMessage = "field is immutable, setting is not allowed"
immutableMessage = "field is immutable"
)

func ensureStringSlicesAreEqual(a []string, b []string) bool {
if len(a) != len(b) {
return false
}

m := map[string]bool{}
for _, v := range a {
m[v] = true
}

for _, v := range b {
if _, ok := m[v]; !ok {
return false
}
}
return true
}

func validateBoolPtrImmutable(path *field.Path, oldVal, newVal *bool) *field.Error {
if oldVal != nil {
// Prevent modification if it was already set to some value
if newVal == nil {
// unsetting the field is not allowed
return field.Invalid(path, newVal, unsetMessage)
}
if *newVal != *oldVal {
// changing the field is not allowed
return field.Invalid(path, newVal, immutableMessage)
}
} else if newVal != nil {
return field.Invalid(path, newVal, setMessage)
}

return nil
}

func validateStringImmutable(path *field.Path, oldVal, newVal string) *field.Error {
if oldVal != "" {
// Prevent modification if it was already set to some value
if newVal == "" {
// unsetting the field is not allowed
return field.Invalid(path, newVal, unsetMessage)
}
if newVal != oldVal {
// changing the field is not allowed
return field.Invalid(path, newVal, immutableMessage)
}
} else if newVal != "" {
return field.Invalid(path, newVal, setMessage)
}

return nil
}

func validateStringPtrImmutable(path *field.Path, oldVal, newVal *string) *field.Error {
if oldVal != nil {
// Prevent modification if it was already set to some value
if newVal == nil {
// unsetting the field is not allowed
return field.Invalid(path, newVal, unsetMessage)
}
if *newVal != *oldVal {
// changing the field is not allowed
return field.Invalid(path, newVal, immutableMessage)
}
} else if newVal != nil {
return field.Invalid(path, newVal, setMessage)
}

return nil
}

func validateInt32PtrImmutable(path *field.Path, oldVal, newVal *int32) *field.Error {
if oldVal != nil {
// Prevent modification if it was already set to some value
if newVal == nil {
// unsetting the field is not allowed
return field.Invalid(path, newVal, unsetMessage)
}
if *newVal != *oldVal {
// changing the field is not allowed
return field.Invalid(path, newVal, immutableMessage)
}
} else if newVal != nil {
return field.Invalid(path, newVal, setMessage)
}

return nil
}

0 comments on commit 31e5ac8

Please sign in to comment.