mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
kubeadm: dual-stack validation allow single stack
It turns out that the dual-stack feature enabled doesn't mean that the cluster MUST be dual-stack, it only indicates that it MAY be dual-stack but CAN be single-stack. We should relax the validation to allow single-stack clusters with dual-stack enabled.
This commit is contained in:
parent
1735f7a2b6
commit
6dda7adaf5
@ -372,33 +372,32 @@ func ValidateHostPort(endpoint string, fldPath *field.Path) field.ErrorList {
|
||||
// ValidateIPNetFromString validates network portion of ip address
|
||||
func ValidateIPNetFromString(subnetStr string, minAddrs int64, isDualStack bool, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if isDualStack {
|
||||
subnets, err := utilnet.ParseCIDRs(strings.Split(subnetStr, ","))
|
||||
subnets, err := utilnet.ParseCIDRs(strings.Split(subnetStr, ","))
|
||||
if err != nil {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, subnetStr, "couldn't parse subnet"))
|
||||
return allErrs
|
||||
}
|
||||
switch {
|
||||
// if DualStack only 2 CIDRs allowed
|
||||
case isDualStack && len(subnets) > 2:
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, subnetStr, "expected one (IPv4 or IPv6) CIDR or two CIDRs from each family for dual-stack networking"))
|
||||
// if DualStack and there are 2 CIDRs validate if there is at least one of each IP family
|
||||
case isDualStack && len(subnets) == 2:
|
||||
areDualStackCIDRs, err := utilnet.IsDualStackCIDRs(subnets)
|
||||
if err != nil {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, subnetStr, err.Error()))
|
||||
} else {
|
||||
areDualStackCIDRs, err := utilnet.IsDualStackCIDRs(subnets)
|
||||
if err != nil {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, subnets, err.Error()))
|
||||
} else if !areDualStackCIDRs {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, subnetStr, "expected at least one IP from each family (v4 or v6) for dual-stack networking"))
|
||||
}
|
||||
for _, s := range subnets {
|
||||
numAddresses := utilnet.RangeSize(s)
|
||||
if numAddresses < minAddrs {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, s, "subnet is too small"))
|
||||
}
|
||||
}
|
||||
} else if !areDualStackCIDRs {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, subnetStr, "expected one (IPv4 or IPv6) CIDR or two CIDRs from each family for dual-stack networking"))
|
||||
}
|
||||
} else {
|
||||
_, svcSubnet, err := net.ParseCIDR(subnetStr)
|
||||
if err != nil {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, subnetStr, "couldn't parse subnet"))
|
||||
return allErrs
|
||||
}
|
||||
numAddresses := utilnet.RangeSize(svcSubnet)
|
||||
// if not DualStack only one CIDR allowed
|
||||
case !isDualStack && len(subnets) > 1:
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, subnetStr, "only one CIDR allowed for single-stack networking"))
|
||||
}
|
||||
// validate the subnet/s
|
||||
for _, s := range subnets {
|
||||
numAddresses := utilnet.RangeSize(s)
|
||||
if numAddresses < minAddrs {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, subnetStr, "subnet is too small"))
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, s, "subnet is too small"))
|
||||
}
|
||||
}
|
||||
return allErrs
|
||||
|
@ -197,18 +197,21 @@ func TestValidateIPNetFromString(t *testing.T) {
|
||||
expected bool
|
||||
}{
|
||||
{"invalid missing CIDR", "", 0, false, false},
|
||||
{"invalid CIDR", "a", 0, false, false},
|
||||
{"invalid CIDR missing decimal points in IPv4 address and / mask", "1234", 0, false, false},
|
||||
{"invalid CIDR use of letters instead of numbers and / mask", "abc", 0, false, false},
|
||||
{"invalid IPv4 address provided instead of CIDR representation", "1.2.3.4", 0, false, false},
|
||||
{"invalid IPv6 address provided instead of CIDR representation", "2001:db8::1", 0, false, false},
|
||||
{"invalid multiple CIDR provided in a single stack cluster", "2001:db8::1/64,1.2.3.4/24", 0, false, false},
|
||||
{"invalid multiple CIDR provided in a single stack cluster and one invalid subnet", "2001:db8::1/64,a", 0, false, false},
|
||||
{"valid, but IPv4 CIDR too small. At least 10 addresses needed", "10.0.0.16/29", 10, false, false},
|
||||
{"valid, but IPv6 CIDR too small. At least 10 addresses needed", "2001:db8::/125", 10, false, false},
|
||||
{"valid IPv4 CIDR", "10.0.0.16/12", 10, false, true},
|
||||
{"valid IPv6 CIDR", "2001:db8::/98", 10, false, true},
|
||||
// dual-stack:
|
||||
{"invalid missing CIDR", "", 0, true, false},
|
||||
{"invalid only an IPv4 CIDR specified", "10.0.0.16/12", 10, true, false},
|
||||
{"invalid only an IPv6 CIDR specified", "2001:db8::/98", 10, true, false},
|
||||
{"valid dual-stack enabled but only an IPv4 CIDR specified", "10.0.0.16/12", 10, true, true},
|
||||
{"valid dual-stack enabled but only an IPv6 CIDR specified", "2001:db8::/98", 10, true, true},
|
||||
{"invalid IPv4 address provided instead of CIDR representation", "1.2.3.4,2001:db8::/98", 0, true, false},
|
||||
{"invalid IPv6 address provided instead of CIDR representation", "2001:db8::1,10.0.0.16/12", 0, true, false},
|
||||
{"valid, but IPv4 CIDR too small. At least 10 addresses needed", "10.0.0.16/29,2001:db8::/98", 10, true, false},
|
||||
@ -217,6 +220,8 @@ func TestValidateIPNetFromString(t *testing.T) {
|
||||
{"valid, but only IPv6 family addresses specified. IPv4 CIDR is necessary.", "2001:db8::/98,2005:db8::/98", 10, true, false},
|
||||
{"valid IPv4 and IPv6 CIDR", "10.0.0.16/12,2001:db8::/98", 10, true, true},
|
||||
{"valid IPv6 and IPv4 CIDR", "10.0.0.16/12,2001:db8::/98", 10, true, true},
|
||||
{"invalid IPv6 and IPv4 CIDR with more than 2 subnets", "10.0.0.16/12,2001:db8::/98,192.168.0.0/16", 10, true, false},
|
||||
{"invalid IPv6 and IPv4 CIDR with more than 2 subnets", "10.0.0.16/12,2001:db8::/98,192.168.0.0/16,a.b.c.d/24", 10, true, false},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
actual := ValidateIPNetFromString(rt.subnet, rt.minaddrs, rt.checkDualStack, nil)
|
||||
|
Loading…
Reference in New Issue
Block a user