mirror of
https://github.com/kubernetes/client-go.git
synced 2025-06-26 07:02:01 +00:00
add --as-group option to cli
The usecase of this change: When a super user grant some RBAC permissions to a group, he can use --as-group to test whether the group get the permissions. Note that now we support as-groups, as-user-extra in kubeconfig file after this change. Kubernetes-commit: e541defd49d01024d17dddf8e966eba2c46a6db0
This commit is contained in:
parent
fdfa162aed
commit
29b5bff0fa
@ -109,6 +109,12 @@ 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.
|
||||||
|
// +optional
|
||||||
|
ImpersonateGroups []string `json:"act-as-groups,omitempty"`
|
||||||
|
// ImpersonateUserExtra contains additional information for impersonated user.
|
||||||
|
// +optional
|
||||||
|
ImpersonateUserExtra map[string][]string `json:"act-as-user-extra,omitempty"`
|
||||||
// Username is the username for basic authentication to the kubernetes cluster.
|
// Username is the username for basic authentication to the kubernetes cluster.
|
||||||
// +optional
|
// +optional
|
||||||
Username string `json:"username,omitempty"`
|
Username string `json:"username,omitempty"`
|
||||||
@ -172,7 +178,10 @@ func NewCluster() *Cluster {
|
|||||||
// NewAuthInfo is a convenience function that returns a new AuthInfo
|
// NewAuthInfo is a convenience function that returns a new AuthInfo
|
||||||
// object with non-nil maps
|
// object with non-nil maps
|
||||||
func NewAuthInfo() *AuthInfo {
|
func NewAuthInfo() *AuthInfo {
|
||||||
return &AuthInfo{Extensions: make(map[string]runtime.Object)}
|
return &AuthInfo{
|
||||||
|
Extensions: make(map[string]runtime.Object),
|
||||||
|
ImpersonateUserExtra: make(map[string][]string),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPreferences is a convenience function that returns a new
|
// NewPreferences is a convenience function that returns a new
|
||||||
|
@ -103,6 +103,12 @@ type AuthInfo struct {
|
|||||||
// Impersonate is the username to imperonate. The name matches the flag.
|
// Impersonate is the username to imperonate. The name matches the flag.
|
||||||
// +optional
|
// +optional
|
||||||
Impersonate string `json:"as,omitempty"`
|
Impersonate string `json:"as,omitempty"`
|
||||||
|
// ImpersonateGroups is the groups to imperonate.
|
||||||
|
// +optional
|
||||||
|
ImpersonateGroups []string `json:"as-groups,omitempty"`
|
||||||
|
// ImpersonateUserExtra contains additional information for impersonated user.
|
||||||
|
// +optional
|
||||||
|
ImpersonateUserExtra map[string][]string `json:"as-user-extra,omitempty"`
|
||||||
// Username is the username for basic authentication to the kubernetes cluster.
|
// Username is the username for basic authentication to the kubernetes cluster.
|
||||||
// +optional
|
// +optional
|
||||||
Username string `json:"username,omitempty"`
|
Username string `json:"username,omitempty"`
|
||||||
|
@ -146,7 +146,11 @@ func (config *DirectClientConfig) ClientConfig() (*restclient.Config, error) {
|
|||||||
clientConfig.Host = u.String()
|
clientConfig.Host = u.String()
|
||||||
}
|
}
|
||||||
if len(configAuthInfo.Impersonate) > 0 {
|
if len(configAuthInfo.Impersonate) > 0 {
|
||||||
clientConfig.Impersonate = restclient.ImpersonationConfig{UserName: configAuthInfo.Impersonate}
|
clientConfig.Impersonate = restclient.ImpersonationConfig{
|
||||||
|
UserName: configAuthInfo.Impersonate,
|
||||||
|
Groups: configAuthInfo.ImpersonateGroups,
|
||||||
|
Extra: configAuthInfo.ImpersonateUserExtra,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// only try to read the auth information if we are secure
|
// only try to read the auth information if we are secure
|
||||||
@ -217,7 +221,11 @@ func (config *DirectClientConfig) getUserIdentificationPartialConfig(configAuthI
|
|||||||
mergedConfig.BearerToken = string(tokenBytes)
|
mergedConfig.BearerToken = string(tokenBytes)
|
||||||
}
|
}
|
||||||
if len(configAuthInfo.Impersonate) > 0 {
|
if len(configAuthInfo.Impersonate) > 0 {
|
||||||
mergedConfig.Impersonate = restclient.ImpersonationConfig{UserName: configAuthInfo.Impersonate}
|
mergedConfig.Impersonate = restclient.ImpersonationConfig{
|
||||||
|
UserName: configAuthInfo.Impersonate,
|
||||||
|
Groups: configAuthInfo.ImpersonateGroups,
|
||||||
|
Extra: configAuthInfo.ImpersonateUserExtra,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if len(configAuthInfo.ClientCertificate) > 0 || len(configAuthInfo.ClientCertificateData) > 0 {
|
if len(configAuthInfo.ClientCertificate) > 0 || len(configAuthInfo.ClientCertificateData) > 0 {
|
||||||
mergedConfig.CertFile = configAuthInfo.ClientCertificate
|
mergedConfig.CertFile = configAuthInfo.ClientCertificate
|
||||||
|
@ -52,6 +52,7 @@ type AuthOverrideFlags struct {
|
|||||||
ClientKey FlagInfo
|
ClientKey FlagInfo
|
||||||
Token FlagInfo
|
Token FlagInfo
|
||||||
Impersonate FlagInfo
|
Impersonate FlagInfo
|
||||||
|
ImpersonateGroups FlagInfo
|
||||||
Username FlagInfo
|
Username FlagInfo
|
||||||
Password FlagInfo
|
Password FlagInfo
|
||||||
}
|
}
|
||||||
@ -100,6 +101,19 @@ func (f FlagInfo) BindStringFlag(flags *pflag.FlagSet, target *string) FlagInfo
|
|||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BindStringSliceFlag binds the flag based on the provided info. If LongName == "", nothing is registered
|
||||||
|
func (f FlagInfo) BindStringArrayFlag(flags *pflag.FlagSet, target *[]string) FlagInfo {
|
||||||
|
// you can't register a flag without a long name
|
||||||
|
if len(f.LongName) > 0 {
|
||||||
|
sliceVal := []string{}
|
||||||
|
if len(f.Default) > 0 {
|
||||||
|
sliceVal = []string{f.Default}
|
||||||
|
}
|
||||||
|
flags.StringArrayVarP(target, f.LongName, f.ShortName, sliceVal, f.Description)
|
||||||
|
}
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
// BindBoolFlag binds the flag based on the provided info. If LongName == "", nothing is registered
|
// BindBoolFlag binds the flag based on the provided info. If LongName == "", nothing is registered
|
||||||
func (f FlagInfo) BindBoolFlag(flags *pflag.FlagSet, target *bool) FlagInfo {
|
func (f FlagInfo) BindBoolFlag(flags *pflag.FlagSet, target *bool) FlagInfo {
|
||||||
// you can't register a flag without a long name
|
// you can't register a flag without a long name
|
||||||
@ -116,22 +130,23 @@ func (f FlagInfo) BindBoolFlag(flags *pflag.FlagSet, target *bool) FlagInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
FlagClusterName = "cluster"
|
FlagClusterName = "cluster"
|
||||||
FlagAuthInfoName = "user"
|
FlagAuthInfoName = "user"
|
||||||
FlagContext = "context"
|
FlagContext = "context"
|
||||||
FlagNamespace = "namespace"
|
FlagNamespace = "namespace"
|
||||||
FlagAPIServer = "server"
|
FlagAPIServer = "server"
|
||||||
FlagAPIVersion = "api-version"
|
FlagAPIVersion = "api-version"
|
||||||
FlagInsecure = "insecure-skip-tls-verify"
|
FlagInsecure = "insecure-skip-tls-verify"
|
||||||
FlagCertFile = "client-certificate"
|
FlagCertFile = "client-certificate"
|
||||||
FlagKeyFile = "client-key"
|
FlagKeyFile = "client-key"
|
||||||
FlagCAFile = "certificate-authority"
|
FlagCAFile = "certificate-authority"
|
||||||
FlagEmbedCerts = "embed-certs"
|
FlagEmbedCerts = "embed-certs"
|
||||||
FlagBearerToken = "token"
|
FlagBearerToken = "token"
|
||||||
FlagImpersonate = "as"
|
FlagImpersonate = "as"
|
||||||
FlagUsername = "username"
|
FlagImpersonateGroup = "as-group"
|
||||||
FlagPassword = "password"
|
FlagUsername = "username"
|
||||||
FlagTimeout = "request-timeout"
|
FlagPassword = "password"
|
||||||
|
FlagTimeout = "request-timeout"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RecommendedConfigOverrideFlags is a convenience method to return recommended flag names prefixed with a string of your choosing
|
// RecommendedConfigOverrideFlags is a convenience method to return recommended flag names prefixed with a string of your choosing
|
||||||
@ -153,6 +168,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"},
|
||||||
|
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"},
|
||||||
}
|
}
|
||||||
@ -192,6 +208,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.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)
|
||||||
}
|
}
|
||||||
|
@ -242,6 +242,10 @@ 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
|
||||||
|
if (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))
|
||||||
|
}
|
||||||
return validationErrors
|
return validationErrors
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user