欢迎关注我的公众号:
目前刚开始写一个月,一共写了18篇原创文章,文章目录如下:
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
}