apiserver: add validation for EgressSelection names in EgressSelectorConfiguration API
Signed-off-by: Andrew Sy Kim <kim.andrewsy@gmail.com>
This commit is contained in:
		@@ -12,6 +12,7 @@ go_library(
 | 
				
			|||||||
    deps = [
 | 
					    deps = [
 | 
				
			||||||
        "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
 | 
					        "//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/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/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:go_default_library",
 | 
				
			||||||
        "//staging/src/k8s.io/apiserver/pkg/apis/apiserver/install:go_default_library",
 | 
					        "//staging/src/k8s.io/apiserver/pkg/apis/apiserver/install:go_default_library",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,6 +22,7 @@ import (
 | 
				
			|||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/runtime"
 | 
						"k8s.io/apimachinery/pkg/runtime"
 | 
				
			||||||
 | 
						"k8s.io/apimachinery/pkg/util/sets"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/util/validation/field"
 | 
						"k8s.io/apimachinery/pkg/util/validation/field"
 | 
				
			||||||
	"k8s.io/apiserver/pkg/apis/apiserver"
 | 
						"k8s.io/apiserver/pkg/apis/apiserver"
 | 
				
			||||||
	"k8s.io/apiserver/pkg/apis/apiserver/install"
 | 
						"k8s.io/apiserver/pkg/apis/apiserver/install"
 | 
				
			||||||
@@ -32,6 +33,10 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
var cfgScheme = runtime.NewScheme()
 | 
					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() {
 | 
					func init() {
 | 
				
			||||||
	install.Install(cfgScheme)
 | 
						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
 | 
						return allErrs
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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 {
 | 
						for _, tc := range testcases {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user