mirror of
https://github.com/kubernetes/client-go.git
synced 2025-08-11 12:11:52 +00:00
Merge pull request #105794 from margocrawf/master
--as-uid flag in kubectl and kubeconfigs. Kubernetes-commit: c9baa14d708415225ed030e520970b3e1b6e4349
This commit is contained in:
commit
6d69eb8ad6
4
go.mod
4
go.mod
@ -31,7 +31,7 @@ require (
|
|||||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac
|
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac
|
||||||
google.golang.org/protobuf v1.26.0
|
google.golang.org/protobuf v1.26.0
|
||||||
k8s.io/api v0.0.0-20211104203923-7979b39b3911
|
k8s.io/api v0.0.0-20211104203923-7979b39b3911
|
||||||
k8s.io/apimachinery v0.0.0-20211104003341-94020522c95c
|
k8s.io/apimachinery v0.0.0-20211105203412-d7e096fd217f
|
||||||
k8s.io/klog/v2 v2.30.0
|
k8s.io/klog/v2 v2.30.0
|
||||||
k8s.io/kube-openapi v0.0.0-20210817084001-7fbd8d59e5b8
|
k8s.io/kube-openapi v0.0.0-20210817084001-7fbd8d59e5b8
|
||||||
k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b
|
k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b
|
||||||
@ -41,5 +41,5 @@ require (
|
|||||||
|
|
||||||
replace (
|
replace (
|
||||||
k8s.io/api => k8s.io/api v0.0.0-20211104203923-7979b39b3911
|
k8s.io/api => k8s.io/api v0.0.0-20211104203923-7979b39b3911
|
||||||
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20211104003341-94020522c95c
|
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20211105203412-d7e096fd217f
|
||||||
)
|
)
|
||||||
|
4
go.sum
4
go.sum
@ -600,8 +600,8 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
|
|||||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
k8s.io/api v0.0.0-20211104203923-7979b39b3911 h1:KKASx2y52X9MofhS6vOnUdLGgz+CH8/OxZrJsG7lnk4=
|
k8s.io/api v0.0.0-20211104203923-7979b39b3911 h1:KKASx2y52X9MofhS6vOnUdLGgz+CH8/OxZrJsG7lnk4=
|
||||||
k8s.io/api v0.0.0-20211104203923-7979b39b3911/go.mod h1:Y3aSuR3Z7RwvAGbnpQ1+oBIWgAIxvlHcaUCVUzOgpuo=
|
k8s.io/api v0.0.0-20211104203923-7979b39b3911/go.mod h1:Y3aSuR3Z7RwvAGbnpQ1+oBIWgAIxvlHcaUCVUzOgpuo=
|
||||||
k8s.io/apimachinery v0.0.0-20211104003341-94020522c95c h1:18i+Svc8AQt2tsHgUJjMgipgIRROqVsdttom0N2URHQ=
|
k8s.io/apimachinery v0.0.0-20211105203412-d7e096fd217f h1:GhfOaNapo86CszGIgYEv2kO136l13jxtg9Ollcge114=
|
||||||
k8s.io/apimachinery v0.0.0-20211104003341-94020522c95c/go.mod h1:NdmIf2dMPBkkSfPmCDRbThro3RAWWypv6x+CttBbMto=
|
k8s.io/apimachinery v0.0.0-20211105203412-d7e096fd217f/go.mod h1:NdmIf2dMPBkkSfPmCDRbThro3RAWWypv6x+CttBbMto=
|
||||||
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||||
k8s.io/klog/v2 v2.30.0 h1:bUO6drIvCIsvZ/XFgfxoGFQU/a4Qkh0iAlvUR7vlHJw=
|
k8s.io/klog/v2 v2.30.0 h1:bUO6drIvCIsvZ/XFgfxoGFQU/a4Qkh0iAlvUR7vlHJw=
|
||||||
|
@ -124,7 +124,10 @@ type AuthInfo struct {
|
|||||||
// Impersonate is the username to act-as.
|
// Impersonate is the username to act-as.
|
||||||
// +optional
|
// +optional
|
||||||
Impersonate string `json:"act-as,omitempty"`
|
Impersonate string `json:"act-as,omitempty"`
|
||||||
// ImpersonateGroups is the groups to imperonate.
|
// ImpersonateUID is the uid to impersonate.
|
||||||
|
// +optional
|
||||||
|
ImpersonateUID string `json:"act-as-uid,omitempty"`
|
||||||
|
// ImpersonateGroups is the groups to impersonate.
|
||||||
// +optional
|
// +optional
|
||||||
ImpersonateGroups []string `json:"act-as-groups,omitempty"`
|
ImpersonateGroups []string `json:"act-as-groups,omitempty"`
|
||||||
// ImpersonateUserExtra contains additional information for impersonated user.
|
// ImpersonateUserExtra contains additional information for impersonated user.
|
||||||
|
@ -111,10 +111,13 @@ type AuthInfo struct {
|
|||||||
// TokenFile is a pointer to a file that contains a bearer token (as described above). If both Token and TokenFile are present, Token takes precedence.
|
// TokenFile is a pointer to a file that contains a bearer token (as described above). If both Token and TokenFile are present, Token takes precedence.
|
||||||
// +optional
|
// +optional
|
||||||
TokenFile string `json:"tokenFile,omitempty"`
|
TokenFile string `json:"tokenFile,omitempty"`
|
||||||
// Impersonate is the username to imperonate. The name matches the flag.
|
// Impersonate is the username to impersonate. The name matches the flag.
|
||||||
// +optional
|
// +optional
|
||||||
Impersonate string `json:"as,omitempty"`
|
Impersonate string `json:"as,omitempty"`
|
||||||
// ImpersonateGroups is the groups to imperonate.
|
// ImpersonateUID is the uid to impersonate.
|
||||||
|
// +optional
|
||||||
|
ImpersonateUID string `json:"as-uid,omitempty"`
|
||||||
|
// ImpersonateGroups is the groups to impersonate.
|
||||||
// +optional
|
// +optional
|
||||||
ImpersonateGroups []string `json:"as-groups,omitempty"`
|
ImpersonateGroups []string `json:"as-groups,omitempty"`
|
||||||
// ImpersonateUserExtra contains additional information for impersonated user.
|
// ImpersonateUserExtra contains additional information for impersonated user.
|
||||||
|
@ -167,6 +167,7 @@ func autoConvert_v1_AuthInfo_To_api_AuthInfo(in *AuthInfo, out *api.AuthInfo, s
|
|||||||
out.Token = in.Token
|
out.Token = in.Token
|
||||||
out.TokenFile = in.TokenFile
|
out.TokenFile = in.TokenFile
|
||||||
out.Impersonate = in.Impersonate
|
out.Impersonate = in.Impersonate
|
||||||
|
out.ImpersonateUID = in.ImpersonateUID
|
||||||
out.ImpersonateGroups = *(*[]string)(unsafe.Pointer(&in.ImpersonateGroups))
|
out.ImpersonateGroups = *(*[]string)(unsafe.Pointer(&in.ImpersonateGroups))
|
||||||
out.ImpersonateUserExtra = *(*map[string][]string)(unsafe.Pointer(&in.ImpersonateUserExtra))
|
out.ImpersonateUserExtra = *(*map[string][]string)(unsafe.Pointer(&in.ImpersonateUserExtra))
|
||||||
out.Username = in.Username
|
out.Username = in.Username
|
||||||
@ -201,6 +202,7 @@ func autoConvert_api_AuthInfo_To_v1_AuthInfo(in *api.AuthInfo, out *AuthInfo, s
|
|||||||
out.Token = in.Token
|
out.Token = in.Token
|
||||||
out.TokenFile = in.TokenFile
|
out.TokenFile = in.TokenFile
|
||||||
out.Impersonate = in.Impersonate
|
out.Impersonate = in.Impersonate
|
||||||
|
out.ImpersonateUID = in.ImpersonateUID
|
||||||
out.ImpersonateGroups = *(*[]string)(unsafe.Pointer(&in.ImpersonateGroups))
|
out.ImpersonateGroups = *(*[]string)(unsafe.Pointer(&in.ImpersonateGroups))
|
||||||
out.ImpersonateUserExtra = *(*map[string][]string)(unsafe.Pointer(&in.ImpersonateUserExtra))
|
out.ImpersonateUserExtra = *(*map[string][]string)(unsafe.Pointer(&in.ImpersonateUserExtra))
|
||||||
out.Username = in.Username
|
out.Username = in.Username
|
||||||
|
@ -181,6 +181,7 @@ func (config *DirectClientConfig) ClientConfig() (*restclient.Config, error) {
|
|||||||
if len(configAuthInfo.Impersonate) > 0 {
|
if len(configAuthInfo.Impersonate) > 0 {
|
||||||
clientConfig.Impersonate = restclient.ImpersonationConfig{
|
clientConfig.Impersonate = restclient.ImpersonationConfig{
|
||||||
UserName: configAuthInfo.Impersonate,
|
UserName: configAuthInfo.Impersonate,
|
||||||
|
UID: configAuthInfo.ImpersonateUID,
|
||||||
Groups: configAuthInfo.ImpersonateGroups,
|
Groups: configAuthInfo.ImpersonateGroups,
|
||||||
Extra: configAuthInfo.ImpersonateUserExtra,
|
Extra: configAuthInfo.ImpersonateUserExtra,
|
||||||
}
|
}
|
||||||
@ -255,6 +256,7 @@ func (config *DirectClientConfig) getUserIdentificationPartialConfig(configAuthI
|
|||||||
if len(configAuthInfo.Impersonate) > 0 {
|
if len(configAuthInfo.Impersonate) > 0 {
|
||||||
mergedConfig.Impersonate = restclient.ImpersonationConfig{
|
mergedConfig.Impersonate = restclient.ImpersonationConfig{
|
||||||
UserName: configAuthInfo.Impersonate,
|
UserName: configAuthInfo.Impersonate,
|
||||||
|
UID: configAuthInfo.ImpersonateUID,
|
||||||
Groups: configAuthInfo.ImpersonateGroups,
|
Groups: configAuthInfo.ImpersonateGroups,
|
||||||
Extra: configAuthInfo.ImpersonateUserExtra,
|
Extra: configAuthInfo.ImpersonateUserExtra,
|
||||||
}
|
}
|
||||||
|
@ -217,6 +217,43 @@ func TestTLSServerNameClearsWhenServerNameSet(t *testing.T) {
|
|||||||
matchStringArg("", actualCfg.ServerName, t)
|
matchStringArg("", actualCfg.ServerName, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFullImpersonateConfig(t *testing.T) {
|
||||||
|
config := createValidTestConfig()
|
||||||
|
config.Clusters["clean"] = &clientcmdapi.Cluster{
|
||||||
|
Server: "https://localhost:8443",
|
||||||
|
}
|
||||||
|
config.AuthInfos["clean"] = &clientcmdapi.AuthInfo{
|
||||||
|
Impersonate: "alice",
|
||||||
|
ImpersonateUID: "abc123",
|
||||||
|
ImpersonateGroups: []string{"group-1"},
|
||||||
|
ImpersonateUserExtra: map[string][]string{"some-key": {"some-value"}},
|
||||||
|
}
|
||||||
|
config.Contexts["clean"] = &clientcmdapi.Context{
|
||||||
|
Cluster: "clean",
|
||||||
|
AuthInfo: "clean",
|
||||||
|
}
|
||||||
|
config.CurrentContext = "clean"
|
||||||
|
|
||||||
|
clientBuilder := NewNonInteractiveClientConfig(*config, "clean", &ConfigOverrides{
|
||||||
|
ClusterInfo: clientcmdapi.Cluster{
|
||||||
|
Server: "http://something",
|
||||||
|
},
|
||||||
|
}, nil)
|
||||||
|
|
||||||
|
actualCfg, err := clientBuilder.ClientConfig()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
matchStringArg("alice", actualCfg.Impersonate.UserName, t)
|
||||||
|
matchStringArg("abc123", actualCfg.Impersonate.UID, t)
|
||||||
|
matchIntArg(1, len(actualCfg.Impersonate.Groups), t)
|
||||||
|
matchStringArg("group-1", actualCfg.Impersonate.Groups[0], t)
|
||||||
|
matchIntArg(1, len(actualCfg.Impersonate.Extra), t)
|
||||||
|
matchIntArg(1, len(actualCfg.Impersonate.Extra["some-key"]), t)
|
||||||
|
matchStringArg("some-value", actualCfg.Impersonate.Extra["some-key"][0], t)
|
||||||
|
}
|
||||||
|
|
||||||
func TestMergeContext(t *testing.T) {
|
func TestMergeContext(t *testing.T) {
|
||||||
const namespace = "overridden-namespace"
|
const namespace = "overridden-namespace"
|
||||||
|
|
||||||
@ -808,6 +845,12 @@ func matchByteArg(expected, got []byte, t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func matchIntArg(expected, got int, t *testing.T) {
|
||||||
|
if expected != got {
|
||||||
|
t.Errorf("Expected %d, got %d", expected, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestNamespaceOverride(t *testing.T) {
|
func TestNamespaceOverride(t *testing.T) {
|
||||||
config := &DirectClientConfig{
|
config := &DirectClientConfig{
|
||||||
overrides: &ConfigOverrides{
|
overrides: &ConfigOverrides{
|
||||||
|
@ -53,6 +53,7 @@ type AuthOverrideFlags struct {
|
|||||||
ClientKey FlagInfo
|
ClientKey FlagInfo
|
||||||
Token FlagInfo
|
Token FlagInfo
|
||||||
Impersonate FlagInfo
|
Impersonate FlagInfo
|
||||||
|
ImpersonateUID FlagInfo
|
||||||
ImpersonateGroups FlagInfo
|
ImpersonateGroups FlagInfo
|
||||||
Username FlagInfo
|
Username FlagInfo
|
||||||
Password FlagInfo
|
Password FlagInfo
|
||||||
@ -154,6 +155,7 @@ const (
|
|||||||
FlagEmbedCerts = "embed-certs"
|
FlagEmbedCerts = "embed-certs"
|
||||||
FlagBearerToken = "token"
|
FlagBearerToken = "token"
|
||||||
FlagImpersonate = "as"
|
FlagImpersonate = "as"
|
||||||
|
FlagImpersonateUID = "as-uid"
|
||||||
FlagImpersonateGroup = "as-group"
|
FlagImpersonateGroup = "as-group"
|
||||||
FlagUsername = "username"
|
FlagUsername = "username"
|
||||||
FlagPassword = "password"
|
FlagPassword = "password"
|
||||||
@ -179,6 +181,7 @@ func RecommendedAuthOverrideFlags(prefix string) AuthOverrideFlags {
|
|||||||
ClientKey: FlagInfo{prefix + FlagKeyFile, "", "", "Path to a client key file for TLS"},
|
ClientKey: FlagInfo{prefix + FlagKeyFile, "", "", "Path to a client key file for TLS"},
|
||||||
Token: FlagInfo{prefix + FlagBearerToken, "", "", "Bearer token for authentication to the API server"},
|
Token: FlagInfo{prefix + FlagBearerToken, "", "", "Bearer token for authentication to the API server"},
|
||||||
Impersonate: FlagInfo{prefix + FlagImpersonate, "", "", "Username to impersonate for the operation"},
|
Impersonate: FlagInfo{prefix + FlagImpersonate, "", "", "Username to impersonate for the operation"},
|
||||||
|
ImpersonateUID: FlagInfo{prefix + FlagImpersonateUID, "", "", "UID to impersonate for the operation"},
|
||||||
ImpersonateGroups: FlagInfo{prefix + FlagImpersonateGroup, "", "", "Group to impersonate for the operation, this flag can be repeated to specify multiple groups."},
|
ImpersonateGroups: FlagInfo{prefix + FlagImpersonateGroup, "", "", "Group to impersonate for the operation, this flag can be repeated to specify multiple groups."},
|
||||||
Username: FlagInfo{prefix + FlagUsername, "", "", "Username for basic authentication to the API server"},
|
Username: FlagInfo{prefix + FlagUsername, "", "", "Username for basic authentication to the API server"},
|
||||||
Password: FlagInfo{prefix + FlagPassword, "", "", "Password for basic authentication to the API server"},
|
Password: FlagInfo{prefix + FlagPassword, "", "", "Password for basic authentication to the API server"},
|
||||||
@ -219,6 +222,7 @@ func BindAuthInfoFlags(authInfo *clientcmdapi.AuthInfo, flags *pflag.FlagSet, fl
|
|||||||
flagNames.ClientKey.BindStringFlag(flags, &authInfo.ClientKey).AddSecretAnnotation(flags)
|
flagNames.ClientKey.BindStringFlag(flags, &authInfo.ClientKey).AddSecretAnnotation(flags)
|
||||||
flagNames.Token.BindStringFlag(flags, &authInfo.Token).AddSecretAnnotation(flags)
|
flagNames.Token.BindStringFlag(flags, &authInfo.Token).AddSecretAnnotation(flags)
|
||||||
flagNames.Impersonate.BindStringFlag(flags, &authInfo.Impersonate).AddSecretAnnotation(flags)
|
flagNames.Impersonate.BindStringFlag(flags, &authInfo.Impersonate).AddSecretAnnotation(flags)
|
||||||
|
flagNames.ImpersonateUID.BindStringFlag(flags, &authInfo.ImpersonateUID).AddSecretAnnotation(flags)
|
||||||
flagNames.ImpersonateGroups.BindStringArrayFlag(flags, &authInfo.ImpersonateGroups).AddSecretAnnotation(flags)
|
flagNames.ImpersonateGroups.BindStringArrayFlag(flags, &authInfo.ImpersonateGroups).AddSecretAnnotation(flags)
|
||||||
flagNames.Username.BindStringFlag(flags, &authInfo.Username).AddSecretAnnotation(flags)
|
flagNames.Username.BindStringFlag(flags, &authInfo.Username).AddSecretAnnotation(flags)
|
||||||
flagNames.Password.BindStringFlag(flags, &authInfo.Password).AddSecretAnnotation(flags)
|
flagNames.Password.BindStringFlag(flags, &authInfo.Password).AddSecretAnnotation(flags)
|
||||||
|
@ -323,9 +323,9 @@ func validateAuthInfo(authInfoName string, authInfo clientcmdapi.AuthInfo) []err
|
|||||||
validationErrors = append(validationErrors, fmt.Errorf("more than one authentication method found for %v; found %v, only one is allowed", authInfoName, methods))
|
validationErrors = append(validationErrors, fmt.Errorf("more than one authentication method found for %v; found %v, only one is allowed", authInfoName, methods))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImpersonateGroups or ImpersonateUserExtra should be requested with a user
|
// ImpersonateUID, ImpersonateGroups or ImpersonateUserExtra should be requested with a user
|
||||||
if (len(authInfo.ImpersonateGroups) > 0 || len(authInfo.ImpersonateUserExtra) > 0) && (len(authInfo.Impersonate) == 0) {
|
if (len(authInfo.ImpersonateUID) > 0 || len(authInfo.ImpersonateGroups) > 0 || len(authInfo.ImpersonateUserExtra) > 0) && (len(authInfo.Impersonate) == 0) {
|
||||||
validationErrors = append(validationErrors, fmt.Errorf("requesting groups or user-extra for %v without impersonating a user", authInfoName))
|
validationErrors = append(validationErrors, fmt.Errorf("requesting uid, groups or user-extra for %v without impersonating a user", authInfoName))
|
||||||
}
|
}
|
||||||
return validationErrors
|
return validationErrors
|
||||||
}
|
}
|
||||||
|
@ -508,6 +508,78 @@ func TestValidateAuthInfoExecInteractiveModeInvalid(t *testing.T) {
|
|||||||
test.testConfig(t)
|
test.testConfig(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestValidateAuthInfoImpersonateUser(t *testing.T) {
|
||||||
|
config := clientcmdapi.NewConfig()
|
||||||
|
config.AuthInfos["user"] = &clientcmdapi.AuthInfo{
|
||||||
|
Impersonate: "user",
|
||||||
|
}
|
||||||
|
test := configValidationTest{
|
||||||
|
config: config,
|
||||||
|
}
|
||||||
|
test.testAuthInfo("user", t)
|
||||||
|
test.testConfig(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestValidateAuthInfoImpersonateEverything(t *testing.T) {
|
||||||
|
config := clientcmdapi.NewConfig()
|
||||||
|
config.AuthInfos["user"] = &clientcmdapi.AuthInfo{
|
||||||
|
Impersonate: "user",
|
||||||
|
ImpersonateUID: "abc123",
|
||||||
|
ImpersonateGroups: []string{"group-1", "group-2"},
|
||||||
|
ImpersonateUserExtra: map[string][]string{"key": {"val1", "val2"}},
|
||||||
|
}
|
||||||
|
test := configValidationTest{
|
||||||
|
config: config,
|
||||||
|
}
|
||||||
|
test.testAuthInfo("user", t)
|
||||||
|
test.testConfig(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestValidateAuthInfoImpersonateGroupsWithoutUserInvalid(t *testing.T) {
|
||||||
|
config := clientcmdapi.NewConfig()
|
||||||
|
config.AuthInfos["user"] = &clientcmdapi.AuthInfo{
|
||||||
|
ImpersonateGroups: []string{"group-1", "group-2"},
|
||||||
|
}
|
||||||
|
test := configValidationTest{
|
||||||
|
config: config,
|
||||||
|
expectedErrorSubstring: []string{
|
||||||
|
`requesting uid, groups or user-extra for user without impersonating a user`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
test.testAuthInfo("user", t)
|
||||||
|
test.testConfig(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestValidateAuthInfoImpersonateExtraWithoutUserInvalid(t *testing.T) {
|
||||||
|
config := clientcmdapi.NewConfig()
|
||||||
|
config.AuthInfos["user"] = &clientcmdapi.AuthInfo{
|
||||||
|
ImpersonateUserExtra: map[string][]string{"key": {"val1", "val2"}},
|
||||||
|
}
|
||||||
|
test := configValidationTest{
|
||||||
|
config: config,
|
||||||
|
expectedErrorSubstring: []string{
|
||||||
|
`requesting uid, groups or user-extra for user without impersonating a user`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
test.testAuthInfo("user", t)
|
||||||
|
test.testConfig(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestValidateAuthInfoImpersonateUIDWithoutUserInvalid(t *testing.T) {
|
||||||
|
config := clientcmdapi.NewConfig()
|
||||||
|
config.AuthInfos["user"] = &clientcmdapi.AuthInfo{
|
||||||
|
ImpersonateUID: "abc123",
|
||||||
|
}
|
||||||
|
test := configValidationTest{
|
||||||
|
config: config,
|
||||||
|
expectedErrorSubstring: []string{
|
||||||
|
`requesting uid, groups or user-extra for user without impersonating a user`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
test.testAuthInfo("user", t)
|
||||||
|
test.testConfig(t)
|
||||||
|
}
|
||||||
|
|
||||||
type configValidationTest struct {
|
type configValidationTest struct {
|
||||||
config *clientcmdapi.Config
|
config *clientcmdapi.Config
|
||||||
expectedErrorSubstring []string
|
expectedErrorSubstring []string
|
||||||
|
Loading…
Reference in New Issue
Block a user