kube-proxy: internal config: refactor ClusterCIDR
Refactor ClusterCIDR for internal configuration of kube-proxy adhering to the v1alpha2 version specifications as detailed in https://kep.k8s.io/784. Signed-off-by: Daman Arora <aroradaman@gmail.com>
This commit is contained in:
@@ -36,11 +36,14 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
|
||||
BindAddress: "192.168.59.103",
|
||||
HealthzBindAddress: "0.0.0.0:10256",
|
||||
MetricsBindAddress: "127.0.0.1:10249",
|
||||
ClusterCIDR: "192.168.59.0/24",
|
||||
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
|
||||
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
|
||||
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
|
||||
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{},
|
||||
DetectLocalMode: kubeproxyconfig.LocalModeClusterCIDR,
|
||||
DetectLocal: kubeproxyconfig.DetectLocalConfiguration{
|
||||
ClusterCIDRs: []string{"192.168.59.0/24"},
|
||||
},
|
||||
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{
|
||||
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
|
||||
MaxPerCore: ptr.To[int32](1),
|
||||
@@ -82,7 +85,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
|
||||
config.BindAddress = "fd00:192:168:59::103"
|
||||
config.HealthzBindAddress = ""
|
||||
config.MetricsBindAddress = "[::1]:10249"
|
||||
config.ClusterCIDR = "fd00:192:168:59::/64"
|
||||
config.DetectLocal.ClusterCIDRs = []string{"fd00:192:168:59::/64"}
|
||||
},
|
||||
},
|
||||
"alternate healthz port": {
|
||||
@@ -92,12 +95,12 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
|
||||
},
|
||||
"ClusterCIDR is wrong IP family": {
|
||||
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
|
||||
config.ClusterCIDR = "fd00:192:168::/64"
|
||||
config.DetectLocal.ClusterCIDRs = []string{"fd00:192:168:59::/64"}
|
||||
},
|
||||
},
|
||||
"ClusterCIDR is dual-stack": {
|
||||
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": {
|
||||
@@ -134,18 +137,6 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
|
||||
},
|
||||
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": {
|
||||
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
|
||||
config.ConfigSyncPeriod = metav1.Duration{Duration: -1 * time.Second}
|
||||
@@ -172,24 +163,6 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
|
||||
},
|
||||
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("SyncPeriod"), metav1.Duration{Duration: 5 * time.Second}, "must be greater than or equal to KubeProxyConfiguration.MinSyncPeriod")},
|
||||
},
|
||||
"interfacePrefix is empty": {
|
||||
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
|
||||
config.DetectLocalMode = kubeproxyconfig.LocalModeInterfaceNamePrefix
|
||||
config.DetectLocal = kubeproxyconfig.DetectLocalConfiguration{
|
||||
InterfaceNamePrefix: "",
|
||||
}
|
||||
},
|
||||
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("InterfacePrefix"), "", "must not be empty")},
|
||||
},
|
||||
"bridgeInterfaceName is empty": {
|
||||
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
|
||||
config.DetectLocalMode = kubeproxyconfig.LocalModeBridgeInterface
|
||||
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")},
|
||||
},
|
||||
"invalid DetectLocalMode": {
|
||||
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
|
||||
config.DetectLocalMode = "Guess"
|
||||
@@ -764,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())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user