Merge pull request #126293 from aroradaman/kube-proxy-refactor-internal-config

Kube proxy refactor internal config
This commit is contained in:
Kubernetes Prow Robot 2024-07-23 11:02:46 -07:00 committed by GitHub
commit 6834a1ef3d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 563 additions and 430 deletions

View File

@ -21,6 +21,7 @@ import (
"fmt" "fmt"
"os" "os"
"strings" "strings"
"time"
"github.com/fsnotify/fsnotify" "github.com/fsnotify/fsnotify"
"github.com/spf13/pflag" "github.com/spf13/pflag"
@ -79,6 +80,14 @@ type Options struct {
hostnameOverride string hostnameOverride string
logger klog.Logger logger klog.Logger
// The fields below here are placeholders for flags that can't be directly mapped into
// config.KubeProxyConfiguration.
iptablesSyncPeriod time.Duration
iptablesMinSyncPeriod time.Duration
ipvsSyncPeriod time.Duration
ipvsMinSyncPeriod time.Duration
clusterCIDRs string
} }
// AddFlags adds flags to fs and binds them to options. // AddFlags adds flags to fs and binds them to options.
@ -120,11 +129,11 @@ func (o *Options) AddFlags(fs *pflag.FlagSet) {
fs.Int32Var(o.config.IPTables.MasqueradeBit, "iptables-masquerade-bit", ptr.Deref(o.config.IPTables.MasqueradeBit, 14), "If using the iptables or ipvs proxy mode, the bit of the fwmark space to mark packets requiring SNAT with. Must be within the range [0, 31].") fs.Int32Var(o.config.IPTables.MasqueradeBit, "iptables-masquerade-bit", ptr.Deref(o.config.IPTables.MasqueradeBit, 14), "If using the iptables or ipvs proxy mode, the bit of the fwmark space to mark packets requiring SNAT with. Must be within the range [0, 31].")
fs.BoolVar(&o.config.Linux.MasqueradeAll, "masquerade-all", o.config.Linux.MasqueradeAll, "SNAT all traffic sent via Service cluster IPs. This may be required with some CNI plugins. Only supported on Linux.") fs.BoolVar(&o.config.Linux.MasqueradeAll, "masquerade-all", o.config.Linux.MasqueradeAll, "SNAT all traffic sent via Service cluster IPs. This may be required with some CNI plugins. Only supported on Linux.")
fs.BoolVar(o.config.IPTables.LocalhostNodePorts, "iptables-localhost-nodeports", ptr.Deref(o.config.IPTables.LocalhostNodePorts, true), "If false, kube-proxy will disable the legacy behavior of allowing NodePort services to be accessed via localhost. (Applies only to iptables mode and IPv4; localhost NodePorts are never allowed with other proxy modes or with IPv6.)") fs.BoolVar(o.config.IPTables.LocalhostNodePorts, "iptables-localhost-nodeports", ptr.Deref(o.config.IPTables.LocalhostNodePorts, true), "If false, kube-proxy will disable the legacy behavior of allowing NodePort services to be accessed via localhost. (Applies only to iptables mode and IPv4; localhost NodePorts are never allowed with other proxy modes or with IPv6.)")
fs.DurationVar(&o.config.IPTables.SyncPeriod.Duration, "iptables-sync-period", o.config.IPTables.SyncPeriod.Duration, "An interval (e.g. '5s', '1m', '2h22m') indicating how frequently various re-synchronizing and cleanup operations are performed. Must be greater than 0.") fs.DurationVar(&o.iptablesSyncPeriod, "iptables-sync-period", o.config.SyncPeriod.Duration, "An interval (e.g. '5s', '1m', '2h22m') indicating how frequently various re-synchronizing and cleanup operations are performed. Must be greater than 0.")
fs.DurationVar(&o.config.IPTables.MinSyncPeriod.Duration, "iptables-min-sync-period", o.config.IPTables.MinSyncPeriod.Duration, "The minimum period between iptables rule resyncs (e.g. '5s', '1m', '2h22m'). A value of 0 means every Service or EndpointSlice change will result in an immediate iptables resync.") fs.DurationVar(&o.iptablesMinSyncPeriod, "iptables-min-sync-period", o.config.MinSyncPeriod.Duration, "The minimum period between iptables rule resyncs (e.g. '5s', '1m', '2h22m'). A value of 0 means every Service or EndpointSlice change will result in an immediate iptables resync.")
fs.DurationVar(&o.config.IPVS.SyncPeriod.Duration, "ipvs-sync-period", o.config.IPVS.SyncPeriod.Duration, "An interval (e.g. '5s', '1m', '2h22m') indicating how frequently various re-synchronizing and cleanup operations are performed. Must be greater than 0.") fs.DurationVar(&o.ipvsSyncPeriod, "ipvs-sync-period", o.config.SyncPeriod.Duration, "An interval (e.g. '5s', '1m', '2h22m') indicating how frequently various re-synchronizing and cleanup operations are performed. Must be greater than 0.")
fs.DurationVar(&o.config.IPVS.MinSyncPeriod.Duration, "ipvs-min-sync-period", o.config.IPVS.MinSyncPeriod.Duration, "The minimum period between IPVS rule resyncs (e.g. '5s', '1m', '2h22m'). A value of 0 means every Service or EndpointSlice change will result in an immediate IPVS resync.") fs.DurationVar(&o.ipvsMinSyncPeriod, "ipvs-min-sync-period", o.config.MinSyncPeriod.Duration, "The minimum period between IPVS rule resyncs (e.g. '5s', '1m', '2h22m'). A value of 0 means every Service or EndpointSlice change will result in an immediate IPVS resync.")
fs.StringVar(&o.config.IPVS.Scheduler, "ipvs-scheduler", o.config.IPVS.Scheduler, "The ipvs scheduler type when proxy mode is ipvs") fs.StringVar(&o.config.IPVS.Scheduler, "ipvs-scheduler", o.config.IPVS.Scheduler, "The ipvs scheduler type when proxy mode is ipvs")
fs.StringSliceVar(&o.config.IPVS.ExcludeCIDRs, "ipvs-exclude-cidrs", o.config.IPVS.ExcludeCIDRs, "A comma-separated list of CIDRs which the ipvs proxier should not touch when cleaning up IPVS rules.") fs.StringSliceVar(&o.config.IPVS.ExcludeCIDRs, "ipvs-exclude-cidrs", o.config.IPVS.ExcludeCIDRs, "A comma-separated list of CIDRs which the ipvs proxier should not touch when cleaning up IPVS rules.")
fs.BoolVar(&o.config.IPVS.StrictARP, "ipvs-strict-arp", o.config.IPVS.StrictARP, "Enable strict ARP by setting arp_ignore to 1 and arp_announce to 2") fs.BoolVar(&o.config.IPVS.StrictARP, "ipvs-strict-arp", o.config.IPVS.StrictARP, "Enable strict ARP by setting arp_ignore to 1 and arp_announce to 2")
@ -135,7 +144,7 @@ func (o *Options) AddFlags(fs *pflag.FlagSet) {
fs.Var(&o.config.DetectLocalMode, "detect-local-mode", "Mode to use to detect local traffic. This parameter is ignored if a config file is specified by --config.") fs.Var(&o.config.DetectLocalMode, "detect-local-mode", "Mode to use to detect local traffic. This parameter is ignored if a config file is specified by --config.")
fs.StringVar(&o.config.DetectLocal.BridgeInterface, "pod-bridge-interface", o.config.DetectLocal.BridgeInterface, "A bridge interface name. When --detect-local-mode is set to BridgeInterface, kube-proxy will consider traffic to be local if it originates from this bridge.") fs.StringVar(&o.config.DetectLocal.BridgeInterface, "pod-bridge-interface", o.config.DetectLocal.BridgeInterface, "A bridge interface name. When --detect-local-mode is set to BridgeInterface, kube-proxy will consider traffic to be local if it originates from this bridge.")
fs.StringVar(&o.config.DetectLocal.InterfaceNamePrefix, "pod-interface-name-prefix", o.config.DetectLocal.InterfaceNamePrefix, "An interface name prefix. When --detect-local-mode is set to InterfaceNamePrefix, kube-proxy will consider traffic to be local if it originates from any interface whose name begins with this prefix.") fs.StringVar(&o.config.DetectLocal.InterfaceNamePrefix, "pod-interface-name-prefix", o.config.DetectLocal.InterfaceNamePrefix, "An interface name prefix. When --detect-local-mode is set to InterfaceNamePrefix, kube-proxy will consider traffic to be local if it originates from any interface whose name begins with this prefix.")
fs.StringVar(&o.config.ClusterCIDR, "cluster-cidr", o.config.ClusterCIDR, "The CIDR range of the pods in the cluster. (For dual-stack clusters, this can be a comma-separated dual-stack pair of CIDR ranges.). When --detect-local-mode is set to ClusterCIDR, kube-proxy will consider traffic to be local if its source IP is in this range. (Otherwise it is not used.) "+ fs.StringVar(&o.clusterCIDRs, "cluster-cidr", strings.Join(o.config.DetectLocal.ClusterCIDRs, ","), "The CIDR range of the pods in the cluster. (For dual-stack clusters, this can be a comma-separated dual-stack pair of CIDR ranges.). When --detect-local-mode is set to ClusterCIDR, kube-proxy will consider traffic to be local if its source IP is in this range. (Otherwise it is not used.) "+
"This parameter is ignored if a config file is specified by --config.") "This parameter is ignored if a config file is specified by --config.")
fs.StringSliceVar(&o.config.NodePortAddresses, "nodeport-addresses", o.config.NodePortAddresses, fs.StringSliceVar(&o.config.NodePortAddresses, "nodeport-addresses", o.config.NodePortAddresses,
@ -161,8 +170,6 @@ func (o *Options) AddFlags(fs *pflag.FlagSet) {
_ = fs.MarkDeprecated("healthz-port", "This flag is deprecated and will be removed in a future release. Please use --healthz-bind-address instead.") _ = fs.MarkDeprecated("healthz-port", "This flag is deprecated and will be removed in a future release. Please use --healthz-bind-address instead.")
fs.Int32Var(&o.metricsPort, "metrics-port", o.metricsPort, "The port to bind the metrics server. Use 0 to disable.") fs.Int32Var(&o.metricsPort, "metrics-port", o.metricsPort, "The port to bind the metrics server. Use 0 to disable.")
_ = fs.MarkDeprecated("metrics-port", "This flag is deprecated and will be removed in a future release. Please use --metrics-bind-address instead.") _ = fs.MarkDeprecated("metrics-port", "This flag is deprecated and will be removed in a future release. Please use --metrics-bind-address instead.")
fs.Var(utilflag.PortRangeVar{Val: &o.config.PortRange}, "proxy-port-range", "This was previously used to configure the userspace proxy, but is now unused.")
_ = fs.MarkDeprecated("proxy-port-range", "This flag has no effect and will be removed in a future release.")
logsapi.AddFlags(&o.config.Logging, fs) logsapi.AddFlags(&o.config.Logging, fs)
} }
@ -216,6 +223,8 @@ func (o *Options) Complete(fs *pflag.FlagSet) error {
if err := o.initWatcher(); err != nil { if err := o.initWatcher(); err != nil {
return err return err
} }
} else {
o.processV1Alpha1Flags(fs)
} }
o.platformApplyDefaults(o.config) o.platformApplyDefaults(o.config)
@ -302,6 +311,25 @@ func (o *Options) processHostnameOverrideFlag() error {
return nil return nil
} }
// processV1Alpha1Flags processes v1alpha1 flags which can't be directly mapped to internal config.
func (o *Options) processV1Alpha1Flags(fs *pflag.FlagSet) {
if fs.Changed("iptables-sync-period") && o.config.Mode != kubeproxyconfig.ProxyModeIPVS {
o.config.SyncPeriod.Duration = o.iptablesSyncPeriod
}
if fs.Changed("iptables-min-sync-period") && o.config.Mode != kubeproxyconfig.ProxyModeIPVS {
o.config.MinSyncPeriod.Duration = o.iptablesMinSyncPeriod
}
if fs.Changed("ipvs-sync-period") && o.config.Mode == kubeproxyconfig.ProxyModeIPVS {
o.config.SyncPeriod.Duration = o.ipvsSyncPeriod
}
if fs.Changed("ipvs-min-sync-period") && o.config.Mode == kubeproxyconfig.ProxyModeIPVS {
o.config.MinSyncPeriod.Duration = o.ipvsMinSyncPeriod
}
if fs.Changed("cluster-cidr") {
o.config.DetectLocal.ClusterCIDRs = strings.Split(o.clusterCIDRs, ",")
}
}
// Validate validates all the required options. // Validate validates all the required options.
func (o *Options) Validate() error { func (o *Options) Validate() error {
if errs := validation.Validate(o.config); len(errs) != 0 { if errs := validation.Validate(o.config); len(errs) != 0 {

View File

@ -20,6 +20,8 @@ import (
"fmt" "fmt"
"os" "os"
"path" "path"
"reflect"
"strings"
"testing" "testing"
"time" "time"
@ -194,7 +196,8 @@ nodePortAddresses:
Kubeconfig: "/path/to/kubeconfig", Kubeconfig: "/path/to/kubeconfig",
QPS: 7, QPS: 7,
}, },
ClusterCIDR: tc.clusterCIDR, MinSyncPeriod: metav1.Duration{Duration: 10 * time.Second},
SyncPeriod: metav1.Duration{Duration: 60 * time.Second},
ConfigSyncPeriod: metav1.Duration{Duration: 15 * time.Second}, ConfigSyncPeriod: metav1.Duration{Duration: 15 * time.Second},
Linux: kubeproxyconfig.KubeProxyLinuxConfiguration{ Linux: kubeproxyconfig.KubeProxyLinuxConfiguration{
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{ Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
@ -212,26 +215,20 @@ nodePortAddresses:
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{ IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
MasqueradeBit: ptr.To[int32](17), MasqueradeBit: ptr.To[int32](17),
LocalhostNodePorts: ptr.To(true), LocalhostNodePorts: ptr.To(true),
MinSyncPeriod: metav1.Duration{Duration: 10 * time.Second},
SyncPeriod: metav1.Duration{Duration: 60 * time.Second},
}, },
IPVS: kubeproxyconfig.KubeProxyIPVSConfiguration{ IPVS: kubeproxyconfig.KubeProxyIPVSConfiguration{
MinSyncPeriod: metav1.Duration{Duration: 10 * time.Second}, ExcludeCIDRs: []string{"10.20.30.40/16", "fd00:1::0/64"},
SyncPeriod: metav1.Duration{Duration: 60 * time.Second},
ExcludeCIDRs: []string{"10.20.30.40/16", "fd00:1::0/64"},
}, },
NFTables: kubeproxyconfig.KubeProxyNFTablesConfiguration{ NFTables: kubeproxyconfig.KubeProxyNFTablesConfiguration{
MasqueradeBit: ptr.To[int32](18), MasqueradeBit: ptr.To[int32](18),
MinSyncPeriod: metav1.Duration{Duration: 10 * time.Second},
SyncPeriod: metav1.Duration{Duration: 60 * time.Second},
}, },
MetricsBindAddress: tc.metricsBindAddress, MetricsBindAddress: tc.metricsBindAddress,
Mode: kubeproxyconfig.ProxyMode(tc.mode), Mode: kubeproxyconfig.ProxyMode(tc.mode),
PortRange: "2-7",
NodePortAddresses: []string{"10.20.30.40/16", "fd00:1::0/64"}, NodePortAddresses: []string{"10.20.30.40/16", "fd00:1::0/64"},
DetectLocalMode: kubeproxyconfig.LocalModeClusterCIDR, DetectLocalMode: kubeproxyconfig.LocalModeClusterCIDR,
DetectLocal: kubeproxyconfig.DetectLocalConfiguration{ DetectLocal: kubeproxyconfig.DetectLocalConfiguration{
BridgeInterface: "cbr0", BridgeInterface: "cbr0",
ClusterCIDRs: strings.Split(tc.clusterCIDR, ","),
InterfaceNamePrefix: "veth", InterfaceNamePrefix: "veth",
}, },
Logging: logsapi.LoggingConfiguration{ Logging: logsapi.LoggingConfiguration{
@ -377,6 +374,99 @@ func TestProcessHostnameOverrideFlag(t *testing.T) {
} }
} }
// TestProcessV1Alpha1Flags tests processing v1alpha1 flags.
func TestProcessV1Alpha1Flags(t *testing.T) {
testCases := []struct {
name string
flags []string
validate func(*kubeproxyconfig.KubeProxyConfiguration) bool
}{
{
name: "iptables configuration",
flags: []string{
"--iptables-sync-period=36s",
"--iptables-min-sync-period=3s",
"--proxy-mode=iptables",
},
validate: func(config *kubeproxyconfig.KubeProxyConfiguration) bool {
return config.SyncPeriod == metav1.Duration{Duration: 36 * time.Second} &&
config.MinSyncPeriod == metav1.Duration{Duration: 3 * time.Second}
},
},
{
name: "iptables + ipvs configuration with iptables mode",
flags: []string{
"--iptables-sync-period=36s",
"--iptables-min-sync-period=3s",
"--ipvs-sync-period=16s",
"--ipvs-min-sync-period=7s",
"--proxy-mode=iptables",
},
validate: func(config *kubeproxyconfig.KubeProxyConfiguration) bool {
return config.SyncPeriod == metav1.Duration{Duration: 36 * time.Second} &&
config.MinSyncPeriod == metav1.Duration{Duration: 3 * time.Second}
},
},
{
name: "winkernel configuration",
flags: []string{
"--iptables-sync-period=36s",
"--iptables-min-sync-period=3s",
"--proxy-mode=kernelspace",
},
validate: func(config *kubeproxyconfig.KubeProxyConfiguration) bool {
return config.SyncPeriod == metav1.Duration{Duration: 36 * time.Second} &&
config.MinSyncPeriod == metav1.Duration{Duration: 3 * time.Second}
},
},
{
name: "ipvs + iptables configuration with ipvs mode",
flags: []string{
"--iptables-sync-period=36s",
"--iptables-min-sync-period=3s",
"--ipvs-sync-period=16s",
"--ipvs-min-sync-period=7s",
"--proxy-mode=ipvs",
},
validate: func(config *kubeproxyconfig.KubeProxyConfiguration) bool {
return config.SyncPeriod == metav1.Duration{Duration: 16 * time.Second} &&
config.MinSyncPeriod == metav1.Duration{Duration: 7 * time.Second}
},
},
{
name: "ipvs configuration",
flags: []string{
"--ipvs-sync-period=16s",
"--ipvs-min-sync-period=7s",
"--proxy-mode=ipvs",
},
validate: func(config *kubeproxyconfig.KubeProxyConfiguration) bool {
return config.SyncPeriod == metav1.Duration{Duration: 16 * time.Second} &&
config.MinSyncPeriod == metav1.Duration{Duration: 7 * time.Second}
},
},
{
name: "cluster cidr",
flags: []string{
"--cluster-cidr=2002:0:0:1234::/64,10.0.0.0/14",
},
validate: func(config *kubeproxyconfig.KubeProxyConfiguration) bool {
return reflect.DeepEqual(config.DetectLocal.ClusterCIDRs, []string{"2002:0:0:1234::/64", "10.0.0.0/14"})
},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
options := NewOptions()
fs := new(pflag.FlagSet)
options.AddFlags(fs)
require.NoError(t, fs.Parse(tc.flags))
options.processV1Alpha1Flags(fs)
require.True(t, tc.validate(options.config))
})
}
}
// TestOptionsComplete checks that command line flags are combined with a // TestOptionsComplete checks that command line flags are combined with a
// config properly. // config properly.
func TestOptionsComplete(t *testing.T) { func TestOptionsComplete(t *testing.T) {

View File

@ -25,7 +25,6 @@ import (
"net" "net"
"net/http" "net/http"
"os" "os"
"strings"
"time" "time"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -222,7 +221,7 @@ func newProxyServer(ctx context.Context, config *kubeproxyconfig.KubeProxyConfig
} }
if len(config.HealthzBindAddress) > 0 { if len(config.HealthzBindAddress) > 0 {
s.HealthzServer = healthcheck.NewProxierHealthServer(config.HealthzBindAddress, 2*config.IPTables.SyncPeriod.Duration) s.HealthzServer = healthcheck.NewProxierHealthServer(config.HealthzBindAddress, 2*config.SyncPeriod.Duration)
} }
err = s.platformSetup(ctx) err = s.platformSetup(ctx)
@ -271,8 +270,7 @@ func checkBadConfig(s *ProxyServer) error {
// we can at least take note of whether there is any explicitly-dual-stack // we can at least take note of whether there is any explicitly-dual-stack
// configuration. // configuration.
anyDualStackConfig := false anyDualStackConfig := false
clusterCIDRs := strings.Split(s.Config.ClusterCIDR, ",") for _, config := range [][]string{s.Config.DetectLocal.ClusterCIDRs, s.Config.NodePortAddresses, s.Config.IPVS.ExcludeCIDRs, s.podCIDRs} {
for _, config := range [][]string{clusterCIDRs, s.Config.NodePortAddresses, s.Config.IPVS.ExcludeCIDRs, s.podCIDRs} {
if dual, _ := netutils.IsDualStackCIDRStrings(config); dual { if dual, _ := netutils.IsDualStackCIDRStrings(config); dual {
anyDualStackConfig = true anyDualStackConfig = true
break break
@ -314,14 +312,11 @@ func checkBadIPConfig(s *ProxyServer, dualStackSupported bool) (err error, fatal
clusterType = fmt.Sprintf("%s-only", s.PrimaryIPFamily) clusterType = fmt.Sprintf("%s-only", s.PrimaryIPFamily)
} }
if s.Config.ClusterCIDR != "" { if badCIDRs(s.Config.DetectLocal.ClusterCIDRs, badFamily) {
clusterCIDRs := strings.Split(s.Config.ClusterCIDR, ",") errors = append(errors, fmt.Errorf("cluster is %s but clusterCIDRs contains only IPv%s addresses", clusterType, badFamily))
if badCIDRs(clusterCIDRs, badFamily) { if s.Config.DetectLocalMode == kubeproxyconfig.LocalModeClusterCIDR && !dualStackSupported {
errors = append(errors, fmt.Errorf("cluster is %s but clusterCIDRs contains only IPv%s addresses", clusterType, badFamily)) // This has always been a fatal error
if s.Config.DetectLocalMode == kubeproxyconfig.LocalModeClusterCIDR && !dualStackSupported { fatal = true
// This has always been a fatal error
fatal = true
}
} }
} }

View File

@ -26,7 +26,6 @@ import (
"errors" "errors"
"fmt" "fmt"
goruntime "runtime" goruntime "runtime"
"strings"
"time" "time"
"github.com/google/cadvisor/machine" "github.com/google/cadvisor/machine"
@ -178,8 +177,8 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
ipt, ipt,
utilsysctl.New(), utilsysctl.New(),
exec.New(), exec.New(),
config.IPTables.SyncPeriod.Duration, config.SyncPeriod.Duration,
config.IPTables.MinSyncPeriod.Duration, config.MinSyncPeriod.Duration,
config.Linux.MasqueradeAll, config.Linux.MasqueradeAll,
*config.IPTables.LocalhostNodePorts, *config.IPTables.LocalhostNodePorts,
int(*config.IPTables.MasqueradeBit), int(*config.IPTables.MasqueradeBit),
@ -202,8 +201,8 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
iptInterface, iptInterface,
utilsysctl.New(), utilsysctl.New(),
exec.New(), exec.New(),
config.IPTables.SyncPeriod.Duration, config.SyncPeriod.Duration,
config.IPTables.MinSyncPeriod.Duration, config.MinSyncPeriod.Duration,
config.Linux.MasqueradeAll, config.Linux.MasqueradeAll,
*config.IPTables.LocalhostNodePorts, *config.IPTables.LocalhostNodePorts,
int(*config.IPTables.MasqueradeBit), int(*config.IPTables.MasqueradeBit),
@ -238,8 +237,8 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
ipsetInterface, ipsetInterface,
utilsysctl.New(), utilsysctl.New(),
execer, execer,
config.IPVS.SyncPeriod.Duration, config.SyncPeriod.Duration,
config.IPVS.MinSyncPeriod.Duration, config.MinSyncPeriod.Duration,
config.IPVS.ExcludeCIDRs, config.IPVS.ExcludeCIDRs,
config.IPVS.StrictARP, config.IPVS.StrictARP,
config.IPVS.TCPTimeout.Duration, config.IPVS.TCPTimeout.Duration,
@ -266,8 +265,8 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
ipsetInterface, ipsetInterface,
utilsysctl.New(), utilsysctl.New(),
execer, execer,
config.IPVS.SyncPeriod.Duration, config.SyncPeriod.Duration,
config.IPVS.MinSyncPeriod.Duration, config.MinSyncPeriod.Duration,
config.IPVS.ExcludeCIDRs, config.IPVS.ExcludeCIDRs,
config.IPVS.StrictARP, config.IPVS.StrictARP,
config.IPVS.TCPTimeout.Duration, config.IPVS.TCPTimeout.Duration,
@ -295,8 +294,8 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
// TODO this has side effects that should only happen when Run() is invoked. // TODO this has side effects that should only happen when Run() is invoked.
proxier, err = nftables.NewDualStackProxier( proxier, err = nftables.NewDualStackProxier(
ctx, ctx,
config.NFTables.SyncPeriod.Duration, config.SyncPeriod.Duration,
config.NFTables.MinSyncPeriod.Duration, config.MinSyncPeriod.Duration,
config.Linux.MasqueradeAll, config.Linux.MasqueradeAll,
int(*config.NFTables.MasqueradeBit), int(*config.NFTables.MasqueradeBit),
localDetectors, localDetectors,
@ -313,8 +312,8 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
proxier, err = nftables.NewProxier( proxier, err = nftables.NewProxier(
ctx, ctx,
s.PrimaryIPFamily, s.PrimaryIPFamily,
config.NFTables.SyncPeriod.Duration, config.SyncPeriod.Duration,
config.NFTables.MinSyncPeriod.Duration, config.MinSyncPeriod.Duration,
config.Linux.MasqueradeAll, config.Linux.MasqueradeAll,
int(*config.NFTables.MasqueradeBit), int(*config.NFTables.MasqueradeBit),
localDetectors[s.PrimaryIPFamily], localDetectors[s.PrimaryIPFamily],
@ -477,12 +476,11 @@ func getLocalDetectors(logger klog.Logger, primaryIPFamily v1.IPFamily, config *
switch config.DetectLocalMode { switch config.DetectLocalMode {
case proxyconfigapi.LocalModeClusterCIDR: case proxyconfigapi.LocalModeClusterCIDR:
clusterCIDRs := strings.Split(strings.TrimSpace(config.ClusterCIDR), ",") for family, cidrs := range proxyutil.MapCIDRsByIPFamily(config.DetectLocal.ClusterCIDRs) {
for family, cidrs := range proxyutil.MapCIDRsByIPFamily(clusterCIDRs) {
localDetectors[family] = proxyutil.NewDetectLocalByCIDR(cidrs[0].String()) localDetectors[family] = proxyutil.NewDetectLocalByCIDR(cidrs[0].String())
} }
if !localDetectors[primaryIPFamily].IsImplemented() { if !localDetectors[primaryIPFamily].IsImplemented() {
logger.Info("Detect-local-mode set to ClusterCIDR, but no cluster CIDR specified for primary IP family", "ipFamily", primaryIPFamily, "clusterCIDR", config.ClusterCIDR) logger.Info("Detect-local-mode set to ClusterCIDR, but no cluster CIDR specified for primary IP family", "ipFamily", primaryIPFamily, "clusterCIDRs", config.DetectLocal.ClusterCIDRs)
} }
case proxyconfigapi.LocalModeNodeCIDR: case proxyconfigapi.LocalModeNodeCIDR:

View File

@ -121,7 +121,9 @@ func Test_getLocalDetectors(t *testing.T) {
name: "LocalModeClusterCIDR, single-stack IPv4 cluster", name: "LocalModeClusterCIDR, single-stack IPv4 cluster",
config: &proxyconfigapi.KubeProxyConfiguration{ config: &proxyconfigapi.KubeProxyConfiguration{
DetectLocalMode: proxyconfigapi.LocalModeClusterCIDR, DetectLocalMode: proxyconfigapi.LocalModeClusterCIDR,
ClusterCIDR: "10.0.0.0/14", DetectLocal: proxyconfigapi.DetectLocalConfiguration{
ClusterCIDRs: []string{"10.0.0.0/14"},
},
}, },
primaryIPFamily: v1.IPv4Protocol, primaryIPFamily: v1.IPv4Protocol,
expected: map[v1.IPFamily]proxyutil.LocalTrafficDetector{ expected: map[v1.IPFamily]proxyutil.LocalTrafficDetector{
@ -133,7 +135,9 @@ func Test_getLocalDetectors(t *testing.T) {
name: "LocalModeClusterCIDR, single-stack IPv6 cluster", name: "LocalModeClusterCIDR, single-stack IPv6 cluster",
config: &proxyconfigapi.KubeProxyConfiguration{ config: &proxyconfigapi.KubeProxyConfiguration{
DetectLocalMode: proxyconfigapi.LocalModeClusterCIDR, DetectLocalMode: proxyconfigapi.LocalModeClusterCIDR,
ClusterCIDR: "2002:0:0:1234::/64", DetectLocal: proxyconfigapi.DetectLocalConfiguration{
ClusterCIDRs: []string{"2002:0:0:1234::/64"},
},
}, },
primaryIPFamily: v1.IPv6Protocol, primaryIPFamily: v1.IPv6Protocol,
expected: map[v1.IPFamily]proxyutil.LocalTrafficDetector{ expected: map[v1.IPFamily]proxyutil.LocalTrafficDetector{
@ -145,7 +149,9 @@ func Test_getLocalDetectors(t *testing.T) {
name: "LocalModeClusterCIDR, single-stack IPv6 cluster with single-stack IPv4 config", name: "LocalModeClusterCIDR, single-stack IPv6 cluster with single-stack IPv4 config",
config: &proxyconfigapi.KubeProxyConfiguration{ config: &proxyconfigapi.KubeProxyConfiguration{
DetectLocalMode: proxyconfigapi.LocalModeClusterCIDR, DetectLocalMode: proxyconfigapi.LocalModeClusterCIDR,
ClusterCIDR: "10.0.0.0/14", DetectLocal: proxyconfigapi.DetectLocalConfiguration{
ClusterCIDRs: []string{"10.0.0.0/14"},
},
}, },
primaryIPFamily: v1.IPv6Protocol, primaryIPFamily: v1.IPv6Protocol,
// This will output a warning that there is no IPv6 CIDR but it // This will output a warning that there is no IPv6 CIDR but it
@ -159,7 +165,9 @@ func Test_getLocalDetectors(t *testing.T) {
name: "LocalModeClusterCIDR, single-stack IPv4 cluster with single-stack IPv6 config", name: "LocalModeClusterCIDR, single-stack IPv4 cluster with single-stack IPv6 config",
config: &proxyconfigapi.KubeProxyConfiguration{ config: &proxyconfigapi.KubeProxyConfiguration{
DetectLocalMode: proxyconfigapi.LocalModeClusterCIDR, DetectLocalMode: proxyconfigapi.LocalModeClusterCIDR,
ClusterCIDR: "2002:0:0:1234::/64", DetectLocal: proxyconfigapi.DetectLocalConfiguration{
ClusterCIDRs: []string{"2002:0:0:1234::/64"},
},
}, },
primaryIPFamily: v1.IPv4Protocol, primaryIPFamily: v1.IPv4Protocol,
// This will output a warning that there is no IPv4 CIDR but it // This will output a warning that there is no IPv4 CIDR but it
@ -173,7 +181,9 @@ func Test_getLocalDetectors(t *testing.T) {
name: "LocalModeClusterCIDR, dual-stack IPv4-primary cluster", name: "LocalModeClusterCIDR, dual-stack IPv4-primary cluster",
config: &proxyconfigapi.KubeProxyConfiguration{ config: &proxyconfigapi.KubeProxyConfiguration{
DetectLocalMode: proxyconfigapi.LocalModeClusterCIDR, DetectLocalMode: proxyconfigapi.LocalModeClusterCIDR,
ClusterCIDR: "10.0.0.0/14,2002:0:0:1234::/64", DetectLocal: proxyconfigapi.DetectLocalConfiguration{
ClusterCIDRs: []string{"10.0.0.0/14", "2002:0:0:1234::/64"},
},
}, },
primaryIPFamily: v1.IPv4Protocol, primaryIPFamily: v1.IPv4Protocol,
expected: map[v1.IPFamily]proxyutil.LocalTrafficDetector{ expected: map[v1.IPFamily]proxyutil.LocalTrafficDetector{
@ -185,7 +195,9 @@ func Test_getLocalDetectors(t *testing.T) {
name: "LocalModeClusterCIDR, dual-stack IPv6-primary cluster", name: "LocalModeClusterCIDR, dual-stack IPv6-primary cluster",
config: &proxyconfigapi.KubeProxyConfiguration{ config: &proxyconfigapi.KubeProxyConfiguration{
DetectLocalMode: proxyconfigapi.LocalModeClusterCIDR, DetectLocalMode: proxyconfigapi.LocalModeClusterCIDR,
ClusterCIDR: "2002:0:0:1234::/64,10.0.0.0/14", DetectLocal: proxyconfigapi.DetectLocalConfiguration{
ClusterCIDRs: []string{"2002:0:0:1234::/64", "10.0.0.0/14"},
},
}, },
primaryIPFamily: v1.IPv6Protocol, primaryIPFamily: v1.IPv6Protocol,
expected: map[v1.IPFamily]proxyutil.LocalTrafficDetector{ expected: map[v1.IPFamily]proxyutil.LocalTrafficDetector{
@ -197,7 +209,9 @@ func Test_getLocalDetectors(t *testing.T) {
name: "LocalModeClusterCIDR, IPv4-primary kube-proxy / IPv6-primary config", name: "LocalModeClusterCIDR, IPv4-primary kube-proxy / IPv6-primary config",
config: &proxyconfigapi.KubeProxyConfiguration{ config: &proxyconfigapi.KubeProxyConfiguration{
DetectLocalMode: proxyconfigapi.LocalModeClusterCIDR, DetectLocalMode: proxyconfigapi.LocalModeClusterCIDR,
ClusterCIDR: "2002:0:0:1234::/64,10.0.0.0/14", DetectLocal: proxyconfigapi.DetectLocalConfiguration{
ClusterCIDRs: []string{"2002:0:0:1234::/64", "10.0.0.0/14"},
},
}, },
primaryIPFamily: v1.IPv4Protocol, primaryIPFamily: v1.IPv4Protocol,
expected: map[v1.IPFamily]proxyutil.LocalTrafficDetector{ expected: map[v1.IPFamily]proxyutil.LocalTrafficDetector{
@ -209,7 +223,9 @@ func Test_getLocalDetectors(t *testing.T) {
name: "LocalModeClusterCIDR, no ClusterCIDR", name: "LocalModeClusterCIDR, no ClusterCIDR",
config: &proxyconfigapi.KubeProxyConfiguration{ config: &proxyconfigapi.KubeProxyConfiguration{
DetectLocalMode: proxyconfigapi.LocalModeClusterCIDR, DetectLocalMode: proxyconfigapi.LocalModeClusterCIDR,
ClusterCIDR: "", DetectLocal: proxyconfigapi.DetectLocalConfiguration{
ClusterCIDRs: []string{""},
},
}, },
primaryIPFamily: v1.IPv4Protocol, primaryIPFamily: v1.IPv4Protocol,
expected: map[v1.IPFamily]proxyutil.LocalTrafficDetector{ expected: map[v1.IPFamily]proxyutil.LocalTrafficDetector{
@ -222,7 +238,9 @@ func Test_getLocalDetectors(t *testing.T) {
name: "LocalModeNodeCIDR, single-stack IPv4 cluster", name: "LocalModeNodeCIDR, single-stack IPv4 cluster",
config: &proxyconfigapi.KubeProxyConfiguration{ config: &proxyconfigapi.KubeProxyConfiguration{
DetectLocalMode: proxyconfigapi.LocalModeNodeCIDR, DetectLocalMode: proxyconfigapi.LocalModeNodeCIDR,
ClusterCIDR: "10.0.0.0/14", DetectLocal: proxyconfigapi.DetectLocalConfiguration{
ClusterCIDRs: []string{"10.0.0.0/14"},
},
}, },
primaryIPFamily: v1.IPv4Protocol, primaryIPFamily: v1.IPv4Protocol,
nodePodCIDRs: []string{"10.0.0.0/24"}, nodePodCIDRs: []string{"10.0.0.0/24"},
@ -235,7 +253,9 @@ func Test_getLocalDetectors(t *testing.T) {
name: "LocalModeNodeCIDR, single-stack IPv6 cluster", name: "LocalModeNodeCIDR, single-stack IPv6 cluster",
config: &proxyconfigapi.KubeProxyConfiguration{ config: &proxyconfigapi.KubeProxyConfiguration{
DetectLocalMode: proxyconfigapi.LocalModeNodeCIDR, DetectLocalMode: proxyconfigapi.LocalModeNodeCIDR,
ClusterCIDR: "2002:0:0:1234::/64", DetectLocal: proxyconfigapi.DetectLocalConfiguration{
ClusterCIDRs: []string{"2002:0:0:1234::/64"},
},
}, },
primaryIPFamily: v1.IPv6Protocol, primaryIPFamily: v1.IPv6Protocol,
nodePodCIDRs: []string{"2002::1234:abcd:ffff:0:0/96"}, nodePodCIDRs: []string{"2002::1234:abcd:ffff:0:0/96"},
@ -248,7 +268,9 @@ func Test_getLocalDetectors(t *testing.T) {
name: "LocalModeNodeCIDR, single-stack IPv6 cluster with single-stack IPv4 config", name: "LocalModeNodeCIDR, single-stack IPv6 cluster with single-stack IPv4 config",
config: &proxyconfigapi.KubeProxyConfiguration{ config: &proxyconfigapi.KubeProxyConfiguration{
DetectLocalMode: proxyconfigapi.LocalModeNodeCIDR, DetectLocalMode: proxyconfigapi.LocalModeNodeCIDR,
ClusterCIDR: "10.0.0.0/14", DetectLocal: proxyconfigapi.DetectLocalConfiguration{
ClusterCIDRs: []string{"10.0.0.0/14"},
},
}, },
primaryIPFamily: v1.IPv6Protocol, primaryIPFamily: v1.IPv6Protocol,
nodePodCIDRs: []string{"10.0.0.0/24"}, nodePodCIDRs: []string{"10.0.0.0/24"},
@ -263,7 +285,9 @@ func Test_getLocalDetectors(t *testing.T) {
name: "LocalModeNodeCIDR, single-stack IPv4 cluster with single-stack IPv6 config", name: "LocalModeNodeCIDR, single-stack IPv4 cluster with single-stack IPv6 config",
config: &proxyconfigapi.KubeProxyConfiguration{ config: &proxyconfigapi.KubeProxyConfiguration{
DetectLocalMode: proxyconfigapi.LocalModeNodeCIDR, DetectLocalMode: proxyconfigapi.LocalModeNodeCIDR,
ClusterCIDR: "2002:0:0:1234::/64", DetectLocal: proxyconfigapi.DetectLocalConfiguration{
ClusterCIDRs: []string{"2002:0:0:1234::/64"},
},
}, },
primaryIPFamily: v1.IPv4Protocol, primaryIPFamily: v1.IPv4Protocol,
nodePodCIDRs: []string{"2002::1234:abcd:ffff:0:0/96"}, nodePodCIDRs: []string{"2002::1234:abcd:ffff:0:0/96"},
@ -278,7 +302,9 @@ func Test_getLocalDetectors(t *testing.T) {
name: "LocalModeNodeCIDR, dual-stack IPv4-primary cluster", name: "LocalModeNodeCIDR, dual-stack IPv4-primary cluster",
config: &proxyconfigapi.KubeProxyConfiguration{ config: &proxyconfigapi.KubeProxyConfiguration{
DetectLocalMode: proxyconfigapi.LocalModeNodeCIDR, DetectLocalMode: proxyconfigapi.LocalModeNodeCIDR,
ClusterCIDR: "10.0.0.0/14,2002:0:0:1234::/64", DetectLocal: proxyconfigapi.DetectLocalConfiguration{
ClusterCIDRs: []string{"10.0.0.0/14", "2002:0:0:1234::/64"},
},
}, },
primaryIPFamily: v1.IPv4Protocol, primaryIPFamily: v1.IPv4Protocol,
nodePodCIDRs: []string{"10.0.0.0/24", "2002::1234:abcd:ffff:0:0/96"}, nodePodCIDRs: []string{"10.0.0.0/24", "2002::1234:abcd:ffff:0:0/96"},
@ -291,7 +317,9 @@ func Test_getLocalDetectors(t *testing.T) {
name: "LocalModeNodeCIDR, dual-stack IPv6-primary cluster", name: "LocalModeNodeCIDR, dual-stack IPv6-primary cluster",
config: &proxyconfigapi.KubeProxyConfiguration{ config: &proxyconfigapi.KubeProxyConfiguration{
DetectLocalMode: proxyconfigapi.LocalModeNodeCIDR, DetectLocalMode: proxyconfigapi.LocalModeNodeCIDR,
ClusterCIDR: "2002:0:0:1234::/64,10.0.0.0/14", DetectLocal: proxyconfigapi.DetectLocalConfiguration{
ClusterCIDRs: []string{"2002:0:0:1234::/64", "10.0.0.0/14"},
},
}, },
primaryIPFamily: v1.IPv6Protocol, primaryIPFamily: v1.IPv6Protocol,
nodePodCIDRs: []string{"2002::1234:abcd:ffff:0:0/96", "10.0.0.0/24"}, nodePodCIDRs: []string{"2002::1234:abcd:ffff:0:0/96", "10.0.0.0/24"},
@ -304,7 +332,9 @@ func Test_getLocalDetectors(t *testing.T) {
name: "LocalModeNodeCIDR, IPv6-primary kube-proxy / IPv4-primary config", name: "LocalModeNodeCIDR, IPv6-primary kube-proxy / IPv4-primary config",
config: &proxyconfigapi.KubeProxyConfiguration{ config: &proxyconfigapi.KubeProxyConfiguration{
DetectLocalMode: proxyconfigapi.LocalModeNodeCIDR, DetectLocalMode: proxyconfigapi.LocalModeNodeCIDR,
ClusterCIDR: "10.0.0.0/14,2002:0:0:1234::/64", DetectLocal: proxyconfigapi.DetectLocalConfiguration{
ClusterCIDRs: []string{"10.0.0.0/14", "2002:0:0:1234::/64"},
},
}, },
primaryIPFamily: v1.IPv6Protocol, primaryIPFamily: v1.IPv6Protocol,
nodePodCIDRs: []string{"10.0.0.0/24", "2002::1234:abcd:ffff:0:0/96"}, nodePodCIDRs: []string{"10.0.0.0/24", "2002::1234:abcd:ffff:0:0/96"},
@ -317,7 +347,9 @@ func Test_getLocalDetectors(t *testing.T) {
name: "LocalModeNodeCIDR, no PodCIDRs", name: "LocalModeNodeCIDR, no PodCIDRs",
config: &proxyconfigapi.KubeProxyConfiguration{ config: &proxyconfigapi.KubeProxyConfiguration{
DetectLocalMode: proxyconfigapi.LocalModeNodeCIDR, DetectLocalMode: proxyconfigapi.LocalModeNodeCIDR,
ClusterCIDR: "", DetectLocal: proxyconfigapi.DetectLocalConfiguration{
ClusterCIDRs: []string{""},
},
}, },
primaryIPFamily: v1.IPv4Protocol, primaryIPFamily: v1.IPv4Protocol,
nodePodCIDRs: []string{}, nodePodCIDRs: []string{},
@ -331,7 +363,9 @@ func Test_getLocalDetectors(t *testing.T) {
name: "unknown LocalMode", name: "unknown LocalMode",
config: &proxyconfigapi.KubeProxyConfiguration{ config: &proxyconfigapi.KubeProxyConfiguration{
DetectLocalMode: proxyconfigapi.LocalMode("abcd"), DetectLocalMode: proxyconfigapi.LocalMode("abcd"),
ClusterCIDR: "10.0.0.0/14", DetectLocal: proxyconfigapi.DetectLocalConfiguration{
ClusterCIDRs: []string{"10.0.0.0/14"},
},
}, },
primaryIPFamily: v1.IPv4Protocol, primaryIPFamily: v1.IPv4Protocol,
expected: map[v1.IPFamily]proxyutil.LocalTrafficDetector{ expected: map[v1.IPFamily]proxyutil.LocalTrafficDetector{
@ -344,7 +378,9 @@ func Test_getLocalDetectors(t *testing.T) {
name: "LocalModeBridgeInterface", name: "LocalModeBridgeInterface",
config: &proxyconfigapi.KubeProxyConfiguration{ config: &proxyconfigapi.KubeProxyConfiguration{
DetectLocalMode: proxyconfigapi.LocalModeBridgeInterface, DetectLocalMode: proxyconfigapi.LocalModeBridgeInterface,
DetectLocal: proxyconfigapi.DetectLocalConfiguration{BridgeInterface: "eth"}, DetectLocal: proxyconfigapi.DetectLocalConfiguration{
BridgeInterface: "eth",
},
}, },
primaryIPFamily: v1.IPv4Protocol, primaryIPFamily: v1.IPv4Protocol,
expected: map[v1.IPFamily]proxyutil.LocalTrafficDetector{ expected: map[v1.IPFamily]proxyutil.LocalTrafficDetector{
@ -356,7 +392,9 @@ func Test_getLocalDetectors(t *testing.T) {
name: "LocalModeBridgeInterface, strange bridge name", name: "LocalModeBridgeInterface, strange bridge name",
config: &proxyconfigapi.KubeProxyConfiguration{ config: &proxyconfigapi.KubeProxyConfiguration{
DetectLocalMode: proxyconfigapi.LocalModeBridgeInterface, DetectLocalMode: proxyconfigapi.LocalModeBridgeInterface,
DetectLocal: proxyconfigapi.DetectLocalConfiguration{BridgeInterface: "1234567890123456789"}, DetectLocal: proxyconfigapi.DetectLocalConfiguration{
BridgeInterface: "1234567890123456789",
},
}, },
primaryIPFamily: v1.IPv4Protocol, primaryIPFamily: v1.IPv4Protocol,
expected: map[v1.IPFamily]proxyutil.LocalTrafficDetector{ expected: map[v1.IPFamily]proxyutil.LocalTrafficDetector{
@ -369,7 +407,9 @@ func Test_getLocalDetectors(t *testing.T) {
name: "LocalModeInterfaceNamePrefix", name: "LocalModeInterfaceNamePrefix",
config: &proxyconfigapi.KubeProxyConfiguration{ config: &proxyconfigapi.KubeProxyConfiguration{
DetectLocalMode: proxyconfigapi.LocalModeInterfaceNamePrefix, DetectLocalMode: proxyconfigapi.LocalModeInterfaceNamePrefix,
DetectLocal: proxyconfigapi.DetectLocalConfiguration{InterfaceNamePrefix: "eth"}, DetectLocal: proxyconfigapi.DetectLocalConfiguration{
InterfaceNamePrefix: "eth",
},
}, },
primaryIPFamily: v1.IPv4Protocol, primaryIPFamily: v1.IPv4Protocol,
expected: map[v1.IPFamily]proxyutil.LocalTrafficDetector{ expected: map[v1.IPFamily]proxyutil.LocalTrafficDetector{
@ -381,7 +421,9 @@ func Test_getLocalDetectors(t *testing.T) {
name: "LocalModeInterfaceNamePrefix, strange interface name", name: "LocalModeInterfaceNamePrefix, strange interface name",
config: &proxyconfigapi.KubeProxyConfiguration{ config: &proxyconfigapi.KubeProxyConfiguration{
DetectLocalMode: proxyconfigapi.LocalModeInterfaceNamePrefix, DetectLocalMode: proxyconfigapi.LocalModeInterfaceNamePrefix,
DetectLocal: proxyconfigapi.DetectLocalConfiguration{InterfaceNamePrefix: "1234567890123456789"}, DetectLocal: proxyconfigapi.DetectLocalConfiguration{
InterfaceNamePrefix: "1234567890123456789",
},
}, },
primaryIPFamily: v1.IPv4Protocol, primaryIPFamily: v1.IPv4Protocol,
expected: map[v1.IPFamily]proxyutil.LocalTrafficDetector{ expected: map[v1.IPFamily]proxyutil.LocalTrafficDetector{

View File

@ -305,7 +305,9 @@ func Test_checkBadConfig(t *testing.T) {
name: "single-stack NodePortAddresses with single-stack config", name: "single-stack NodePortAddresses with single-stack config",
proxy: &ProxyServer{ proxy: &ProxyServer{
Config: &kubeproxyconfig.KubeProxyConfiguration{ Config: &kubeproxyconfig.KubeProxyConfiguration{
ClusterCIDR: "10.0.0.0/8", DetectLocal: kubeproxyconfig.DetectLocalConfiguration{
ClusterCIDRs: []string{"10.0.0.0/8"},
},
NodePortAddresses: []string{"192.168.0.0/24"}, NodePortAddresses: []string{"192.168.0.0/24"},
}, },
PrimaryIPFamily: v1.IPv4Protocol, PrimaryIPFamily: v1.IPv4Protocol,
@ -316,7 +318,9 @@ func Test_checkBadConfig(t *testing.T) {
name: "dual-stack NodePortAddresses with dual-stack config", name: "dual-stack NodePortAddresses with dual-stack config",
proxy: &ProxyServer{ proxy: &ProxyServer{
Config: &kubeproxyconfig.KubeProxyConfiguration{ Config: &kubeproxyconfig.KubeProxyConfiguration{
ClusterCIDR: "10.0.0.0/8,fd09::/64", DetectLocal: kubeproxyconfig.DetectLocalConfiguration{
ClusterCIDRs: []string{"10.0.0.0/8", "fd09::/64"},
},
NodePortAddresses: []string{"192.168.0.0/24", "fd03::/64"}, NodePortAddresses: []string{"192.168.0.0/24", "fd03::/64"},
}, },
PrimaryIPFamily: v1.IPv4Protocol, PrimaryIPFamily: v1.IPv4Protocol,
@ -337,7 +341,9 @@ func Test_checkBadConfig(t *testing.T) {
name: "single-stack NodePortAddresses with dual-stack config", name: "single-stack NodePortAddresses with dual-stack config",
proxy: &ProxyServer{ proxy: &ProxyServer{
Config: &kubeproxyconfig.KubeProxyConfiguration{ Config: &kubeproxyconfig.KubeProxyConfiguration{
ClusterCIDR: "10.0.0.0/8,fd09::/64", DetectLocal: kubeproxyconfig.DetectLocalConfiguration{
ClusterCIDRs: []string{"10.0.0.0/8", "fd09::/64"},
},
NodePortAddresses: []string{"192.168.0.0/24"}, NodePortAddresses: []string{"192.168.0.0/24"},
}, },
PrimaryIPFamily: v1.IPv4Protocol, PrimaryIPFamily: v1.IPv4Protocol,
@ -348,7 +354,9 @@ func Test_checkBadConfig(t *testing.T) {
name: "wrong-single-stack NodePortAddresses", name: "wrong-single-stack NodePortAddresses",
proxy: &ProxyServer{ proxy: &ProxyServer{
Config: &kubeproxyconfig.KubeProxyConfiguration{ Config: &kubeproxyconfig.KubeProxyConfiguration{
ClusterCIDR: "fd09::/64", DetectLocal: kubeproxyconfig.DetectLocalConfiguration{
ClusterCIDRs: []string{"fd09::/64"},
},
NodePortAddresses: []string{"192.168.0.0/24"}, NodePortAddresses: []string{"192.168.0.0/24"},
}, },
PrimaryIPFamily: v1.IPv6Protocol, PrimaryIPFamily: v1.IPv6Protocol,
@ -392,7 +400,9 @@ func Test_checkBadIPConfig(t *testing.T) {
name: "ok single-stack clusterCIDR", name: "ok single-stack clusterCIDR",
proxy: &ProxyServer{ proxy: &ProxyServer{
Config: &kubeproxyconfig.KubeProxyConfiguration{ Config: &kubeproxyconfig.KubeProxyConfiguration{
ClusterCIDR: "10.0.0.0/8", DetectLocal: kubeproxyconfig.DetectLocalConfiguration{
ClusterCIDRs: []string{"10.0.0.0/8"},
},
}, },
PrimaryIPFamily: v1.IPv4Protocol, PrimaryIPFamily: v1.IPv4Protocol,
}, },
@ -403,7 +413,9 @@ func Test_checkBadIPConfig(t *testing.T) {
name: "ok dual-stack clusterCIDR", name: "ok dual-stack clusterCIDR",
proxy: &ProxyServer{ proxy: &ProxyServer{
Config: &kubeproxyconfig.KubeProxyConfiguration{ Config: &kubeproxyconfig.KubeProxyConfiguration{
ClusterCIDR: "10.0.0.0/8,fd01:2345::/64", DetectLocal: kubeproxyconfig.DetectLocalConfiguration{
ClusterCIDRs: []string{"10.0.0.0/8", "fd01:2345::/64"},
},
}, },
PrimaryIPFamily: v1.IPv4Protocol, PrimaryIPFamily: v1.IPv4Protocol,
}, },
@ -414,7 +426,9 @@ func Test_checkBadIPConfig(t *testing.T) {
name: "ok reversed dual-stack clusterCIDR", name: "ok reversed dual-stack clusterCIDR",
proxy: &ProxyServer{ proxy: &ProxyServer{
Config: &kubeproxyconfig.KubeProxyConfiguration{ Config: &kubeproxyconfig.KubeProxyConfiguration{
ClusterCIDR: "fd01:2345::/64,10.0.0.0/8", DetectLocal: kubeproxyconfig.DetectLocalConfiguration{
ClusterCIDRs: []string{"fd01:2345::/64", "10.0.0.0/8"},
},
}, },
PrimaryIPFamily: v1.IPv4Protocol, PrimaryIPFamily: v1.IPv4Protocol,
}, },
@ -425,7 +439,9 @@ func Test_checkBadIPConfig(t *testing.T) {
name: "wrong-family clusterCIDR", name: "wrong-family clusterCIDR",
proxy: &ProxyServer{ proxy: &ProxyServer{
Config: &kubeproxyconfig.KubeProxyConfiguration{ Config: &kubeproxyconfig.KubeProxyConfiguration{
ClusterCIDR: "fd01:2345::/64", DetectLocal: kubeproxyconfig.DetectLocalConfiguration{
ClusterCIDRs: []string{"fd01:2345::/64"},
},
}, },
PrimaryIPFamily: v1.IPv4Protocol, PrimaryIPFamily: v1.IPv4Protocol,
}, },
@ -438,7 +454,9 @@ func Test_checkBadIPConfig(t *testing.T) {
name: "wrong-family clusterCIDR when using ClusterCIDR LocalDetector", name: "wrong-family clusterCIDR when using ClusterCIDR LocalDetector",
proxy: &ProxyServer{ proxy: &ProxyServer{
Config: &kubeproxyconfig.KubeProxyConfiguration{ Config: &kubeproxyconfig.KubeProxyConfiguration{
ClusterCIDR: "fd01:2345::/64", DetectLocal: kubeproxyconfig.DetectLocalConfiguration{
ClusterCIDRs: []string{"fd01:2345::/64"},
},
DetectLocalMode: kubeproxyconfig.LocalModeClusterCIDR, DetectLocalMode: kubeproxyconfig.LocalModeClusterCIDR,
}, },
PrimaryIPFamily: v1.IPv4Protocol, PrimaryIPFamily: v1.IPv4Protocol,

View File

@ -91,8 +91,8 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
if dualStackMode { if dualStackMode {
proxier, err = winkernel.NewDualStackProxier( proxier, err = winkernel.NewDualStackProxier(
config.IPTables.SyncPeriod.Duration, config.SyncPeriod.Duration,
config.IPTables.MinSyncPeriod.Duration, config.MinSyncPeriod.Duration,
s.Hostname, s.Hostname,
s.NodeIPs, s.NodeIPs,
s.Recorder, s.Recorder,
@ -103,8 +103,8 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
} else { } else {
proxier, err = winkernel.NewProxier( proxier, err = winkernel.NewProxier(
s.PrimaryIPFamily, s.PrimaryIPFamily,
config.IPTables.SyncPeriod.Duration, config.SyncPeriod.Duration,
config.IPTables.MinSyncPeriod.Duration, config.MinSyncPeriod.Duration,
s.Hostname, s.Hostname,
s.NodeIPs[s.PrimaryIPFamily], s.NodeIPs[s.PrimaryIPFamily],
s.Recorder, s.Recorder,

View File

@ -35,7 +35,7 @@ ipvs:
minSyncPeriod: 0s minSyncPeriod: 0s
scheduler: "" scheduler: ""
strictARP: false strictARP: false
syncPeriod: 30s syncPeriod: 0s
tcpFinTimeout: 0s tcpFinTimeout: 0s
tcpTimeout: 0s tcpTimeout: 0s
udpTimeout: 0s udpTimeout: 0s
@ -54,8 +54,8 @@ mode: ""
nftables: nftables:
masqueradeAll: false masqueradeAll: false
masqueradeBit: 14 masqueradeBit: 14
minSyncPeriod: 1s minSyncPeriod: 0s
syncPeriod: 30s syncPeriod: 0s
nodePortAddresses: null nodePortAddresses: null
oomScoreAdj: -999 oomScoreAdj: -999
portRange: "" portRange: ""

View File

@ -35,7 +35,7 @@ ipvs:
minSyncPeriod: 0s minSyncPeriod: 0s
scheduler: "" scheduler: ""
strictARP: false strictARP: false
syncPeriod: 30s syncPeriod: 0s
tcpFinTimeout: 0s tcpFinTimeout: 0s
tcpTimeout: 0s tcpTimeout: 0s
udpTimeout: 0s udpTimeout: 0s
@ -54,8 +54,8 @@ mode: ""
nftables: nftables:
masqueradeAll: false masqueradeAll: false
masqueradeBit: 14 masqueradeBit: 14
minSyncPeriod: 1s minSyncPeriod: 0s
syncPeriod: 30s syncPeriod: 0s
nodePortAddresses: null nodePortAddresses: null
oomScoreAdj: -999 oomScoreAdj: -999
portRange: "" portRange: ""

View File

@ -53,27 +53,11 @@ type KubeProxyIPTablesConfiguration struct {
// iptables mode and IPv4; localhost NodePorts are never allowed with other proxy // iptables mode and IPv4; localhost NodePorts are never allowed with other proxy
// modes or with IPv6.) // modes or with IPv6.)
LocalhostNodePorts *bool LocalhostNodePorts *bool
// syncPeriod is an interval (e.g. '5s', '1m', '2h22m') indicating how frequently
// various re-synchronizing and cleanup operations are performed. Must be greater
// than 0.
SyncPeriod metav1.Duration
// minSyncPeriod is the minimum period between iptables rule resyncs (e.g. '5s',
// '1m', '2h22m'). A value of 0 means every Service or EndpointSlice change will
// result in an immediate iptables resync.
MinSyncPeriod metav1.Duration
} }
// KubeProxyIPVSConfiguration contains ipvs-related configuration // KubeProxyIPVSConfiguration contains ipvs-related configuration
// details for the Kubernetes proxy server. // details for the Kubernetes proxy server.
type KubeProxyIPVSConfiguration struct { type KubeProxyIPVSConfiguration struct {
// syncPeriod is an interval (e.g. '5s', '1m', '2h22m') indicating how frequently
// various re-synchronizing and cleanup operations are performed. Must be greater
// than 0.
SyncPeriod metav1.Duration
// minSyncPeriod is the minimum period between IPVS rule resyncs (e.g. '5s', '1m',
// '2h22m'). A value of 0 means every Service or EndpointSlice change will result
// in an immediate IPVS resync.
MinSyncPeriod metav1.Duration
// scheduler is the IPVS scheduler to use // scheduler is the IPVS scheduler to use
Scheduler string Scheduler string
// excludeCIDRs is a list of CIDRs which the ipvs proxier should not touch // excludeCIDRs is a list of CIDRs which the ipvs proxier should not touch
@ -99,14 +83,6 @@ type KubeProxyNFTablesConfiguration struct {
// masqueradeBit is the bit of the iptables fwmark space to use for SNAT if using // masqueradeBit is the bit of the iptables fwmark space to use for SNAT if using
// the nftables proxy mode. Values must be within the range [0, 31]. // the nftables proxy mode. Values must be within the range [0, 31].
MasqueradeBit *int32 MasqueradeBit *int32
// syncPeriod is an interval (e.g. '5s', '1m', '2h22m') indicating how frequently
// various re-synchronizing and cleanup operations are performed. Must be greater
// than 0.
SyncPeriod metav1.Duration
// minSyncPeriod is the minimum period between iptables rule resyncs (e.g. '5s',
// '1m', '2h22m'). A value of 0 means every Service or EndpointSlice change will
// result in an immediate iptables resync.
MinSyncPeriod metav1.Duration
} }
// KubeProxyConntrackConfiguration contains conntrack settings for // KubeProxyConntrackConfiguration contains conntrack settings for
@ -165,6 +141,10 @@ type DetectLocalConfiguration struct {
// LocalModeBridgeInterface, kube-proxy will consider traffic to be local if // LocalModeBridgeInterface, kube-proxy will consider traffic to be local if
// it originates from this bridge. // it originates from this bridge.
BridgeInterface string BridgeInterface string
// clusterCIDRs is the dual-stack list of CIDR ranges of the pods in the cluster. When
// DetectLocalMode is set to LocalModeClusterCIDR, kube-proxy will consider
// traffic to be local if its source IP is in the range of any given CIDR.
ClusterCIDRs []string
// interfaceNamePrefix is an interface name prefix. When DetectLocalMode is set to // interfaceNamePrefix is an interface name prefix. When DetectLocalMode is set to
// LocalModeInterfaceNamePrefix, kube-proxy will consider traffic to be local if // LocalModeInterfaceNamePrefix, kube-proxy will consider traffic to be local if
// it originates from any interface whose name begins with this prefix. // it originates from any interface whose name begins with this prefix.
@ -236,12 +216,6 @@ type KubeProxyConfiguration struct {
DetectLocalMode LocalMode DetectLocalMode LocalMode
// detectLocal contains optional configuration settings related to DetectLocalMode. // detectLocal contains optional configuration settings related to DetectLocalMode.
DetectLocal DetectLocalConfiguration DetectLocal DetectLocalConfiguration
// clusterCIDR is the CIDR range of the pods in the cluster. (For dual-stack
// clusters, this can be a comma-separated dual-stack pair of CIDR ranges.). When
// DetectLocalMode is set to LocalModeClusterCIDR, kube-proxy will consider
// traffic to be local if its source IP is in this range. (Otherwise it is not
// used.)
ClusterCIDR string
// nodePortAddresses is a list of CIDR ranges that contain valid node IPs, or // nodePortAddresses is a list of CIDR ranges that contain valid node IPs, or
// alternatively, the single string 'primary'. If set to a list of CIDRs, // alternatively, the single string 'primary'. If set to a list of CIDRs,
@ -251,12 +225,17 @@ type KubeProxyConfiguration struct {
// object. If unset, NodePort connections will be accepted on all local IPs. // object. If unset, NodePort connections will be accepted on all local IPs.
NodePortAddresses []string NodePortAddresses []string
// syncPeriod is an interval (e.g. '5s', '1m', '2h22m') indicating how frequently
// various re-synchronizing and cleanup operations are performed. Must be greater
// than 0.
SyncPeriod metav1.Duration
// minSyncPeriod is the minimum period between proxier rule resyncs (e.g. '5s',
// '1m', '2h22m'). A value of 0 means every Service or EndpointSlice change will
// result in an immediate proxier resync.
MinSyncPeriod metav1.Duration
// configSyncPeriod is how often configuration from the apiserver is refreshed. Must be greater // configSyncPeriod is how often configuration from the apiserver is refreshed. Must be greater
// than 0. // than 0.
ConfigSyncPeriod metav1.Duration ConfigSyncPeriod metav1.Duration
// portRange was previously used to configure the userspace proxy, but is now unused.
PortRange string
} }
// ProxyMode represents modes used by the Kubernetes proxy server. // ProxyMode represents modes used by the Kubernetes proxy server.

View File

@ -17,6 +17,8 @@ limitations under the License.
package v1alpha1 package v1alpha1
import ( import (
"strings"
"k8s.io/apimachinery/pkg/conversion" "k8s.io/apimachinery/pkg/conversion"
"k8s.io/kube-proxy/config/v1alpha1" "k8s.io/kube-proxy/config/v1alpha1"
"k8s.io/kubernetes/pkg/proxy/apis/config" "k8s.io/kubernetes/pkg/proxy/apis/config"
@ -36,6 +38,22 @@ func Convert_config_KubeProxyConfiguration_To_v1alpha1_KubeProxyConfiguration(in
default: default:
out.IPTables.MasqueradeAll = in.Linux.MasqueradeAll out.IPTables.MasqueradeAll = in.Linux.MasqueradeAll
} }
switch in.Mode {
case config.ProxyModeIPVS:
out.IPVS.SyncPeriod = in.SyncPeriod
out.IPVS.MinSyncPeriod = in.MinSyncPeriod
case config.ProxyModeNFTables:
out.NFTables.SyncPeriod = in.SyncPeriod
out.NFTables.MinSyncPeriod = in.MinSyncPeriod
default:
out.IPTables.SyncPeriod = in.SyncPeriod
out.IPTables.MinSyncPeriod = in.MinSyncPeriod
}
if len(in.DetectLocal.ClusterCIDRs) > 0 {
out.ClusterCIDR = strings.Join(in.DetectLocal.ClusterCIDRs, ",")
}
return nil return nil
} }
@ -53,6 +71,22 @@ func Convert_v1alpha1_KubeProxyConfiguration_To_config_KubeProxyConfiguration(in
default: default:
out.Linux.MasqueradeAll = in.IPTables.MasqueradeAll out.Linux.MasqueradeAll = in.IPTables.MasqueradeAll
} }
switch config.ProxyMode(in.Mode) {
case config.ProxyModeIPVS:
out.SyncPeriod = in.IPVS.SyncPeriod
out.MinSyncPeriod = in.IPVS.MinSyncPeriod
case config.ProxyModeNFTables:
out.SyncPeriod = in.NFTables.SyncPeriod
out.MinSyncPeriod = in.NFTables.MinSyncPeriod
default:
out.SyncPeriod = in.IPTables.SyncPeriod
out.MinSyncPeriod = in.IPTables.MinSyncPeriod
}
if len(in.ClusterCIDR) > 0 {
out.DetectLocal.ClusterCIDRs = strings.Split(in.ClusterCIDR, ",")
}
return nil return nil
} }
@ -61,7 +95,17 @@ func Convert_v1alpha1_KubeProxyIPTablesConfiguration_To_config_KubeProxyIPTables
return autoConvert_v1alpha1_KubeProxyIPTablesConfiguration_To_config_KubeProxyIPTablesConfiguration(in, out, scope) return autoConvert_v1alpha1_KubeProxyIPTablesConfiguration_To_config_KubeProxyIPTablesConfiguration(in, out, scope)
} }
// Convert_v1alpha1_KubeProxyIPVSConfiguration_To_config_KubeProxyIPVSConfiguration is defined here, because public conversion is not auto-generated due to existing warnings.
func Convert_v1alpha1_KubeProxyIPVSConfiguration_To_config_KubeProxyIPVSConfiguration(in *v1alpha1.KubeProxyIPVSConfiguration, out *config.KubeProxyIPVSConfiguration, scope conversion.Scope) error {
return autoConvert_v1alpha1_KubeProxyIPVSConfiguration_To_config_KubeProxyIPVSConfiguration(in, out, scope)
}
// Convert_v1alpha1_KubeProxyNFTablesConfiguration_To_config_KubeProxyNFTablesConfiguration is defined here, because public conversion is not auto-generated due to existing warnings. // Convert_v1alpha1_KubeProxyNFTablesConfiguration_To_config_KubeProxyNFTablesConfiguration is defined here, because public conversion is not auto-generated due to existing warnings.
func Convert_v1alpha1_KubeProxyNFTablesConfiguration_To_config_KubeProxyNFTablesConfiguration(in *v1alpha1.KubeProxyNFTablesConfiguration, out *config.KubeProxyNFTablesConfiguration, scope conversion.Scope) error { func Convert_v1alpha1_KubeProxyNFTablesConfiguration_To_config_KubeProxyNFTablesConfiguration(in *v1alpha1.KubeProxyNFTablesConfiguration, out *config.KubeProxyNFTablesConfiguration, scope conversion.Scope) error {
return autoConvert_v1alpha1_KubeProxyNFTablesConfiguration_To_config_KubeProxyNFTablesConfiguration(in, out, scope) return autoConvert_v1alpha1_KubeProxyNFTablesConfiguration_To_config_KubeProxyNFTablesConfiguration(in, out, scope)
} }
// Convert_config_DetectLocalConfiguration_To_v1alpha1_DetectLocalConfiguration is defined here, because public conversion is not auto-generated due to existing warnings.
func Convert_config_DetectLocalConfiguration_To_v1alpha1_DetectLocalConfiguration(in *config.DetectLocalConfiguration, out *v1alpha1.DetectLocalConfiguration, s conversion.Scope) error {
return autoConvert_config_DetectLocalConfiguration_To_v1alpha1_DetectLocalConfiguration(in, out, s)
}

View File

@ -44,11 +44,6 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil { }); err != nil {
return err return err
} }
if err := s.AddGeneratedConversionFunc((*config.DetectLocalConfiguration)(nil), (*v1alpha1.DetectLocalConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_config_DetectLocalConfiguration_To_v1alpha1_DetectLocalConfiguration(a.(*config.DetectLocalConfiguration), b.(*v1alpha1.DetectLocalConfiguration), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*v1alpha1.KubeProxyConntrackConfiguration)(nil), (*config.KubeProxyConntrackConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { if err := s.AddGeneratedConversionFunc((*v1alpha1.KubeProxyConntrackConfiguration)(nil), (*config.KubeProxyConntrackConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha1_KubeProxyConntrackConfiguration_To_config_KubeProxyConntrackConfiguration(a.(*v1alpha1.KubeProxyConntrackConfiguration), b.(*config.KubeProxyConntrackConfiguration), scope) return Convert_v1alpha1_KubeProxyConntrackConfiguration_To_config_KubeProxyConntrackConfiguration(a.(*v1alpha1.KubeProxyConntrackConfiguration), b.(*config.KubeProxyConntrackConfiguration), scope)
}); err != nil { }); err != nil {
@ -64,11 +59,6 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil { }); err != nil {
return err return err
} }
if err := s.AddGeneratedConversionFunc((*v1alpha1.KubeProxyIPVSConfiguration)(nil), (*config.KubeProxyIPVSConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha1_KubeProxyIPVSConfiguration_To_config_KubeProxyIPVSConfiguration(a.(*v1alpha1.KubeProxyIPVSConfiguration), b.(*config.KubeProxyIPVSConfiguration), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*config.KubeProxyIPVSConfiguration)(nil), (*v1alpha1.KubeProxyIPVSConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { if err := s.AddGeneratedConversionFunc((*config.KubeProxyIPVSConfiguration)(nil), (*v1alpha1.KubeProxyIPVSConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_config_KubeProxyIPVSConfiguration_To_v1alpha1_KubeProxyIPVSConfiguration(a.(*config.KubeProxyIPVSConfiguration), b.(*v1alpha1.KubeProxyIPVSConfiguration), scope) return Convert_config_KubeProxyIPVSConfiguration_To_v1alpha1_KubeProxyIPVSConfiguration(a.(*config.KubeProxyIPVSConfiguration), b.(*v1alpha1.KubeProxyIPVSConfiguration), scope)
}); err != nil { }); err != nil {
@ -89,6 +79,11 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil { }); err != nil {
return err return err
} }
if err := s.AddConversionFunc((*config.DetectLocalConfiguration)(nil), (*v1alpha1.DetectLocalConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_config_DetectLocalConfiguration_To_v1alpha1_DetectLocalConfiguration(a.(*config.DetectLocalConfiguration), b.(*v1alpha1.DetectLocalConfiguration), scope)
}); err != nil {
return err
}
if err := s.AddConversionFunc((*config.KubeProxyConfiguration)(nil), (*v1alpha1.KubeProxyConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { if err := s.AddConversionFunc((*config.KubeProxyConfiguration)(nil), (*v1alpha1.KubeProxyConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_config_KubeProxyConfiguration_To_v1alpha1_KubeProxyConfiguration(a.(*config.KubeProxyConfiguration), b.(*v1alpha1.KubeProxyConfiguration), scope) return Convert_config_KubeProxyConfiguration_To_v1alpha1_KubeProxyConfiguration(a.(*config.KubeProxyConfiguration), b.(*v1alpha1.KubeProxyConfiguration), scope)
}); err != nil { }); err != nil {
@ -104,6 +99,11 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil { }); err != nil {
return err return err
} }
if err := s.AddConversionFunc((*v1alpha1.KubeProxyIPVSConfiguration)(nil), (*config.KubeProxyIPVSConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha1_KubeProxyIPVSConfiguration_To_config_KubeProxyIPVSConfiguration(a.(*v1alpha1.KubeProxyIPVSConfiguration), b.(*config.KubeProxyIPVSConfiguration), scope)
}); err != nil {
return err
}
if err := s.AddConversionFunc((*v1alpha1.KubeProxyNFTablesConfiguration)(nil), (*config.KubeProxyNFTablesConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { if err := s.AddConversionFunc((*v1alpha1.KubeProxyNFTablesConfiguration)(nil), (*config.KubeProxyNFTablesConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha1_KubeProxyNFTablesConfiguration_To_config_KubeProxyNFTablesConfiguration(a.(*v1alpha1.KubeProxyNFTablesConfiguration), b.(*config.KubeProxyNFTablesConfiguration), scope) return Convert_v1alpha1_KubeProxyNFTablesConfiguration_To_config_KubeProxyNFTablesConfiguration(a.(*v1alpha1.KubeProxyNFTablesConfiguration), b.(*config.KubeProxyNFTablesConfiguration), scope)
}); err != nil { }); err != nil {
@ -125,15 +125,11 @@ func Convert_v1alpha1_DetectLocalConfiguration_To_config_DetectLocalConfiguratio
func autoConvert_config_DetectLocalConfiguration_To_v1alpha1_DetectLocalConfiguration(in *config.DetectLocalConfiguration, out *v1alpha1.DetectLocalConfiguration, s conversion.Scope) error { func autoConvert_config_DetectLocalConfiguration_To_v1alpha1_DetectLocalConfiguration(in *config.DetectLocalConfiguration, out *v1alpha1.DetectLocalConfiguration, s conversion.Scope) error {
out.BridgeInterface = in.BridgeInterface out.BridgeInterface = in.BridgeInterface
// WARNING: in.ClusterCIDRs requires manual conversion: does not exist in peer-type
out.InterfaceNamePrefix = in.InterfaceNamePrefix out.InterfaceNamePrefix = in.InterfaceNamePrefix
return nil return nil
} }
// Convert_config_DetectLocalConfiguration_To_v1alpha1_DetectLocalConfiguration is an autogenerated conversion function.
func Convert_config_DetectLocalConfiguration_To_v1alpha1_DetectLocalConfiguration(in *config.DetectLocalConfiguration, out *v1alpha1.DetectLocalConfiguration, s conversion.Scope) error {
return autoConvert_config_DetectLocalConfiguration_To_v1alpha1_DetectLocalConfiguration(in, out, s)
}
func autoConvert_v1alpha1_KubeProxyConfiguration_To_config_KubeProxyConfiguration(in *v1alpha1.KubeProxyConfiguration, out *config.KubeProxyConfiguration, s conversion.Scope) error { func autoConvert_v1alpha1_KubeProxyConfiguration_To_config_KubeProxyConfiguration(in *v1alpha1.KubeProxyConfiguration, out *config.KubeProxyConfiguration, s conversion.Scope) error {
out.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.FeatureGates)) out.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.FeatureGates))
if err := componentbaseconfigv1alpha1.Convert_v1alpha1_ClientConnectionConfiguration_To_config_ClientConnectionConfiguration(&in.ClientConnection, &out.ClientConnection, s); err != nil { if err := componentbaseconfigv1alpha1.Convert_v1alpha1_ClientConnectionConfiguration_To_config_ClientConnectionConfiguration(&in.ClientConnection, &out.ClientConnection, s); err != nil {
@ -164,12 +160,12 @@ func autoConvert_v1alpha1_KubeProxyConfiguration_To_config_KubeProxyConfiguratio
if err := Convert_v1alpha1_DetectLocalConfiguration_To_config_DetectLocalConfiguration(&in.DetectLocal, &out.DetectLocal, s); err != nil { if err := Convert_v1alpha1_DetectLocalConfiguration_To_config_DetectLocalConfiguration(&in.DetectLocal, &out.DetectLocal, s); err != nil {
return err return err
} }
out.ClusterCIDR = in.ClusterCIDR // WARNING: in.ClusterCIDR requires manual conversion: does not exist in peer-type
out.NodePortAddresses = *(*[]string)(unsafe.Pointer(&in.NodePortAddresses)) out.NodePortAddresses = *(*[]string)(unsafe.Pointer(&in.NodePortAddresses))
// WARNING: in.OOMScoreAdj requires manual conversion: does not exist in peer-type // WARNING: in.OOMScoreAdj requires manual conversion: does not exist in peer-type
// WARNING: in.Conntrack requires manual conversion: does not exist in peer-type // WARNING: in.Conntrack requires manual conversion: does not exist in peer-type
out.ConfigSyncPeriod = in.ConfigSyncPeriod out.ConfigSyncPeriod = in.ConfigSyncPeriod
out.PortRange = in.PortRange // WARNING: in.PortRange requires manual conversion: does not exist in peer-type
// WARNING: in.WindowsRunAsService requires manual conversion: does not exist in peer-type // WARNING: in.WindowsRunAsService requires manual conversion: does not exist in peer-type
return nil return nil
} }
@ -206,10 +202,10 @@ func autoConvert_config_KubeProxyConfiguration_To_v1alpha1_KubeProxyConfiguratio
if err := Convert_config_DetectLocalConfiguration_To_v1alpha1_DetectLocalConfiguration(&in.DetectLocal, &out.DetectLocal, s); err != nil { if err := Convert_config_DetectLocalConfiguration_To_v1alpha1_DetectLocalConfiguration(&in.DetectLocal, &out.DetectLocal, s); err != nil {
return err return err
} }
out.ClusterCIDR = in.ClusterCIDR
out.NodePortAddresses = *(*[]string)(unsafe.Pointer(&in.NodePortAddresses)) out.NodePortAddresses = *(*[]string)(unsafe.Pointer(&in.NodePortAddresses))
// WARNING: in.SyncPeriod requires manual conversion: does not exist in peer-type
// WARNING: in.MinSyncPeriod requires manual conversion: does not exist in peer-type
out.ConfigSyncPeriod = in.ConfigSyncPeriod out.ConfigSyncPeriod = in.ConfigSyncPeriod
out.PortRange = in.PortRange
return nil return nil
} }
@ -249,16 +245,14 @@ func autoConvert_v1alpha1_KubeProxyIPTablesConfiguration_To_config_KubeProxyIPTa
out.MasqueradeBit = (*int32)(unsafe.Pointer(in.MasqueradeBit)) out.MasqueradeBit = (*int32)(unsafe.Pointer(in.MasqueradeBit))
// WARNING: in.MasqueradeAll requires manual conversion: does not exist in peer-type // WARNING: in.MasqueradeAll requires manual conversion: does not exist in peer-type
out.LocalhostNodePorts = (*bool)(unsafe.Pointer(in.LocalhostNodePorts)) out.LocalhostNodePorts = (*bool)(unsafe.Pointer(in.LocalhostNodePorts))
out.SyncPeriod = in.SyncPeriod // WARNING: in.SyncPeriod requires manual conversion: does not exist in peer-type
out.MinSyncPeriod = in.MinSyncPeriod // WARNING: in.MinSyncPeriod requires manual conversion: does not exist in peer-type
return nil return nil
} }
func autoConvert_config_KubeProxyIPTablesConfiguration_To_v1alpha1_KubeProxyIPTablesConfiguration(in *config.KubeProxyIPTablesConfiguration, out *v1alpha1.KubeProxyIPTablesConfiguration, s conversion.Scope) error { func autoConvert_config_KubeProxyIPTablesConfiguration_To_v1alpha1_KubeProxyIPTablesConfiguration(in *config.KubeProxyIPTablesConfiguration, out *v1alpha1.KubeProxyIPTablesConfiguration, s conversion.Scope) error {
out.MasqueradeBit = (*int32)(unsafe.Pointer(in.MasqueradeBit)) out.MasqueradeBit = (*int32)(unsafe.Pointer(in.MasqueradeBit))
out.LocalhostNodePorts = (*bool)(unsafe.Pointer(in.LocalhostNodePorts)) out.LocalhostNodePorts = (*bool)(unsafe.Pointer(in.LocalhostNodePorts))
out.SyncPeriod = in.SyncPeriod
out.MinSyncPeriod = in.MinSyncPeriod
return nil return nil
} }
@ -268,8 +262,8 @@ func Convert_config_KubeProxyIPTablesConfiguration_To_v1alpha1_KubeProxyIPTables
} }
func autoConvert_v1alpha1_KubeProxyIPVSConfiguration_To_config_KubeProxyIPVSConfiguration(in *v1alpha1.KubeProxyIPVSConfiguration, out *config.KubeProxyIPVSConfiguration, s conversion.Scope) error { func autoConvert_v1alpha1_KubeProxyIPVSConfiguration_To_config_KubeProxyIPVSConfiguration(in *v1alpha1.KubeProxyIPVSConfiguration, out *config.KubeProxyIPVSConfiguration, s conversion.Scope) error {
out.SyncPeriod = in.SyncPeriod // WARNING: in.SyncPeriod requires manual conversion: does not exist in peer-type
out.MinSyncPeriod = in.MinSyncPeriod // WARNING: in.MinSyncPeriod requires manual conversion: does not exist in peer-type
out.Scheduler = in.Scheduler out.Scheduler = in.Scheduler
out.ExcludeCIDRs = *(*[]string)(unsafe.Pointer(&in.ExcludeCIDRs)) out.ExcludeCIDRs = *(*[]string)(unsafe.Pointer(&in.ExcludeCIDRs))
out.StrictARP = in.StrictARP out.StrictARP = in.StrictARP
@ -279,14 +273,7 @@ func autoConvert_v1alpha1_KubeProxyIPVSConfiguration_To_config_KubeProxyIPVSConf
return nil return nil
} }
// Convert_v1alpha1_KubeProxyIPVSConfiguration_To_config_KubeProxyIPVSConfiguration is an autogenerated conversion function.
func Convert_v1alpha1_KubeProxyIPVSConfiguration_To_config_KubeProxyIPVSConfiguration(in *v1alpha1.KubeProxyIPVSConfiguration, out *config.KubeProxyIPVSConfiguration, s conversion.Scope) error {
return autoConvert_v1alpha1_KubeProxyIPVSConfiguration_To_config_KubeProxyIPVSConfiguration(in, out, s)
}
func autoConvert_config_KubeProxyIPVSConfiguration_To_v1alpha1_KubeProxyIPVSConfiguration(in *config.KubeProxyIPVSConfiguration, out *v1alpha1.KubeProxyIPVSConfiguration, s conversion.Scope) error { func autoConvert_config_KubeProxyIPVSConfiguration_To_v1alpha1_KubeProxyIPVSConfiguration(in *config.KubeProxyIPVSConfiguration, out *v1alpha1.KubeProxyIPVSConfiguration, s conversion.Scope) error {
out.SyncPeriod = in.SyncPeriod
out.MinSyncPeriod = in.MinSyncPeriod
out.Scheduler = in.Scheduler out.Scheduler = in.Scheduler
out.ExcludeCIDRs = *(*[]string)(unsafe.Pointer(&in.ExcludeCIDRs)) out.ExcludeCIDRs = *(*[]string)(unsafe.Pointer(&in.ExcludeCIDRs))
out.StrictARP = in.StrictARP out.StrictARP = in.StrictARP
@ -304,15 +291,13 @@ func Convert_config_KubeProxyIPVSConfiguration_To_v1alpha1_KubeProxyIPVSConfigur
func autoConvert_v1alpha1_KubeProxyNFTablesConfiguration_To_config_KubeProxyNFTablesConfiguration(in *v1alpha1.KubeProxyNFTablesConfiguration, out *config.KubeProxyNFTablesConfiguration, s conversion.Scope) error { func autoConvert_v1alpha1_KubeProxyNFTablesConfiguration_To_config_KubeProxyNFTablesConfiguration(in *v1alpha1.KubeProxyNFTablesConfiguration, out *config.KubeProxyNFTablesConfiguration, s conversion.Scope) error {
out.MasqueradeBit = (*int32)(unsafe.Pointer(in.MasqueradeBit)) out.MasqueradeBit = (*int32)(unsafe.Pointer(in.MasqueradeBit))
// WARNING: in.MasqueradeAll requires manual conversion: does not exist in peer-type // WARNING: in.MasqueradeAll requires manual conversion: does not exist in peer-type
out.SyncPeriod = in.SyncPeriod // WARNING: in.SyncPeriod requires manual conversion: does not exist in peer-type
out.MinSyncPeriod = in.MinSyncPeriod // WARNING: in.MinSyncPeriod requires manual conversion: does not exist in peer-type
return nil return nil
} }
func autoConvert_config_KubeProxyNFTablesConfiguration_To_v1alpha1_KubeProxyNFTablesConfiguration(in *config.KubeProxyNFTablesConfiguration, out *v1alpha1.KubeProxyNFTablesConfiguration, s conversion.Scope) error { func autoConvert_config_KubeProxyNFTablesConfiguration_To_v1alpha1_KubeProxyNFTablesConfiguration(in *config.KubeProxyNFTablesConfiguration, out *v1alpha1.KubeProxyNFTablesConfiguration, s conversion.Scope) error {
out.MasqueradeBit = (*int32)(unsafe.Pointer(in.MasqueradeBit)) out.MasqueradeBit = (*int32)(unsafe.Pointer(in.MasqueradeBit))
out.SyncPeriod = in.SyncPeriod
out.MinSyncPeriod = in.MinSyncPeriod
return nil return nil
} }

View File

@ -23,7 +23,6 @@ import (
"strconv" "strconv"
"strings" "strings"
utilnet "k8s.io/apimachinery/pkg/util/net"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apimachinery/pkg/util/validation/field"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
@ -61,6 +60,15 @@ func Validate(config *kubeproxyconfig.KubeProxyConfiguration) field.ErrorList {
if config.ConfigSyncPeriod.Duration <= 0 { if config.ConfigSyncPeriod.Duration <= 0 {
allErrs = append(allErrs, field.Invalid(newPath.Child("ConfigSyncPeriod"), config.ConfigSyncPeriod, "must be greater than 0")) allErrs = append(allErrs, field.Invalid(newPath.Child("ConfigSyncPeriod"), config.ConfigSyncPeriod, "must be greater than 0"))
} }
if config.SyncPeriod.Duration <= 0 {
allErrs = append(allErrs, field.Invalid(newPath.Child("SyncPeriod"), config.SyncPeriod, "must be greater than 0"))
}
if config.MinSyncPeriod.Duration < 0 {
allErrs = append(allErrs, field.Invalid(newPath.Child("MinSyncPeriod"), config.MinSyncPeriod, "must be greater than or equal to 0"))
}
if config.MinSyncPeriod.Duration > config.SyncPeriod.Duration {
allErrs = append(allErrs, field.Invalid(newPath.Child("SyncPeriod"), config.MinSyncPeriod, fmt.Sprintf("must be greater than or equal to %s", newPath.Child("MinSyncPeriod").String())))
}
if netutils.ParseIPSloppy(config.BindAddress) == nil { if netutils.ParseIPSloppy(config.BindAddress) == nil {
allErrs = append(allErrs, field.Invalid(newPath.Child("BindAddress"), config.BindAddress, "not a valid textual representation of an IP address")) allErrs = append(allErrs, field.Invalid(newPath.Child("BindAddress"), config.BindAddress, "not a valid textual representation of an IP address"))
@ -71,39 +79,11 @@ func Validate(config *kubeproxyconfig.KubeProxyConfiguration) field.ErrorList {
} }
allErrs = append(allErrs, validateHostPort(config.MetricsBindAddress, newPath.Child("MetricsBindAddress"))...) 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)"))
}
allErrs = append(allErrs, validateKubeProxyNodePortAddress(config.NodePortAddresses, newPath.Child("NodePortAddresses"))...) allErrs = append(allErrs, validateKubeProxyNodePortAddress(config.NodePortAddresses, newPath.Child("NodePortAddresses"))...)
allErrs = append(allErrs, validateShowHiddenMetricsVersion(config.ShowHiddenMetricsForVersion, newPath.Child("ShowHiddenMetricsForVersion"))...) allErrs = append(allErrs, validateShowHiddenMetricsVersion(config.ShowHiddenMetricsForVersion, newPath.Child("ShowHiddenMetricsForVersion"))...)
allErrs = append(allErrs, validateDetectLocalMode(config.DetectLocalMode, newPath.Child("DetectLocalMode"))...) allErrs = append(allErrs, validateDetectLocalMode(config.DetectLocalMode, newPath.Child("DetectLocalMode"))...)
if config.DetectLocalMode == kubeproxyconfig.LocalModeBridgeInterface { allErrs = append(allErrs, validateDetectLocalConfiguration(config.DetectLocalMode, config.DetectLocal, newPath.Child("DetectLocalConfiguration"))...)
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, logsapi.Validate(&config.Logging, effectiveFeatures, newPath.Child("logging"))...) allErrs = append(allErrs, logsapi.Validate(&config.Logging, effectiveFeatures, newPath.Child("logging"))...)
return allErrs return allErrs
@ -115,37 +95,12 @@ func validateKubeProxyIPTablesConfiguration(config kubeproxyconfig.KubeProxyIPTa
if config.MasqueradeBit != nil && (*config.MasqueradeBit < 0 || *config.MasqueradeBit > 31) { if config.MasqueradeBit != nil && (*config.MasqueradeBit < 0 || *config.MasqueradeBit > 31) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("MasqueradeBit"), config.MasqueradeBit, "must be within the range [0, 31]")) allErrs = append(allErrs, field.Invalid(fldPath.Child("MasqueradeBit"), config.MasqueradeBit, "must be within the range [0, 31]"))
} }
if config.SyncPeriod.Duration <= 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("SyncPeriod"), config.SyncPeriod, "must be greater than 0"))
}
if config.MinSyncPeriod.Duration < 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("MinSyncPeriod"), config.MinSyncPeriod, "must be greater than or equal to 0"))
}
if config.MinSyncPeriod.Duration > config.SyncPeriod.Duration {
allErrs = append(allErrs, field.Invalid(fldPath.Child("SyncPeriod"), config.MinSyncPeriod, fmt.Sprintf("must be greater than or equal to %s", fldPath.Child("MinSyncPeriod").String())))
}
return allErrs return allErrs
} }
func validateKubeProxyIPVSConfiguration(config kubeproxyconfig.KubeProxyIPVSConfiguration, fldPath *field.Path) field.ErrorList { func validateKubeProxyIPVSConfiguration(config kubeproxyconfig.KubeProxyIPVSConfiguration, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{} allErrs := field.ErrorList{}
if config.SyncPeriod.Duration <= 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("SyncPeriod"), config.SyncPeriod, "must be greater than 0"))
}
if config.MinSyncPeriod.Duration < 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("MinSyncPeriod"), config.MinSyncPeriod, "must be greater than or equal to 0"))
}
if config.MinSyncPeriod.Duration > config.SyncPeriod.Duration {
allErrs = append(allErrs, field.Invalid(fldPath.Child("SyncPeriod"), config.MinSyncPeriod, fmt.Sprintf("must be greater than or equal to %s", fldPath.Child("MinSyncPeriod").String())))
}
allErrs = append(allErrs, validateIPVSTimeout(config, fldPath)...) allErrs = append(allErrs, validateIPVSTimeout(config, fldPath)...)
allErrs = append(allErrs, validateIPVSExcludeCIDRs(config.ExcludeCIDRs, fldPath.Child("ExcludeCidrs"))...) allErrs = append(allErrs, validateIPVSExcludeCIDRs(config.ExcludeCIDRs, fldPath.Child("ExcludeCidrs"))...)
@ -159,18 +114,6 @@ func validateKubeProxyNFTablesConfiguration(config kubeproxyconfig.KubeProxyNFTa
allErrs = append(allErrs, field.Invalid(fldPath.Child("MasqueradeBit"), config.MasqueradeBit, "must be within the range [0, 31]")) allErrs = append(allErrs, field.Invalid(fldPath.Child("MasqueradeBit"), config.MasqueradeBit, "must be within the range [0, 31]"))
} }
if config.SyncPeriod.Duration <= 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("SyncPeriod"), config.SyncPeriod, "must be greater than 0"))
}
if config.MinSyncPeriod.Duration < 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("MinSyncPeriod"), config.MinSyncPeriod, "must be greater than or equal to 0"))
}
if config.MinSyncPeriod.Duration > config.SyncPeriod.Duration {
allErrs = append(allErrs, field.Invalid(fldPath.Child("SyncPeriod"), config.MinSyncPeriod, fmt.Sprintf("must be greater than or equal to %s", fldPath.Child("MinSyncPeriod").String())))
}
return allErrs return allErrs
} }
@ -366,3 +309,41 @@ func validateInterface(iface string, fldPath *field.Path) field.ErrorList {
} }
return allErrs 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
}

View File

@ -1,42 +0,0 @@
//go:build !windows
// +build !windows
/*
Copyright 2024 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package validation
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/validation/field"
kubeproxyconfig "k8s.io/kubernetes/pkg/proxy/apis/config"
)
var (
kubeProxyConfigNewPath = field.NewPath("KubeProxyConfiguration")
osKubeProxyConfigTestCases = map[string]struct {
mutateConfigFunc func(*kubeproxyconfig.KubeProxyConfiguration)
expectedErrs field.ErrorList
}{
// Windows doesn't support IPVS, so this test will fail.
"IPVS mode selected without providing required SyncPeriod": {
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
config.Mode = kubeproxyconfig.ProxyModeIPVS
},
expectedErrs: field.ErrorList{field.Invalid(kubeProxyConfigNewPath.Child("KubeProxyIPVSConfiguration.SyncPeriod"), metav1.Duration{Duration: 0}, "must be greater than 0")},
},
}
)

View File

@ -36,12 +36,14 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
BindAddress: "192.168.59.103", BindAddress: "192.168.59.103",
HealthzBindAddress: "0.0.0.0:10256", HealthzBindAddress: "0.0.0.0:10256",
MetricsBindAddress: "127.0.0.1:10249", MetricsBindAddress: "127.0.0.1:10249",
ClusterCIDR: "192.168.59.0/24", DetectLocalMode: kubeproxyconfig.LocalModeClusterCIDR,
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second}, DetectLocal: kubeproxyconfig.DetectLocalConfiguration{
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{ ClusterCIDRs: []string{"192.168.59.0/24"},
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
}, },
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{},
Linux: kubeproxyconfig.KubeProxyLinuxConfiguration{ Linux: kubeproxyconfig.KubeProxyLinuxConfiguration{
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{ Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
MaxPerCore: ptr.To[int32](1), MaxPerCore: ptr.To[int32](1),
@ -70,10 +72,6 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
config.Mode = kubeproxyconfig.ProxyModeKernelspace config.Mode = kubeproxyconfig.ProxyModeKernelspace
} else { } else {
config.Mode = kubeproxyconfig.ProxyModeIPVS config.Mode = kubeproxyconfig.ProxyModeIPVS
config.IPVS = kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 10 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
}
} }
}, },
}, },
@ -87,7 +85,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
config.BindAddress = "fd00:192:168:59::103" config.BindAddress = "fd00:192:168:59::103"
config.HealthzBindAddress = "" config.HealthzBindAddress = ""
config.MetricsBindAddress = "[::1]:10249" config.MetricsBindAddress = "[::1]:10249"
config.ClusterCIDR = "fd00:192:168:59::/64" config.DetectLocal.ClusterCIDRs = []string{"fd00:192:168:59::/64"}
}, },
}, },
"alternate healthz port": { "alternate healthz port": {
@ -97,12 +95,12 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
}, },
"ClusterCIDR is wrong IP family": { "ClusterCIDR is wrong IP family": {
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) { mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
config.ClusterCIDR = "fd00:192:168::/64" config.DetectLocal.ClusterCIDRs = []string{"fd00:192:168:59::/64"}
}, },
}, },
"ClusterCIDR is dual-stack": { "ClusterCIDR is dual-stack": {
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) { mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
config.ClusterCIDR = "192.168.59.0/24,fd00:192:168::/64" config.DetectLocal.ClusterCIDRs = []string{"192.168.59.0/24", "fd00:192:168::/64"}
}, },
}, },
"LocalModeInterfaceNamePrefix": { "LocalModeInterfaceNamePrefix": {
@ -139,41 +137,31 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
}, },
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("MetricsBindAddress"), "127.0.0.1", "must be IP:port")}, expectedErrs: field.ErrorList{field.Invalid(newPath.Child("MetricsBindAddress"), "127.0.0.1", "must be IP:port")},
}, },
"ClusterCIDR missing subset range": {
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
config.ClusterCIDR = "192.168.59.0"
},
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("ClusterCIDR"), "192.168.59.0", "must be a valid CIDR block (e.g. 10.100.0.0/16 or fde4:8dba:82e1::/48)")},
},
"Invalid number of ClusterCIDRs": {
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
config.ClusterCIDR = "192.168.59.0/24,fd00:192:168::/64,10.0.0.0/16"
},
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("ClusterCIDR"), "192.168.59.0/24,fd00:192:168::/64,10.0.0.0/16", "only one CIDR allowed or a valid DualStack CIDR (e.g. 10.100.0.0/16,fde4:8dba:82e1::/48)")},
},
"ConfigSyncPeriod must be > 0": { "ConfigSyncPeriod must be > 0": {
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) { mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
config.ConfigSyncPeriod = metav1.Duration{Duration: -1 * time.Second} config.ConfigSyncPeriod = metav1.Duration{Duration: -1 * time.Second}
}, },
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("ConfigSyncPeriod"), metav1.Duration{Duration: -1 * time.Second}, "must be greater than 0")}, expectedErrs: field.ErrorList{field.Invalid(newPath.Child("ConfigSyncPeriod"), metav1.Duration{Duration: -1 * time.Second}, "must be greater than 0")},
}, },
"interfacePrefix is empty": { "SyncPeriod must be > 0": {
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) { mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
config.DetectLocalMode = kubeproxyconfig.LocalModeInterfaceNamePrefix config.SyncPeriod = metav1.Duration{Duration: -5 * time.Second}
config.DetectLocal = kubeproxyconfig.DetectLocalConfiguration{
InterfaceNamePrefix: "",
}
}, },
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("InterfacePrefix"), "", "must not be empty")}, expectedErrs: field.ErrorList{field.Invalid(newPath.Child("SyncPeriod"), metav1.Duration{Duration: -5 * time.Second}, "must be greater than 0"),
field.Invalid(newPath.Child("SyncPeriod"), metav1.Duration{Duration: 2 * time.Second}, "must be greater than or equal to KubeProxyConfiguration.MinSyncPeriod")},
}, },
"bridgeInterfaceName is empty": { "MinSyncPeriod must be > 0": {
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) { mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
config.DetectLocalMode = kubeproxyconfig.LocalModeBridgeInterface config.MinSyncPeriod = metav1.Duration{Duration: -2 * time.Second}
config.DetectLocal = kubeproxyconfig.DetectLocalConfiguration{
InterfaceNamePrefix: "eth0", // we won't care about prefix since mode is not prefix
}
}, },
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("InterfaceName"), "", "must not be empty")}, expectedErrs: field.ErrorList{field.Invalid(newPath.Child("MinSyncPeriod"), metav1.Duration{Duration: -2 * time.Second}, "must be greater than or equal to 0")},
},
"SyncPeriod must be >= MinSyncPeriod": {
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
config.SyncPeriod = metav1.Duration{Duration: 1 * time.Second}
config.MinSyncPeriod = metav1.Duration{Duration: 5 * time.Second}
},
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("SyncPeriod"), metav1.Duration{Duration: 5 * time.Second}, "must be greater than or equal to KubeProxyConfiguration.MinSyncPeriod")},
}, },
"invalid DetectLocalMode": { "invalid DetectLocalMode": {
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) { mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
@ -191,10 +179,6 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
}, },
} }
for name, testCase := range osKubeProxyConfigTestCases {
testCases[name] = testCase
}
for name, testCase := range testCases { for name, testCase := range testCases {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
config := baseConfig.DeepCopy() config := baseConfig.DeepCopy()
@ -216,53 +200,18 @@ func TestValidateKubeProxyIPTablesConfiguration(t *testing.T) {
config kubeproxyconfig.KubeProxyIPTablesConfiguration config kubeproxyconfig.KubeProxyIPTablesConfiguration
expectedErrs field.ErrorList expectedErrs field.ErrorList
}{ }{
"valid iptables config": {
config: kubeproxyconfig.KubeProxyIPTablesConfiguration{
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
},
expectedErrs: field.ErrorList{},
},
"valid custom MasqueradeBit": { "valid custom MasqueradeBit": {
config: kubeproxyconfig.KubeProxyIPTablesConfiguration{ config: kubeproxyconfig.KubeProxyIPTablesConfiguration{
MasqueradeBit: ptr.To[int32](5), MasqueradeBit: ptr.To[int32](5),
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
}, },
expectedErrs: field.ErrorList{}, expectedErrs: field.ErrorList{},
}, },
"SyncPeriod must be > 0": {
config: kubeproxyconfig.KubeProxyIPTablesConfiguration{
SyncPeriod: metav1.Duration{Duration: -5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
},
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("KubeIPTablesConfiguration.SyncPeriod"), metav1.Duration{Duration: -5 * time.Second}, "must be greater than 0"),
field.Invalid(newPath.Child("KubeIPTablesConfiguration.SyncPeriod"), metav1.Duration{Duration: 2 * time.Second}, "must be greater than or equal to KubeProxyConfiguration.KubeIPTablesConfiguration.MinSyncPeriod")},
},
"MinSyncPeriod must be > 0": {
config: kubeproxyconfig.KubeProxyIPTablesConfiguration{
MasqueradeBit: ptr.To[int32](5),
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: -1 * time.Second},
},
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("KubeIPTablesConfiguration.MinSyncPeriod"), metav1.Duration{Duration: -1 * time.Second}, "must be greater than or equal to 0")},
},
"MasqueradeBit cannot be < 0": { "MasqueradeBit cannot be < 0": {
config: kubeproxyconfig.KubeProxyIPTablesConfiguration{ config: kubeproxyconfig.KubeProxyIPTablesConfiguration{
MasqueradeBit: ptr.To[int32](-10), MasqueradeBit: ptr.To[int32](-10),
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
}, },
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("KubeIPTablesConfiguration.MasqueradeBit"), ptr.To[int32](-10), "must be within the range [0, 31]")}, expectedErrs: field.ErrorList{field.Invalid(newPath.Child("KubeIPTablesConfiguration.MasqueradeBit"), ptr.To[int32](-10), "must be within the range [0, 31]")},
}, },
"SyncPeriod must be >= MinSyncPeriod": {
config: kubeproxyconfig.KubeProxyIPTablesConfiguration{
MasqueradeBit: ptr.To[int32](5),
SyncPeriod: metav1.Duration{Duration: 1 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
},
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("KubeIPTablesConfiguration.SyncPeriod"), metav1.Duration{Duration: 5 * time.Second}, "must be greater than or equal to KubeProxyConfiguration.KubeIPTablesConfiguration.MinSyncPeriod")},
},
} { } {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
errs := validateKubeProxyIPTablesConfiguration(testCase.config, newPath.Child("KubeIPTablesConfiguration")) errs := validateKubeProxyIPTablesConfiguration(testCase.config, newPath.Child("KubeIPTablesConfiguration"))
@ -277,60 +226,8 @@ func TestValidateKubeProxyIPVSConfiguration(t *testing.T) {
config kubeproxyconfig.KubeProxyIPVSConfiguration config kubeproxyconfig.KubeProxyIPVSConfiguration
expectedErrs field.ErrorList expectedErrs field.ErrorList
}{ }{
"SyncPeriod is not greater than 0": {
config: kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: -5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
},
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("KubeIPVSConfiguration.SyncPeriod"), metav1.Duration{Duration: -5 * time.Second}, "must be greater than 0"),
field.Invalid(newPath.Child("KubeIPVSConfiguration.SyncPeriod"), metav1.Duration{Duration: 2 * time.Second}, "must be greater than or equal to KubeProxyConfiguration.KubeIPVSConfiguration.MinSyncPeriod")},
},
"SyncPeriod cannot be 0": {
config: kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 0 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 10 * time.Second},
},
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("KubeIPVSConfiguration.SyncPeriod"), metav1.Duration{Duration: 0}, "must be greater than 0"),
field.Invalid(newPath.Child("KubeIPVSConfiguration.SyncPeriod"), metav1.Duration{Duration: 10 * time.Second}, "must be greater than or equal to KubeProxyConfiguration.KubeIPVSConfiguration.MinSyncPeriod")},
},
"MinSyncPeriod cannot be less than 0": {
config: kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: -1 * time.Second},
},
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("KubeIPVSConfiguration.MinSyncPeriod"), metav1.Duration{Duration: -1 * time.Second}, "must be greater than or equal to 0")},
},
"SyncPeriod must be greater than MinSyncPeriod": {
config: kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 1 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
},
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("KubeIPVSConfiguration.SyncPeriod"), metav1.Duration{Duration: 5 * time.Second}, "must be greater than or equal to KubeProxyConfiguration.KubeIPVSConfiguration.MinSyncPeriod")},
},
"SyncPeriod == MinSyncPeriod": {
config: kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 10 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 10 * time.Second},
},
expectedErrs: field.ErrorList{},
},
"SyncPeriod should be > MinSyncPeriod": {
config: kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 10 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
},
expectedErrs: field.ErrorList{},
},
"MinSyncPeriod can be 0": {
config: kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 0 * time.Second},
},
expectedErrs: field.ErrorList{},
},
"IPVS Timeout can be 0": { "IPVS Timeout can be 0": {
config: kubeproxyconfig.KubeProxyIPVSConfiguration{ config: kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
TCPTimeout: metav1.Duration{Duration: 0 * time.Second}, TCPTimeout: metav1.Duration{Duration: 0 * time.Second},
TCPFinTimeout: metav1.Duration{Duration: 0 * time.Second}, TCPFinTimeout: metav1.Duration{Duration: 0 * time.Second},
UDPTimeout: metav1.Duration{Duration: 0 * time.Second}, UDPTimeout: metav1.Duration{Duration: 0 * time.Second},
@ -339,7 +236,6 @@ func TestValidateKubeProxyIPVSConfiguration(t *testing.T) {
}, },
"IPVS Timeout > 0": { "IPVS Timeout > 0": {
config: kubeproxyconfig.KubeProxyIPVSConfiguration{ config: kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
TCPTimeout: metav1.Duration{Duration: 1 * time.Second}, TCPTimeout: metav1.Duration{Duration: 1 * time.Second},
TCPFinTimeout: metav1.Duration{Duration: 2 * time.Second}, TCPFinTimeout: metav1.Duration{Duration: 2 * time.Second},
UDPTimeout: metav1.Duration{Duration: 3 * time.Second}, UDPTimeout: metav1.Duration{Duration: 3 * time.Second},
@ -348,7 +244,6 @@ func TestValidateKubeProxyIPVSConfiguration(t *testing.T) {
}, },
"TCP,TCPFin,UDP Timeouts < 0": { "TCP,TCPFin,UDP Timeouts < 0": {
config: kubeproxyconfig.KubeProxyIPVSConfiguration{ config: kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
TCPTimeout: metav1.Duration{Duration: -1 * time.Second}, TCPTimeout: metav1.Duration{Duration: -1 * time.Second},
UDPTimeout: metav1.Duration{Duration: -1 * time.Second}, UDPTimeout: metav1.Duration{Duration: -1 * time.Second},
TCPFinTimeout: metav1.Duration{Duration: -1 * time.Second}, TCPFinTimeout: metav1.Duration{Duration: -1 * time.Second},
@ -842,3 +737,154 @@ func TestValidateKubeProxyExcludeCIDRs(t *testing.T) {
}) })
} }
} }
func TestValidateDetectLocalConfiguration(t *testing.T) {
newPath := field.NewPath("KubeProxyConfiguration")
testCases := []struct {
name string
mode kubeproxyconfig.LocalMode
config kubeproxyconfig.DetectLocalConfiguration
expectedErrs field.ErrorList
}{
{
name: "valid interface name prefix",
mode: kubeproxyconfig.LocalModeInterfaceNamePrefix,
config: kubeproxyconfig.DetectLocalConfiguration{
InterfaceNamePrefix: "vethabcde",
},
expectedErrs: field.ErrorList{},
},
{
name: "valid bridge interface",
mode: kubeproxyconfig.LocalModeBridgeInterface,
config: kubeproxyconfig.DetectLocalConfiguration{
BridgeInterface: "avz",
},
expectedErrs: field.ErrorList{},
},
{
name: "interfacePrefix is empty",
mode: kubeproxyconfig.LocalModeInterfaceNamePrefix,
config: kubeproxyconfig.DetectLocalConfiguration{
InterfaceNamePrefix: "",
},
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("DetectLocal").Child("InterfacePrefix"), "", "must not be empty")},
},
{
name: "bridgeInterfaceName is empty",
mode: kubeproxyconfig.LocalModeBridgeInterface,
config: kubeproxyconfig.DetectLocalConfiguration{
InterfaceNamePrefix: "eth0", // we won't care about prefix since mode is not prefix
},
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("DetectLocal").Child("InterfaceName"), "", "must not be empty")},
},
{
name: "valid cluster cidr",
mode: kubeproxyconfig.LocalModeClusterCIDR,
config: kubeproxyconfig.DetectLocalConfiguration{
ClusterCIDRs: []string{"192.168.59.0/24", "fd00:192:168::/64"},
},
expectedErrs: field.ErrorList{},
},
{
name: "invalid number of cluster cidrs",
mode: kubeproxyconfig.LocalModeClusterCIDR,
config: kubeproxyconfig.DetectLocalConfiguration{
ClusterCIDRs: []string{"192.168.59.0/24", "fd00:192:168::/64", "10.0.0.0/16"},
},
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("DetectLocal").Child("ClusterCIDRs"), []string{"192.168.59.0/24", "fd00:192:168::/64", "10.0.0.0/16"}, "must be a either a single CIDR or dual-stack pair of CIDRs (e.g. [10.100.0.0/16, fde4:8dba:82e1::/48]")},
},
{
name: "invalid cluster cidr",
mode: kubeproxyconfig.LocalModeClusterCIDR,
config: kubeproxyconfig.DetectLocalConfiguration{
ClusterCIDRs: []string{"192.168.59.0"},
},
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("DetectLocal").Child("ClusterCIDRs").Index(0), "192.168.59.0", "must be a valid CIDR block (e.g. 10.100.0.0/16 or fde4:8dba:82e1::/48)")},
},
{
name: "empty cluster cidrs with cluster cidr mode",
mode: kubeproxyconfig.LocalModeClusterCIDR,
config: kubeproxyconfig.DetectLocalConfiguration{
ClusterCIDRs: []string{},
},
expectedErrs: field.ErrorList{},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
errs := validateDetectLocalConfiguration(tc.mode, tc.config, newPath.Child("DetectLocal"))
assert.Equalf(t, len(tc.expectedErrs), len(errs),
"expected %d errors, got %d errors: %v", len(tc.expectedErrs), len(errs), errs,
)
for i, err := range errs {
assert.Equal(t, tc.expectedErrs[i].Error(), err.Error())
}
})
}
}
func TestValidateDualStackCIDRStrings(t *testing.T) {
newPath := field.NewPath("KubeProxyConfiguration")
testCases := []struct {
name string
cidrStrings []string
expectedErrs field.ErrorList
}{
{
name: "empty cidr string",
cidrStrings: []string{},
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("DualStackCIDRList"), []string{}, "must contain at least one CIDR")},
},
{
name: "single ipv4 cidr",
cidrStrings: []string{"192.168.0.0/16"},
expectedErrs: field.ErrorList{},
},
{
name: "single ipv6 cidr",
cidrStrings: []string{"fd00:10:96::/112"},
expectedErrs: field.ErrorList{},
},
{
name: "dual stack cidr pair",
cidrStrings: []string{"172.16.200.0/24", "fde4:8dba:82e1::/48"},
expectedErrs: field.ErrorList{},
},
{
name: "multiple ipv4 cidrs",
cidrStrings: []string{"10.100.0.0/16", "192.168.0.0/16", "fde4:8dba:82e1::/48"},
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("DualStackCIDRList"), []string{"10.100.0.0/16", "192.168.0.0/16", "fde4:8dba:82e1::/48"}, "must be a either a single CIDR or dual-stack pair of CIDRs (e.g. [10.100.0.0/16, fde4:8dba:82e1::/48]")},
},
{
name: "multiple ipv6 cidrs",
cidrStrings: []string{"fd00:10:96::/112", "fde4:8dba:82e1::/48"},
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("DualStackCIDRList"), []string{"fd00:10:96::/112", "fde4:8dba:82e1::/48"}, "must be a either a single CIDR or dual-stack pair of CIDRs (e.g. [10.100.0.0/16, fde4:8dba:82e1::/48]")},
},
{
name: "malformed ipv4 cidr",
cidrStrings: []string{"fde4:8dba:82e1::/48", "172.16.200.0:24"},
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("DualStackCIDRList").Index(1), "172.16.200.0:24", "must be a valid CIDR block (e.g. 10.100.0.0/16 or fde4:8dba:82e1::/48)")},
},
{
name: "malformed ipv6 cidr",
cidrStrings: []string{"fd00:10:96::", "192.168.0.0/16"},
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("DualStackCIDRList").Index(0), "fd00:10:96::", "must be a valid CIDR block (e.g. 10.100.0.0/16 or fde4:8dba:82e1::/48)")},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
errs := validateDualStackCIDRStrings(tc.cidrStrings, newPath.Child("DualStackCIDRList"))
assert.Equalf(t, len(tc.expectedErrs), len(errs),
"expected %d errors, got %d errors: %v", len(tc.expectedErrs), len(errs), errs,
)
for i, err := range errs {
assert.Equal(t, tc.expectedErrs[i].Error(), err.Error())
}
})
}
}

View File

@ -1,32 +0,0 @@
//go:build windows
// +build windows
/*
Copyright 2024 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package validation
import (
"k8s.io/apimachinery/pkg/util/validation/field"
kubeproxyconfig "k8s.io/kubernetes/pkg/proxy/apis/config"
)
var (
osKubeProxyConfigTestCases = map[string]struct {
mutateConfigFunc func(*kubeproxyconfig.KubeProxyConfiguration)
expectedErrs field.ErrorList
}{}
)

View File

@ -29,6 +29,11 @@ import (
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *DetectLocalConfiguration) DeepCopyInto(out *DetectLocalConfiguration) { func (in *DetectLocalConfiguration) DeepCopyInto(out *DetectLocalConfiguration) {
*out = *in *out = *in
if in.ClusterCIDRs != nil {
in, out := &in.ClusterCIDRs, &out.ClusterCIDRs
*out = make([]string, len(*in))
copy(*out, *in)
}
return return
} }
@ -61,12 +66,14 @@ func (in *KubeProxyConfiguration) DeepCopyInto(out *KubeProxyConfiguration) {
in.IPVS.DeepCopyInto(&out.IPVS) in.IPVS.DeepCopyInto(&out.IPVS)
out.Winkernel = in.Winkernel out.Winkernel = in.Winkernel
in.NFTables.DeepCopyInto(&out.NFTables) in.NFTables.DeepCopyInto(&out.NFTables)
out.DetectLocal = in.DetectLocal in.DetectLocal.DeepCopyInto(&out.DetectLocal)
if in.NodePortAddresses != nil { if in.NodePortAddresses != nil {
in, out := &in.NodePortAddresses, &out.NodePortAddresses in, out := &in.NodePortAddresses, &out.NodePortAddresses
*out = make([]string, len(*in)) *out = make([]string, len(*in))
copy(*out, *in) copy(*out, *in)
} }
out.SyncPeriod = in.SyncPeriod
out.MinSyncPeriod = in.MinSyncPeriod
out.ConfigSyncPeriod = in.ConfigSyncPeriod out.ConfigSyncPeriod = in.ConfigSyncPeriod
return return
} }
@ -140,8 +147,6 @@ func (in *KubeProxyIPTablesConfiguration) DeepCopyInto(out *KubeProxyIPTablesCon
*out = new(bool) *out = new(bool)
**out = **in **out = **in
} }
out.SyncPeriod = in.SyncPeriod
out.MinSyncPeriod = in.MinSyncPeriod
return return
} }
@ -158,8 +163,6 @@ func (in *KubeProxyIPTablesConfiguration) DeepCopy() *KubeProxyIPTablesConfigura
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *KubeProxyIPVSConfiguration) DeepCopyInto(out *KubeProxyIPVSConfiguration) { func (in *KubeProxyIPVSConfiguration) DeepCopyInto(out *KubeProxyIPVSConfiguration) {
*out = *in *out = *in
out.SyncPeriod = in.SyncPeriod
out.MinSyncPeriod = in.MinSyncPeriod
if in.ExcludeCIDRs != nil { if in.ExcludeCIDRs != nil {
in, out := &in.ExcludeCIDRs, &out.ExcludeCIDRs in, out := &in.ExcludeCIDRs, &out.ExcludeCIDRs
*out = make([]string, len(*in)) *out = make([]string, len(*in))
@ -211,8 +214,6 @@ func (in *KubeProxyNFTablesConfiguration) DeepCopyInto(out *KubeProxyNFTablesCon
*out = new(int32) *out = new(int32)
**out = **in **out = **in
} }
out.SyncPeriod = in.SyncPeriod
out.MinSyncPeriod = in.MinSyncPeriod
return return
} }