123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994 |
- /*
- Copyright 2017 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 (
- "fmt"
- "runtime"
- "strings"
- "testing"
- "time"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/util/validation/field"
- componentbaseconfig "k8s.io/component-base/config"
- kubeproxyconfig "k8s.io/kubernetes/pkg/proxy/apis/config"
- "k8s.io/utils/pointer"
- )
- func TestValidateKubeProxyConfiguration(t *testing.T) {
- var proxyMode kubeproxyconfig.ProxyMode
- if runtime.GOOS == "windows" {
- proxyMode = kubeproxyconfig.ProxyModeKernelspace
- } else {
- proxyMode = kubeproxyconfig.ProxyModeIPVS
- }
- successCases := []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",
- UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
- 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: pointer.Int32Ptr(1),
- Min: pointer.Int32Ptr(1),
- TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
- TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
- },
- },
- {
- BindAddress: "192.168.59.103",
- HealthzBindAddress: "0.0.0.0:10256",
- MetricsBindAddress: "127.0.0.1:10249",
- ClusterCIDR: "192.168.59.0/24",
- UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
- 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: pointer.Int32Ptr(1),
- Min: pointer.Int32Ptr(1),
- TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
- TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
- },
- },
- {
- BindAddress: "192.168.59.103",
- HealthzBindAddress: "",
- MetricsBindAddress: "127.0.0.1:10249",
- ClusterCIDR: "192.168.59.0/24",
- UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
- 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: pointer.Int32Ptr(1),
- Min: pointer.Int32Ptr(1),
- TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
- TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
- },
- },
- {
- BindAddress: "fd00:192:168:59::103",
- HealthzBindAddress: "",
- MetricsBindAddress: "[::1]:10249",
- ClusterCIDR: "fd00:192:168:59::/64",
- UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
- 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: pointer.Int32Ptr(1),
- Min: pointer.Int32Ptr(1),
- TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
- TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
- },
- },
- {
- BindAddress: "10.10.12.11",
- HealthzBindAddress: "0.0.0.0:12345",
- MetricsBindAddress: "127.0.0.1:10249",
- FeatureGates: map[string]bool{"IPv6DualStack": true},
- ClusterCIDR: "192.168.59.0/24",
- UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
- 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: pointer.Int32Ptr(1),
- Min: pointer.Int32Ptr(1),
- TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
- TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
- },
- },
- {
- BindAddress: "10.10.12.11",
- HealthzBindAddress: "0.0.0.0:12345",
- MetricsBindAddress: "127.0.0.1:10249",
- FeatureGates: map[string]bool{"IPv6DualStack": true},
- ClusterCIDR: "fd00:192:168::/64",
- UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
- 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: pointer.Int32Ptr(1),
- Min: pointer.Int32Ptr(1),
- TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
- TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
- },
- },
- {
- BindAddress: "10.10.12.11",
- HealthzBindAddress: "0.0.0.0:12345",
- MetricsBindAddress: "127.0.0.1:10249",
- FeatureGates: map[string]bool{"IPv6DualStack": true},
- ClusterCIDR: "192.168.59.0/24,fd00:192:168::/64",
- UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
- 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: pointer.Int32Ptr(1),
- Min: pointer.Int32Ptr(1),
- TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
- TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
- },
- },
- }
- for _, successCase := range successCases {
- if errs := Validate(&successCase); len(errs) != 0 {
- t.Errorf("expected success: %v", errs)
- }
- }
- errorCases := []struct {
- config kubeproxyconfig.KubeProxyConfiguration
- msg string
- }{
- {
- config: kubeproxyconfig.KubeProxyConfiguration{
- // only BindAddress is invalid
- BindAddress: "10.10.12.11:2000",
- HealthzBindAddress: "0.0.0.0:10256",
- MetricsBindAddress: "127.0.0.1:10249",
- ClusterCIDR: "192.168.59.0/24",
- UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
- 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: pointer.Int32Ptr(1),
- Min: pointer.Int32Ptr(1),
- TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
- TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
- },
- },
- msg: "not a valid textual representation of an IP address",
- },
- {
- config: kubeproxyconfig.KubeProxyConfiguration{
- BindAddress: "10.10.12.11",
- // only HealthzBindAddress is invalid
- HealthzBindAddress: "0.0.0.0",
- MetricsBindAddress: "127.0.0.1:10249",
- ClusterCIDR: "192.168.59.0/24",
- UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
- 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: pointer.Int32Ptr(1),
- Min: pointer.Int32Ptr(1),
- TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
- TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
- },
- },
- msg: "must be IP:port",
- },
- {
- config: kubeproxyconfig.KubeProxyConfiguration{
- BindAddress: "10.10.12.11",
- HealthzBindAddress: "0.0.0.0:12345",
- // only MetricsBindAddress is invalid
- MetricsBindAddress: "127.0.0.1",
- ClusterCIDR: "192.168.59.0/24",
- UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
- 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: pointer.Int32Ptr(1),
- Min: pointer.Int32Ptr(1),
- TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
- TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
- },
- },
- msg: "must be IP:port",
- },
- {
- config: kubeproxyconfig.KubeProxyConfiguration{
- BindAddress: "10.10.12.11",
- HealthzBindAddress: "0.0.0.0:12345",
- MetricsBindAddress: "127.0.0.1:10249",
- // only ClusterCIDR is invalid
- ClusterCIDR: "192.168.59.0",
- UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
- 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: pointer.Int32Ptr(1),
- Min: pointer.Int32Ptr(1),
- TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
- TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
- },
- },
- msg: "must be a valid CIDR block (e.g. 10.100.0.0/16 or fde4:8dba:82e1::/48)",
- },
- {
- config: kubeproxyconfig.KubeProxyConfiguration{
- BindAddress: "10.10.12.11",
- HealthzBindAddress: "0.0.0.0:12345",
- MetricsBindAddress: "127.0.0.1:10249",
- // DualStack ClusterCIDR without feature flag enabled
- FeatureGates: map[string]bool{"IPv6DualStack": false},
- ClusterCIDR: "192.168.59.0/24,fd00:192:168::/64",
- UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
- 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: pointer.Int32Ptr(1),
- Min: pointer.Int32Ptr(1),
- TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
- TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
- },
- },
- msg: "only one CIDR allowed (e.g. 10.100.0.0/16 or fde4:8dba:82e1::/48)",
- },
- {
- config: kubeproxyconfig.KubeProxyConfiguration{
- BindAddress: "10.10.12.11",
- HealthzBindAddress: "0.0.0.0:12345",
- MetricsBindAddress: "127.0.0.1:10249",
- // DualStack with multiple CIDRs but only one IP family
- FeatureGates: map[string]bool{"IPv6DualStack": true},
- ClusterCIDR: "192.168.59.0/24,10.0.0.0/16",
- UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
- 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: pointer.Int32Ptr(1),
- Min: pointer.Int32Ptr(1),
- TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
- TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
- },
- },
- msg: "must be a valid DualStack CIDR (e.g. 10.100.0.0/16,fde4:8dba:82e1::/48)",
- },
- {
- config: kubeproxyconfig.KubeProxyConfiguration{
- BindAddress: "10.10.12.11",
- HealthzBindAddress: "0.0.0.0:12345",
- MetricsBindAddress: "127.0.0.1:10249",
- // DualStack with an invalid subnet
- FeatureGates: map[string]bool{"IPv6DualStack": true},
- ClusterCIDR: "192.168.59.0/24,fd00:192:168::/64,a.b.c.d/f",
- UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
- 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: pointer.Int32Ptr(1),
- Min: pointer.Int32Ptr(1),
- TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
- TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
- },
- },
- msg: "only one CIDR allowed or a valid DualStack CIDR (e.g. 10.100.0.0/16,fde4:8dba:82e1::/48)",
- },
- {
- config: kubeproxyconfig.KubeProxyConfiguration{
- BindAddress: "10.10.12.11",
- HealthzBindAddress: "0.0.0.0:12345",
- MetricsBindAddress: "127.0.0.1:10249",
- FeatureGates: map[string]bool{"IPv6DualStack": true},
- ClusterCIDR: "192.168.59.0/24,fd00:192:168::/64,10.0.0.0/16",
- UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
- 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: pointer.Int32Ptr(1),
- Min: pointer.Int32Ptr(1),
- TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
- TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
- },
- },
- msg: "only one CIDR allowed or a valid DualStack CIDR (e.g. 10.100.0.0/16,fde4:8dba:82e1::/48)",
- },
- {
- config: kubeproxyconfig.KubeProxyConfiguration{
- BindAddress: "10.10.12.11",
- HealthzBindAddress: "0.0.0.0:12345",
- MetricsBindAddress: "127.0.0.1:10249",
- ClusterCIDR: "192.168.59.0/24",
- // only UDPIdleTimeout is invalid
- UDPIdleTimeout: metav1.Duration{Duration: -1 * time.Second},
- 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: pointer.Int32Ptr(1),
- Min: pointer.Int32Ptr(1),
- TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
- TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
- },
- },
- msg: "must be greater than 0",
- },
- {
- config: kubeproxyconfig.KubeProxyConfiguration{
- BindAddress: "10.10.12.11",
- HealthzBindAddress: "0.0.0.0:12345",
- MetricsBindAddress: "127.0.0.1:10249",
- ClusterCIDR: "192.168.59.0/24",
- UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
- // only ConfigSyncPeriod is invalid
- 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: pointer.Int32Ptr(1),
- Min: pointer.Int32Ptr(1),
- TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
- TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
- },
- },
- msg: "must be greater than 0",
- },
- {
- 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",
- UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
- 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: pointer.Int32Ptr(1),
- Min: pointer.Int32Ptr(1),
- TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
- TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
- },
- },
- msg: "must be greater than 0",
- },
- }
- for _, errorCase := range errorCases {
- if errs := Validate(&errorCase.config); len(errs) == 0 {
- t.Errorf("expected failure for %s", errorCase.msg)
- } else if !strings.Contains(errs[0].Error(), errorCase.msg) {
- t.Errorf("unexpected error: %v, expected: %s", errs[0], errorCase.msg)
- }
- }
- }
- func TestValidateKubeProxyIPTablesConfiguration(t *testing.T) {
- valid := int32(5)
- successCases := []kubeproxyconfig.KubeProxyIPTablesConfiguration{
- {
- MasqueradeAll: true,
- SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
- MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
- },
- {
- MasqueradeBit: &valid,
- MasqueradeAll: true,
- SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
- MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
- },
- }
- newPath := field.NewPath("KubeProxyConfiguration")
- for _, successCase := range successCases {
- if errs := validateKubeProxyIPTablesConfiguration(successCase, newPath.Child("KubeProxyIPTablesConfiguration")); len(errs) != 0 {
- t.Errorf("expected success: %v", errs)
- }
- }
- invalid := int32(-10)
- errorCases := []struct {
- config kubeproxyconfig.KubeProxyIPTablesConfiguration
- msg string
- }{
- {
- config: kubeproxyconfig.KubeProxyIPTablesConfiguration{
- MasqueradeAll: true,
- SyncPeriod: metav1.Duration{Duration: -5 * time.Second},
- MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
- },
- msg: "must be greater than 0",
- },
- {
- config: kubeproxyconfig.KubeProxyIPTablesConfiguration{
- MasqueradeBit: &valid,
- MasqueradeAll: true,
- SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
- MinSyncPeriod: metav1.Duration{Duration: -1 * time.Second},
- },
- msg: "must be greater than or equal to 0",
- },
- {
- config: kubeproxyconfig.KubeProxyIPTablesConfiguration{
- MasqueradeBit: &invalid,
- MasqueradeAll: true,
- SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
- MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
- },
- msg: "must be within the range [0, 31]",
- },
- // SyncPeriod must be >= MinSyncPeriod
- {
- config: kubeproxyconfig.KubeProxyIPTablesConfiguration{
- MasqueradeBit: &valid,
- MasqueradeAll: true,
- SyncPeriod: metav1.Duration{Duration: 1 * time.Second},
- MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
- },
- msg: fmt.Sprintf("must be greater than or equal to %s", newPath.Child("KubeProxyIPTablesConfiguration").Child("MinSyncPeriod").String()),
- },
- }
- for _, errorCase := range errorCases {
- if errs := validateKubeProxyIPTablesConfiguration(errorCase.config, newPath.Child("KubeProxyIPTablesConfiguration")); len(errs) == 0 {
- t.Errorf("expected failure for %s", errorCase.msg)
- } else if !strings.Contains(errs[0].Error(), errorCase.msg) {
- t.Errorf("unexpected error: %v, expected: %s", errs[0], errorCase.msg)
- }
- }
- }
- func TestValidateKubeProxyIPVSConfiguration(t *testing.T) {
- newPath := field.NewPath("KubeProxyConfiguration")
- testCases := []struct {
- config kubeproxyconfig.KubeProxyIPVSConfiguration
- expectErr bool
- reason string
- }{
- {
- config: kubeproxyconfig.KubeProxyIPVSConfiguration{
- SyncPeriod: metav1.Duration{Duration: -5 * time.Second},
- MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
- },
- expectErr: true,
- reason: "SyncPeriod must be greater than 0",
- },
- {
- config: kubeproxyconfig.KubeProxyIPVSConfiguration{
- SyncPeriod: metav1.Duration{Duration: 0 * time.Second},
- MinSyncPeriod: metav1.Duration{Duration: 10 * time.Second},
- },
- expectErr: true,
- reason: "SyncPeriod must be greater than 0",
- },
- {
- config: kubeproxyconfig.KubeProxyIPVSConfiguration{
- SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
- MinSyncPeriod: metav1.Duration{Duration: -1 * time.Second},
- },
- expectErr: true,
- reason: "MinSyncPeriod must be greater than or equal to 0",
- },
- {
- config: kubeproxyconfig.KubeProxyIPVSConfiguration{
- SyncPeriod: metav1.Duration{Duration: 1 * time.Second},
- MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
- },
- expectErr: true,
- reason: "SyncPeriod must be greater than or equal to MinSyncPeriod",
- },
- // SyncPeriod == MinSyncPeriod
- {
- config: kubeproxyconfig.KubeProxyIPVSConfiguration{
- SyncPeriod: metav1.Duration{Duration: 10 * time.Second},
- MinSyncPeriod: metav1.Duration{Duration: 10 * time.Second},
- },
- expectErr: false,
- },
- // SyncPeriod > MinSyncPeriod
- {
- config: kubeproxyconfig.KubeProxyIPVSConfiguration{
- SyncPeriod: metav1.Duration{Duration: 10 * time.Second},
- MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
- },
- expectErr: false,
- },
- // SyncPeriod can be 0
- {
- config: kubeproxyconfig.KubeProxyIPVSConfiguration{
- SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
- MinSyncPeriod: metav1.Duration{Duration: 0 * time.Second},
- },
- expectErr: false,
- },
- }
- for _, test := range testCases {
- errs := validateKubeProxyIPVSConfiguration(test.config, newPath.Child("KubeProxyIPVSConfiguration"))
- if len(errs) == 0 && test.expectErr {
- t.Errorf("Expect error, got nil, reason: %s", test.reason)
- }
- if len(errs) > 0 && !test.expectErr {
- t.Errorf("Unexpected error: %v", errs)
- }
- }
- }
- func TestValidateKubeProxyConntrackConfiguration(t *testing.T) {
- successCases := []kubeproxyconfig.KubeProxyConntrackConfiguration{
- {
- MaxPerCore: pointer.Int32Ptr(1),
- Min: pointer.Int32Ptr(1),
- TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
- TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
- },
- {
- MaxPerCore: pointer.Int32Ptr(0),
- Min: pointer.Int32Ptr(0),
- TCPEstablishedTimeout: &metav1.Duration{Duration: 0 * time.Second},
- TCPCloseWaitTimeout: &metav1.Duration{Duration: 0 * time.Second},
- },
- }
- newPath := field.NewPath("KubeProxyConfiguration")
- for _, successCase := range successCases {
- if errs := validateKubeProxyConntrackConfiguration(successCase, newPath.Child("KubeProxyConntrackConfiguration")); len(errs) != 0 {
- t.Errorf("expected success: %v", errs)
- }
- }
- errorCases := []struct {
- config kubeproxyconfig.KubeProxyConntrackConfiguration
- msg string
- }{
- {
- config: kubeproxyconfig.KubeProxyConntrackConfiguration{
- MaxPerCore: pointer.Int32Ptr(-1),
- Min: pointer.Int32Ptr(1),
- TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
- TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
- },
- msg: "must be greater than or equal to 0",
- },
- {
- config: kubeproxyconfig.KubeProxyConntrackConfiguration{
- MaxPerCore: pointer.Int32Ptr(1),
- Min: pointer.Int32Ptr(-1),
- TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
- TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
- },
- msg: "must be greater than or equal to 0",
- },
- {
- config: kubeproxyconfig.KubeProxyConntrackConfiguration{
- MaxPerCore: pointer.Int32Ptr(1),
- Min: pointer.Int32Ptr(3),
- TCPEstablishedTimeout: &metav1.Duration{Duration: -5 * time.Second},
- TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
- },
- msg: "must be greater than or equal to 0",
- },
- {
- config: kubeproxyconfig.KubeProxyConntrackConfiguration{
- MaxPerCore: pointer.Int32Ptr(1),
- Min: pointer.Int32Ptr(3),
- TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
- TCPCloseWaitTimeout: &metav1.Duration{Duration: -5 * time.Second},
- },
- msg: "must be greater than or equal to 0",
- },
- }
- for _, errorCase := range errorCases {
- if errs := validateKubeProxyConntrackConfiguration(errorCase.config, newPath.Child("KubeProxyConntrackConfiguration")); len(errs) == 0 {
- t.Errorf("expected failure for %s", errorCase.msg)
- } else if !strings.Contains(errs[0].Error(), errorCase.msg) {
- t.Errorf("unexpected error: %v, expected: %s", errs[0], errorCase.msg)
- }
- }
- }
- func TestValidateProxyMode(t *testing.T) {
- newPath := field.NewPath("KubeProxyConfiguration")
- successCases := []kubeproxyconfig.ProxyMode{
- kubeproxyconfig.ProxyModeUserspace,
- kubeproxyconfig.ProxyMode(""),
- }
- if runtime.GOOS == "windows" {
- successCases = append(successCases, kubeproxyconfig.ProxyModeKernelspace)
- } else {
- successCases = append(successCases, kubeproxyconfig.ProxyModeIPTables, kubeproxyconfig.ProxyModeIPVS)
- }
- for _, successCase := range successCases {
- if errs := validateProxyMode(successCase, newPath.Child("ProxyMode")); len(errs) != 0 {
- t.Errorf("expected success: %v", errs)
- }
- }
- errorCases := []struct {
- mode kubeproxyconfig.ProxyMode
- msg string
- }{
- {
- mode: kubeproxyconfig.ProxyMode("non-existing"),
- msg: "or blank (blank means the",
- },
- }
- for _, errorCase := range errorCases {
- if errs := validateProxyMode(errorCase.mode, newPath.Child("ProxyMode")); len(errs) == 0 {
- t.Errorf("expected failure %s for %v", errorCase.msg, errorCase.mode)
- } else if !strings.Contains(errs[0].Error(), errorCase.msg) {
- t.Errorf("unexpected error: %v, expected: %s", errs[0], errorCase.msg)
- }
- }
- }
- func TestValidateClientConnectionConfiguration(t *testing.T) {
- newPath := field.NewPath("KubeProxyConfiguration")
- successCases := []componentbaseconfig.ClientConnectionConfiguration{
- {
- Burst: 0,
- },
- {
- Burst: 5,
- },
- }
- for _, successCase := range successCases {
- if errs := validateClientConnectionConfiguration(successCase, newPath.Child("Burst")); len(errs) != 0 {
- t.Errorf("expected success: %v", errs)
- }
- }
- errorCases := []struct {
- ccc componentbaseconfig.ClientConnectionConfiguration
- msg string
- }{
- {
- ccc: componentbaseconfig.ClientConnectionConfiguration{Burst: -5},
- msg: "must be greater than or equal to 0",
- },
- }
- for _, errorCase := range errorCases {
- if errs := validateClientConnectionConfiguration(errorCase.ccc, newPath.Child("Burst")); len(errs) == 0 {
- t.Errorf("expected failure for %s", errorCase.msg)
- } else if !strings.Contains(errs[0].Error(), errorCase.msg) {
- t.Errorf("unexpected error: %v, expected: %s", errs[0], errorCase.msg)
- }
- }
- }
- func TestValidateHostPort(t *testing.T) {
- newPath := field.NewPath("KubeProxyConfiguration")
- successCases := []string{
- "0.0.0.0:10256",
- "127.0.0.1:10256",
- "10.10.10.10:10256",
- }
- for _, successCase := range successCases {
- if errs := validateHostPort(successCase, newPath.Child("HealthzBindAddress")); len(errs) != 0 {
- t.Errorf("expected success: %v", errs)
- }
- }
- errorCases := []struct {
- ccc string
- msg string
- }{
- {
- ccc: "10.10.10.10",
- msg: "must be IP:port",
- },
- {
- ccc: "123.456.789.10:12345",
- msg: "must be a valid IP",
- },
- {
- ccc: "10.10.10.10:foo",
- msg: "must be a valid port",
- },
- {
- ccc: "10.10.10.10:0",
- msg: "must be a valid port",
- },
- {
- ccc: "10.10.10.10:65536",
- msg: "must be a valid port",
- },
- }
- for _, errorCase := range errorCases {
- if errs := validateHostPort(errorCase.ccc, newPath.Child("HealthzBindAddress")); len(errs) == 0 {
- t.Errorf("expected failure for %s", errorCase.msg)
- } else if !strings.Contains(errs[0].Error(), errorCase.msg) {
- t.Errorf("unexpected error: %v, expected: %s", errs[0], errorCase.msg)
- }
- }
- }
- func TestValidateIPVSSchedulerMethod(t *testing.T) {
- newPath := field.NewPath("KubeProxyConfiguration")
- successCases := []kubeproxyconfig.IPVSSchedulerMethod{
- kubeproxyconfig.RoundRobin,
- kubeproxyconfig.WeightedRoundRobin,
- kubeproxyconfig.LeastConnection,
- kubeproxyconfig.WeightedLeastConnection,
- kubeproxyconfig.LocalityBasedLeastConnection,
- kubeproxyconfig.LocalityBasedLeastConnectionWithReplication,
- kubeproxyconfig.SourceHashing,
- kubeproxyconfig.DestinationHashing,
- kubeproxyconfig.ShortestExpectedDelay,
- kubeproxyconfig.NeverQueue,
- "",
- }
- for _, successCase := range successCases {
- if errs := validateIPVSSchedulerMethod(successCase, newPath.Child("Scheduler")); len(errs) != 0 {
- t.Errorf("expected success: %v", errs)
- }
- }
- errorCases := []struct {
- mode kubeproxyconfig.IPVSSchedulerMethod
- msg string
- }{
- {
- mode: kubeproxyconfig.IPVSSchedulerMethod("non-existing"),
- msg: "blank means the default algorithm method (currently rr)",
- },
- }
- for _, errorCase := range errorCases {
- if errs := validateIPVSSchedulerMethod(errorCase.mode, newPath.Child("ProxyMode")); len(errs) == 0 {
- t.Errorf("expected failure for %s", errorCase.msg)
- } else if !strings.Contains(errs[0].Error(), errorCase.msg) {
- t.Errorf("unexpected error: %v, expected: %s", errs[0], errorCase.msg)
- }
- }
- }
- func TestValidateKubeProxyNodePortAddress(t *testing.T) {
- newPath := field.NewPath("KubeProxyConfiguration")
- successCases := []struct {
- addresses []string
- }{
- {[]string{}},
- {[]string{"127.0.0.0/8"}},
- {[]string{"0.0.0.0/0"}},
- {[]string{"::/0"}},
- {[]string{"127.0.0.1/32", "1.2.3.0/24"}},
- {[]string{"127.0.0.0/8"}},
- {[]string{"127.0.0.1/32"}},
- {[]string{"::1/128"}},
- {[]string{"1.2.3.4/32"}},
- {[]string{"10.20.30.0/24"}},
- {[]string{"10.20.0.0/16", "100.200.0.0/16"}},
- {[]string{"10.0.0.0/8"}},
- {[]string{"2001:db8::/32"}},
- }
- for _, successCase := range successCases {
- if errs := validateKubeProxyNodePortAddress(successCase.addresses, newPath.Child("NodePortAddresses")); len(errs) != 0 {
- t.Errorf("expected success: %v", errs)
- }
- }
- errorCases := []struct {
- addresses []string
- msg string
- }{
- {
- addresses: []string{"foo"},
- msg: "must be a valid IP block",
- },
- {
- addresses: []string{"1.2.3"},
- msg: "must be a valid IP block",
- },
- {
- addresses: []string{""},
- msg: "must be a valid IP block",
- },
- {
- addresses: []string{"10.20.30.40"},
- msg: "must be a valid IP block",
- },
- {
- addresses: []string{"::1"},
- msg: "must be a valid IP block",
- },
- {
- addresses: []string{"2001:db8:1"},
- msg: "must be a valid IP block",
- },
- {
- addresses: []string{"2001:db8:xyz/64"},
- msg: "must be a valid IP block",
- },
- }
- for _, errorCase := range errorCases {
- if errs := validateKubeProxyNodePortAddress(errorCase.addresses, newPath.Child("NodePortAddresses")); len(errs) == 0 {
- t.Errorf("expected failure for %s", errorCase.msg)
- } else if !strings.Contains(errs[0].Error(), errorCase.msg) {
- t.Errorf("unexpected error: %v, expected: %s", errs[0], errorCase.msg)
- }
- }
- }
- func TestValidateKubeProxyExcludeCIDRs(t *testing.T) {
- // TODO(rramkumar): This test is a copy of TestValidateKubeProxyNodePortAddress.
- // Maybe some code can be shared?
- newPath := field.NewPath("KubeProxyConfiguration")
- successCases := []struct {
- addresses []string
- }{
- {[]string{}},
- {[]string{"127.0.0.0/8"}},
- {[]string{"0.0.0.0/0"}},
- {[]string{"::/0"}},
- {[]string{"127.0.0.1/32", "1.2.3.0/24"}},
- {[]string{"127.0.0.0/8"}},
- {[]string{"127.0.0.1/32"}},
- {[]string{"::1/128"}},
- {[]string{"1.2.3.4/32"}},
- {[]string{"10.20.30.0/24"}},
- {[]string{"10.20.0.0/16", "100.200.0.0/16"}},
- {[]string{"10.0.0.0/8"}},
- {[]string{"2001:db8::/32"}},
- }
- for _, successCase := range successCases {
- if errs := validateIPVSExcludeCIDRs(successCase.addresses, newPath.Child("ExcludeCIDRs")); len(errs) != 0 {
- t.Errorf("expected success: %v", errs)
- }
- }
- errorCases := []struct {
- addresses []string
- msg string
- }{
- {
- addresses: []string{"foo"},
- msg: "must be a valid IP block",
- },
- {
- addresses: []string{"1.2.3"},
- msg: "must be a valid IP block",
- },
- {
- addresses: []string{""},
- msg: "must be a valid IP block",
- },
- {
- addresses: []string{"10.20.30.40"},
- msg: "must be a valid IP block",
- },
- {
- addresses: []string{"::1"},
- msg: "must be a valid IP block",
- },
- {
- addresses: []string{"2001:db8:1"},
- msg: "must be a valid IP block",
- },
- {
- addresses: []string{"2001:db8:xyz/64"},
- msg: "must be a valid IP block",
- },
- }
- for _, errorCase := range errorCases {
- if errs := validateIPVSExcludeCIDRs(errorCase.addresses, newPath.Child("ExcludeCIDRs")); len(errs) == 0 {
- t.Errorf("expected failure for %s", errorCase.msg)
- } else if !strings.Contains(errs[0].Error(), errorCase.msg) {
- t.Errorf("unexpected error: %v, expected: %s", errs[0], errorCase.msg)
- }
- }
- }
|