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:

committed by
GitHub

parent
c74d799677
commit
a53e2eaeab
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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 {
|
||||
|
@@ -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 {
|
||||
|
@@ -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)
|
||||
}
|
||||
|
@@ -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()
|
||||
|
||||
|
@@ -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 {
|
||||
|
@@ -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)()
|
||||
|
Reference in New Issue
Block a user