mirror of
https://github.com/kubernetes/client-go.git
synced 2025-07-17 16:52:22 +00:00
Merge pull request #50579 from erhudy/bugfix/29271-accept-prefixed-namespaces
Automatic merge from submit-queue Fixes kubernetes/kubernetes#29271: accept prefixed namespaces **What this PR does / why we need it**: `kubectl get namespaces -o name` outputs the names of all namespaces, prefixed with `namespaces/`. This changeset allows these namespace names to be passed directly back in to `kubectl` via the `-n` flag without reprocessing them to remove `namespaces/`. **Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes #29271 **Special notes for your reviewer**: **Release note**: ```NONE ``` Kubernetes-commit: ab27bc9e6e020fc475b4872a6c049ac7fe91edbb
This commit is contained in:
commit
74549f85f4
@ -12,12 +12,14 @@ go_test(
|
|||||||
"client_config_test.go",
|
"client_config_test.go",
|
||||||
"loader_test.go",
|
"loader_test.go",
|
||||||
"merged_client_builder_test.go",
|
"merged_client_builder_test.go",
|
||||||
|
"overrides_test.go",
|
||||||
"validation_test.go",
|
"validation_test.go",
|
||||||
],
|
],
|
||||||
library = ":go_default_library",
|
library = ":go_default_library",
|
||||||
deps = [
|
deps = [
|
||||||
"//vendor/github.com/ghodss/yaml:go_default_library",
|
"//vendor/github.com/ghodss/yaml:go_default_library",
|
||||||
"//vendor/github.com/imdario/mergo:go_default_library",
|
"//vendor/github.com/imdario/mergo:go_default_library",
|
||||||
|
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||||
@ -33,6 +35,7 @@ go_library(
|
|||||||
"client_config.go",
|
"client_config.go",
|
||||||
"config.go",
|
"config.go",
|
||||||
"doc.go",
|
"doc.go",
|
||||||
|
"flag.go",
|
||||||
"helpers.go",
|
"helpers.go",
|
||||||
"loader.go",
|
"loader.go",
|
||||||
"merged_client_builder.go",
|
"merged_client_builder.go",
|
||||||
|
49
tools/clientcmd/flag.go
Normal file
49
tools/clientcmd/flag.go
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
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 clientcmd
|
||||||
|
|
||||||
|
// transformingStringValue implements pflag.Value to store string values,
|
||||||
|
// allowing transforming them while being set
|
||||||
|
type transformingStringValue struct {
|
||||||
|
target *string
|
||||||
|
transformer func(string) (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newTransformingStringValue(val string, target *string, transformer func(string) (string, error)) *transformingStringValue {
|
||||||
|
*target = val
|
||||||
|
return &transformingStringValue{
|
||||||
|
target: target,
|
||||||
|
transformer: transformer,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *transformingStringValue) Set(val string) error {
|
||||||
|
val, err := t.transformer(val)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*t.target = val
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *transformingStringValue) Type() string {
|
||||||
|
return "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *transformingStringValue) String() string {
|
||||||
|
return string(*t.target)
|
||||||
|
}
|
@ -18,6 +18,7 @@ package clientcmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
|
|
||||||
@ -101,6 +102,15 @@ func (f FlagInfo) BindStringFlag(flags *pflag.FlagSet, target *string) FlagInfo
|
|||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BindTransformingStringFlag binds the flag based on the provided info. If LongName == "", nothing is registered
|
||||||
|
func (f FlagInfo) BindTransformingStringFlag(flags *pflag.FlagSet, target *string, transformer func(string) (string, error)) FlagInfo {
|
||||||
|
// you can't register a flag without a long name
|
||||||
|
if len(f.LongName) > 0 {
|
||||||
|
flags.VarP(newTransformingStringValue(f.Default, target, transformer), f.LongName, f.ShortName, f.Description)
|
||||||
|
}
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
// BindStringSliceFlag binds the flag based on the provided info. If LongName == "", nothing is registered
|
// BindStringSliceFlag binds the flag based on the provided info. If LongName == "", nothing is registered
|
||||||
func (f FlagInfo) BindStringArrayFlag(flags *pflag.FlagSet, target *[]string) FlagInfo {
|
func (f FlagInfo) BindStringArrayFlag(flags *pflag.FlagSet, target *[]string) FlagInfo {
|
||||||
// you can't register a flag without a long name
|
// you can't register a flag without a long name
|
||||||
@ -222,5 +232,16 @@ func BindClusterFlags(clusterInfo *clientcmdapi.Cluster, flags *pflag.FlagSet, f
|
|||||||
func BindContextFlags(contextInfo *clientcmdapi.Context, flags *pflag.FlagSet, flagNames ContextOverrideFlags) {
|
func BindContextFlags(contextInfo *clientcmdapi.Context, flags *pflag.FlagSet, flagNames ContextOverrideFlags) {
|
||||||
flagNames.ClusterName.BindStringFlag(flags, &contextInfo.Cluster)
|
flagNames.ClusterName.BindStringFlag(flags, &contextInfo.Cluster)
|
||||||
flagNames.AuthInfoName.BindStringFlag(flags, &contextInfo.AuthInfo)
|
flagNames.AuthInfoName.BindStringFlag(flags, &contextInfo.AuthInfo)
|
||||||
flagNames.Namespace.BindStringFlag(flags, &contextInfo.Namespace)
|
flagNames.Namespace.BindTransformingStringFlag(flags, &contextInfo.Namespace, RemoveNamespacesPrefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveNamespacesPrefix is a transformer that strips "ns/", "namespace/" and "namespaces/" prefixes case-insensitively
|
||||||
|
func RemoveNamespacesPrefix(value string) (string, error) {
|
||||||
|
for _, prefix := range []string{"namespaces/", "namespace/", "ns/"} {
|
||||||
|
if len(value) > len(prefix) && strings.EqualFold(value[0:len(prefix)], prefix) {
|
||||||
|
value = value[len(prefix):]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value, nil
|
||||||
}
|
}
|
||||||
|
50
tools/clientcmd/overrides_test.go
Normal file
50
tools/clientcmd/overrides_test.go
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
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 clientcmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/spf13/pflag"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNamespacePrefixStrip(t *testing.T) {
|
||||||
|
testData := map[string]string{
|
||||||
|
"namespaces/foo": "foo",
|
||||||
|
"NAMESPACES/foo": "foo",
|
||||||
|
"NameSpaces/foo": "foo",
|
||||||
|
"namespace/foo": "foo",
|
||||||
|
"NAMESPACE/foo": "foo",
|
||||||
|
"nameSpace/foo": "foo",
|
||||||
|
"ns/foo": "foo",
|
||||||
|
"NS/foo": "foo",
|
||||||
|
"namespaces/": "namespaces/",
|
||||||
|
"namespace/": "namespace/",
|
||||||
|
"ns/": "ns/",
|
||||||
|
}
|
||||||
|
|
||||||
|
for before, after := range testData {
|
||||||
|
overrides := &ConfigOverrides{}
|
||||||
|
fs := &pflag.FlagSet{}
|
||||||
|
BindOverrideFlags(overrides, fs, RecommendedConfigOverrideFlags(""))
|
||||||
|
fs.Parse([]string{"--namespace", before})
|
||||||
|
|
||||||
|
if overrides.Context.Namespace != after {
|
||||||
|
t.Fatalf("Expected %s, got %s", after, overrides.Context.Namespace)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user