diff --git a/staging/src/k8s.io/apiserver/pkg/server/egressselector/BUILD b/staging/src/k8s.io/apiserver/pkg/server/egressselector/BUILD index bc730f43ff6..e9f44cd55c6 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/egressselector/BUILD +++ b/staging/src/k8s.io/apiserver/pkg/server/egressselector/BUILD @@ -12,6 +12,7 @@ go_library( deps = [ "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", "//staging/src/k8s.io/apiserver/pkg/apis/apiserver:go_default_library", "//staging/src/k8s.io/apiserver/pkg/apis/apiserver/install:go_default_library", diff --git a/staging/src/k8s.io/apiserver/pkg/server/egressselector/config.go b/staging/src/k8s.io/apiserver/pkg/server/egressselector/config.go index e608565c076..b7e378e430f 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/egressselector/config.go +++ b/staging/src/k8s.io/apiserver/pkg/server/egressselector/config.go @@ -22,6 +22,7 @@ import ( "strings" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apiserver/pkg/apis/apiserver" "k8s.io/apiserver/pkg/apis/apiserver/install" @@ -32,6 +33,10 @@ import ( var cfgScheme = runtime.NewScheme() +// validEgressSelectorNames contains the set of valid egress selctor names. +// 'master' is deprecated in favor of 'controlplane' and will be removed in v1.22. +var validEgressSelectorNames = sets.NewString("master", "controlplane", "cluster", "etcd") + func init() { install.Install(cfgScheme) } @@ -97,6 +102,30 @@ func ValidateEgressSelectorConfiguration(config *apiserver.EgressSelectorConfigu })) } } + + var foundControlPlane, foundMaster bool + for _, service := range config.EgressSelections { + canonicalName := strings.ToLower(service.Name) + + if !validEgressSelectorNames.Has(canonicalName) { + allErrs = append(allErrs, field.NotSupported(field.NewPath("egressSelection", "name"), canonicalName, validEgressSelectorNames.List())) + continue + } + + if canonicalName == "master" { + foundMaster = true + } + + if canonicalName == "controlplane" { + foundControlPlane = true + } + } + + // error if both master and controlplane egress selectors are set + if foundMaster && foundControlPlane { + allErrs = append(allErrs, field.Forbidden(field.NewPath("egressSelection", "name"), "both egressSelection names 'master' and 'controlplane' are specified, only one is allowed")) + } + return allErrs } diff --git a/staging/src/k8s.io/apiserver/pkg/server/egressselector/config_test.go b/staging/src/k8s.io/apiserver/pkg/server/egressselector/config_test.go index 9067938e7d5..2ddc3e69a81 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/egressselector/config_test.go +++ b/staging/src/k8s.io/apiserver/pkg/server/egressselector/config_test.go @@ -413,6 +413,48 @@ func TestValidateEgressSelectorConfiguration(t *testing.T) { }, }, }, + { + name: "invalid egress selection name", + expectError: true, + contents: &apiserver.EgressSelectorConfiguration{ + TypeMeta: metav1.TypeMeta{ + Kind: "", + APIVersion: "", + }, + EgressSelections: []apiserver.EgressSelection{ + { + Name: "invalid", + Connection: apiserver.Connection{ + ProxyProtocol: apiserver.ProtocolDirect, + }, + }, + }, + }, + }, + { + name: "both master and controlplane egress selection configured", + expectError: true, + contents: &apiserver.EgressSelectorConfiguration{ + TypeMeta: metav1.TypeMeta{ + Kind: "", + APIVersion: "", + }, + EgressSelections: []apiserver.EgressSelection{ + { + Name: "controlplane", + Connection: apiserver.Connection{ + ProxyProtocol: apiserver.ProtocolDirect, + }, + }, + { + Name: "master", + Connection: apiserver.Connection{ + ProxyProtocol: apiserver.ProtocolDirect, + }, + }, + }, + }, + }, } for _, tc := range testcases {