feature(scheduler): implement matchLabelKeys in PodAffinity and PodAntiAffinity
This commit is contained in:
@@ -534,7 +534,8 @@ func dropDisabledFields(
|
||||
|
||||
dropDisabledTopologySpreadConstraintsFields(podSpec, oldPodSpec)
|
||||
dropDisabledNodeInclusionPolicyFields(podSpec, oldPodSpec)
|
||||
dropDisabledMatchLabelKeysField(podSpec, oldPodSpec)
|
||||
dropDisabledMatchLabelKeysFieldInTopologySpread(podSpec, oldPodSpec)
|
||||
dropDisabledMatchLabelKeysFieldInPodAffinity(podSpec, oldPodSpec)
|
||||
dropDisabledDynamicResourceAllocationFields(podSpec, oldPodSpec)
|
||||
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScaling) && !inPlacePodVerticalScalingInUse(oldPodSpec) {
|
||||
@@ -752,19 +753,89 @@ func dropDisabledNodeInclusionPolicyFields(podSpec, oldPodSpec *api.PodSpec) {
|
||||
}
|
||||
}
|
||||
|
||||
// dropDisabledMatchLabelKeysField removes disabled fields from PodSpec related
|
||||
// to MatchLabelKeys only if it is not already used by the old spec.
|
||||
func dropDisabledMatchLabelKeysField(podSpec, oldPodSpec *api.PodSpec) {
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.MatchLabelKeysInPodTopologySpread) && !matchLabelKeysInUse(oldPodSpec) {
|
||||
// dropDisabledMatchLabelKeysFieldInPodAffinity removes disabled fields from PodSpec related
|
||||
// to MatchLabelKeys in required/preferred PodAffinity/PodAntiAffinity only if it is not already used by the old spec.
|
||||
func dropDisabledMatchLabelKeysFieldInPodAffinity(podSpec, oldPodSpec *api.PodSpec) {
|
||||
if podSpec == nil || podSpec.Affinity == nil || utilfeature.DefaultFeatureGate.Enabled(features.MatchLabelKeysInPodAffinity) || matchLabelKeysFieldInPodAffinityInUse(oldPodSpec) {
|
||||
return
|
||||
}
|
||||
|
||||
if affinity := podSpec.Affinity.PodAffinity; affinity != nil {
|
||||
dropMatchLabelKeysFieldInPodAffnityTerm(affinity.RequiredDuringSchedulingIgnoredDuringExecution)
|
||||
dropMatchLabelKeysFieldInWeightedPodAffnityTerm(affinity.PreferredDuringSchedulingIgnoredDuringExecution)
|
||||
}
|
||||
if antiaffinity := podSpec.Affinity.PodAntiAffinity; antiaffinity != nil {
|
||||
dropMatchLabelKeysFieldInPodAffnityTerm(antiaffinity.RequiredDuringSchedulingIgnoredDuringExecution)
|
||||
dropMatchLabelKeysFieldInWeightedPodAffnityTerm(antiaffinity.PreferredDuringSchedulingIgnoredDuringExecution)
|
||||
}
|
||||
}
|
||||
|
||||
// dropDisabledMatchLabelKeysFieldInTopologySpread removes disabled fields from PodSpec related
|
||||
// to MatchLabelKeys in TopologySpread only if it is not already used by the old spec.
|
||||
func dropDisabledMatchLabelKeysFieldInTopologySpread(podSpec, oldPodSpec *api.PodSpec) {
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.MatchLabelKeysInPodTopologySpread) && !matchLabelKeysInTopologySpreadInUse(oldPodSpec) {
|
||||
for i := range podSpec.TopologySpreadConstraints {
|
||||
podSpec.TopologySpreadConstraints[i].MatchLabelKeys = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// matchLabelKeysInUse returns true if the pod spec is non-nil
|
||||
// dropMatchLabelKeysFieldInWeightedPodAffnityTerm removes MatchLabelKeys and MismatchLabelKeys fields from WeightedPodAffinityTerm
|
||||
func dropMatchLabelKeysFieldInWeightedPodAffnityTerm(terms []api.WeightedPodAffinityTerm) {
|
||||
for i := range terms {
|
||||
terms[i].PodAffinityTerm.MatchLabelKeys = nil
|
||||
terms[i].PodAffinityTerm.MismatchLabelKeys = nil
|
||||
}
|
||||
}
|
||||
|
||||
// dropMatchLabelKeysFieldInPodAffnityTerm removes MatchLabelKeys and MismatchLabelKeys fields from PodAffinityTerm
|
||||
func dropMatchLabelKeysFieldInPodAffnityTerm(terms []api.PodAffinityTerm) {
|
||||
for i := range terms {
|
||||
terms[i].MatchLabelKeys = nil
|
||||
terms[i].MismatchLabelKeys = nil
|
||||
}
|
||||
}
|
||||
|
||||
// matchLabelKeysFieldInPodAffinityInUse returns true if given affinityTerms have MatchLabelKeys field set.
|
||||
func matchLabelKeysFieldInPodAffinityInUse(podSpec *api.PodSpec) bool {
|
||||
if podSpec == nil || podSpec.Affinity == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if affinity := podSpec.Affinity.PodAffinity; affinity != nil {
|
||||
for _, c := range affinity.RequiredDuringSchedulingIgnoredDuringExecution {
|
||||
if len(c.MatchLabelKeys) > 0 || len(c.MismatchLabelKeys) > 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
for _, c := range affinity.PreferredDuringSchedulingIgnoredDuringExecution {
|
||||
if len(c.PodAffinityTerm.MatchLabelKeys) > 0 || len(c.PodAffinityTerm.MismatchLabelKeys) > 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if antiAffinity := podSpec.Affinity.PodAntiAffinity; antiAffinity != nil {
|
||||
for _, c := range antiAffinity.RequiredDuringSchedulingIgnoredDuringExecution {
|
||||
if len(c.MatchLabelKeys) > 0 || len(c.MismatchLabelKeys) > 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
for _, c := range antiAffinity.PreferredDuringSchedulingIgnoredDuringExecution {
|
||||
if len(c.PodAffinityTerm.MatchLabelKeys) > 0 || len(c.PodAffinityTerm.MismatchLabelKeys) > 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// matchLabelKeysInTopologySpreadInUse returns true if the pod spec is non-nil
|
||||
// and has MatchLabelKeys field set in TopologySpreadConstraints.
|
||||
func matchLabelKeysInUse(podSpec *api.PodSpec) bool {
|
||||
func matchLabelKeysInTopologySpreadInUse(podSpec *api.PodSpec) bool {
|
||||
if podSpec == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -1515,7 +1515,862 @@ func TestDropNodeInclusionPolicyFields(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDropDisabledMatchLabelKeysField(t *testing.T) {
|
||||
func Test_dropDisabledMatchLabelKeysFieldInPodAffinity(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
enabled bool
|
||||
podSpec *api.PodSpec
|
||||
oldPodSpec *api.PodSpec
|
||||
wantPodSpec *api.PodSpec
|
||||
}{
|
||||
{
|
||||
name: "[PodAffinity/required] feature disabled, both pods don't use MatchLabelKeys/MismatchLabelKeys fields",
|
||||
enabled: false,
|
||||
oldPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
podSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[PodAffinity/required] feature disabled, only old pod uses MatchLabelKeys/MismatchLabelKeys field",
|
||||
enabled: false,
|
||||
oldPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{
|
||||
{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
podSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[PodAffinity/required] feature disabled, only current pod uses MatchLabelKeys/MismatchLabelKeys field",
|
||||
enabled: false,
|
||||
oldPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
podSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{
|
||||
{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{{}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[PodAffinity/required] feature disabled, both pods use MatchLabelKeys/MismatchLabelKeys fields",
|
||||
enabled: false,
|
||||
oldPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{
|
||||
{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
podSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{
|
||||
{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{
|
||||
{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[PodAffinity/required] feature enabled, only old pod uses MatchLabelKeys/MismatchLabelKeys field",
|
||||
enabled: true,
|
||||
oldPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{
|
||||
{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
podSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[PodAffinity/required] feature enabled, only current pod uses MatchLabelKeys/MismatchLabelKeys field",
|
||||
enabled: true,
|
||||
oldPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
podSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{
|
||||
{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{
|
||||
{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[PodAffinity/required] feature enabled, both pods use MatchLabelKeys/MismatchLabelKeys fields",
|
||||
enabled: false,
|
||||
oldPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{
|
||||
{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
podSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{
|
||||
{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{
|
||||
{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[PodAffinity/preferred] feature disabled, both pods don't use MatchLabelKeys/MismatchLabelKeys fields",
|
||||
enabled: false,
|
||||
oldPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
podSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[PodAffinity/preferred] feature disabled, only old pod uses MatchLabelKeys/MismatchLabelKeys field",
|
||||
enabled: false,
|
||||
oldPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{
|
||||
{
|
||||
PodAffinityTerm: api.PodAffinityTerm{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
podSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[PodAffinity/preferred] feature disabled, only current pod uses MatchLabelKeys/MismatchLabelKeys field",
|
||||
enabled: false,
|
||||
oldPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
podSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{
|
||||
{
|
||||
PodAffinityTerm: api.PodAffinityTerm{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{{}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[PodAffinity/preferred] feature disabled, both pods use MatchLabelKeys/MismatchLabelKeys fields",
|
||||
enabled: false,
|
||||
oldPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{
|
||||
{
|
||||
PodAffinityTerm: api.PodAffinityTerm{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
podSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{
|
||||
{
|
||||
PodAffinityTerm: api.PodAffinityTerm{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{
|
||||
{
|
||||
PodAffinityTerm: api.PodAffinityTerm{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[PodAffinity/preferred] feature enabled, only old pod uses MatchLabelKeys/MismatchLabelKeys field",
|
||||
enabled: true,
|
||||
oldPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{
|
||||
{
|
||||
PodAffinityTerm: api.PodAffinityTerm{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
podSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[PodAffinity/preferred] feature enabled, only current pod uses MatchLabelKeys/MismatchLabelKeys field",
|
||||
enabled: true,
|
||||
oldPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
podSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{
|
||||
{
|
||||
PodAffinityTerm: api.PodAffinityTerm{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{
|
||||
{
|
||||
PodAffinityTerm: api.PodAffinityTerm{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[PodAffinity/preferred] feature enabled, both pods use MatchLabelKeys/MismatchLabelKeys fields",
|
||||
enabled: false,
|
||||
oldPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{
|
||||
{
|
||||
PodAffinityTerm: api.PodAffinityTerm{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
podSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{
|
||||
{
|
||||
PodAffinityTerm: api.PodAffinityTerm{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{
|
||||
{
|
||||
PodAffinityTerm: api.PodAffinityTerm{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[PodAntiAffinity/required] feature disabled, both pods don't use MatchLabelKeys/MismatchLabelKeys fields",
|
||||
enabled: false,
|
||||
oldPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
podSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[PodAntiAffinity/required] feature disabled, only old pod uses MatchLabelKeys/MismatchLabelKeys field",
|
||||
enabled: false,
|
||||
oldPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{
|
||||
{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
podSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[PodAntiAffinity/required] feature disabled, only current pod uses MatchLabelKeys/MismatchLabelKeys field",
|
||||
enabled: false,
|
||||
oldPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
podSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{
|
||||
{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{{}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[PodAntiAffinity/required] feature disabled, both pods use MatchLabelKeys/MismatchLabelKeys fields",
|
||||
enabled: false,
|
||||
oldPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{
|
||||
{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
podSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{
|
||||
{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{
|
||||
{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[PodAntiAffinity/required] feature enabled, only old pod uses MatchLabelKeys/MismatchLabelKeys field",
|
||||
enabled: true,
|
||||
oldPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{
|
||||
{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
podSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[PodAntiAffinity/required] feature enabled, only current pod uses MatchLabelKeys/MismatchLabelKeys field",
|
||||
enabled: true,
|
||||
oldPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
podSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{
|
||||
{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{
|
||||
{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[PodAntiAffinity/required] feature enabled, both pods use MatchLabelKeys/MismatchLabelKeys fields",
|
||||
enabled: false,
|
||||
oldPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{
|
||||
{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
podSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{
|
||||
{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{
|
||||
{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
name: "[PodAntiAffinity/preferred] feature disabled, both pods don't use MatchLabelKeys/MismatchLabelKeys fields",
|
||||
enabled: false,
|
||||
oldPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
podSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[PodAntiAffinity/preferred] feature disabled, only old pod uses MatchLabelKeys/MismatchLabelKeys field",
|
||||
enabled: false,
|
||||
oldPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{
|
||||
{
|
||||
PodAffinityTerm: api.PodAffinityTerm{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
podSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[PodAntiAffinity/preferred] feature disabled, only current pod uses MatchLabelKeys/MismatchLabelKeys field",
|
||||
enabled: false,
|
||||
oldPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
podSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{
|
||||
{
|
||||
PodAffinityTerm: api.PodAffinityTerm{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{{}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[PodAntiAffinity/preferred] feature disabled, both pods use MatchLabelKeys/MismatchLabelKeys fields",
|
||||
enabled: false,
|
||||
oldPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{
|
||||
{
|
||||
PodAffinityTerm: api.PodAffinityTerm{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
podSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{
|
||||
{
|
||||
PodAffinityTerm: api.PodAffinityTerm{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{
|
||||
{
|
||||
PodAffinityTerm: api.PodAffinityTerm{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[PodAntiAffinity/preferred] feature enabled, only old pod uses MatchLabelKeys/MismatchLabelKeys field",
|
||||
enabled: true,
|
||||
oldPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{
|
||||
{
|
||||
PodAffinityTerm: api.PodAffinityTerm{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
podSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[PodAntiAffinity/preferred] feature enabled, only current pod uses MatchLabelKeys/MismatchLabelKeys field",
|
||||
enabled: true,
|
||||
oldPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{},
|
||||
},
|
||||
},
|
||||
},
|
||||
podSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{
|
||||
{
|
||||
PodAffinityTerm: api.PodAffinityTerm{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{
|
||||
{
|
||||
PodAffinityTerm: api.PodAffinityTerm{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "[PodAntiAffinity/preferred] feature enabled, both pods use MatchLabelKeys/MismatchLabelKeys fields",
|
||||
enabled: false,
|
||||
oldPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{
|
||||
{
|
||||
PodAffinityTerm: api.PodAffinityTerm{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
podSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{
|
||||
{
|
||||
PodAffinityTerm: api.PodAffinityTerm{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantPodSpec: &api.PodSpec{
|
||||
Affinity: &api.Affinity{
|
||||
PodAntiAffinity: &api.PodAntiAffinity{
|
||||
PreferredDuringSchedulingIgnoredDuringExecution: []api.WeightedPodAffinityTerm{
|
||||
{
|
||||
PodAffinityTerm: api.PodAffinityTerm{MatchLabelKeys: []string{"foo"}, MismatchLabelKeys: []string{"foo"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.MatchLabelKeysInPodAffinity, test.enabled)()
|
||||
|
||||
dropDisabledFields(test.podSpec, nil, test.oldPodSpec, nil)
|
||||
if diff := cmp.Diff(test.wantPodSpec, test.podSpec); diff != "" {
|
||||
t.Errorf("unexpected pod spec (-want, +got):\n%s", diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_dropDisabledMatchLabelKeysFieldInTopologySpread(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
enabled bool
|
||||
|
||||
Reference in New Issue
Block a user