kubectl源码分析之config set-credentials

 欢迎关注我的公众号:

 目前刚开始写一个月,一共写了18篇原创文章,文章目录如下:

istio多集群探秘,部署了50次多集群后我得出的结论

istio多集群链路追踪,附实操视频

istio防故障利器,你知道几个,istio新手不要读,太难!

istio业务权限控制,原来可以这么玩

istio实现非侵入压缩,微服务之间如何实现压缩

不懂envoyfilter也敢说精通istio系列-http-rbac-不要只会用AuthorizationPolicy配置权限

不懂envoyfilter也敢说精通istio系列-02-http-corsFilter-不要只会vs

不懂envoyfilter也敢说精通istio系列-03-http-csrf filter-再也不用再代码里写csrf逻辑了

不懂envoyfilter也敢说精通istio系列http-jwt_authn-不要只会RequestAuthorization

不懂envoyfilter也敢说精通istio系列-05-fault-filter-故障注入不止是vs

不懂envoyfilter也敢说精通istio系列-06-http-match-配置路由不只是vs

不懂envoyfilter也敢说精通istio系列-07-负载均衡配置不止是dr

不懂envoyfilter也敢说精通istio系列-08-连接池和断路器

不懂envoyfilter也敢说精通istio系列-09-http-route filter

不懂envoyfilter也敢说精通istio系列-network filter-redis proxy

不懂envoyfilter也敢说精通istio系列-network filter-HttpConnectionManager

不懂envoyfilter也敢说精通istio系列-ratelimit-istio ratelimit完全手册

 

————————————————

type createAuthInfoOptions struct {//set-credentials结构体
	configAccess      clientcmd.ConfigAccess
	name              string
	authPath          cliflag.StringFlag
	clientCertificate cliflag.StringFlag
	clientKey         cliflag.StringFlag
	token             cliflag.StringFlag
	username          cliflag.StringFlag
	password          cliflag.StringFlag
	embedCertData     cliflag.Tristate
	authProvider      cliflag.StringFlag

	authProviderArgs         map[string]string
	authProviderArgsToRemove []string

	execCommand     cliflag.StringFlag
	execAPIVersion  cliflag.StringFlag
	execArgs        []string
	execEnv         map[string]string
	execEnvToRemove []string
}
//创建set-credentials命令
func NewCmdConfigSetAuthInfo(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command {
	options := &createAuthInfoOptions{configAccess: configAccess}//初始化结构体
	return newCmdConfigSetAuthInfo(out, options)//创建命令
}

func newCmdConfigSetAuthInfo(out io.Writer, options *createAuthInfoOptions) *cobra.Command {
	cmd := &cobra.Command{//创建cobra命令
		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] "+
				"[--%v=exec_command] "+
				"[--%v=exec_api_version] "+
				"[--%v=arg] "+
				"[--%v=key=value]",
			clientcmd.FlagCertFile,
			clientcmd.FlagKeyFile,
			clientcmd.FlagBearerToken,
			clientcmd.FlagUsername,
			clientcmd.FlagPassword,
			flagAuthProvider,
			flagAuthProviderArg,
			flagExecCommand,
			flagExecAPIVersion,
			flagExecArg,
			flagExecEnv,
		),
		DisableFlagsInUseLine: true,
		Short:                 i18n.T("Sets a user entry in kubeconfig"),
		Long:                  createAuthInfoLong,
		Example:               createAuthInfoExample,
		Run: func(cmd *cobra.Command, args []string) {
			err := options.complete(cmd, out)//准备
			if err != nil {
				cmd.Help()
				cmdutil.CheckErr(err)
			}
			cmdutil.CheckErr(options.run())//运行
			fmt.Fprintf(out, "User %q set.\n", options.name)//打印结果
		},
	}

	cmd.Flags().Var(&options.clientCertificate, clientcmd.FlagCertFile, "Path to "+clientcmd.FlagCertFile+" file for the user entry in kubeconfig")//clientCertificate选项
	cmd.MarkFlagFilename(clientcmd.FlagCertFile)
	cmd.Flags().Var(&options.clientKey, clientcmd.FlagKeyFile, "Path to "+clientcmd.FlagKeyFile+" file for the user entry in kubeconfig")//clientKey选项
	cmd.MarkFlagFilename(clientcmd.FlagKeyFile)
	cmd.Flags().Var(&options.token, clientcmd.FlagBearerToken, clientcmd.FlagBearerToken+" for the user entry in kubeconfig")//token选项
	cmd.Flags().Var(&options.username, clientcmd.FlagUsername, clientcmd.FlagUsername+" for the user entry in kubeconfig")//username选项
	cmd.Flags().Var(&options.password, clientcmd.FlagPassword, clientcmd.FlagPassword+" for the user entry in kubeconfig")//password选项
	cmd.Flags().Var(&options.authProvider, flagAuthProvider, "Auth provider for the user entry in kubeconfig")//authProvider选项
	cmd.Flags().StringSlice(flagAuthProviderArg, nil, "'key=value' arguments for the auth provider")//AuthProviderArg选项
	cmd.Flags().Var(&options.execCommand, flagExecCommand, "Command for the exec credential plugin for the user entry in kubeconfig")//execCommand选项
	cmd.Flags().Var(&options.execAPIVersion, flagExecAPIVersion, "API version of the exec credential plugin for the user entry in kubeconfig")//execAPIVersion选项
	cmd.Flags().StringSlice(flagExecArg, nil, "New arguments for the exec credential plugin command for the user entry in kubeconfig")//ExecArg选项
	cmd.Flags().StringArray(flagExecEnv, nil, "'key=value' environment values for the exec credential plugin")//ExecEnv选项
	f := cmd.Flags().VarPF(&options.embedCertData, clientcmd.FlagEmbedCerts, "", "Embed client cert/key for the user entry in kubeconfig")//embed-certs选项
	f.NoOptDefVal = "true"

	return cmd
}
//准备
func (o *createAuthInfoOptions) complete(cmd *cobra.Command, out io.Writer) error {
	args := cmd.Flags().Args()//获取参数
	if len(args) != 1 {//参数必须是1个
		return fmt.Errorf("Unexpected args: %v", args)
	}

	authProviderArgs, err := cmd.Flags().GetStringSlice(flagAuthProviderArg)//获取authProviderArgs
	if err != nil {
		return fmt.Errorf("Error: %s", err)
	}

	if len(authProviderArgs) > 0 {
		newPairs, removePairs, err := cmdutil.ParsePairs(authProviderArgs, flagAuthProviderArg, true)//解析authProviderArgs
		if err != nil {
			return fmt.Errorf("Error: %s", err)
		}
		o.authProviderArgs = newPairs//设置要添加的authProviderArgs
		o.authProviderArgsToRemove = removePairs//设置要删除的authProviderArgs
	}

	execArgs, err := cmd.Flags().GetStringSlice(flagExecArg)//获取execArgs
	if err != nil {
		return fmt.Errorf("Error: %s", err)
	}
	if len(execArgs) > 0 {//设置execArgs
		o.execArgs = execArgs
	}

	execEnv, err := cmd.Flags().GetStringArray(flagExecEnv)//获取execEnv
	if err != nil {
		return fmt.Errorf("Error: %s", err)
	}
	if len(execEnv) > 0 {
		newPairs, removePairs, err := cmdutil.ParsePairs(execEnv, flagExecEnv, true)//解析execEnv
		if err != nil {
			return fmt.Errorf("Error: %s", err)
		}
		o.execEnv = newPairs//设置要添加的execEnv
		o.execEnvToRemove = removePairs//设置要删除的execEnv
	}

	o.name = args[0]//设置name
	return nil
}
func (o createAuthInfoOptions) run() error {//运行
	err := o.validate()//校验
	if err != nil {
		return err
	}

	config, err := o.configAccess.GetStartingConfig()//加载config
	if err != nil {
		return err
	}

	startingStanza, exists := config.AuthInfos[o.name]//获取已经存在的authinfo
	if !exists {//不存在则创建
		startingStanza = clientcmdapi.NewAuthInfo()
	}
	authInfo := o.modifyAuthInfo(*startingStanza)//修改authinfo
	config.AuthInfos[o.name] = &authInfo//设置authinfo

	if err := clientcmd.ModifyConfig(o.configAccess, *config, true); err != nil {//把配置写回文件
		return err
	}

	return nil
}
/校验
func (o createAuthInfoOptions) validate() error {
	if len(o.name) == 0 {//name不能为空
		return errors.New("you must specify a non-empty user name")
	}
	methods := []string{}//定义methods
	if len(o.token.Value()) > 0 {//如果token有值,append methods
		methods = append(methods, fmt.Sprintf("--%v", clientcmd.FlagBearerToken))
	}
	if len(o.username.Value()) > 0 || len(o.password.Value()) > 0 {//如果用户名或密码有值
		methods = append(methods, fmt.Sprintf("--%v/--%v", clientcmd.FlagUsername, clientcmd.FlagPassword))// append methods
	}
	if len(methods) > 1 {//如果methods值大于1个,则报错
		return fmt.Errorf("you cannot specify more than one authentication method at the same time: %v", strings.Join(methods, ", "))
	}
	if o.embedCertData.Value() {//如果embed-certs为true
		certPath := o.clientCertificate.Value()//获取client-certificte的值
		keyPath := o.clientKey.Value()//获取client-key的值
		if certPath == "" && keyPath == "" {//如果certPath和keyPath都为空,则报错
			return fmt.Errorf("you must specify a --%s or --%s to embed", clientcmd.FlagCertFile, clientcmd.FlagKeyFile)
		}
		if certPath != "" {// 如果certPath不为空,判断是否可读取
			if _, err := ioutil.ReadFile(certPath); err != nil {
				return fmt.Errorf("error reading %s data from %s: %v", clientcmd.FlagCertFile, certPath, err)
			}
		}
		if keyPath != "" {//如果keypath不为空,判断是否可读取
			if _, err := ioutil.ReadFile(keyPath); err != nil {
				return fmt.Errorf("error reading %s data from %s: %v", clientcmd.FlagKeyFile, keyPath, err)
			}
		}
	}

	return nil
}
//修改authinfo
func (o *createAuthInfoOptions) modifyAuthInfo(existingAuthInfo clientcmdapi.AuthInfo) clientcmdapi.AuthInfo {
	modifiedAuthInfo := existingAuthInfo

	var setToken, setBasic bool//定义变量

	if o.clientCertificate.Provided() {//如果client-certificate有值
		certPath := o.clientCertificate.Value()//获取certPath
		if o.embedCertData.Value() {//如果embed-cert为true
			modifiedAuthInfo.ClientCertificateData, _ = ioutil.ReadFile(certPath)//设置ClientCertificateData为certPath的内容
			modifiedAuthInfo.ClientCertificate = ""//设置ClientCertificate 为空
		} else {
			certPath, _ = filepath.Abs(certPath)//获取certPath绝对路径
			modifiedAuthInfo.ClientCertificate = certPath//设置ClientCertificate 
			if len(modifiedAuthInfo.ClientCertificate) > 0 {//如果ClientCertificate 有值
				modifiedAuthInfo.ClientCertificateData = nil//设置ClientCertificateData 为nil
			}
		}
	}
	if o.clientKey.Provided() {//如果client-key有值
		keyPath := o.clientKey.Value()//获取keypath
		if o.embedCertData.Value() {//如果embed-certs为true
			modifiedAuthInfo.ClientKeyData, _ = ioutil.ReadFile(keyPath)//设置ClientKeyData为keyPath的内容
			modifiedAuthInfo.ClientKey = ""//设置ClientKey 为空
		} else {
			keyPath, _ = filepath.Abs(keyPath)//获取keyPath的绝对路径
			modifiedAuthInfo.ClientKey = keyPath//设置ClientKey 
			if len(modifiedAuthInfo.ClientKey) > 0 {//如果ClientKey 有值
				modifiedAuthInfo.ClientKeyData = nil//设置ClientKeyData 为nil
			}
		}
	}

	if o.token.Provided() {//如果token有值
		modifiedAuthInfo.Token = o.token.Value()//设置token
		setToken = len(modifiedAuthInfo.Token) > 0//设置setToken 
	}

	if o.username.Provided() {//如果username有值
		modifiedAuthInfo.Username = o.username.Value()//设置Username 
		setBasic = setBasic || len(modifiedAuthInfo.Username) > 0//设置setBasic 
	}
	if o.password.Provided() {//如果password有值
		modifiedAuthInfo.Password = o.password.Value()//设置Password 
		setBasic = setBasic || len(modifiedAuthInfo.Password) > 0//设置setBasic 
	}
	if o.authProvider.Provided() {//乳沟auth-provider有值
		newName := o.authProvider.Value()//获取auth-provider

		// Only overwrite if the existing auth-provider is nil, or different than the newly specified one.
		if modifiedAuthInfo.AuthProvider == nil || modifiedAuthInfo.AuthProvider.Name != newName {//如果authProvider为空获取name不同
			modifiedAuthInfo.AuthProvider = &clientcmdapi.AuthProviderConfig{//设置authProvider
				Name: newName,
			}
		}
	}

	if modifiedAuthInfo.AuthProvider != nil {//如果authProvider不为nil
		if modifiedAuthInfo.AuthProvider.Config == nil {//如果authprovider的config为空
			modifiedAuthInfo.AuthProvider.Config = make(map[string]string)//创建config
		}
		for _, toRemove := range o.authProviderArgsToRemove {// 遍历要删除的providerargs
			delete(modifiedAuthInfo.AuthProvider.Config, toRemove)//删除provider-args
		}
		for key, value := range o.authProviderArgs {//遍历要添加的provider-args
			modifiedAuthInfo.AuthProvider.Config[key] = value//添加provider args
		}
	}

	if o.execCommand.Provided() {//如果exec-command有值
		newExecCommand := o.execCommand.Value()//获取exec-command的值

		// create new Exec if doesn't exist, otherwise just modify the command
		if modifiedAuthInfo.Exec == nil {//如果exec为空,则创建
			modifiedAuthInfo.Exec = &clientcmdapi.ExecConfig{
				Command: newExecCommand,
			}
		} else {
			modifiedAuthInfo.Exec.Command = newExecCommand// 设置command
			// explicitly reset exec arguments
			modifiedAuthInfo.Exec.Args = nil//设置args为空
		}
	}

	// modify next values only if Exec exists, ignore these changes otherwise
	if modifiedAuthInfo.Exec != nil {//如果exec不为空
		if o.execAPIVersion.Provided() {//有过exec-apiversion有值
			modifiedAuthInfo.Exec.APIVersion = o.execAPIVersion.Value()//设置apiVersion
		}

		// rewrite exec arguments list with new values
		if o.execArgs != nil {// 如果args不为空
			modifiedAuthInfo.Exec.Args = o.execArgs//设置args
		}

		// iterate over the existing exec env values and remove the specified
		if o.execEnvToRemove != nil {//如果要删除的env不为空
			newExecEnv := []clientcmdapi.ExecEnvVar{}
			for _, value := range modifiedAuthInfo.Exec.Env {//遍历authinfo的env
				needToRemove := false
				for _, elemToRemove := range o.execEnvToRemove {
					if value.Name == elemToRemove {//如果名称和要删除的相同
						needToRemove = true//设置needtoremove为true
						break
					}
				}
				if !needToRemove {//如果needtoremove为false
					newExecEnv = append(newExecEnv, value)//添加env
				}
			}
			modifiedAuthInfo.Exec.Env = newExecEnv//设置env
		}

		// update or create specified environment variables for the exec plugin
		if o.execEnv != nil {//如果要添加的env不为空
			newEnv := []clientcmdapi.ExecEnvVar{}
			for newEnvName, newEnvValue := range o.execEnv {//遍历要添加env
				needToCreate := true
				for i := 0; i < len(modifiedAuthInfo.Exec.Env); i++ {// 遍历authinfo的env
					if modifiedAuthInfo.Exec.Env[i].Name == newEnvName {// 如果名称相同
						// update the existing value
						needToCreate = false
						modifiedAuthInfo.Exec.Env[i].Value = newEnvValue//设置value
						break
					}
				}
				if needToCreate {//如果needtocreate为true
					// create a new env value
					newEnv = append(newEnv, clientcmdapi.ExecEnvVar{Name: newEnvName, Value: newEnvValue})//追加env
				}
			}
			modifiedAuthInfo.Exec.Env = append(modifiedAuthInfo.Exec.Env, newEnv...)// 追加authinfo的env
		}
	}

	// If any auth info was set, make sure any other existing auth types are cleared
	if setToken || setBasic {//如果setToken或setBasic为true
		if !setToken {// 如果settoken为false
			modifiedAuthInfo.Token = ""//设置Token 
		}
		if !setBasic {//如果setBasic 为false,设置用户名和密码
			modifiedAuthInfo.Username = ""
			modifiedAuthInfo.Password = ""
		}
	}

	return modifiedAuthInfo
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hxpjava1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值