feature(scheduler): implement matchLabelKeys in PodAffinity and PodAntiAffinity

This commit is contained in:
Kensei Nakada
2023-02-26 04:25:59 +00:00
parent dc8b57d8a7
commit d5d3c26337
81 changed files with 4922 additions and 1112 deletions

View File

@@ -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
}

View File

@@ -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