kube-proxy: internal config: refactor ClusterCIDR

Refactor ClusterCIDR for internal configuration of kube-proxy
adhering to the v1alpha2 version specifications as detailed in
https://kep.k8s.io/784.

Signed-off-by: Daman Arora <aroradaman@gmail.com>
This commit is contained in:
Daman Arora
2024-07-17 23:46:28 +05:30
parent 380adb93cc
commit c57e1156f5
12 changed files with 348 additions and 129 deletions

View File

@@ -80,25 +80,6 @@ func Validate(config *kubeproxyconfig.KubeProxyConfiguration) field.ErrorList {
}
allErrs = append(allErrs, validateHostPort(config.MetricsBindAddress, newPath.Child("MetricsBindAddress"))...)
if config.ClusterCIDR != "" {
cidrs := strings.Split(config.ClusterCIDR, ",")
switch {
case len(cidrs) > 2:
allErrs = append(allErrs, field.Invalid(newPath.Child("ClusterCIDR"), config.ClusterCIDR, "only one CIDR allowed or a valid DualStack CIDR (e.g. 10.100.0.0/16,fde4:8dba:82e1::/48)"))
// if DualStack and two cidrs validate if there is at least one of each IP family
case len(cidrs) == 2:
isDual, err := netutils.IsDualStackCIDRStrings(cidrs)
if err != nil || !isDual {
allErrs = append(allErrs, field.Invalid(newPath.Child("ClusterCIDR"), config.ClusterCIDR, "must be a valid DualStack CIDR (e.g. 10.100.0.0/16,fde4:8dba:82e1::/48)"))
}
// if we are here means that len(cidrs) == 1, we need to validate it
default:
if _, _, err := netutils.ParseCIDRSloppy(config.ClusterCIDR); err != nil {
allErrs = append(allErrs, field.Invalid(newPath.Child("ClusterCIDR"), config.ClusterCIDR, "must be a valid CIDR block (e.g. 10.100.0.0/16 or fde4:8dba:82e1::/48)"))
}
}
}
if _, err := utilnet.ParsePortRange(config.PortRange); err != nil {
allErrs = append(allErrs, field.Invalid(newPath.Child("PortRange"), config.PortRange, "must be a valid port range (e.g. 300-2000)"))
}
@@ -107,12 +88,7 @@ func Validate(config *kubeproxyconfig.KubeProxyConfiguration) field.ErrorList {
allErrs = append(allErrs, validateShowHiddenMetricsVersion(config.ShowHiddenMetricsForVersion, newPath.Child("ShowHiddenMetricsForVersion"))...)
allErrs = append(allErrs, validateDetectLocalMode(config.DetectLocalMode, newPath.Child("DetectLocalMode"))...)
if config.DetectLocalMode == kubeproxyconfig.LocalModeBridgeInterface {
allErrs = append(allErrs, validateInterface(config.DetectLocal.BridgeInterface, newPath.Child("InterfaceName"))...)
}
if config.DetectLocalMode == kubeproxyconfig.LocalModeInterfaceNamePrefix {
allErrs = append(allErrs, validateInterface(config.DetectLocal.InterfaceNamePrefix, newPath.Child("InterfacePrefix"))...)
}
allErrs = append(allErrs, validateDetectLocalConfiguration(config.DetectLocalMode, config.DetectLocal, newPath.Child("DetectLocalConfiguration"))...)
allErrs = append(allErrs, logsapi.Validate(&config.Logging, effectiveFeatures, newPath.Child("logging"))...)
return allErrs
@@ -338,3 +314,41 @@ func validateInterface(iface string, fldPath *field.Path) field.ErrorList {
}
return allErrs
}
func validateDualStackCIDRStrings(cidrStrings []string, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
switch {
case len(cidrStrings) == 0:
allErrs = append(allErrs, field.Invalid(fldPath, cidrStrings, "must contain at least one CIDR"))
case len(cidrStrings) > 2:
allErrs = append(allErrs, field.Invalid(fldPath, cidrStrings, "must be a either a single CIDR or dual-stack pair of CIDRs (e.g. [10.100.0.0/16, fde4:8dba:82e1::/48]"))
default:
for i, cidrString := range cidrStrings {
if _, _, err := netutils.ParseCIDRSloppy(cidrString); err != nil {
allErrs = append(allErrs, field.Invalid(fldPath.Index(i), cidrString, "must be a valid CIDR block (e.g. 10.100.0.0/16 or fde4:8dba:82e1::/48)"))
}
}
if len(cidrStrings) == 2 {
ifDualStack, err := netutils.IsDualStackCIDRStrings(cidrStrings)
if err == nil && !ifDualStack {
allErrs = append(allErrs, field.Invalid(fldPath, cidrStrings, "must be a either a single CIDR or dual-stack pair of CIDRs (e.g. [10.100.0.0/16, fde4:8dba:82e1::/48]"))
}
}
}
return allErrs
}
func validateDetectLocalConfiguration(mode kubeproxyconfig.LocalMode, config kubeproxyconfig.DetectLocalConfiguration, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
switch mode {
case kubeproxyconfig.LocalModeBridgeInterface:
allErrs = append(allErrs, validateInterface(config.BridgeInterface, fldPath.Child("InterfaceName"))...)
case kubeproxyconfig.LocalModeInterfaceNamePrefix:
allErrs = append(allErrs, validateInterface(config.InterfaceNamePrefix, fldPath.Child("InterfacePrefix"))...)
case kubeproxyconfig.LocalModeClusterCIDR:
if len(config.ClusterCIDRs) > 0 {
allErrs = append(allErrs, validateDualStackCIDRStrings(config.ClusterCIDRs, fldPath.Child("ClusterCIDRs"))...)
}
}
return allErrs
}