move IPv6DualStack feature to stable. (#104691)

* kube-proxy

* endpoints controller

* app: kube-controller-manager

* app: cloud-controller-manager

* kubelet

* app: api-server

* node utils + registry/strategy

* api: validation (comment removal)

* api:pod strategy (util pkg)

* api: docs

* core: integration testing

* kubeadm: change feature gate to GA

* service registry and rest stack

* move feature to GA

* generated
This commit is contained in:
Khaled Henidak (Kal)
2021-09-24 16:30:22 -07:00
committed by GitHub
parent c74d799677
commit a53e2eaeab
42 changed files with 455 additions and 1373 deletions

View File

@@ -104,23 +104,6 @@ func dropDisabledFields(node *api.Node, oldNode *api.Node) {
node.Spec.ConfigSource = nil
}
if !utilfeature.DefaultFeatureGate.Enabled(features.IPv6DualStack) && !multiNodeCIDRsInUse(oldNode) {
if len(node.Spec.PodCIDRs) > 1 {
node.Spec.PodCIDRs = node.Spec.PodCIDRs[0:1]
}
}
}
// multiNodeCIDRsInUse returns true if Node.Spec.PodCIDRs is greater than one
func multiNodeCIDRsInUse(node *api.Node) bool {
if node == nil {
return false
}
if len(node.Spec.PodCIDRs) > 1 {
return true
}
return false
}
// nodeConfigSourceInUse returns true if node's Spec ConfigSource is set(used)

View File

@@ -92,78 +92,42 @@ func TestDropFields(t *testing.T) {
node *api.Node
oldNode *api.Node
compareNode *api.Node
enableDualStack bool
enableNodeDynamicConfig bool
}{
{
name: "nil pod cidrs",
enableDualStack: false,
node: makeNode(nil, false, false),
oldNode: nil,
compareNode: makeNode(nil, false, false),
name: "nil pod cidrs",
node: makeNode(nil, false, false),
oldNode: nil,
compareNode: makeNode(nil, false, false),
},
{
name: "empty pod ips",
enableDualStack: false,
node: makeNode([]string{}, false, false),
oldNode: nil,
compareNode: makeNode([]string{}, false, false),
name: "empty pod ips",
node: makeNode([]string{}, false, false),
oldNode: nil,
compareNode: makeNode([]string{}, false, false),
},
{
name: "single family ipv6",
enableDualStack: false,
node: makeNode([]string{"2000::/10"}, false, false),
compareNode: makeNode([]string{"2000::/10"}, false, false),
name: "single family ipv6",
node: makeNode([]string{"2000::/10"}, false, false),
compareNode: makeNode([]string{"2000::/10"}, false, false),
},
{
name: "single family ipv4",
enableDualStack: false,
node: makeNode([]string{"10.0.0.0/8"}, false, false),
compareNode: makeNode([]string{"10.0.0.0/8"}, false, false),
name: "single family ipv4",
node: makeNode([]string{"10.0.0.0/8"}, false, false),
compareNode: makeNode([]string{"10.0.0.0/8"}, false, false),
},
{
name: "dualstack 4-6",
enableDualStack: true,
node: makeNode([]string{"10.0.0.0/8", "2000::/10"}, false, false),
compareNode: makeNode([]string{"10.0.0.0/8", "2000::/10"}, false, false),
name: "dualstack 4-6",
node: makeNode([]string{"10.0.0.0/8", "2000::/10"}, false, false),
compareNode: makeNode([]string{"10.0.0.0/8", "2000::/10"}, false, false),
},
{
name: "dualstack 6-4",
enableDualStack: true,
node: makeNode([]string{"2000::/10", "10.0.0.0/8"}, false, false),
compareNode: makeNode([]string{"2000::/10", "10.0.0.0/8"}, false, false),
},
{
name: "not dualstack 6-4=>4only",
enableDualStack: false,
node: makeNode([]string{"2000::/10", "10.0.0.0/8"}, false, false),
oldNode: nil,
compareNode: makeNode([]string{"2000::/10"}, false, false),
},
{
name: "not dualstack 6-4=>as is (used in old)",
enableDualStack: false,
node: makeNode([]string{"2000::/10", "10.0.0.0/8"}, false, false),
oldNode: makeNode([]string{"2000::/10", "10.0.0.0/8"}, false, false),
compareNode: makeNode([]string{"2000::/10", "10.0.0.0/8"}, false, false),
},
{
name: "not dualstack 6-4=>6only",
enableDualStack: false,
node: makeNode([]string{"2000::/10", "10.0.0.0/8"}, false, false),
oldNode: nil,
compareNode: makeNode([]string{"2000::/10"}, false, false),
},
{
name: "not dualstack 6-4=>as is (used in old)",
enableDualStack: false,
node: makeNode([]string{"2000::/10", "10.0.0.0/8"}, false, false),
oldNode: makeNode([]string{"2000::/10", "10.0.0.0/8"}, false, false),
compareNode: makeNode([]string{"2000::/10", "10.0.0.0/8"}, false, false),
name: "dualstack 6-4",
node: makeNode([]string{"2000::/10", "10.0.0.0/8"}, false, false),
compareNode: makeNode([]string{"2000::/10", "10.0.0.0/8"}, false, false),
},
{
name: "new with no Spec.ConfigSource and no Status.Config , enableNodeDynamicConfig disabled",
enableDualStack: false,
enableNodeDynamicConfig: false,
node: makeNode(nil, false, false),
oldNode: nil,
@@ -171,7 +135,6 @@ func TestDropFields(t *testing.T) {
},
{
name: "new with Spec.ConfigSource and no Status.Config, enableNodeDynamicConfig disabled",
enableDualStack: false,
enableNodeDynamicConfig: false,
node: makeNode(nil, true, false),
oldNode: nil,
@@ -179,7 +142,6 @@ func TestDropFields(t *testing.T) {
},
{
name: "new with Spec.ConfigSource and Status.Config, enableNodeDynamicConfig disabled",
enableDualStack: false,
enableNodeDynamicConfig: false,
node: makeNode(nil, true, true),
oldNode: nil,
@@ -187,7 +149,6 @@ func TestDropFields(t *testing.T) {
},
{
name: "update with Spec.ConfigSource and Status.Config (old has none), enableNodeDynamicConfig disabled",
enableDualStack: false,
enableNodeDynamicConfig: false,
node: makeNode(nil, true, true),
oldNode: makeNode(nil, false, false),
@@ -195,7 +156,6 @@ func TestDropFields(t *testing.T) {
},
{
name: "update with Spec.ConfigSource and Status.Config (old has them), enableNodeDynamicConfig disabled",
enableDualStack: false,
enableNodeDynamicConfig: false,
node: makeNode(nil, true, true),
oldNode: makeNode(nil, true, true),
@@ -203,7 +163,6 @@ func TestDropFields(t *testing.T) {
},
{
name: "update with Spec.ConfigSource and Status.Config (old has Status.Config), enableNodeDynamicConfig disabled",
enableDualStack: false,
enableNodeDynamicConfig: false,
node: makeNode(nil, true, true),
oldNode: makeNode(nil, false, true),
@@ -211,7 +170,6 @@ func TestDropFields(t *testing.T) {
},
{
name: "new with Spec.ConfigSource and Status.Config, enableNodeDynamicConfig enabled",
enableDualStack: false,
enableNodeDynamicConfig: true,
node: makeNode(nil, true, true),
oldNode: nil,
@@ -221,7 +179,6 @@ func TestDropFields(t *testing.T) {
for _, tc := range testCases {
func() {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, tc.enableDualStack)()
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DynamicKubeletConfig, tc.enableNodeDynamicConfig)()
dropDisabledFields(tc.node, tc.oldNode)

View File

@@ -215,7 +215,7 @@ func (c LegacyRESTStorageProvider) NewLegacyRESTStorage(restOptionsGetter generi
// allocator for secondary service ip range
var secondaryServiceClusterIPAllocator ipallocator.Interface
if utilfeature.DefaultFeatureGate.Enabled(features.IPv6DualStack) && c.SecondaryServiceIPRange.IP != nil {
if c.SecondaryServiceIPRange.IP != nil {
var secondaryServiceClusterIPRegistry rangeallocation.RangeRegistry
secondaryServiceClusterIPAllocator, err = ipallocator.New(&c.SecondaryServiceIPRange, func(max int, rangeSpec string) (allocator.Interface, error) {
mem := allocator.NewAllocationMap(max, rangeSpec)

View File

@@ -29,10 +29,6 @@ import (
api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/registry/core/service/ipallocator"
netutils "k8s.io/utils/net"
utilfeature "k8s.io/apiserver/pkg/util/feature"
featuregatetesting "k8s.io/component-base/featuregate/testing"
"k8s.io/kubernetes/pkg/features"
)
type mockRangeRegistry struct {
@@ -328,8 +324,6 @@ func TestShouldWorkOnSecondary(t *testing.T) {
}
func TestRepairDualStack(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, true)()
fakeClient := fake.NewSimpleClientset()
ipregistry := &mockRangeRegistry{
item: &api.RangeAllocation{Range: "192.168.1.0/24"},
@@ -368,8 +362,6 @@ func TestRepairDualStack(t *testing.T) {
}
func TestRepairLeakDualStack(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, true)()
_, cidr, _ := netutils.ParseCIDRSloppy("192.168.1.0/24")
previous, err := ipallocator.NewInMemory(cidr)
if err != nil {
@@ -466,7 +458,6 @@ func TestRepairWithExistingDualStack(t *testing.T) {
// we can saftly create tests that has ipFamilyPolicy:nil
// this will work every where except alloc & validation
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, true)()
_, cidr, _ := netutils.ParseCIDRSloppy("192.168.1.0/24")
previous, err := ipallocator.NewInMemory(cidr)
if err != nil {

View File

@@ -107,12 +107,6 @@ func (al *Allocators) initIPFamilyFields(after After, before Before) error {
return nil
}
// gate off. We don't need to validate or default new fields
// we totally depend on existing validation in apis/validation
if !utilfeature.DefaultFeatureGate.Enabled(features.IPv6DualStack) {
return nil
}
// We don't want to auto-upgrade (add an IP) or downgrade (remove an IP)
// PreferDualStack services following a cluster change to/from
// dual-stackness.
@@ -343,10 +337,6 @@ func (al *Allocators) allocClusterIPs(service *api.Service, dryRun bool) (map[ap
return nil, nil
}
if !utilfeature.DefaultFeatureGate.Enabled(features.IPv6DualStack) {
return al.allocClusterIP(service, dryRun)
}
toAlloc := make(map[api.IPFamily]string)
// at this stage, the only fact we know is that service has correct ip families
// assigned to it. It may have partial assigned ClusterIPs (Upgrade to dual stack)
@@ -391,25 +381,6 @@ func (al *Allocators) allocClusterIPs(service *api.Service, dryRun bool) (map[ap
return allocated, err
}
// standard allocator for dualstackgate==Off, hard wired dependency
// and ignores policy, families and clusterIPs
func (al *Allocators) allocClusterIP(service *api.Service, dryRun bool) (map[api.IPFamily]string, error) {
toAlloc := make(map[api.IPFamily]string)
// get clusterIP.. empty string if user did not specify an ip
toAlloc[al.defaultServiceIPFamily] = service.Spec.ClusterIP
// alloc
allocated, err := al.allocIPs(service, toAlloc, dryRun)
// set
if err == nil {
service.Spec.ClusterIP = allocated[al.defaultServiceIPFamily]
service.Spec.ClusterIPs = []string{allocated[al.defaultServiceIPFamily]}
}
return allocated, err
}
func (al *Allocators) allocIPs(service *api.Service, toAlloc map[api.IPFamily]string, dryRun bool) (map[api.IPFamily]string, error) {
allocated := make(map[api.IPFamily]string)
@@ -687,24 +658,12 @@ func (al *Allocators) updateClusterIPs(after After, before Before, dryRun bool)
// Update service from non-ExternalName to ExternalName, should release ClusterIP if exists.
if oldService.Spec.Type != api.ServiceTypeExternalName && service.Spec.Type == api.ServiceTypeExternalName {
toRelease = make(map[api.IPFamily]string)
if !utilfeature.DefaultFeatureGate.Enabled(features.IPv6DualStack) {
// for non dual stack enabled cluster we use clusterIPs
toRelease[al.defaultServiceIPFamily] = oldService.Spec.ClusterIP
} else {
// dual stack is enabled, collect ClusterIPs by families
for i, family := range oldService.Spec.IPFamilies {
toRelease[family] = oldService.Spec.ClusterIPs[i]
}
for i, family := range oldService.Spec.IPFamilies {
toRelease[family] = oldService.Spec.ClusterIPs[i]
}
return nil, toRelease, nil
}
// upgrade and downgrade are specific to dualstack
if !utilfeature.DefaultFeatureGate.Enabled(features.IPv6DualStack) {
return nil, nil, nil
}
upgraded := len(oldService.Spec.IPFamilies) == 1 && len(service.Spec.IPFamilies) == 2
downgraded := len(oldService.Spec.IPFamilies) == 2 && len(service.Spec.IPFamilies) == 1
@@ -909,10 +868,6 @@ func (al *Allocators) releaseClusterIPs(service *api.Service) (released map[api.
return nil, nil
}
if !utilfeature.DefaultFeatureGate.Enabled(features.IPv6DualStack) {
return al.releaseClusterIP(service)
}
toRelease := make(map[api.IPFamily]string)
for _, ip := range service.Spec.ClusterIPs {
if netutils.IsIPv6String(ip) {
@@ -924,21 +879,6 @@ func (al *Allocators) releaseClusterIPs(service *api.Service) (released map[api.
return al.releaseIPs(toRelease)
}
// for pre dual stack (gate == off). Hardwired to ClusterIP and ignores all new fields
func (al *Allocators) releaseClusterIP(service *api.Service) (released map[api.IPFamily]string, err error) {
toRelease := make(map[api.IPFamily]string)
// we need to do that to handle cases where allocator is no longer configured on
// cluster
if netutils.IsIPv6String(service.Spec.ClusterIP) {
toRelease[api.IPv6Protocol] = service.Spec.ClusterIP
} else {
toRelease[api.IPv4Protocol] = service.Spec.ClusterIP
}
return al.releaseIPs(toRelease)
}
// This is O(N), but we expect haystack to be small;
// so small that we expect a linear search to be faster
func containsNumber(haystack []int, needle int) bool {

View File

@@ -36,10 +36,8 @@ import (
genericregistry "k8s.io/apiserver/pkg/registry/generic/registry"
"k8s.io/apiserver/pkg/registry/rest"
"k8s.io/apiserver/pkg/util/dryrun"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/klog/v2"
api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/printers"
printersinternal "k8s.io/kubernetes/pkg/printers/internalversion"
printerstorage "k8s.io/kubernetes/pkg/printers/storage"
@@ -242,11 +240,6 @@ func (r *REST) defaultOnReadService(service *api.Service) {
// We still want to present a consistent view of them.
normalizeClusterIPs(After{service}, Before{nil})
// The rest of this does not apply unless dual-stack is enabled.
if !utilfeature.DefaultFeatureGate.Enabled(features.IPv6DualStack) {
return
}
// Set ipFamilies and ipFamilyPolicy if needed.
r.defaultOnReadIPFamilies(service)
}

View File

@@ -639,8 +639,6 @@ func TestServiceDefaultOnRead(t *testing.T) {
input: &api.Pod{},
}}
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, true)()
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
storage, _, server := newStorage(t, []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol})
@@ -727,9 +725,6 @@ func helpTestCreateUpdateDeleteWithFamilies(t *testing.T, testCases []cudTestCas
// NOTE: do not call t.Helper() here. It's more useful for errors to be
// attributed to lines in this function than the caller of it.
// This test is ONLY with the gate enabled.
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, true)()
storage, _, server := newStorage(t, ipFamilies)
defer server.Terminate(t)
defer storage.Store.DestroyFunc()
@@ -850,20 +845,18 @@ func verifyEquiv(t testingTInterface, call string, tc *svcTestCase, got *api.Ser
if want.Spec.ClusterIP == "" {
want.Spec.ClusterIP = got.Spec.ClusterIP
}
if utilfeature.DefaultFeatureGate.Enabled(features.IPv6DualStack) {
if want.Spec.IPFamilyPolicy == nil {
want.Spec.IPFamilyPolicy = got.Spec.IPFamilyPolicy
}
if tc.expectStackDowngrade && len(want.Spec.ClusterIPs) > len(got.Spec.ClusterIPs) {
want.Spec.ClusterIPs = want.Spec.ClusterIPs[0:1]
} else if len(got.Spec.ClusterIPs) > len(want.Spec.ClusterIPs) {
want.Spec.ClusterIPs = append(want.Spec.ClusterIPs, got.Spec.ClusterIPs[len(want.Spec.ClusterIPs):]...)
}
if tc.expectStackDowngrade && len(want.Spec.IPFamilies) > len(got.Spec.ClusterIPs) {
want.Spec.IPFamilies = want.Spec.IPFamilies[0:1]
} else if len(got.Spec.IPFamilies) > len(want.Spec.IPFamilies) {
want.Spec.IPFamilies = append(want.Spec.IPFamilies, got.Spec.IPFamilies[len(want.Spec.IPFamilies):]...)
}
if want.Spec.IPFamilyPolicy == nil {
want.Spec.IPFamilyPolicy = got.Spec.IPFamilyPolicy
}
if tc.expectStackDowngrade && len(want.Spec.ClusterIPs) > len(got.Spec.ClusterIPs) {
want.Spec.ClusterIPs = want.Spec.ClusterIPs[0:1]
} else if len(got.Spec.ClusterIPs) > len(want.Spec.ClusterIPs) {
want.Spec.ClusterIPs = append(want.Spec.ClusterIPs, got.Spec.ClusterIPs[len(want.Spec.ClusterIPs):]...)
}
if tc.expectStackDowngrade && len(want.Spec.IPFamilies) > len(got.Spec.ClusterIPs) {
want.Spec.IPFamilies = want.Spec.IPFamilies[0:1]
} else if len(got.Spec.IPFamilies) > len(want.Spec.IPFamilies) {
want.Spec.IPFamilies = append(want.Spec.IPFamilies, got.Spec.IPFamilies[len(want.Spec.IPFamilies):]...)
}
}
@@ -1021,8 +1014,6 @@ func TestVerifyEquiv(t *testing.T) {
expect: false,
}}
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, true)()
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
result := verifyEquiv(fakeTestingT{t}, "test", &tc.input, tc.output)
@@ -1098,22 +1089,14 @@ func proveClusterIPsAllocated(t *testing.T, storage *wrapperRESTForTests, before
t.Errorf("%s: expected clusterIP == clusterIPs[0]: %q != %q", callName(before, after), sing, plur)
}
clips := []string{}
if utilfeature.DefaultFeatureGate.Enabled(features.IPv6DualStack) {
clips = after.Spec.ClusterIPs
} else {
clips = append(clips, after.Spec.ClusterIP)
}
for _, clip := range clips {
for _, clip := range after.Spec.ClusterIPs {
if !ipIsAllocated(t, storage.alloc.serviceIPAllocatorsByFamily[familyOf(clip)], clip) {
t.Errorf("%s: expected clusterIP to be allocated: %q", callName(before, after), clip)
}
}
if utilfeature.DefaultFeatureGate.Enabled(features.IPv6DualStack) {
if lc, lf := len(after.Spec.ClusterIPs), len(after.Spec.IPFamilies); lc != lf {
t.Errorf("%s: expected same number of clusterIPs and ipFamilies: %d != %d", callName(before, after), lc, lf)
}
if lc, lf := len(after.Spec.ClusterIPs), len(after.Spec.IPFamilies); lc != lf {
t.Errorf("%s: expected same number of clusterIPs and ipFamilies: %d != %d", callName(before, after), lc, lf)
}
for i, fam := range after.Spec.IPFamilies {
@@ -1122,23 +1105,21 @@ func proveClusterIPsAllocated(t *testing.T, storage *wrapperRESTForTests, before
}
}
if utilfeature.DefaultFeatureGate.Enabled(features.IPv6DualStack) {
if after.Spec.IPFamilyPolicy == nil {
t.Errorf("%s: expected ipFamilyPolicy to be set", callName(before, after))
} else {
pol := *after.Spec.IPFamilyPolicy
fams := len(after.Spec.IPFamilies)
clus := 1
if storage.secondaryIPFamily != "" {
clus = 2
}
if pol == api.IPFamilyPolicySingleStack && fams != 1 {
t.Errorf("%s: expected 1 ipFamily, got %d", callName(before, after), fams)
} else if pol == api.IPFamilyPolicyRequireDualStack && fams != 2 {
t.Errorf("%s: expected 2 ipFamilies, got %d", callName(before, after), fams)
} else if pol == api.IPFamilyPolicyPreferDualStack && fams != clus {
t.Errorf("%s: expected %d ipFamilies, got %d", callName(before, after), clus, fams)
}
if after.Spec.IPFamilyPolicy == nil {
t.Errorf("%s: expected ipFamilyPolicy to be set", callName(before, after))
} else {
pol := *after.Spec.IPFamilyPolicy
fams := len(after.Spec.IPFamilies)
clus := 1
if storage.secondaryIPFamily != "" {
clus = 2
}
if pol == api.IPFamilyPolicySingleStack && fams != 1 {
t.Errorf("%s: expected 1 ipFamily, got %d", callName(before, after), fams)
} else if pol == api.IPFamilyPolicyRequireDualStack && fams != 2 {
t.Errorf("%s: expected 2 ipFamilies, got %d", callName(before, after), fams)
} else if pol == api.IPFamilyPolicyPreferDualStack && fams != clus {
t.Errorf("%s: expected %d ipFamilies, got %d", callName(before, after), clus, fams)
}
}
@@ -1180,13 +1161,7 @@ func proveClusterIPsDeallocated(t *testing.T, storage *wrapperRESTForTests, befo
}
if before != nil && before.Spec.ClusterIP != api.ClusterIPNone {
clips := []string{}
if utilfeature.DefaultFeatureGate.Enabled(features.IPv6DualStack) {
clips = before.Spec.ClusterIPs
} else {
clips = append(clips, before.Spec.ClusterIP)
}
for _, clip := range clips {
for _, clip := range before.Spec.ClusterIPs {
if ipIsAllocated(t, storage.alloc.serviceIPAllocatorsByFamily[familyOf(clip)], clip) {
t.Errorf("%s: expected clusterIP to be deallocated: %q", callName(before, after), clip)
}
@@ -1289,35 +1264,10 @@ func TestCreateIgnoresIPsForExternalName(t *testing.T) {
testCases := []struct {
name string
clusterFamilies []api.IPFamily
enableDualStack bool
cases []testCase
}{{
name: "singlestack:v4_gate:off",
clusterFamilies: []api.IPFamily{api.IPv4Protocol},
enableDualStack: false,
cases: []testCase{{
name: "Policy:unset_Families:unset",
svc: svctest.MakeService("foo"),
}, {
name: "Policy:SingleStack_Families:v4",
svc: svctest.MakeService("foo",
svctest.SetIPFamilyPolicy(api.IPFamilyPolicySingleStack),
svctest.SetIPFamilies(api.IPv4Protocol)),
}, {
name: "Policy:PreferDualStack_Families:v4v6",
svc: svctest.MakeService("foo",
svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack),
svctest.SetIPFamilies(api.IPv4Protocol, api.IPv6Protocol)),
}, {
name: "Policy:RequireDualStack_Families:v6v4",
svc: svctest.MakeService("foo",
svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack),
svctest.SetIPFamilies(api.IPv6Protocol, api.IPv4Protocol)),
}},
}, {
name: "singlestack:v6_gate:on",
name: "singlestack:v6",
clusterFamilies: []api.IPFamily{api.IPv6Protocol},
enableDualStack: true,
cases: []testCase{{
name: "Policy:unset_Families:unset",
svc: svctest.MakeService("foo"),
@@ -1341,32 +1291,8 @@ func TestCreateIgnoresIPsForExternalName(t *testing.T) {
expectError: true,
}},
}, {
name: "dualstack:v4v6_gate:off",
clusterFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol},
enableDualStack: false,
cases: []testCase{{
name: "Policy:unset_Families:unset",
svc: svctest.MakeService("foo"),
}, {
name: "Policy:SingleStack_Families:v4",
svc: svctest.MakeService("foo",
svctest.SetIPFamilyPolicy(api.IPFamilyPolicySingleStack),
svctest.SetIPFamilies(api.IPv4Protocol)),
}, {
name: "Policy:PreferDualStack_Families:v4v6",
svc: svctest.MakeService("foo",
svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack),
svctest.SetIPFamilies(api.IPv4Protocol, api.IPv6Protocol)),
}, {
name: "Policy:RequireDualStack_Families:v6v4",
svc: svctest.MakeService("foo",
svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack),
svctest.SetIPFamilies(api.IPv6Protocol, api.IPv4Protocol)),
}},
}, {
name: "dualstack:v6v4_gate:on",
name: "dualstack:v6v4",
clusterFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol},
enableDualStack: true,
cases: []testCase{{
name: "Policy:unset_Families:unset",
svc: svctest.MakeService("foo"),
@@ -1393,8 +1319,6 @@ func TestCreateIgnoresIPsForExternalName(t *testing.T) {
for _, otc := range testCases {
t.Run(otc.name, func(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, otc.enableDualStack)()
storage, _, server := newStorage(t, otc.clusterFamilies)
defer server.Terminate(t)
defer storage.Store.DestroyFunc()
@@ -1437,159 +1361,6 @@ func TestCreateIgnoresIPsForExternalName(t *testing.T) {
}
}
// Prove that create ignores IPFamily stuff when dual-stack is disabled.
func TestCreateIgnoresIPFamilyWithoutDualStack(t *testing.T) {
// These cases were chosen from the full gamut to ensure all "interesting"
// cases are covered.
testCases := []struct {
name string
svc *api.Service
}{
//----------------------------------------
// ClusterIP:unset
//----------------------------------------
{
name: "ClusterIP:unset_Policy:unset_Families:unset",
svc: svctest.MakeService("foo"),
}, {
name: "ClusterIP:unset_Policy:unset_Families:v4",
svc: svctest.MakeService("foo",
svctest.SetIPFamilies(api.IPv4Protocol)),
}, {
name: "ClusterIP:unset_Policy:unset_Families:v6v4",
svc: svctest.MakeService("foo",
svctest.SetIPFamilies(api.IPv6Protocol, api.IPv4Protocol)),
}, {
name: "ClusterIP:unset_Policy:SingleStack_Families:unset",
svc: svctest.MakeService("foo",
svctest.SetIPFamilyPolicy(api.IPFamilyPolicySingleStack)),
}, {
name: "ClusterIP:unset_Policy:SingleStack_Families:v4",
svc: svctest.MakeService("foo",
svctest.SetIPFamilyPolicy(api.IPFamilyPolicySingleStack),
svctest.SetIPFamilies(api.IPv4Protocol)),
}, {
name: "ClusterIP:unset_Policy:SingleStack_Families:v6v4",
svc: svctest.MakeService("foo",
svctest.SetIPFamilyPolicy(api.IPFamilyPolicySingleStack),
svctest.SetIPFamilies(api.IPv6Protocol, api.IPv4Protocol)),
}, {
name: "ClusterIP:unset_Policy:PreferDualStack_Families:unset",
svc: svctest.MakeService("foo",
svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)),
}, {
name: "ClusterIP:unset_Policy:PreferDualStack_Families:v4",
svc: svctest.MakeService("foo",
svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack),
svctest.SetIPFamilies(api.IPv4Protocol)),
}, {
name: "ClusterIP:unset_Policy:PreferDualStack_Families:v6v4",
svc: svctest.MakeService("foo",
svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack),
svctest.SetIPFamilies(api.IPv6Protocol, api.IPv4Protocol)),
}, {
name: "ClusterIP:unset_Policy:RequireDualStack_Families:unset",
svc: svctest.MakeService("foo",
svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack)),
}, {
name: "ClusterIP:unset_Policy:RequireDualStack_Families:v4",
svc: svctest.MakeService("foo",
svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack),
svctest.SetIPFamilies(api.IPv4Protocol)),
}, {
name: "ClusterIP:unset_Policy:RequireDualStack_Families:v6v4",
svc: svctest.MakeService("foo",
svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack),
svctest.SetIPFamilies(api.IPv6Protocol, api.IPv4Protocol)),
},
//----------------------------------------
// ClusterIPs:v4v6
//----------------------------------------
{
name: "ClusterIPs:v4v6_Policy:unset_Families:unset",
svc: svctest.MakeService("foo",
svctest.SetClusterIPs("10.0.0.1", "2000::1")),
}, {
name: "ClusterIPs:v4v6_Policy:unset_Families:v4",
svc: svctest.MakeService("foo",
svctest.SetClusterIPs("10.0.0.1", "2000::1"),
svctest.SetIPFamilies(api.IPv4Protocol)),
}, {
name: "ClusterIPs:v4v6_Policy:RequireDualStack_Families:unset",
svc: svctest.MakeService("foo",
svctest.SetClusterIPs("10.0.0.1", "2000::1"),
svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack)),
},
//----------------------------------------
// Headless
//----------------------------------------
{
name: "Headless_Policy:unset_Families:unset",
svc: svctest.MakeService("foo",
svctest.SetHeadless),
}, {
name: "Headless_Policy:unset_Families:v4",
svc: svctest.MakeService("foo",
svctest.SetHeadless,
svctest.SetIPFamilies(api.IPv4Protocol)),
}, {
name: "Headless_Policy:RequireDualStack_Families:unset",
svc: svctest.MakeService("foo",
svctest.SetHeadless,
svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack)),
},
//----------------------------------------
// HeadlessSelectorless
//----------------------------------------
{
name: "HeadlessSelectorless_Policy:unset_Families:unset",
svc: svctest.MakeService("foo",
svctest.SetHeadless,
svctest.SetSelector(nil)),
}, {
name: "HeadlessSelectorless_Policy:unset_Families:v4",
svc: svctest.MakeService("foo",
svctest.SetHeadless,
svctest.SetSelector(nil),
svctest.SetIPFamilies(api.IPv4Protocol)),
}, {
name: "HeadlessSelectorless_Policy:RequireDualStack_Families:unset",
svc: svctest.MakeService("foo",
svctest.SetHeadless,
svctest.SetSelector(nil),
svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack)),
},
}
// This test is ONLY with the gate off.
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, false)()
// Do this in the outer scope for performance.
storage, _, server := newStorage(t, []api.IPFamily{api.IPv4Protocol})
defer server.Terminate(t)
defer storage.Store.DestroyFunc()
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
ctx := genericapirequest.NewDefaultContext()
createdObj, err := storage.Create(ctx, tc.svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{})
if err != nil {
t.Fatalf("unexpected error creating service: %v", err)
}
defer storage.Delete(ctx, tc.svc.Name, rest.ValidateAllObjectFunc, &metav1.DeleteOptions{})
createdSvc := createdObj.(*api.Service)
// The gate is off - these should always be empty.
if want, got := fmtIPFamilyPolicy(nil), fmtIPFamilyPolicy(createdSvc.Spec.IPFamilyPolicy); want != got {
t.Errorf("wrong IPFamilyPolicy: want %s, got %s", want, got)
}
if want, got := fmtIPFamilies(nil), fmtIPFamilies(createdSvc.Spec.IPFamilies); want != got {
t.Errorf("wrong IPFamilies: want %s, got %s", want, got)
}
})
}
}
// Prove that create initializes clusterIPs from clusterIP. This simplifies
// later tests to not need to re-prove this.
func TestCreateInitClusterIPsFromClusterIP(t *testing.T) {
@@ -1635,9 +1406,6 @@ func TestCreateInitClusterIPsFromClusterIP(t *testing.T) {
svctest.SetClusterIP("2000::1")),
}}
// This test is ONLY with the gate enabled.
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, true)()
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
storage, _, server := newStorage(t, tc.clusterFamilies)
@@ -6093,9 +5861,6 @@ func TestCreateInitIPFields(t *testing.T) {
},
}
// This test is ONLY with the gate enabled.
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, true)()
for _, otc := range testCases {
t.Run(otc.name, func(t *testing.T) {
@@ -6250,8 +6015,6 @@ func TestCreateInvalidClusterIPInputs(t *testing.T) {
expect: []string{"must be a valid IP"},
}}
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, true)()
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
storage, _, server := newStorage(t, tc.families)
@@ -6291,9 +6054,6 @@ func TestCreateDeleteReuse(t *testing.T) {
svctest.SetIPFamilies(api.IPv4Protocol, api.IPv6Protocol)),
}}
// This test is ONLY with the gate enabled.
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, true)()
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
storage, _, server := newStorage(t, []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol})
@@ -6729,47 +6489,38 @@ func TestCreateSkipsAllocationsForHeadless(t *testing.T) {
testCases := []struct {
name string
clusterFamilies []api.IPFamily
enableDualStack bool
svc *api.Service
expectError bool
}{{
name: "singlestack:v4_gate:off",
name: "singlestack:v4",
clusterFamilies: []api.IPFamily{api.IPv4Protocol},
enableDualStack: false,
svc: svctest.MakeService("foo"),
}, {
name: "singlestack:v6_gate:on",
name: "singlestack:v6",
clusterFamilies: []api.IPFamily{api.IPv6Protocol},
enableDualStack: true,
svc: svctest.MakeService("foo"),
}, {
name: "dualstack:v4v6_gate:off",
name: "dualstack:v4v6",
clusterFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol},
enableDualStack: false,
svc: svctest.MakeService("foo"),
}, {
name: "dualstack:v6v4_gate:on",
name: "dualstack:v6v4",
clusterFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol},
enableDualStack: true,
svc: svctest.MakeService("foo"),
}, {
name: "singlestack:v4_gate:off_type:NodePort",
name: "singlestack:v4_type:NodePort",
clusterFamilies: []api.IPFamily{api.IPv4Protocol},
enableDualStack: false,
svc: svctest.MakeService("foo", svctest.SetTypeNodePort),
expectError: true,
}, {
name: "singlestack:v6_gate:on_type:LoadBalancer",
name: "singlestack:v6_type:LoadBalancer",
clusterFamilies: []api.IPFamily{api.IPv6Protocol},
enableDualStack: true,
svc: svctest.MakeService("foo", svctest.SetTypeLoadBalancer),
expectError: true,
}}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, tc.enableDualStack)()
storage, _, server := newStorage(t, tc.clusterFamilies)
defer server.Terminate(t)
defer storage.Store.DestroyFunc()
@@ -6805,54 +6556,43 @@ func TestCreateDryRun(t *testing.T) {
testCases := []struct {
name string
clusterFamilies []api.IPFamily
enableDualStack bool
svc *api.Service
}{{
name: "singlestack:v4_gate:off_clusterip:unset",
name: "singlestack:v4_clusterip:unset",
clusterFamilies: []api.IPFamily{api.IPv4Protocol},
enableDualStack: false,
svc: svctest.MakeService("foo"),
}, {
name: "singlestack:v4_gate:off_clusterip:set",
name: "singlestack:v4_clusterip:set",
clusterFamilies: []api.IPFamily{api.IPv4Protocol},
enableDualStack: false,
svc: svctest.MakeService("foo", svctest.SetClusterIPs("10.0.0.1")),
}, {
name: "singlestack:v6_gate:on_clusterip:unset",
name: "singlestack:v6_clusterip:unset",
clusterFamilies: []api.IPFamily{api.IPv6Protocol},
enableDualStack: true,
svc: svctest.MakeService("foo"),
}, {
name: "singlestack:v6_gate:on_clusterip:set",
name: "singlestack:v6_clusterip:set",
clusterFamilies: []api.IPFamily{api.IPv6Protocol},
enableDualStack: true,
svc: svctest.MakeService("foo", svctest.SetClusterIPs("2000::1")),
}, {
name: "dualstack:v4v6_gate:on_clusterip:unset",
name: "dualstack:v4v6_clusterip:unset",
clusterFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol},
enableDualStack: true,
svc: svctest.MakeService("foo", svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)),
}, {
name: "dualstack:v4v6_gate:on_clusterip:set",
name: "dualstack:v4v6_clusterip:set",
clusterFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol},
enableDualStack: true,
svc: svctest.MakeService("foo", svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), svctest.SetClusterIPs("10.0.0.1", "2000::1")),
}, {
name: "singlestack:v4_gate:off_type:NodePort_nodeport:unset",
name: "singlestack:v4_type:NodePort_nodeport:unset",
clusterFamilies: []api.IPFamily{api.IPv4Protocol},
enableDualStack: false,
svc: svctest.MakeService("foo", svctest.SetTypeNodePort),
}, {
name: "singlestack:v4_gate:on_type:LoadBalancer_nodePort:set",
name: "singlestack:v4_type:LoadBalancer_nodePort:set",
clusterFamilies: []api.IPFamily{api.IPv4Protocol},
enableDualStack: true,
svc: svctest.MakeService("foo", svctest.SetTypeLoadBalancer, svctest.SetUniqueNodePorts),
}}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, tc.enableDualStack)()
storage, _, server := newStorage(t, tc.clusterFamilies)
defer server.Terminate(t)
defer storage.Store.DestroyFunc()
@@ -6886,9 +6626,6 @@ func TestCreateDryRun(t *testing.T) {
func TestDeleteWithFinalizer(t *testing.T) {
svcName := "foo"
// This test is ONLY with the gate enabled.
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, true)()
storage, _, server := newStorage(t, []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol})
defer server.Terminate(t)
defer storage.Store.DestroyFunc()
@@ -6962,33 +6699,29 @@ func TestDeleteWithFinalizer(t *testing.T) {
// Prove that a dry-run delete doesn't actually deallocate IPs or ports.
func TestDeleteDryRun(t *testing.T) {
testCases := []struct {
name string
enableDualStack bool
svc *api.Service
}{{
name: "gate:off",
enableDualStack: false,
svc: svctest.MakeService("foo",
svctest.SetTypeLoadBalancer,
svctest.SetExternalTrafficPolicy(api.ServiceExternalTrafficPolicyTypeLocal)),
}, {
name: "gate:on",
enableDualStack: true,
svc: svctest.MakeService("foo",
svctest.SetTypeLoadBalancer,
svctest.SetExternalTrafficPolicy(api.ServiceExternalTrafficPolicyTypeLocal)),
}}
name string
svc *api.Service
}{
{
name: "v4",
svc: svctest.MakeService("foo",
svctest.SetTypeLoadBalancer,
svctest.SetIPFamilies(api.IPv4Protocol),
svctest.SetExternalTrafficPolicy(api.ServiceExternalTrafficPolicyTypeLocal)),
},
{
name: "v4v6",
svc: svctest.MakeService("foo",
svctest.SetTypeLoadBalancer,
svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack),
svctest.SetIPFamilies(api.IPv4Protocol, api.IPv6Protocol),
svctest.SetExternalTrafficPolicy(api.ServiceExternalTrafficPolicyTypeLocal)),
}}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, tc.enableDualStack)()
families := []api.IPFamily{api.IPv4Protocol}
if tc.enableDualStack {
families = append(families, api.IPv6Protocol)
}
storage, _, server := newStorage(t, families)
storage, _, server := newStorage(t, tc.svc.Spec.IPFamilies)
defer server.Terminate(t)
defer storage.Store.DestroyFunc()

View File

@@ -162,14 +162,6 @@ func (svcStrategy) AllowUnconditionalUpdate() bool {
// newSvc.Spec.MyFeature = nil
// }
func dropServiceDisabledFields(newSvc *api.Service, oldSvc *api.Service) {
if !utilfeature.DefaultFeatureGate.Enabled(features.IPv6DualStack) && !serviceDualStackFieldsInUse(oldSvc) {
newSvc.Spec.IPFamilies = nil
newSvc.Spec.IPFamilyPolicy = nil
if len(newSvc.Spec.ClusterIPs) > 1 {
newSvc.Spec.ClusterIPs = newSvc.Spec.ClusterIPs[0:1]
}
}
// Clear AllocateLoadBalancerNodePorts if ServiceLBNodePortControl is not enabled
if !utilfeature.DefaultFeatureGate.Enabled(features.ServiceLBNodePortControl) {
if !allocateLoadBalancerNodePortsInUse(oldSvc) {
@@ -211,19 +203,6 @@ func allocateLoadBalancerNodePortsInUse(svc *api.Service) bool {
return svc.Spec.AllocateLoadBalancerNodePorts != nil
}
// returns true if svc.Spec.ServiceIPFamily field is in use
func serviceDualStackFieldsInUse(svc *api.Service) bool {
if svc == nil {
return false
}
ipFamilyPolicyInUse := svc.Spec.IPFamilyPolicy != nil
ipFamiliesInUse := len(svc.Spec.IPFamilies) > 0
ClusterIPsInUse := len(svc.Spec.ClusterIPs) > 1
return ipFamilyPolicyInUse || ipFamiliesInUse || ClusterIPsInUse
}
// returns true when the svc.Status.Conditions field is in use.
func serviceConditionsInUse(svc *api.Service) bool {
if svc == nil {

View File

@@ -144,15 +144,6 @@ func TestServiceStatusStrategy(t *testing.T) {
}
}
func makeServiceWithIPFamilies(ipfamilies []api.IPFamily, ipFamilyPolicy *api.IPFamilyPolicyType) *api.Service {
return &api.Service{
Spec: api.ServiceSpec{
IPFamilies: ipfamilies,
IPFamilyPolicy: ipFamilyPolicy,
},
}
}
func makeServiceWithConditions(conditions []metav1.Condition) *api.Service {
return &api.Service{
Status: api.ServiceStatus{
@@ -192,15 +183,10 @@ func makeServiceWithInternalTrafficPolicy(policy *api.ServiceInternalTrafficPoli
}
func TestDropDisabledField(t *testing.T) {
requireDualStack := api.IPFamilyPolicyRequireDualStack
preferDualStack := api.IPFamilyPolicyPreferDualStack
singleStack := api.IPFamilyPolicySingleStack
localInternalTrafficPolicy := api.ServiceInternalTrafficPolicyLocal
testCases := []struct {
name string
enableDualStack bool
enableMixedProtocol bool
enableLoadBalancerClass bool
enableInternalTrafficPolicy bool
@@ -208,64 +194,6 @@ func TestDropDisabledField(t *testing.T) {
oldSvc *api.Service
compareSvc *api.Service
}{
{
name: "not dual stack, field not used",
enableDualStack: false,
svc: makeServiceWithIPFamilies(nil, nil),
oldSvc: nil,
compareSvc: makeServiceWithIPFamilies(nil, nil),
},
{
name: "not dual stack, field used in old and new",
enableDualStack: false,
svc: makeServiceWithIPFamilies([]api.IPFamily{api.IPv4Protocol}, nil),
oldSvc: makeServiceWithIPFamilies([]api.IPFamily{api.IPv4Protocol}, nil),
compareSvc: makeServiceWithIPFamilies([]api.IPFamily{api.IPv4Protocol}, nil),
},
{
name: "dualstack, field used",
enableDualStack: true,
svc: makeServiceWithIPFamilies([]api.IPFamily{api.IPv6Protocol}, nil),
oldSvc: nil,
compareSvc: makeServiceWithIPFamilies([]api.IPFamily{api.IPv6Protocol}, nil),
},
/* preferDualStack field */
{
name: "not dual stack, fields is not use",
enableDualStack: false,
svc: makeServiceWithIPFamilies(nil, nil),
oldSvc: nil,
compareSvc: makeServiceWithIPFamilies(nil, nil),
},
{
name: "not dual stack, fields used in new, not in old",
enableDualStack: false,
svc: makeServiceWithIPFamilies(nil, &preferDualStack),
oldSvc: nil,
compareSvc: makeServiceWithIPFamilies(nil, nil),
},
{
name: "not dual stack, fields used in new, not in old",
enableDualStack: false,
svc: makeServiceWithIPFamilies(nil, &requireDualStack),
oldSvc: nil,
compareSvc: makeServiceWithIPFamilies(nil, nil),
},
{
name: "not dual stack, fields not used in old (single stack)",
enableDualStack: false,
svc: makeServiceWithIPFamilies(nil, nil),
oldSvc: makeServiceWithIPFamilies(nil, &singleStack),
compareSvc: makeServiceWithIPFamilies(nil, nil),
},
{
name: "dualstack, field used",
enableDualStack: true,
svc: makeServiceWithIPFamilies(nil, &singleStack),
oldSvc: nil,
compareSvc: makeServiceWithIPFamilies(nil, &singleStack),
},
/* svc.Status.Conditions */
{
name: "mixed protocol not enabled, field not used in old, not used in new",
@@ -463,7 +391,6 @@ func TestDropDisabledField(t *testing.T) {
}
for _, tc := range testCases {
func() {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, tc.enableDualStack)()
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.MixedProtocolLBService, tc.enableMixedProtocol)()
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ServiceLoadBalancerClass, tc.enableLoadBalancerClass)()
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ServiceInternalTrafficPolicy, tc.enableInternalTrafficPolicy)()