Allow multiple node cidr masks in cm

update tests

add comment

amend var name

update comment

add check for empty slice

fix tests

fix mask size in test

review feedback

add ipv4 and ipv6 flag for mask sizes

add to violation exception list

remove import alias

run update-openapi-spec

review feedback

run update-bazel

review feedback

review feedback
This commit is contained in:
Anish Ramasekar
2019-07-09 14:47:01 -07:00
parent cb2684c416
commit 796faba4ac
17 changed files with 343 additions and 198 deletions

View File

@@ -22,6 +22,10 @@ type NodeIPAMControllerConfiguration struct {
ServiceCIDR string
// secondaryServiceCIDR is CIDR Range for Services in cluster. This is used in dual stack clusters. SecondaryServiceCIDR must be of different IP family than ServiceCIDR
SecondaryServiceCIDR string
// NodeCIDRMaskSize is the mask size for node cidr in cluster.
// NodeCIDRMaskSize is the mask size for node cidr in single-stack cluster.
NodeCIDRMaskSize int32
// NodeCIDRMaskSizeIPv4 is the mask size for node cidr in dual-stack cluster.
NodeCIDRMaskSizeIPv4 int32
// NodeCIDRMaskSizeIPv6 is the mask size for node cidr in dual-stack cluster.
NodeCIDRMaskSizeIPv6 int32
}

View File

@@ -30,7 +30,6 @@ import (
// be no easy way to opt-out. Instead, if you want to use this defaulting method
// run it in your wrapper struct of this type in its `SetDefaults_` method.
func RecommendedDefaultNodeIPAMControllerConfiguration(obj *kubectrlmgrconfigv1alpha1.NodeIPAMControllerConfiguration) {
if obj.NodeCIDRMaskSize == 0 {
obj.NodeCIDRMaskSize = 24
}
// The default mask size is not set here because we need to determine the cluster cidr family before setting the
// appropriate mask size.
}

View File

@@ -84,6 +84,8 @@ func autoConvert_v1alpha1_NodeIPAMControllerConfiguration_To_config_NodeIPAMCont
out.ServiceCIDR = in.ServiceCIDR
out.SecondaryServiceCIDR = in.SecondaryServiceCIDR
out.NodeCIDRMaskSize = in.NodeCIDRMaskSize
out.NodeCIDRMaskSizeIPv4 = in.NodeCIDRMaskSizeIPv4
out.NodeCIDRMaskSizeIPv6 = in.NodeCIDRMaskSizeIPv6
return nil
}
@@ -91,5 +93,7 @@ func autoConvert_config_NodeIPAMControllerConfiguration_To_v1alpha1_NodeIPAMCont
out.ServiceCIDR = in.ServiceCIDR
out.SecondaryServiceCIDR = in.SecondaryServiceCIDR
out.NodeCIDRMaskSize = in.NodeCIDRMaskSize
out.NodeCIDRMaskSizeIPv4 = in.NodeCIDRMaskSizeIPv4
out.NodeCIDRMaskSizeIPv6 = in.NodeCIDRMaskSizeIPv6
return nil
}

View File

@@ -88,8 +88,21 @@ type CIDRAllocator interface {
Run(stopCh <-chan struct{})
}
// CIDRAllocatorParams is parameters that's required for creating new
// cidr range allocator.
type CIDRAllocatorParams struct {
// ClusterCIDRs is list of cluster cidrs
ClusterCIDRs []*net.IPNet
// ServiceCIDR is primary service cidr for cluster
ServiceCIDR *net.IPNet
// SecondaryServiceCIDR is secondary service cidr for cluster
SecondaryServiceCIDR *net.IPNet
// NodeCIDRMaskSizes is list of node cidr mask sizes
NodeCIDRMaskSizes []int
}
// New creates a new CIDR range allocator.
func New(kubeClient clientset.Interface, cloud cloudprovider.Interface, nodeInformer informers.NodeInformer, allocatorType CIDRAllocatorType, clusterCIDRs []*net.IPNet, serviceCIDR *net.IPNet, secondaryServiceCIDR *net.IPNet, nodeCIDRMaskSize int) (CIDRAllocator, error) {
func New(kubeClient clientset.Interface, cloud cloudprovider.Interface, nodeInformer informers.NodeInformer, allocatorType CIDRAllocatorType, allocatorParams CIDRAllocatorParams) (CIDRAllocator, error) {
nodeList, err := listNodes(kubeClient)
if err != nil {
return nil, err
@@ -97,7 +110,7 @@ func New(kubeClient clientset.Interface, cloud cloudprovider.Interface, nodeInfo
switch allocatorType {
case RangeAllocatorType:
return NewCIDRRangeAllocator(kubeClient, nodeInformer, clusterCIDRs, serviceCIDR, secondaryServiceCIDR, nodeCIDRMaskSize, nodeList)
return NewCIDRRangeAllocator(kubeClient, nodeInformer, allocatorParams, nodeList)
case CloudAllocatorType:
return NewCloudCIDRAllocator(kubeClient, cloud, nodeInformer)
default:

View File

@@ -43,6 +43,8 @@ const (
// The subnet mask size cannot be greater than 16 more than the cluster mask size
// TODO: https://github.com/kubernetes/kubernetes/issues/44918
// clusterSubnetMaxDiff limited to 16 due to the uncompressed bitmap
// Due to this limitation the subnet mask for IPv6 cluster cidr needs to be >= 48
// as default mask size for IPv6 is 64.
clusterSubnetMaxDiff = 16
// halfIPv6Len is the half of the IPv6 length
halfIPv6Len = net.IPv6len / 2

View File

@@ -21,9 +21,9 @@ import (
"net"
"sync"
"k8s.io/api/core/v1"
"k8s.io/klog"
v1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/types"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
@@ -71,7 +71,7 @@ type rangeAllocator struct {
// Caller must always pass in a list of existing nodes so the new allocator.
// Caller must ensure that ClusterCIDRs are semantically correct e.g (1 for non DualStack, 2 for DualStack etc..)
// can initialize its CIDR map. NodeList is only nil in testing.
func NewCIDRRangeAllocator(client clientset.Interface, nodeInformer informers.NodeInformer, clusterCIDRs []*net.IPNet, serviceCIDR *net.IPNet, secondaryServiceCIDR *net.IPNet, subNetMaskSize int, nodeList *v1.NodeList) (CIDRAllocator, error) {
func NewCIDRRangeAllocator(client clientset.Interface, nodeInformer informers.NodeInformer, allocatorParams CIDRAllocatorParams, nodeList *v1.NodeList) (CIDRAllocator, error) {
if client == nil {
klog.Fatalf("kubeClient is nil when starting NodeController")
}
@@ -84,9 +84,9 @@ func NewCIDRRangeAllocator(client clientset.Interface, nodeInformer informers.No
// create a cidrSet for each cidr we operate on
// cidrSet are mapped to clusterCIDR by index
cidrSets := make([]*cidrset.CidrSet, len(clusterCIDRs))
for idx, cidr := range clusterCIDRs {
cidrSet, err := cidrset.NewCIDRSet(cidr, subNetMaskSize)
cidrSets := make([]*cidrset.CidrSet, len(allocatorParams.ClusterCIDRs))
for idx, cidr := range allocatorParams.ClusterCIDRs {
cidrSet, err := cidrset.NewCIDRSet(cidr, allocatorParams.NodeCIDRMaskSizes[idx])
if err != nil {
return nil, err
}
@@ -95,7 +95,7 @@ func NewCIDRRangeAllocator(client clientset.Interface, nodeInformer informers.No
ra := &rangeAllocator{
client: client,
clusterCIDRs: clusterCIDRs,
clusterCIDRs: allocatorParams.ClusterCIDRs,
cidrSets: cidrSets,
nodeLister: nodeInformer.Lister(),
nodesSynced: nodeInformer.Informer().HasSynced,
@@ -104,14 +104,14 @@ func NewCIDRRangeAllocator(client clientset.Interface, nodeInformer informers.No
nodesInProcessing: sets.NewString(),
}
if serviceCIDR != nil {
ra.filterOutServiceRange(serviceCIDR)
if allocatorParams.ServiceCIDR != nil {
ra.filterOutServiceRange(allocatorParams.ServiceCIDR)
} else {
klog.V(0).Info("No Service CIDR provided. Skipping filtering out service addresses.")
}
if secondaryServiceCIDR != nil {
ra.filterOutServiceRange(secondaryServiceCIDR)
if allocatorParams.SecondaryServiceCIDR != nil {
ra.filterOutServiceRange(allocatorParams.SecondaryServiceCIDR)
} else {
klog.V(0).Info("No Secondary Service CIDR provided. Skipping filtering out secondary service addresses.")
}

View File

@@ -60,12 +60,9 @@ func getFakeNodeInformer(fakeNodeHandler *testutil.FakeNodeHandler) coreinformer
}
type testCase struct {
description string
fakeNodeHandler *testutil.FakeNodeHandler
clusterCIDRs []*net.IPNet
serviceCIDR *net.IPNet
secondaryServiceCIDR *net.IPNet
subNetMaskSize int
description string
fakeNodeHandler *testutil.FakeNodeHandler
allocatorParams CIDRAllocatorParams
// key is index of the cidr allocated
expectedAllocatedCIDR map[int]string
allocatedCIDRs map[int][]string
@@ -88,13 +85,15 @@ func TestOccupyPreExistingCIDR(t *testing.T) {
},
Clientset: fake.NewSimpleClientset(),
},
clusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
return []*net.IPNet{clusterCIDRv4}
}(),
serviceCIDR: nil,
secondaryServiceCIDR: nil,
subNetMaskSize: 24,
allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
return []*net.IPNet{clusterCIDRv4}
}(),
ServiceCIDR: nil,
SecondaryServiceCIDR: nil,
NodeCIDRMaskSizes: []int{24},
},
allocatedCIDRs: nil,
expectedAllocatedCIDR: nil,
ctrlCreateFail: false,
@@ -111,14 +110,16 @@ func TestOccupyPreExistingCIDR(t *testing.T) {
},
Clientset: fake.NewSimpleClientset(),
},
clusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
_, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/8")
return []*net.IPNet{clusterCIDRv4, clusterCIDRv6}
}(),
serviceCIDR: nil,
secondaryServiceCIDR: nil,
subNetMaskSize: 24,
allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
_, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/8")
return []*net.IPNet{clusterCIDRv4, clusterCIDRv6}
}(),
ServiceCIDR: nil,
SecondaryServiceCIDR: nil,
NodeCIDRMaskSizes: []int{24, 24},
},
allocatedCIDRs: nil,
expectedAllocatedCIDR: nil,
ctrlCreateFail: false,
@@ -138,13 +139,15 @@ func TestOccupyPreExistingCIDR(t *testing.T) {
},
Clientset: fake.NewSimpleClientset(),
},
clusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
return []*net.IPNet{clusterCIDRv4}
}(),
serviceCIDR: nil,
secondaryServiceCIDR: nil,
subNetMaskSize: 24,
allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
return []*net.IPNet{clusterCIDRv4}
}(),
ServiceCIDR: nil,
SecondaryServiceCIDR: nil,
NodeCIDRMaskSizes: []int{24},
},
allocatedCIDRs: nil,
expectedAllocatedCIDR: nil,
ctrlCreateFail: false,
@@ -164,14 +167,16 @@ func TestOccupyPreExistingCIDR(t *testing.T) {
},
Clientset: fake.NewSimpleClientset(),
},
clusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
_, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/8")
return []*net.IPNet{clusterCIDRv4, clusterCIDRv6}
}(),
serviceCIDR: nil,
secondaryServiceCIDR: nil,
subNetMaskSize: 24,
allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
_, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/8")
return []*net.IPNet{clusterCIDRv4, clusterCIDRv6}
}(),
ServiceCIDR: nil,
SecondaryServiceCIDR: nil,
NodeCIDRMaskSizes: []int{24, 24},
},
allocatedCIDRs: nil,
expectedAllocatedCIDR: nil,
ctrlCreateFail: false,
@@ -192,13 +197,15 @@ func TestOccupyPreExistingCIDR(t *testing.T) {
},
Clientset: fake.NewSimpleClientset(),
},
clusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
return []*net.IPNet{clusterCIDRv4}
}(),
serviceCIDR: nil,
secondaryServiceCIDR: nil,
subNetMaskSize: 24,
allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
return []*net.IPNet{clusterCIDRv4}
}(),
ServiceCIDR: nil,
SecondaryServiceCIDR: nil,
NodeCIDRMaskSizes: []int{24},
},
allocatedCIDRs: nil,
expectedAllocatedCIDR: nil,
ctrlCreateFail: true,
@@ -219,13 +226,15 @@ func TestOccupyPreExistingCIDR(t *testing.T) {
},
Clientset: fake.NewSimpleClientset(),
},
clusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
return []*net.IPNet{clusterCIDRv4}
}(),
serviceCIDR: nil,
secondaryServiceCIDR: nil,
subNetMaskSize: 24,
allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
return []*net.IPNet{clusterCIDRv4}
}(),
ServiceCIDR: nil,
SecondaryServiceCIDR: nil,
NodeCIDRMaskSizes: []int{24},
},
allocatedCIDRs: nil,
expectedAllocatedCIDR: nil,
ctrlCreateFail: true,
@@ -246,14 +255,16 @@ func TestOccupyPreExistingCIDR(t *testing.T) {
},
Clientset: fake.NewSimpleClientset(),
},
clusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
_, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/8")
return []*net.IPNet{clusterCIDRv4, clusterCIDRv6}
}(),
serviceCIDR: nil,
secondaryServiceCIDR: nil,
subNetMaskSize: 24,
allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
_, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/8")
return []*net.IPNet{clusterCIDRv4, clusterCIDRv6}
}(),
ServiceCIDR: nil,
SecondaryServiceCIDR: nil,
NodeCIDRMaskSizes: []int{24, 24},
},
allocatedCIDRs: nil,
expectedAllocatedCIDR: nil,
ctrlCreateFail: true,
@@ -274,14 +285,16 @@ func TestOccupyPreExistingCIDR(t *testing.T) {
},
Clientset: fake.NewSimpleClientset(),
},
clusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
_, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/8")
return []*net.IPNet{clusterCIDRv4, clusterCIDRv6}
}(),
serviceCIDR: nil,
secondaryServiceCIDR: nil,
subNetMaskSize: 24,
allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
_, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/8")
return []*net.IPNet{clusterCIDRv4, clusterCIDRv6}
}(),
ServiceCIDR: nil,
SecondaryServiceCIDR: nil,
NodeCIDRMaskSizes: []int{24, 24},
},
allocatedCIDRs: nil,
expectedAllocatedCIDR: nil,
ctrlCreateFail: true,
@@ -294,7 +307,7 @@ func TestOccupyPreExistingCIDR(t *testing.T) {
// Initialize the range allocator.
fakeNodeInformer := getFakeNodeInformer(tc.fakeNodeHandler)
nodeList, _ := tc.fakeNodeHandler.List(metav1.ListOptions{})
_, err := NewCIDRRangeAllocator(tc.fakeNodeHandler, fakeNodeInformer, tc.clusterCIDRs, tc.serviceCIDR, tc.secondaryServiceCIDR, tc.subNetMaskSize, nodeList)
_, err := NewCIDRRangeAllocator(tc.fakeNodeHandler, fakeNodeInformer, tc.allocatorParams, nodeList)
if err == nil && tc.ctrlCreateFail {
t.Fatalf("creating range allocator was expected to fail, but it did not")
}
@@ -320,13 +333,15 @@ func TestAllocateOrOccupyCIDRSuccess(t *testing.T) {
},
Clientset: fake.NewSimpleClientset(),
},
clusterCIDRs: func() []*net.IPNet {
_, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/24")
return []*net.IPNet{clusterCIDR}
}(),
serviceCIDR: nil,
secondaryServiceCIDR: nil,
subNetMaskSize: 30,
allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/24")
return []*net.IPNet{clusterCIDR}
}(),
ServiceCIDR: nil,
SecondaryServiceCIDR: nil,
NodeCIDRMaskSizes: []int{30},
},
expectedAllocatedCIDR: map[int]string{
0: "127.123.234.0/30",
},
@@ -343,16 +358,18 @@ func TestAllocateOrOccupyCIDRSuccess(t *testing.T) {
},
Clientset: fake.NewSimpleClientset(),
},
clusterCIDRs: func() []*net.IPNet {
_, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/24")
return []*net.IPNet{clusterCIDR}
}(),
serviceCIDR: func() *net.IPNet {
_, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26")
return serviceCIDR
}(),
secondaryServiceCIDR: nil,
subNetMaskSize: 30,
allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/24")
return []*net.IPNet{clusterCIDR}
}(),
ServiceCIDR: func() *net.IPNet {
_, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26")
return serviceCIDR
}(),
SecondaryServiceCIDR: nil,
NodeCIDRMaskSizes: []int{30},
},
// it should return first /30 CIDR after service range
expectedAllocatedCIDR: map[int]string{
0: "127.123.234.64/30",
@@ -370,16 +387,18 @@ func TestAllocateOrOccupyCIDRSuccess(t *testing.T) {
},
Clientset: fake.NewSimpleClientset(),
},
clusterCIDRs: func() []*net.IPNet {
_, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/24")
return []*net.IPNet{clusterCIDR}
}(),
serviceCIDR: func() *net.IPNet {
_, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26")
return serviceCIDR
}(),
secondaryServiceCIDR: nil,
subNetMaskSize: 30,
allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/24")
return []*net.IPNet{clusterCIDR}
}(),
ServiceCIDR: func() *net.IPNet {
_, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26")
return serviceCIDR
}(),
SecondaryServiceCIDR: nil,
NodeCIDRMaskSizes: []int{30},
},
allocatedCIDRs: map[int][]string{
0: {"127.123.234.64/30", "127.123.234.68/30", "127.123.234.72/30", "127.123.234.80/30"},
},
@@ -399,16 +418,19 @@ func TestAllocateOrOccupyCIDRSuccess(t *testing.T) {
},
Clientset: fake.NewSimpleClientset(),
},
clusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("127.123.234.0/8")
_, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/8")
return []*net.IPNet{clusterCIDRv4, clusterCIDRv6}
}(),
serviceCIDR: func() *net.IPNet {
_, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26")
return serviceCIDR
}(),
secondaryServiceCIDR: nil,
allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("127.123.234.0/8")
_, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/84")
return []*net.IPNet{clusterCIDRv4, clusterCIDRv6}
}(),
ServiceCIDR: func() *net.IPNet {
_, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26")
return serviceCIDR
}(),
SecondaryServiceCIDR: nil,
NodeCIDRMaskSizes: []int{24, 98},
},
},
{
description: "Dualstack CIDRs v6,v4",
@@ -422,18 +444,20 @@ func TestAllocateOrOccupyCIDRSuccess(t *testing.T) {
},
Clientset: fake.NewSimpleClientset(),
},
clusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("127.123.234.0/8")
_, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/8")
return []*net.IPNet{clusterCIDRv6, clusterCIDRv4}
}(),
serviceCIDR: func() *net.IPNet {
_, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26")
return serviceCIDR
}(),
secondaryServiceCIDR: nil,
allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("127.123.234.0/8")
_, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/84")
return []*net.IPNet{clusterCIDRv6, clusterCIDRv4}
}(),
ServiceCIDR: func() *net.IPNet {
_, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26")
return serviceCIDR
}(),
SecondaryServiceCIDR: nil,
NodeCIDRMaskSizes: []int{98, 24},
},
},
{
description: "Dualstack CIDRs, more than two",
fakeNodeHandler: &testutil.FakeNodeHandler{
@@ -446,24 +470,27 @@ func TestAllocateOrOccupyCIDRSuccess(t *testing.T) {
},
Clientset: fake.NewSimpleClientset(),
},
clusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("127.123.234.0/8")
_, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/8")
_, clusterCIDRv4_2, _ := net.ParseCIDR("10.0.0.0/8")
return []*net.IPNet{clusterCIDRv4, clusterCIDRv6, clusterCIDRv4_2}
}(),
serviceCIDR: func() *net.IPNet {
_, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26")
return serviceCIDR
}(),
secondaryServiceCIDR: nil,
allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDRv4, _ := net.ParseCIDR("127.123.234.0/8")
_, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/84")
_, clusterCIDRv4_2, _ := net.ParseCIDR("10.0.0.0/8")
return []*net.IPNet{clusterCIDRv4, clusterCIDRv6, clusterCIDRv4_2}
}(),
ServiceCIDR: func() *net.IPNet {
_, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26")
return serviceCIDR
}(),
SecondaryServiceCIDR: nil,
NodeCIDRMaskSizes: []int{24, 98, 24},
},
},
}
// test function
testFunc := func(tc testCase) {
// Initialize the range allocator.
allocator, err := NewCIDRRangeAllocator(tc.fakeNodeHandler, getFakeNodeInformer(tc.fakeNodeHandler), tc.clusterCIDRs, tc.serviceCIDR, tc.secondaryServiceCIDR, tc.subNetMaskSize, nil)
allocator, err := NewCIDRRangeAllocator(tc.fakeNodeHandler, getFakeNodeInformer(tc.fakeNodeHandler), tc.allocatorParams, nil)
if err != nil {
t.Errorf("%v: failed to create CIDRRangeAllocator with error %v", tc.description, err)
return
@@ -535,13 +562,15 @@ func TestAllocateOrOccupyCIDRFailure(t *testing.T) {
},
Clientset: fake.NewSimpleClientset(),
},
clusterCIDRs: func() []*net.IPNet {
_, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/28")
return []*net.IPNet{clusterCIDR}
}(),
serviceCIDR: nil,
secondaryServiceCIDR: nil,
subNetMaskSize: 30,
allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/28")
return []*net.IPNet{clusterCIDR}
}(),
ServiceCIDR: nil,
SecondaryServiceCIDR: nil,
NodeCIDRMaskSizes: []int{30},
},
allocatedCIDRs: map[int][]string{
0: {"127.123.234.0/30", "127.123.234.4/30", "127.123.234.8/30", "127.123.234.12/30"},
},
@@ -550,7 +579,7 @@ func TestAllocateOrOccupyCIDRFailure(t *testing.T) {
testFunc := func(tc testCase) {
// Initialize the range allocator.
allocator, err := NewCIDRRangeAllocator(tc.fakeNodeHandler, getFakeNodeInformer(tc.fakeNodeHandler), tc.clusterCIDRs, tc.serviceCIDR, tc.secondaryServiceCIDR, tc.subNetMaskSize, nil)
allocator, err := NewCIDRRangeAllocator(tc.fakeNodeHandler, getFakeNodeInformer(tc.fakeNodeHandler), tc.allocatorParams, nil)
if err != nil {
t.Logf("%v: failed to create CIDRRangeAllocator with error %v", tc.description, err)
}
@@ -609,10 +638,7 @@ func TestAllocateOrOccupyCIDRFailure(t *testing.T) {
type releaseTestCase struct {
description string
fakeNodeHandler *testutil.FakeNodeHandler
clusterCIDRs []*net.IPNet
serviceCIDR *net.IPNet
secondaryServiceCIDR *net.IPNet
subNetMaskSize int
allocatorParams CIDRAllocatorParams
expectedAllocatedCIDRFirstRound map[int]string
expectedAllocatedCIDRSecondRound map[int]string
allocatedCIDRs map[int][]string
@@ -633,13 +659,15 @@ func TestReleaseCIDRSuccess(t *testing.T) {
},
Clientset: fake.NewSimpleClientset(),
},
clusterCIDRs: func() []*net.IPNet {
_, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/28")
return []*net.IPNet{clusterCIDR}
}(),
serviceCIDR: nil,
secondaryServiceCIDR: nil,
subNetMaskSize: 30,
allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/28")
return []*net.IPNet{clusterCIDR}
}(),
ServiceCIDR: nil,
SecondaryServiceCIDR: nil,
NodeCIDRMaskSizes: []int{30},
},
allocatedCIDRs: map[int][]string{
0: {"127.123.234.0/30", "127.123.234.4/30", "127.123.234.8/30", "127.123.234.12/30"},
},
@@ -663,13 +691,15 @@ func TestReleaseCIDRSuccess(t *testing.T) {
},
Clientset: fake.NewSimpleClientset(),
},
clusterCIDRs: func() []*net.IPNet {
_, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/28")
return []*net.IPNet{clusterCIDR}
}(),
serviceCIDR: nil,
secondaryServiceCIDR: nil,
subNetMaskSize: 30,
allocatorParams: CIDRAllocatorParams{
ClusterCIDRs: func() []*net.IPNet {
_, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/28")
return []*net.IPNet{clusterCIDR}
}(),
ServiceCIDR: nil,
SecondaryServiceCIDR: nil,
NodeCIDRMaskSizes: []int{30},
},
allocatedCIDRs: map[int][]string{
0: {"127.123.234.4/30", "127.123.234.8/30", "127.123.234.12/30"},
},
@@ -687,7 +717,7 @@ func TestReleaseCIDRSuccess(t *testing.T) {
testFunc := func(tc releaseTestCase) {
// Initialize the range allocator.
allocator, _ := NewCIDRRangeAllocator(tc.fakeNodeHandler, getFakeNodeInformer(tc.fakeNodeHandler), tc.clusterCIDRs, tc.serviceCIDR, tc.secondaryServiceCIDR, tc.subNetMaskSize, nil)
allocator, _ := NewCIDRRangeAllocator(tc.fakeNodeHandler, getFakeNodeInformer(tc.fakeNodeHandler), tc.allocatorParams, nil)
rangeAllocator, ok := allocator.(*rangeAllocator)
if !ok {
t.Logf("%v: found non-default implementation of CIDRAllocator, skipping white-box test...", tc.description)

View File

@@ -37,7 +37,7 @@ func startLegacyIPAM(
kubeClient clientset.Interface,
clusterCIDRs []*net.IPNet,
serviceCIDR *net.IPNet,
nodeCIDRMaskSize int,
nodeCIDRMaskSizes []int,
) {
cfg := &ipam.Config{
Resync: ipamResyncInterval,
@@ -59,7 +59,7 @@ func startLegacyIPAM(
if len(clusterCIDRs) > 1 {
klog.Warningf("Multiple cidrs were configured with FromCluster or FromCloud. cidrs except first one were discarded")
}
ipamc, err := ipam.NewController(cfg, kubeClient, cloud, cidr, serviceCIDR, nodeCIDRMaskSize)
ipamc, err := ipam.NewController(cfg, kubeClient, cloud, cidr, serviceCIDR, nodeCIDRMaskSizes[0])
if err != nil {
klog.Fatalf("Error creating ipam controller: %v", err)
}

View File

@@ -81,7 +81,7 @@ func NewNodeIpamController(
clusterCIDRs []*net.IPNet,
serviceCIDR *net.IPNet,
secondaryServiceCIDR *net.IPNet,
nodeCIDRMaskSize int,
nodeCIDRMaskSizes []int,
allocatorType ipam.CIDRAllocatorType) (*Controller, error) {
if kubeClient == nil {
@@ -111,11 +111,11 @@ func NewNodeIpamController(
// - modify mask to allow flexible masks for IPv4 and IPv6
// - for alpha status they are the same
// for each cidr, cidr mask size must be <= node mask
for _, cidr := range clusterCIDRs {
// for each cidr, node mask size must be <= cidr mask
for idx, cidr := range clusterCIDRs {
mask := cidr.Mask
if maskSize, _ := mask.Size(); maskSize > nodeCIDRMaskSize {
klog.Fatal("Controller: Invalid --cluster-cidr, mask size of cluster CIDR must be less than or equal to --node-cidr-mask-size")
if maskSize, _ := mask.Size(); maskSize > nodeCIDRMaskSizes[idx] {
klog.Fatal("Controller: Invalid --cluster-cidr, mask size of cluster CIDR must be less than or equal to --node-cidr-mask-size configured for CIDR family")
}
}
}
@@ -132,10 +132,18 @@ func NewNodeIpamController(
// TODO: Abstract this check into a generic controller manager should run method.
if ic.allocatorType == ipam.IPAMFromClusterAllocatorType || ic.allocatorType == ipam.IPAMFromCloudAllocatorType {
startLegacyIPAM(ic, nodeInformer, cloud, kubeClient, clusterCIDRs, serviceCIDR, nodeCIDRMaskSize)
startLegacyIPAM(ic, nodeInformer, cloud, kubeClient, clusterCIDRs, serviceCIDR, nodeCIDRMaskSizes)
} else {
var err error
ic.cidrAllocator, err = ipam.New(kubeClient, cloud, nodeInformer, ic.allocatorType, clusterCIDRs, ic.serviceCIDR, ic.secondaryServiceCIDR, nodeCIDRMaskSize)
allocatorParams := ipam.CIDRAllocatorParams{
ClusterCIDRs: clusterCIDRs,
ServiceCIDR: ic.serviceCIDR,
SecondaryServiceCIDR: ic.secondaryServiceCIDR,
NodeCIDRMaskSizes: nodeCIDRMaskSizes,
}
ic.cidrAllocator, err = ipam.New(kubeClient, cloud, nodeInformer, ic.allocatorType, allocatorParams)
if err != nil {
return nil, err
}

View File

@@ -34,7 +34,7 @@ import (
netutils "k8s.io/utils/net"
)
func newTestNodeIpamController(clusterCIDR []*net.IPNet, serviceCIDR *net.IPNet, secondaryServiceCIDR *net.IPNet, nodeCIDRMaskSize int, allocatorType ipam.CIDRAllocatorType) (*Controller, error) {
func newTestNodeIpamController(clusterCIDR []*net.IPNet, serviceCIDR *net.IPNet, secondaryServiceCIDR *net.IPNet, nodeCIDRMaskSizes []int, allocatorType ipam.CIDRAllocatorType) (*Controller, error) {
clientSet := fake.NewSimpleClientset()
fakeNodeHandler := &testutil.FakeNodeHandler{
Existing: []*v1.Node{
@@ -53,7 +53,7 @@ func newTestNodeIpamController(clusterCIDR []*net.IPNet, serviceCIDR *net.IPNet,
fakeGCE := gce.NewFakeGCECloud(gce.DefaultTestClusterValues())
return NewNodeIpamController(
fakeNodeInformer, fakeGCE, clientSet,
clusterCIDR, serviceCIDR, secondaryServiceCIDR, nodeCIDRMaskSize, allocatorType,
clusterCIDR, serviceCIDR, secondaryServiceCIDR, nodeCIDRMaskSizes, allocatorType,
)
}
@@ -66,23 +66,24 @@ func TestNewNodeIpamControllerWithCIDRMasks(t *testing.T) {
clusterCIDR string
serviceCIDR string
secondaryServiceCIDR string
maskSize int
maskSize []int
allocatorType ipam.CIDRAllocatorType
wantFatal bool
}{
{"valid_range_allocator", "10.0.0.0/21", "10.1.0.0/21", emptyServiceCIDR, 24, ipam.RangeAllocatorType, false},
{"valid_range_allocator", "10.0.0.0/21", "10.1.0.0/21", emptyServiceCIDR, []int{24}, ipam.RangeAllocatorType, false},
{"valid_range_allocator_dualstack", "10.0.0.0/21,2000::/10", "10.1.0.0/21", emptyServiceCIDR, 24, ipam.RangeAllocatorType, false},
{"valid_range_allocator_dualstack_dualstackservice", "10.0.0.0/21,2000::/10", "10.1.0.0/21", "3000::/10", 24, ipam.RangeAllocatorType, false},
{"valid_range_allocator_dualstack", "10.0.0.0/21,2000::/10", "10.1.0.0/21", emptyServiceCIDR, []int{24, 98}, ipam.RangeAllocatorType, false},
{"valid_range_allocator_dualstack_dualstackservice", "10.0.0.0/21,2000::/10", "10.1.0.0/21", "3000::/10", []int{24, 98}, ipam.RangeAllocatorType, false},
{"valid_cloud_allocator", "10.0.0.0/21", "10.1.0.0/21", emptyServiceCIDR, 24, ipam.CloudAllocatorType, false},
{"valid_ipam_from_cluster", "10.0.0.0/21", "10.1.0.0/21", emptyServiceCIDR, 24, ipam.IPAMFromClusterAllocatorType, false},
{"valid_ipam_from_cloud", "10.0.0.0/21", "10.1.0.0/21", emptyServiceCIDR, 24, ipam.IPAMFromCloudAllocatorType, false},
{"valid_skip_cluster_CIDR_validation_for_cloud_allocator", "invalid", "10.1.0.0/21", emptyServiceCIDR, 24, ipam.CloudAllocatorType, false},
{"invalid_cluster_CIDR", "invalid", "10.1.0.0/21", emptyServiceCIDR, 24, ipam.IPAMFromClusterAllocatorType, true},
{"valid_CIDR_smaller_than_mask_cloud_allocator", "10.0.0.0/26", "10.1.0.0/21", emptyServiceCIDR, 24, ipam.CloudAllocatorType, false},
{"invalid_CIDR_smaller_than_mask_other_allocators", "10.0.0.0/26", "10.1.0.0/21", emptyServiceCIDR, 24, ipam.IPAMFromCloudAllocatorType, true},
{"invalid_serviceCIDR_contains_clusterCIDR", "10.0.0.0/23", "10.0.0.0/21", emptyServiceCIDR, 24, ipam.IPAMFromClusterAllocatorType, true},
{"valid_cloud_allocator", "10.0.0.0/21", "10.1.0.0/21", emptyServiceCIDR, []int{24}, ipam.CloudAllocatorType, false},
{"valid_ipam_from_cluster", "10.0.0.0/21", "10.1.0.0/21", emptyServiceCIDR, []int{24}, ipam.IPAMFromClusterAllocatorType, false},
{"valid_ipam_from_cloud", "10.0.0.0/21", "10.1.0.0/21", emptyServiceCIDR, []int{24}, ipam.IPAMFromCloudAllocatorType, false},
{"valid_skip_cluster_CIDR_validation_for_cloud_allocator", "invalid", "10.1.0.0/21", emptyServiceCIDR, []int{24}, ipam.CloudAllocatorType, false},
{"invalid_cluster_CIDR", "invalid", "10.1.0.0/21", emptyServiceCIDR, []int{24}, ipam.IPAMFromClusterAllocatorType, true},
{"valid_CIDR_smaller_than_mask_cloud_allocator", "10.0.0.0/26", "10.1.0.0/21", emptyServiceCIDR, []int{24}, ipam.CloudAllocatorType, false},
{"invalid_CIDR_smaller_than_mask_other_allocators", "10.0.0.0/26", "10.1.0.0/21", emptyServiceCIDR, []int{24}, ipam.IPAMFromCloudAllocatorType, true},
{"invalid_serviceCIDR_contains_clusterCIDR", "10.0.0.0/23", "10.0.0.0/21", emptyServiceCIDR, []int{24}, ipam.IPAMFromClusterAllocatorType, true},
{"invalid_CIDR_mask_size", "10.0.0.0/24,2000::/64", "10.1.0.0/21", emptyServiceCIDR, []int{24, 48}, ipam.IPAMFromClusterAllocatorType, true},
} {
t.Run(tc.desc, func(t *testing.T) {
clusterCidrs, _ := netutils.ParseCIDRs(strings.Split(tc.clusterCIDR, ","))