diff --git a/pkg/util/subnet/subnet.go b/pkg/util/subnet/subnet.go index 57e4173cda..666728178b 100644 --- a/pkg/util/subnet/subnet.go +++ b/pkg/util/subnet/subnet.go @@ -45,6 +45,11 @@ func BelongsTo(parent *net.IPNet, child *net.IPNet) bool { return childMasked.Equal(parentMasked) } +// SplitInto1 splits the parent IPNet into 1 subnet +func SplitInto1(parent *net.IPNet) ([]*net.IPNet, error) { + return SplitInto(0, parent) +} + // SplitInto2 splits the parent IPNet into 2 subnets func SplitInto2(parent *net.IPNet) ([]*net.IPNet, error) { return SplitInto(1, parent) @@ -61,13 +66,9 @@ func SplitInto8(parent *net.IPNet) ([]*net.IPNet, error) { } // SplitInto splits the parent IPNet into subnets with the specified number of additional bits in the prefix. -func SplitInto(additionalBits int, parent *net.IPNet) ([]*net.IPNet, error) { - if additionalBits < 1 || additionalBits > 3 { - return nil, fmt.Errorf("additionalBits value must be between 1 and 3, not %d", additionalBits) - } - +func SplitInto(additionalBits uint, parent *net.IPNet) ([]*net.IPNet, error) { networkLength, _ := parent.Mask.Size() - networkLength += additionalBits + networkLength += int(additionalBits) var subnets []*net.IPNet for i := 0; i < 1< 0 { + cidrCount += 1 + } var bigCIDRs []*net.IPNet - if len(bigSubnets)+1 <= 2 { + if cidrCount <= 1 { + bigCIDRs, err = subnet.SplitInto1(cidr) + } else if cidrCount <= 2 { bigCIDRs, err = subnet.SplitInto2(cidr) - } else if len(bigSubnets)+1 <= 4 { + } else if cidrCount <= 4 { bigCIDRs, err = subnet.SplitInto4(cidr) } else { bigCIDRs, err = subnet.SplitInto8(cidr) @@ -164,16 +175,30 @@ func assignCIDRsToSubnets(c *kops.Cluster, cloud fi.Cloud) error { return fmt.Errorf("could not find any non-overlapping CIDRs in parent NetworkCIDR; cannot automatically assign CIDR to subnet") } - littleCIDRs, err := subnet.SplitInto8(bigCIDRs[0]) - if err != nil { - return err + // Assign CIDRs to little subnets + if len(littleSubnets) > 0 { + littleCIDRs, err := subnet.SplitInto8(bigCIDRs[0]) + if err != nil { + return err + } + bigCIDRs = bigCIDRs[1:] + + for _, subnet := range littleSubnets { + if subnet.CIDR != "" { + continue + } + + if len(littleCIDRs) == 0 { + return fmt.Errorf("insufficient (little) CIDRs remaining for automatic CIDR allocation to subnet %q", subnet.Name) + } + subnet.CIDR = littleCIDRs[0].String() + klog.Infof("Assigned CIDR %s to subnet %s", subnet.CIDR, subnet.Name) + + littleCIDRs = littleCIDRs[1:] + } } - bigCIDRs = bigCIDRs[1:] - - // Assign a consistent order - sort.Sort(ByZone(bigSubnets)) - sort.Sort(ByZone(littleSubnets)) + // Assign CIDRs to big subnets for _, subnet := range bigSubnets { if subnet.CIDR != "" { continue @@ -191,20 +216,6 @@ func assignCIDRsToSubnets(c *kops.Cluster, cloud fi.Cloud) error { bigCIDRs = bigCIDRs[1:] } - for _, subnet := range littleSubnets { - if subnet.CIDR != "" { - continue - } - - if len(littleCIDRs) == 0 { - return fmt.Errorf("insufficient (little) CIDRs remaining for automatic CIDR allocation to subnet %q", subnet.Name) - } - subnet.CIDR = littleCIDRs[0].String() - klog.Infof("Assigned CIDR %s to subnet %s", subnet.CIDR, subnet.Name) - - littleCIDRs = littleCIDRs[1:] - } - return nil } diff --git a/upup/pkg/fi/cloudup/subnets_test.go b/upup/pkg/fi/cloudup/subnets_test.go index eb375380d8..aa6698e4b8 100644 --- a/upup/pkg/fi/cloudup/subnets_test.go +++ b/upup/pkg/fi/cloudup/subnets_test.go @@ -39,35 +39,35 @@ func Test_AssignSubnets(t *testing.T) { subnets: []kops.ClusterSubnetSpec{ {Name: "a", Zone: "a", CIDR: "", Type: kops.SubnetTypePublic}, }, - expected: []string{"10.128.0.0/9"}, + expected: []string{"10.0.0.0/8"}, }, { subnets: []kops.ClusterSubnetSpec{ {Name: "a", Zone: "a", CIDR: "", Type: kops.SubnetTypePublic}, {Name: "b", Zone: "b", CIDR: "", Type: kops.SubnetTypePublic}, }, - expected: []string{"10.64.0.0/10", "10.128.0.0/10"}, + expected: []string{"10.0.0.0/9", "10.128.0.0/9"}, }, { subnets: []kops.ClusterSubnetSpec{ {Name: "a", Zone: "b", CIDR: "", Type: kops.SubnetTypePublic}, {Name: "b", Zone: "a", CIDR: "", Type: kops.SubnetTypePublic}, }, - expected: []string{"10.128.0.0/10", "10.64.0.0/10"}, + expected: []string{"10.128.0.0/9", "10.0.0.0/9"}, }, { subnets: []kops.ClusterSubnetSpec{ {Name: "a", Zone: "a", CIDR: "10.64.0.0/11", Type: kops.SubnetTypePublic}, {Name: "b", Zone: "b", CIDR: "", Type: kops.SubnetTypePublic}, }, - expected: []string{"10.64.0.0/11", "10.128.0.0/10"}, + expected: []string{"10.64.0.0/11", "10.128.0.0/9"}, }, { subnets: []kops.ClusterSubnetSpec{ {Name: "a", Zone: "a", CIDR: "10.0.0.0/9", Type: kops.SubnetTypePublic}, {Name: "b", Zone: "b", CIDR: "", Type: kops.SubnetTypePublic}, }, - expected: []string{"10.0.0.0/9", "10.192.0.0/10"}, + expected: []string{"10.0.0.0/9", "10.128.0.0/9"}, }, { @@ -94,7 +94,7 @@ func Test_AssignSubnets(t *testing.T) { subnets: []kops.ClusterSubnetSpec{ {Name: "a", Zone: "a", CIDR: "", Type: kops.SubnetTypePrivate}, }, - expected: []string{"10.128.0.0/9"}, + expected: []string{"10.0.0.0/8"}, }, { subnets: []kops.ClusterSubnetSpec{ @@ -106,7 +106,7 @@ func Test_AssignSubnets(t *testing.T) { subnets: []kops.ClusterSubnetSpec{ {Name: "a", Zone: "a", CIDR: "", IPv6CIDR: "/64#0", Type: kops.SubnetTypeDualStack}, }, - expected: []string{"10.128.0.0/9"}, + expected: []string{"10.0.0.0/8"}, }, { subnets: []kops.ClusterSubnetSpec{