mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-02 16:29:21 +00:00
kube-proxy: refactor config validation unit test
Refactor the TestValidateKubeProxyConfiguration by adding a mutating function that adjusts the configuration according to each test case, thereby enhancing readability. Signed-off-by: Daman Arora <aroradaman@gmail.com>
This commit is contained in:
parent
f4ecae8324
commit
a577c0b324
@ -28,526 +28,176 @@ import (
|
|||||||
componentbaseconfig "k8s.io/component-base/config"
|
componentbaseconfig "k8s.io/component-base/config"
|
||||||
logsapi "k8s.io/component-base/logs/api/v1"
|
logsapi "k8s.io/component-base/logs/api/v1"
|
||||||
kubeproxyconfig "k8s.io/kubernetes/pkg/proxy/apis/config"
|
kubeproxyconfig "k8s.io/kubernetes/pkg/proxy/apis/config"
|
||||||
|
|
||||||
"k8s.io/utils/ptr"
|
"k8s.io/utils/ptr"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestValidateKubeProxyConfiguration(t *testing.T) {
|
func TestValidateKubeProxyConfiguration(t *testing.T) {
|
||||||
var proxyMode kubeproxyconfig.ProxyMode
|
baseConfig := &kubeproxyconfig.KubeProxyConfiguration{
|
||||||
if runtime.GOOS == "windows" {
|
BindAddress: "192.168.59.103",
|
||||||
proxyMode = kubeproxyconfig.ProxyModeKernelspace
|
HealthzBindAddress: "0.0.0.0:10256",
|
||||||
} else {
|
MetricsBindAddress: "127.0.0.1:10249",
|
||||||
proxyMode = kubeproxyconfig.ProxyModeIPVS
|
ClusterCIDR: "192.168.59.0/24",
|
||||||
|
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
|
||||||
|
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
|
||||||
|
MasqueradeAll: true,
|
||||||
|
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
|
||||||
|
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
|
||||||
|
},
|
||||||
|
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
|
||||||
|
MaxPerCore: ptr.To[int32](1),
|
||||||
|
Min: ptr.To[int32](1),
|
||||||
|
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
||||||
|
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
||||||
|
},
|
||||||
|
Logging: logsapi.LoggingConfiguration{
|
||||||
|
Format: "text",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
newPath := field.NewPath("KubeProxyConfiguration")
|
newPath := field.NewPath("KubeProxyConfiguration")
|
||||||
|
|
||||||
for name, testCase := range map[string]struct {
|
for name, testCase := range map[string]struct {
|
||||||
config kubeproxyconfig.KubeProxyConfiguration
|
mutateConfigFunc func(*kubeproxyconfig.KubeProxyConfiguration)
|
||||||
expectedErrs field.ErrorList
|
expectedErrs field.ErrorList
|
||||||
}{
|
}{
|
||||||
"Mode specified, extra mode-specific configs": {
|
|
||||||
config: kubeproxyconfig.KubeProxyConfiguration{
|
|
||||||
BindAddress: "192.168.59.103",
|
|
||||||
HealthzBindAddress: "0.0.0.0:10256",
|
|
||||||
MetricsBindAddress: "127.0.0.1:10249",
|
|
||||||
ClusterCIDR: "192.168.59.0/24",
|
|
||||||
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
|
|
||||||
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
|
|
||||||
MasqueradeAll: true,
|
|
||||||
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
|
|
||||||
},
|
|
||||||
Mode: proxyMode,
|
|
||||||
IPVS: kubeproxyconfig.KubeProxyIPVSConfiguration{
|
|
||||||
SyncPeriod: metav1.Duration{Duration: 10 * time.Second},
|
|
||||||
MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
},
|
|
||||||
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
|
|
||||||
MaxPerCore: ptr.To[int32](1),
|
|
||||||
Min: ptr.To[int32](1),
|
|
||||||
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
},
|
|
||||||
Logging: logsapi.LoggingConfiguration{
|
|
||||||
Format: "text",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"basic config, unspecified Mode": {
|
"basic config, unspecified Mode": {
|
||||||
config: kubeproxyconfig.KubeProxyConfiguration{
|
mutateConfigFunc: func(_ *kubeproxyconfig.KubeProxyConfiguration) {},
|
||||||
BindAddress: "192.168.59.103",
|
},
|
||||||
HealthzBindAddress: "0.0.0.0:10256",
|
"Mode specified, extra mode-specific configs": {
|
||||||
MetricsBindAddress: "127.0.0.1:10249",
|
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
|
||||||
ClusterCIDR: "192.168.59.0/24",
|
if runtime.GOOS == "windows" {
|
||||||
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
|
config.Mode = kubeproxyconfig.ProxyModeKernelspace
|
||||||
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
|
} else {
|
||||||
MasqueradeAll: true,
|
config.Mode = kubeproxyconfig.ProxyModeIPVS
|
||||||
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
|
config.IPVS = kubeproxyconfig.KubeProxyIPVSConfiguration{
|
||||||
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
|
SyncPeriod: metav1.Duration{Duration: 10 * time.Second},
|
||||||
},
|
MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
|
||||||
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
|
}
|
||||||
MaxPerCore: ptr.To[int32](1),
|
}
|
||||||
Min: ptr.To[int32](1),
|
|
||||||
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
},
|
|
||||||
Logging: logsapi.LoggingConfiguration{
|
|
||||||
Format: "text",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"empty HealthzBindAddress": {
|
"empty HealthzBindAddress": {
|
||||||
config: kubeproxyconfig.KubeProxyConfiguration{
|
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
|
||||||
BindAddress: "192.168.59.103",
|
config.HealthzBindAddress = ""
|
||||||
HealthzBindAddress: "",
|
|
||||||
MetricsBindAddress: "127.0.0.1:10249",
|
|
||||||
ClusterCIDR: "192.168.59.0/24",
|
|
||||||
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
|
|
||||||
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
|
|
||||||
MasqueradeAll: true,
|
|
||||||
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
|
|
||||||
},
|
|
||||||
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
|
|
||||||
MaxPerCore: ptr.To[int32](1),
|
|
||||||
Min: ptr.To[int32](1),
|
|
||||||
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
},
|
|
||||||
Logging: logsapi.LoggingConfiguration{
|
|
||||||
Format: "text",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"IPv6": {
|
"IPv6": {
|
||||||
config: kubeproxyconfig.KubeProxyConfiguration{
|
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
|
||||||
BindAddress: "fd00:192:168:59::103",
|
config.BindAddress = "fd00:192:168:59::103"
|
||||||
HealthzBindAddress: "",
|
config.HealthzBindAddress = ""
|
||||||
MetricsBindAddress: "[::1]:10249",
|
config.MetricsBindAddress = "[::1]:10249"
|
||||||
ClusterCIDR: "fd00:192:168:59::/64",
|
config.ClusterCIDR = "fd00:192:168:59::/64"
|
||||||
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
|
|
||||||
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
|
|
||||||
MasqueradeAll: true,
|
|
||||||
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
|
|
||||||
},
|
|
||||||
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
|
|
||||||
MaxPerCore: ptr.To[int32](1),
|
|
||||||
Min: ptr.To[int32](1),
|
|
||||||
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
},
|
|
||||||
Logging: logsapi.LoggingConfiguration{
|
|
||||||
Format: "text",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"alternate healthz port": {
|
"alternate healthz port": {
|
||||||
config: kubeproxyconfig.KubeProxyConfiguration{
|
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
|
||||||
BindAddress: "10.10.12.11",
|
config.HealthzBindAddress = "0.0.0.0:12345"
|
||||||
HealthzBindAddress: "0.0.0.0:12345",
|
|
||||||
MetricsBindAddress: "127.0.0.1:10249",
|
|
||||||
ClusterCIDR: "192.168.59.0/24",
|
|
||||||
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
|
|
||||||
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
|
|
||||||
MasqueradeAll: true,
|
|
||||||
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
|
|
||||||
},
|
|
||||||
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
|
|
||||||
MaxPerCore: ptr.To[int32](1),
|
|
||||||
Min: ptr.To[int32](1),
|
|
||||||
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
},
|
|
||||||
Logging: logsapi.LoggingConfiguration{
|
|
||||||
Format: "text",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"ClusterCIDR is wrong IP family": {
|
"ClusterCIDR is wrong IP family": {
|
||||||
config: kubeproxyconfig.KubeProxyConfiguration{
|
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
|
||||||
BindAddress: "10.10.12.11",
|
config.ClusterCIDR = "fd00:192:168::/64"
|
||||||
HealthzBindAddress: "0.0.0.0:12345",
|
|
||||||
MetricsBindAddress: "127.0.0.1:10249",
|
|
||||||
ClusterCIDR: "fd00:192:168::/64",
|
|
||||||
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
|
|
||||||
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
|
|
||||||
MasqueradeAll: true,
|
|
||||||
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
|
|
||||||
},
|
|
||||||
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
|
|
||||||
MaxPerCore: ptr.To[int32](1),
|
|
||||||
Min: ptr.To[int32](1),
|
|
||||||
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
},
|
|
||||||
Logging: logsapi.LoggingConfiguration{
|
|
||||||
Format: "text",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"ClusterCIDR is dual-stack": {
|
"ClusterCIDR is dual-stack": {
|
||||||
config: kubeproxyconfig.KubeProxyConfiguration{
|
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
|
||||||
BindAddress: "10.10.12.11",
|
config.ClusterCIDR = "192.168.59.0/24,fd00:192:168::/64"
|
||||||
HealthzBindAddress: "0.0.0.0:12345",
|
|
||||||
MetricsBindAddress: "127.0.0.1:10249",
|
|
||||||
ClusterCIDR: "192.168.59.0/24,fd00:192:168::/64",
|
|
||||||
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
|
|
||||||
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
|
|
||||||
MasqueradeAll: true,
|
|
||||||
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
|
|
||||||
},
|
|
||||||
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
|
|
||||||
MaxPerCore: ptr.To[int32](1),
|
|
||||||
Min: ptr.To[int32](1),
|
|
||||||
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
},
|
|
||||||
Logging: logsapi.LoggingConfiguration{
|
|
||||||
Format: "text",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"LocalModeInterfaceNamePrefix": {
|
"LocalModeInterfaceNamePrefix": {
|
||||||
config: kubeproxyconfig.KubeProxyConfiguration{
|
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
|
||||||
BindAddress: "10.10.12.11",
|
config.DetectLocalMode = kubeproxyconfig.LocalModeInterfaceNamePrefix
|
||||||
HealthzBindAddress: "0.0.0.0:12345",
|
config.DetectLocal = kubeproxyconfig.DetectLocalConfiguration{
|
||||||
MetricsBindAddress: "127.0.0.1:10249",
|
|
||||||
ClusterCIDR: "192.168.59.0/24",
|
|
||||||
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
|
|
||||||
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
|
|
||||||
MasqueradeAll: true,
|
|
||||||
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
|
|
||||||
},
|
|
||||||
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
|
|
||||||
MaxPerCore: ptr.To[int32](1),
|
|
||||||
Min: ptr.To[int32](1),
|
|
||||||
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
},
|
|
||||||
DetectLocalMode: kubeproxyconfig.LocalModeInterfaceNamePrefix,
|
|
||||||
DetectLocal: kubeproxyconfig.DetectLocalConfiguration{
|
|
||||||
InterfaceNamePrefix: "vethabcde",
|
InterfaceNamePrefix: "vethabcde",
|
||||||
},
|
}
|
||||||
Logging: logsapi.LoggingConfiguration{
|
|
||||||
Format: "text",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"LocalModeBridgeInterface": {
|
"LocalModeBridgeInterface": {
|
||||||
config: kubeproxyconfig.KubeProxyConfiguration{
|
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
|
||||||
BindAddress: "10.10.12.11",
|
config.DetectLocalMode = kubeproxyconfig.LocalModeBridgeInterface
|
||||||
HealthzBindAddress: "0.0.0.0:12345",
|
config.DetectLocal = kubeproxyconfig.DetectLocalConfiguration{
|
||||||
MetricsBindAddress: "127.0.0.1:10249",
|
|
||||||
ClusterCIDR: "192.168.59.0/24",
|
|
||||||
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
|
|
||||||
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
|
|
||||||
MasqueradeAll: true,
|
|
||||||
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
|
|
||||||
},
|
|
||||||
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
|
|
||||||
MaxPerCore: ptr.To[int32](1),
|
|
||||||
Min: ptr.To[int32](1),
|
|
||||||
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
},
|
|
||||||
DetectLocalMode: kubeproxyconfig.LocalModeBridgeInterface,
|
|
||||||
DetectLocal: kubeproxyconfig.DetectLocalConfiguration{
|
|
||||||
BridgeInterface: "avz",
|
BridgeInterface: "avz",
|
||||||
},
|
}
|
||||||
Logging: logsapi.LoggingConfiguration{
|
|
||||||
Format: "text",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"invalid BindAddress": {
|
"invalid BindAddress": {
|
||||||
config: kubeproxyconfig.KubeProxyConfiguration{
|
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
|
||||||
BindAddress: "10.10.12.11:2000",
|
config.BindAddress = "10.10.12.11:2000"
|
||||||
HealthzBindAddress: "0.0.0.0:10256",
|
|
||||||
MetricsBindAddress: "127.0.0.1:10249",
|
|
||||||
ClusterCIDR: "192.168.59.0/24",
|
|
||||||
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
|
|
||||||
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
|
|
||||||
MasqueradeAll: true,
|
|
||||||
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
|
|
||||||
},
|
|
||||||
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
|
|
||||||
MaxPerCore: ptr.To[int32](1),
|
|
||||||
Min: ptr.To[int32](1),
|
|
||||||
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
},
|
|
||||||
Logging: logsapi.LoggingConfiguration{
|
|
||||||
Format: "text",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("BindAddress"), "10.10.12.11:2000", "not a valid textual representation of an IP address")},
|
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("BindAddress"), "10.10.12.11:2000", "not a valid textual representation of an IP address")},
|
||||||
},
|
},
|
||||||
"invalid HealthzBindAddress": {
|
"invalid HealthzBindAddress": {
|
||||||
config: kubeproxyconfig.KubeProxyConfiguration{
|
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
|
||||||
BindAddress: "10.10.12.11",
|
config.HealthzBindAddress = "0.0.0.0"
|
||||||
HealthzBindAddress: "0.0.0.0",
|
|
||||||
MetricsBindAddress: "127.0.0.1:10249",
|
|
||||||
ClusterCIDR: "192.168.59.0/24",
|
|
||||||
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
|
|
||||||
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
|
|
||||||
MasqueradeAll: true,
|
|
||||||
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
|
|
||||||
},
|
|
||||||
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
|
|
||||||
MaxPerCore: ptr.To[int32](1),
|
|
||||||
Min: ptr.To[int32](1),
|
|
||||||
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
},
|
|
||||||
Logging: logsapi.LoggingConfiguration{
|
|
||||||
Format: "text",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("HealthzBindAddress"), "0.0.0.0", "must be IP:port")},
|
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("HealthzBindAddress"), "0.0.0.0", "must be IP:port")},
|
||||||
},
|
},
|
||||||
"invalid MetricsBindAddress": {
|
"invalid MetricsBindAddress": {
|
||||||
config: kubeproxyconfig.KubeProxyConfiguration{
|
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
|
||||||
BindAddress: "10.10.12.11",
|
config.MetricsBindAddress = "127.0.0.1"
|
||||||
HealthzBindAddress: "0.0.0.0:12345",
|
|
||||||
MetricsBindAddress: "127.0.0.1",
|
|
||||||
ClusterCIDR: "192.168.59.0/24",
|
|
||||||
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
|
|
||||||
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
|
|
||||||
MasqueradeAll: true,
|
|
||||||
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
|
|
||||||
},
|
|
||||||
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
|
|
||||||
MaxPerCore: ptr.To[int32](1),
|
|
||||||
Min: ptr.To[int32](1),
|
|
||||||
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
},
|
|
||||||
Logging: logsapi.LoggingConfiguration{
|
|
||||||
Format: "text",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
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": {
|
"ClusterCIDR missing subset range": {
|
||||||
config: kubeproxyconfig.KubeProxyConfiguration{
|
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
|
||||||
BindAddress: "10.10.12.11",
|
config.ClusterCIDR = "192.168.59.0"
|
||||||
HealthzBindAddress: "0.0.0.0:12345",
|
|
||||||
MetricsBindAddress: "127.0.0.1:10249",
|
|
||||||
ClusterCIDR: "192.168.59.0",
|
|
||||||
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
|
|
||||||
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
|
|
||||||
MasqueradeAll: true,
|
|
||||||
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
|
|
||||||
},
|
|
||||||
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
|
|
||||||
MaxPerCore: ptr.To[int32](1),
|
|
||||||
Min: ptr.To[int32](1),
|
|
||||||
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
},
|
|
||||||
Logging: logsapi.LoggingConfiguration{
|
|
||||||
Format: "text",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
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)")},
|
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": {
|
"Invalid number of ClusterCIDRs": {
|
||||||
config: kubeproxyconfig.KubeProxyConfiguration{
|
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
|
||||||
BindAddress: "10.10.12.11",
|
config.ClusterCIDR = "192.168.59.0/24,fd00:192:168::/64,10.0.0.0/16"
|
||||||
HealthzBindAddress: "0.0.0.0:12345",
|
|
||||||
MetricsBindAddress: "127.0.0.1:10249",
|
|
||||||
ClusterCIDR: "192.168.59.0/24,fd00:192:168::/64,10.0.0.0/16",
|
|
||||||
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
|
|
||||||
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
|
|
||||||
MasqueradeAll: true,
|
|
||||||
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
|
|
||||||
},
|
|
||||||
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
|
|
||||||
MaxPerCore: ptr.To[int32](1),
|
|
||||||
Min: ptr.To[int32](1),
|
|
||||||
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
},
|
|
||||||
Logging: logsapi.LoggingConfiguration{
|
|
||||||
Format: "text",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
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)")},
|
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": {
|
||||||
config: kubeproxyconfig.KubeProxyConfiguration{
|
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
|
||||||
BindAddress: "10.10.12.11",
|
config.ConfigSyncPeriod = metav1.Duration{Duration: -1 * time.Second}
|
||||||
HealthzBindAddress: "0.0.0.0:12345",
|
|
||||||
MetricsBindAddress: "127.0.0.1:10249",
|
|
||||||
ClusterCIDR: "192.168.59.0/24",
|
|
||||||
ConfigSyncPeriod: metav1.Duration{Duration: -1 * time.Second},
|
|
||||||
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
|
|
||||||
MasqueradeAll: true,
|
|
||||||
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
|
|
||||||
},
|
|
||||||
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
|
|
||||||
MaxPerCore: ptr.To[int32](1),
|
|
||||||
Min: ptr.To[int32](1),
|
|
||||||
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
},
|
|
||||||
Logging: logsapi.LoggingConfiguration{
|
|
||||||
Format: "text",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
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")},
|
||||||
},
|
},
|
||||||
"IPVS mode selected without providing required SyncPeriod": {
|
"IPVS mode selected without providing required SyncPeriod": {
|
||||||
config: kubeproxyconfig.KubeProxyConfiguration{
|
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
|
||||||
BindAddress: "192.168.59.103",
|
config.Mode = kubeproxyconfig.ProxyModeIPVS
|
||||||
HealthzBindAddress: "0.0.0.0:10256",
|
|
||||||
MetricsBindAddress: "127.0.0.1:10249",
|
|
||||||
ClusterCIDR: "192.168.59.0/24",
|
|
||||||
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
|
|
||||||
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
|
|
||||||
MasqueradeAll: true,
|
|
||||||
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
|
|
||||||
},
|
|
||||||
// not specifying valid period in IPVS mode.
|
|
||||||
Mode: kubeproxyconfig.ProxyModeIPVS,
|
|
||||||
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
|
|
||||||
MaxPerCore: ptr.To[int32](1),
|
|
||||||
Min: ptr.To[int32](1),
|
|
||||||
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
},
|
|
||||||
Logging: logsapi.LoggingConfiguration{
|
|
||||||
Format: "text",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("KubeProxyIPVSConfiguration.SyncPeriod"), metav1.Duration{Duration: 0}, "must be greater than 0")},
|
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("KubeProxyIPVSConfiguration.SyncPeriod"), metav1.Duration{Duration: 0}, "must be greater than 0")},
|
||||||
},
|
},
|
||||||
"interfacePrefix is empty": {
|
"interfacePrefix is empty": {
|
||||||
config: kubeproxyconfig.KubeProxyConfiguration{
|
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
|
||||||
BindAddress: "10.10.12.11",
|
config.DetectLocalMode = kubeproxyconfig.LocalModeInterfaceNamePrefix
|
||||||
HealthzBindAddress: "0.0.0.0:12345",
|
config.DetectLocal = kubeproxyconfig.DetectLocalConfiguration{
|
||||||
MetricsBindAddress: "127.0.0.1:10249",
|
|
||||||
ClusterCIDR: "192.168.59.0/24",
|
|
||||||
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
|
|
||||||
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
|
|
||||||
MasqueradeAll: true,
|
|
||||||
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
|
|
||||||
},
|
|
||||||
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
|
|
||||||
MaxPerCore: ptr.To[int32](1),
|
|
||||||
Min: ptr.To[int32](1),
|
|
||||||
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
},
|
|
||||||
DetectLocalMode: kubeproxyconfig.LocalModeInterfaceNamePrefix,
|
|
||||||
DetectLocal: kubeproxyconfig.DetectLocalConfiguration{
|
|
||||||
InterfaceNamePrefix: "",
|
InterfaceNamePrefix: "",
|
||||||
},
|
}
|
||||||
Logging: logsapi.LoggingConfiguration{
|
|
||||||
Format: "text",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("InterfacePrefix"), "", "must not be empty")},
|
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("InterfacePrefix"), "", "must not be empty")},
|
||||||
},
|
},
|
||||||
"bridgeInterfaceName is empty": {
|
"bridgeInterfaceName is empty": {
|
||||||
config: kubeproxyconfig.KubeProxyConfiguration{
|
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
|
||||||
BindAddress: "10.10.12.11",
|
config.DetectLocalMode = kubeproxyconfig.LocalModeBridgeInterface
|
||||||
HealthzBindAddress: "0.0.0.0:12345",
|
config.DetectLocal = kubeproxyconfig.DetectLocalConfiguration{
|
||||||
MetricsBindAddress: "127.0.0.1:10249",
|
|
||||||
ClusterCIDR: "192.168.59.0/24",
|
|
||||||
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
|
|
||||||
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
|
|
||||||
MasqueradeAll: true,
|
|
||||||
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
|
|
||||||
},
|
|
||||||
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
|
|
||||||
MaxPerCore: ptr.To[int32](1),
|
|
||||||
Min: ptr.To[int32](1),
|
|
||||||
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
},
|
|
||||||
DetectLocalMode: kubeproxyconfig.LocalModeBridgeInterface,
|
|
||||||
DetectLocal: kubeproxyconfig.DetectLocalConfiguration{
|
|
||||||
InterfaceNamePrefix: "eth0", // we won't care about prefix since mode is not prefix
|
InterfaceNamePrefix: "eth0", // we won't care about prefix since mode is not prefix
|
||||||
},
|
}
|
||||||
Logging: logsapi.LoggingConfiguration{
|
|
||||||
Format: "text",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("InterfaceName"), "", "must not be empty")},
|
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("InterfaceName"), "", "must not be empty")},
|
||||||
},
|
},
|
||||||
"invalid DetectLocalMode": {
|
"invalid DetectLocalMode": {
|
||||||
config: kubeproxyconfig.KubeProxyConfiguration{
|
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
|
||||||
BindAddress: "10.10.12.11",
|
config.DetectLocalMode = "Guess"
|
||||||
HealthzBindAddress: "0.0.0.0:12345",
|
|
||||||
MetricsBindAddress: "127.0.0.1:10249",
|
|
||||||
ClusterCIDR: "192.168.59.0/24",
|
|
||||||
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
|
|
||||||
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
|
|
||||||
MasqueradeAll: true,
|
|
||||||
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
|
|
||||||
},
|
|
||||||
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
|
|
||||||
MaxPerCore: ptr.To[int32](1),
|
|
||||||
Min: ptr.To[int32](1),
|
|
||||||
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
},
|
|
||||||
DetectLocalMode: "Guess",
|
|
||||||
Logging: logsapi.LoggingConfiguration{
|
|
||||||
Format: "text",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
expectedErrs: field.ErrorList{field.NotSupported(newPath.Child("DetectLocalMode"), "Guess", []string{"ClusterCIDR", "NodeCIDR", "BridgeInterface", "InterfaceNamePrefix", ""})},
|
expectedErrs: field.ErrorList{field.NotSupported(newPath.Child("DetectLocalMode"), "Guess", []string{"ClusterCIDR", "NodeCIDR", "BridgeInterface", "InterfaceNamePrefix", ""})},
|
||||||
},
|
},
|
||||||
"invalid logging format": {
|
"invalid logging format": {
|
||||||
config: kubeproxyconfig.KubeProxyConfiguration{
|
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
|
||||||
BindAddress: "10.10.12.11",
|
config.Logging = logsapi.LoggingConfiguration{
|
||||||
HealthzBindAddress: "0.0.0.0:12345",
|
|
||||||
MetricsBindAddress: "127.0.0.1:10249",
|
|
||||||
ClusterCIDR: "192.168.59.0/24",
|
|
||||||
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
|
|
||||||
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
|
|
||||||
MasqueradeAll: true,
|
|
||||||
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
|
|
||||||
},
|
|
||||||
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
|
|
||||||
MaxPerCore: ptr.To[int32](1),
|
|
||||||
Min: ptr.To[int32](1),
|
|
||||||
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
|
|
||||||
},
|
|
||||||
Logging: logsapi.LoggingConfiguration{
|
|
||||||
Format: "unsupported format",
|
Format: "unsupported format",
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("logging.format"), "unsupported format", "Unsupported log format")},
|
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("logging.format"), "unsupported format", "Unsupported log format")},
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
if runtime.GOOS == "windows" && testCase.config.Mode == kubeproxyconfig.ProxyModeIPVS {
|
|
||||||
// IPVS is not supported on Windows.
|
|
||||||
t.Log("Skipping test on Windows: ", name)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
errs := Validate(&testCase.config)
|
config := baseConfig.DeepCopy()
|
||||||
|
testCase.mutateConfigFunc(config)
|
||||||
|
errs := Validate(config)
|
||||||
if len(testCase.expectedErrs) == 0 {
|
if len(testCase.expectedErrs) == 0 {
|
||||||
assert.Equal(t, field.ErrorList{}, errs, "expected no validation errors")
|
assert.Equal(t, field.ErrorList{}, errs, "expected no validation errors")
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user