Skip to content

Commit a556e4f

Browse files
committed
Allow to define exec credential plugin config options from kubectl
This commit adds support of setting config options to the exec plugin from cli. Next options are added: * --exec-command new command for the exec credential plugin * --exec-api-version API version of the exec credential plugin. * --exec-arg new arguments for the exec credential plugin command * --exec-env add, update or remove environment values for the exec credential plugin
1 parent 7a8e11c commit a556e4f

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)