Skip to content

Commit 19b83c3

Browse files
authored
Merge pull request kubernetes#73230 from Fedosin/cli_exec_auth
Allow to define exec credential plugin config options from kubectl
2 parents 203d5f0 + a556e4f commit 19b83c3

File tree

2 files changed

+360
-2
lines changed

2 files changed

+360
-2
lines changed

pkg/kubectl/cmd/config/create_authinfo.go

Lines changed: 139 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,22 @@ type createAuthInfoOptions struct {
4848

4949
authProviderArgs map[string]string
5050
authProviderArgsToRemove []string
51+
52+
execCommand cliflag.StringFlag
53+
execAPIVersion cliflag.StringFlag
54+
execArgs []string
55+
execEnv map[string]string
56+
execEnvToRemove []string
5157
}
5258

5359
const (
5460
flagAuthProvider = "auth-provider"
5561
flagAuthProviderArg = "auth-provider-arg"
62+
63+
flagExecCommand = "exec-command"
64+
flagExecAPIVersion = "exec-api-version"
65+
flagExecArg = "exec-arg"
66+
flagExecEnv = "exec-env"
5667
)
5768

5869
var (
@@ -90,7 +101,19 @@ var (
90101
kubectl config set-credentials cluster-admin --auth-provider=oidc --auth-provider-arg=client-id=foo --auth-provider-arg=client-secret=bar
91102
92103
# Remove the "client-secret" config value for the OpenID Connect auth provider for the "cluster-admin" entry
93-
kubectl config set-credentials cluster-admin --auth-provider=oidc --auth-provider-arg=client-secret-`)
104+
kubectl config set-credentials cluster-admin --auth-provider=oidc --auth-provider-arg=client-secret-
105+
106+
# Enable new exec auth plugin for the "cluster-admin" entry
107+
kubectl config set-credentials cluster-admin --exec-command=/path/to/the/executable --exec-api-version=client.authentication.k8s.io/v1beta
108+
109+
# Define new exec auth plugin args for the "cluster-admin" entry
110+
kubectl config set-credentials cluster-admin --exec-arg=arg1 --exec-arg=arg2
111+
112+
# Create or update exec auth plugin environment variables for the "cluster-admin" entry
113+
kubectl config set-credentials cluster-admin --exec-env=key1=val1 --exec-env=key2=val2
114+
115+
# Remove exec auth plugin environment variables for the "cluster-admin" entry
116+
kubectl config set-credentials cluster-admin --exec-env=var-to-remove-`)
94117
)
95118

96119
// NewCmdConfigSetAuthInfo returns an Command option instance for 'config set-credentials' sub command
@@ -101,7 +124,30 @@ func NewCmdConfigSetAuthInfo(out io.Writer, configAccess clientcmd.ConfigAccess)
101124

102125
func newCmdConfigSetAuthInfo(out io.Writer, options *createAuthInfoOptions) *cobra.Command {
103126
cmd := &cobra.Command{
104-
Use: fmt.Sprintf("set-credentials NAME [--%v=path/to/certfile] [--%v=path/to/keyfile] [--%v=bearer_token] [--%v=basic_user] [--%v=basic_password] [--%v=provider_name] [--%v=key=value]", clientcmd.FlagCertFile, clientcmd.FlagKeyFile, clientcmd.FlagBearerToken, clientcmd.FlagUsername, clientcmd.FlagPassword, flagAuthProvider, flagAuthProviderArg),
127+
Use: fmt.Sprintf(
128+
"set-credentials NAME [--%v=path/to/certfile] "+
129+
"[--%v=path/to/keyfile] "+
130+
"[--%v=bearer_token] "+
131+
"[--%v=basic_user] "+
132+
"[--%v=basic_password] "+
133+
"[--%v=provider_name] "+
134+
"[--%v=key=value] "+
135+
"[--%v=exec_command] "+
136+
"[--%v=exec_api_version] "+
137+
"[--%v=arg] "+
138+
"[--%v=key=value]",
139+
clientcmd.FlagCertFile,
140+
clientcmd.FlagKeyFile,
141+
clientcmd.FlagBearerToken,
142+
clientcmd.FlagUsername,
143+
clientcmd.FlagPassword,
144+
flagAuthProvider,
145+
flagAuthProviderArg,
146+
flagExecCommand,
147+
flagExecAPIVersion,
148+
flagExecArg,
149+
flagExecEnv,
150+
),
105151
DisableFlagsInUseLine: true,
106152
Short: i18n.T("Sets a user entry in kubeconfig"),
107153
Long: createAuthInfoLong,
@@ -126,6 +172,10 @@ func newCmdConfigSetAuthInfo(out io.Writer, options *createAuthInfoOptions) *cob
126172
cmd.Flags().Var(&options.password, clientcmd.FlagPassword, clientcmd.FlagPassword+" for the user entry in kubeconfig")
127173
cmd.Flags().Var(&options.authProvider, flagAuthProvider, "Auth provider for the user entry in kubeconfig")
128174
cmd.Flags().StringSlice(flagAuthProviderArg, nil, "'key=value' arguments for the auth provider")
175+
cmd.Flags().Var(&options.execCommand, flagExecCommand, "Command for the exec credential plugin for the user entry in kubeconfig")
176+
cmd.Flags().Var(&options.execAPIVersion, flagExecAPIVersion, "API version of the exec credential plugin for the user entry in kubeconfig")
177+
cmd.Flags().StringSlice(flagExecArg, nil, "New arguments for the exec credential plugin command for the user entry in kubeconfig")
178+
cmd.Flags().StringArray(flagExecEnv, nil, "'key=value' environment values for the exec credential plugin")
129179
f := cmd.Flags().VarPF(&options.embedCertData, clientcmd.FlagEmbedCerts, "", "Embed client cert/key for the user entry in kubeconfig")
130180
f.NoOptDefVal = "true"
131181

@@ -226,6 +276,72 @@ func (o *createAuthInfoOptions) modifyAuthInfo(existingAuthInfo clientcmdapi.Aut
226276
}
227277
}
228278

279+
if o.execCommand.Provided() {
280+
newExecCommand := o.execCommand.Value()
281+
282+
// create new Exec if doesn't exist, otherwise just modify the command
283+
if modifiedAuthInfo.Exec == nil {
284+
modifiedAuthInfo.Exec = &clientcmdapi.ExecConfig{
285+
Command: newExecCommand,
286+
}
287+
} else {
288+
modifiedAuthInfo.Exec.Command = newExecCommand
289+
// explicitly reset exec arguments
290+
modifiedAuthInfo.Exec.Args = nil
291+
}
292+
}
293+
294+
// modify next values only if Exec exists, ignore these changes otherwise
295+
if modifiedAuthInfo.Exec != nil {
296+
if o.execAPIVersion.Provided() {
297+
modifiedAuthInfo.Exec.APIVersion = o.execAPIVersion.Value()
298+
}
299+
300+
// rewrite exec arguments list with new values
301+
if o.execArgs != nil {
302+
modifiedAuthInfo.Exec.Args = o.execArgs
303+
}
304+
305+
// iterate over the existing exec env values and remove the specified
306+
if o.execEnvToRemove != nil {
307+
newExecEnv := []clientcmdapi.ExecEnvVar{}
308+
for _, value := range modifiedAuthInfo.Exec.Env {
309+
needToRemove := false
310+
for _, elemToRemove := range o.execEnvToRemove {
311+
if value.Name == elemToRemove {
312+
needToRemove = true
313+
break
314+
}
315+
}
316+
if !needToRemove {
317+
newExecEnv = append(newExecEnv, value)
318+
}
319+
}
320+
modifiedAuthInfo.Exec.Env = newExecEnv
321+
}
322+
323+
// update or create specified environment variables for the exec plugin
324+
if o.execEnv != nil {
325+
newEnv := []clientcmdapi.ExecEnvVar{}
326+
for newEnvName, newEnvValue := range o.execEnv {
327+
needToCreate := true
328+
for i := 0; i < len(modifiedAuthInfo.Exec.Env); i++ {
329+
if modifiedAuthInfo.Exec.Env[i].Name == newEnvName {
330+
// update the existing value
331+
needToCreate = false
332+
modifiedAuthInfo.Exec.Env[i].Value = newEnvValue
333+
break
334+
}
335+
}
336+
if needToCreate {
337+
// create a new env value
338+
newEnv = append(newEnv, clientcmdapi.ExecEnvVar{Name: newEnvName, Value: newEnvValue})
339+
}
340+
}
341+
modifiedAuthInfo.Exec.Env = append(modifiedAuthInfo.Exec.Env, newEnv...)
342+
}
343+
}
344+
229345
// If any auth info was set, make sure any other existing auth types are cleared
230346
if setToken || setBasic {
231347
if !setToken {
@@ -260,6 +376,27 @@ func (o *createAuthInfoOptions) complete(cmd *cobra.Command, out io.Writer) erro
260376
o.authProviderArgsToRemove = removePairs
261377
}
262378

379+
execArgs, err := cmd.Flags().GetStringSlice(flagExecArg)
380+
if err != nil {
381+
return fmt.Errorf("Error: %s", err)
382+
}
383+
if len(execArgs) > 0 {
384+
o.execArgs = execArgs
385+
}
386+
387+
execEnv, err := cmd.Flags().GetStringArray(flagExecEnv)
388+
if err != nil {
389+
return fmt.Errorf("Error: %s", err)
390+
}
391+
if len(execEnv) > 0 {
392+
newPairs, removePairs, err := cmdutil.ParsePairs(execEnv, flagExecEnv, true)
393+
if err != nil {
394+
return fmt.Errorf("Error: %s", err)
395+
}
396+
o.execEnv = newPairs
397+
o.execEnvToRemove = removePairs
398+
}
399+
263400
o.name = args[0]
264401
return nil
265402
}

0 commit comments

Comments
 (0)