Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 2 additions & 24 deletions pkg/apis/core/validation/shoot.go
Original file line number Diff line number Diff line change
Expand Up @@ -3229,33 +3229,11 @@ func validateHAShootControlPlaneConfigurationValue(shoot *core.Shoot) field.Erro
return allErrs
}

func validateShootHAControlPlaneSpecUpdate(newShoot, oldShoot *core.Shoot, fldPath *field.Path) field.ErrorList {
func validateShootHAControlPlaneSpecUpdate(_, _ *core.Shoot, _ *field.Path) field.ErrorList {
var (
allErrs = field.ErrorList{}
shootIsScheduled = newShoot.Spec.SeedName != nil

oldVal, newVal core.FailureToleranceType
oldValExists bool
allErrs = field.ErrorList{}
)

if oldShoot.Spec.ControlPlane != nil && oldShoot.Spec.ControlPlane.HighAvailability != nil {
oldVal = oldShoot.Spec.ControlPlane.HighAvailability.FailureTolerance.Type
oldValExists = true
}

if newShoot.Spec.ControlPlane != nil && newShoot.Spec.ControlPlane.HighAvailability != nil {
newVal = newShoot.Spec.ControlPlane.HighAvailability.FailureTolerance.Type
// TODO(@aaronfern): remove this validation of not allowing scale-up to HA while hibernated when https://github.com/gardener/etcd-druid/issues/589 is resolved
if !oldValExists && helper.IsShootInHibernation(newShoot) {
allErrs = append(allErrs, field.Forbidden(fldPath.Child("highAvailability", "failureTolerance", "type"), "Shoot is currently hibernated and cannot be scaled up to HA. Please make sure your cluster has woken up before scaling it up to HA"))
}
}

if oldValExists && shootIsScheduled {
// If the HighAvailability field is already set for the shoot then enforce that it cannot be changed.
allErrs = append(allErrs, apivalidation.ValidateImmutableField(newVal, oldVal, fldPath.Child("highAvailability", "failureTolerance", "type"))...)
}

return allErrs
}

Expand Down
135 changes: 0 additions & 135 deletions pkg/apis/core/validation/shoot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -352,141 +352,6 @@ var _ = Describe("Shoot Validation Tests", func() {
))
})

Context("#ValidateShootHAControlPlaneUpdate", func() {
It("should pass as Shoot ControlPlane Spec with HA set to zone has not changed", func() {
shoot.Spec.ControlPlane = &core.ControlPlane{HighAvailability: &core.HighAvailability{FailureTolerance: core.FailureTolerance{Type: core.FailureToleranceTypeZone}}}
newShoot := prepareShootForUpdate(shoot)
errorList := ValidateShootHAConfigUpdate(newShoot, shoot)
Expect(errorList).To(BeEmpty())
})

It("should pass as non-HA Shoot ControlPlane Spec has not changed", func() {
newShoot := prepareShootForUpdate(shoot)
errorList := ValidateShootHAConfigUpdate(newShoot, shoot)
Expect(errorList).To(BeEmpty())
})

It("should allow upgrading from non-HA to HA Shoot ControlPlane.HighAvailability Spec", func() {
shoot.Spec.ControlPlane = &core.ControlPlane{}
newShoot := prepareShootForUpdate(shoot)
newShoot.Spec.ControlPlane = &core.ControlPlane{HighAvailability: &core.HighAvailability{FailureTolerance: core.FailureTolerance{Type: core.FailureToleranceTypeZone}}}
errorList := ValidateShootHAConfigUpdate(newShoot, shoot)
Expect(errorList).To(BeEmpty())
})

Context("shoot is scheduled", func() {
BeforeEach(func() {
shoot.Spec.SeedName = ptr.To("someSeed")
})

It("should forbid to change the Shoot ControlPlane spec", func() {
shoot.Spec.ControlPlane = &core.ControlPlane{HighAvailability: &core.HighAvailability{FailureTolerance: core.FailureTolerance{Type: core.FailureToleranceTypeZone}}}
newShoot := prepareShootForUpdate(shoot)
newShoot.Spec.ControlPlane = &core.ControlPlane{HighAvailability: &core.HighAvailability{FailureTolerance: core.FailureTolerance{Type: core.FailureToleranceTypeNode}}}

errorList := ValidateShootHAConfigUpdate(newShoot, shoot)
Expect(errorList).To(ConsistOf(
PointTo(MatchFields(IgnoreExtras, Fields{
"Type": Equal(field.ErrorTypeInvalid),
"BadValue": Equal(core.FailureToleranceTypeNode),
"Field": Equal("spec.controlPlane.highAvailability.failureTolerance.type"),
})),
))
})

It("should forbid to unset of Shoot ControlPlane", func() {
shoot.Spec.ControlPlane = &core.ControlPlane{HighAvailability: &core.HighAvailability{FailureTolerance: core.FailureTolerance{Type: core.FailureToleranceTypeZone}}}
newShoot := prepareShootForUpdate(shoot)
newShoot.Spec.ControlPlane = nil

errorList := ValidateShootHAConfigUpdate(newShoot, shoot)

Expect(errorList).To(ConsistOf(
PointTo(MatchFields(IgnoreExtras, Fields{
"Type": Equal(field.ErrorTypeInvalid),
"Field": Equal("spec.controlPlane.highAvailability.failureTolerance.type"),
})),
))
})
})

Context("shoot is not scheduled", func() {
It("should allow to change the Shoot ControlPlane spec", func() {
shoot.Spec.ControlPlane = &core.ControlPlane{HighAvailability: &core.HighAvailability{FailureTolerance: core.FailureTolerance{Type: core.FailureToleranceTypeZone}}}
newShoot := prepareShootForUpdate(shoot)
newShoot.Spec.ControlPlane = &core.ControlPlane{HighAvailability: &core.HighAvailability{FailureTolerance: core.FailureTolerance{Type: core.FailureToleranceTypeNode}}}

Expect(ValidateShootHAConfigUpdate(newShoot, shoot)).To(BeEmpty())
})

It("should allow to unset of Shoot ControlPlane", func() {
shoot.Spec.ControlPlane = &core.ControlPlane{HighAvailability: &core.HighAvailability{FailureTolerance: core.FailureTolerance{Type: core.FailureToleranceTypeZone}}}
newShoot := prepareShootForUpdate(shoot)
newShoot.Spec.ControlPlane = nil

Expect(ValidateShootHAConfigUpdate(newShoot, shoot)).To(BeEmpty())
})
})

Context("shoot is hibernated", func() {
It("should not allow upgrading from non-HA to HA when Spec.Hibernation.Enabled is set to `true`", func() {
shoot.Spec.ControlPlane = &core.ControlPlane{}
newShoot := prepareShootForUpdate(shoot)
newShoot.Spec.ControlPlane = &core.ControlPlane{HighAvailability: &core.HighAvailability{FailureTolerance: core.FailureTolerance{Type: core.FailureToleranceTypeZone}}}
newShoot.Spec.Hibernation = &core.Hibernation{Enabled: ptr.To(true)}
errorList := ValidateShootHAConfigUpdate(newShoot, shoot)
Expect(errorList).To(ConsistOf(
PointTo(MatchFields(IgnoreExtras, Fields{
"Type": Equal(field.ErrorTypeForbidden),
"Field": Equal("spec.controlPlane.highAvailability.failureTolerance.type"),
"Detail": Equal("Shoot is currently hibernated and cannot be scaled up to HA. Please make sure your cluster has woken up before scaling it up to HA"),
})),
))
})

It("should not allow upgrading from non-HA to HA when Status.IsHibernation is set to `true`", func() {
shoot.Spec.ControlPlane = &core.ControlPlane{}
newShoot := prepareShootForUpdate(shoot)
newShoot.Spec.ControlPlane = &core.ControlPlane{HighAvailability: &core.HighAvailability{FailureTolerance: core.FailureTolerance{Type: core.FailureToleranceTypeNode}}}
newShoot.Status.IsHibernated = true
errorList := ValidateShootHAConfigUpdate(newShoot, shoot)
Expect(errorList).To(ConsistOf(
PointTo(MatchFields(IgnoreExtras, Fields{
"Type": Equal(field.ErrorTypeForbidden),
"Field": Equal("spec.controlPlane.highAvailability.failureTolerance.type"),
"Detail": Equal("Shoot is currently hibernated and cannot be scaled up to HA. Please make sure your cluster has woken up before scaling it up to HA"),
})),
))
})

It("should not allow upgrading from non-HA to HA when Spec.Hibernation.Enabled is set to `false` and Status.IsHibernation is set to `true`", func() {
shoot.Spec.ControlPlane = &core.ControlPlane{}
newShoot := prepareShootForUpdate(shoot)
newShoot.Spec.ControlPlane = &core.ControlPlane{HighAvailability: &core.HighAvailability{FailureTolerance: core.FailureTolerance{Type: core.FailureToleranceTypeNode}}}
newShoot.Spec.Hibernation = &core.Hibernation{Enabled: ptr.To(false)}
newShoot.Status.IsHibernated = true
errorList := ValidateShootHAConfigUpdate(newShoot, shoot)
Expect(errorList).To(ConsistOf(
PointTo(MatchFields(IgnoreExtras, Fields{
"Type": Equal(field.ErrorTypeForbidden),
"Field": Equal("spec.controlPlane.highAvailability.failureTolerance.type"),
"Detail": Equal("Shoot is currently hibernated and cannot be scaled up to HA. Please make sure your cluster has woken up before scaling it up to HA"),
})),
))
})

It("should allow upgrading from non-HA to HA when Spec.Hibernation.Enabled is set to `false` and Status.IsHibernation is set to `false`", func() {
shoot.Spec.ControlPlane = &core.ControlPlane{}
newShoot := prepareShootForUpdate(shoot)
newShoot.Spec.ControlPlane = &core.ControlPlane{HighAvailability: &core.HighAvailability{FailureTolerance: core.FailureTolerance{Type: core.FailureToleranceTypeNode}}}
newShoot.Spec.Hibernation = &core.Hibernation{Enabled: ptr.To(false)}
newShoot.Status.IsHibernated = false
errorList := ValidateShootHAConfigUpdate(newShoot, shoot)
Expect(errorList).To(BeEmpty())
})
})
})

Context("#ValidateShootHAConfig", func() {
It("should forbid to set unsupported failure tolerance type", func() {
shoot.Spec.ControlPlane = &core.ControlPlane{}
Expand Down