欢迎关注我的公众号:
目前刚开始写一个月,一共写了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 APIResourceOptions struct {//apiResource结构体
Output string
APIGroup string
Namespaced bool
Verbs []string
NoHeaders bool
Cached bool
genericclioptions.IOStreams
}
func NewAPIResourceOptions(ioStreams genericclioptions.IOStreams) *APIResourceOptions {
return &APIResourceOptions{//初始化结构体
IOStreams: ioStreams,
Namespaced: true,
}
}
//创建apiResources命令
func NewCmdAPIResources(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
o := NewAPIResourceOptions(ioStreams)//初始化结构体
cmd := &cobra.Command{//创建cobra命令
Use: "api-resources",
Short: "Print the supported API resources on the server",
Long: "Print the supported API resources on the server",
Example: apiresourcesExample,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(cmd, args))//准备
cmdutil.CheckErr(o.Validate())//校验
cmdutil.CheckErr(o.RunAPIResources(cmd, f))//运行
},
}
cmd.Flags().BoolVar(&o.NoHeaders, "no-headers", o.NoHeaders, "When using the default or custom-column output format, don't print headers (default print headers).")//no-headers选项
cmd.Flags().StringVarP(&o.Output, "output", "o", o.Output, "Output format. One of: wide|name.")//output选项
cmd.Flags().StringVar(&o.APIGroup, "api-group", o.APIGroup, "Limit to resources in the specified API group.")//api-group选项
cmd.Flags().BoolVar(&o.Namespaced, "namespaced", o.Namespaced, "If false, non-namespaced resources will be returned, otherwise returning namespaced resources by default.")//namespaced选项
cmd.Flags().StringSliceVar(&o.Verbs, "verbs", o.Verbs, "Limit to resources that support the specified verbs.")//verbs选项
cmd.Flags().BoolVar(&o.Cached, "cached", o.Cached, "Use the cached list of resources if available.")//cached选项
return cmd
}
准备
func (o *APIResourceOptions) Complete(cmd *cobra.Command, args []string) error {
if len(args) != 0 {//参数不等于0个报错
return cmdutil.UsageErrorf(cmd, "unexpected arguments: %v", args)
}
return nil
}
//校验
func (o *APIResourceOptions) Validate() error {
supportedOutputTypes := sets.NewString("", "wide", "name")
if !supportedOutputTypes.Has(o.Output) {//output必须是name或wide
return fmt.Errorf("--output %v is not available", o.Output)
}
return nil
}
//运行
func (o *APIResourceOptions) RunAPIResources(cmd *cobra.Command, f cmdutil.Factory) error {
w := printers.GetNewTabWriter(o.Out)//获取writer
defer w.Flush()
discoveryclient, err := f.ToDiscoveryClient()//获取discoveryClient
if err != nil {
return err
}
if !o.Cached {//如果没有指定cache
// Always request fresh data from the server
discoveryclient.Invalidate()//使缓存失效
}
errs := []error{}
lists, err := discoveryclient.ServerPreferredResources()//获取资源列表
if err != nil {
errs = append(errs, err)
}
resources := []groupResource{}//创建groupResource slice
groupChanged := cmd.Flags().Changed("api-group")//判断api-group是否设置
nsChanged := cmd.Flags().Changed("namespaced")//判断namespaced是否设置
for _, list := range lists {//遍历list
if len(list.APIResources) == 0 {//如果apiReosurce为空则跳过
continue
}
gv, err := schema.ParseGroupVersion(list.GroupVersion)//解析GroupVersion
if err != nil {
continue
}
for _, resource := range list.APIResources {//遍历ApiResources
if len(resource.Verbs) == 0 {//如果动作为空,跳过
continue
}
// filter apiGroup
if groupChanged && o.APIGroup != gv.Group {//设置了api-group,group不相等则跳过
continue
}
// filter namespaced
if nsChanged && o.Namespaced != resource.Namespaced {//设置了namespaced,namespaced不相等则跳过
continue
}
// filter to resources that support the specified verbs
if len(o.Verbs) > 0 && !sets.NewString(resource.Verbs...).HasAll(o.Verbs...) {//设置了verbs,如果资源的verbs,不包含所有的设置的verbs则表过
continue
}
resources = append(resources, groupResource{// append groupResource
APIGroup: gv.Group,
APIResource: resource,
})
}
}
if o.NoHeaders == false && o.Output != "name" {//如果没有指定no-headers,并且output不为name
if err = printContextHeaders(w, o.Output); err != nil {//打印头
return err
}
}
sort.Stable(sortableGroupResource(resources))//对groupResources进行排序
for _, r := range resources {//遍历groupResoruces
switch o.Output {
case "name"://如果output为name
name := r.APIResource.Name
if len(r.APIGroup) > 0 {
name += "." + r.APIGroup
}
if _, err := fmt.Fprintf(w, "%s\n", name); err != nil {//打印name
errs = append(errs, err)
}
case "wide"://如果output为wide
if _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%v\t%s\t%v\n",
r.APIResource.Name,
strings.Join(r.APIResource.ShortNames, ","),
r.APIGroup,
r.APIResource.Namespaced,
r.APIResource.Kind,
r.APIResource.Verbs); err != nil {//打印拼接的字符串
errs = append(errs, err)
}
case ""://如果output为空
if _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%v\t%s\n",
r.APIResource.Name,
strings.Join(r.APIResource.ShortNames, ","),
r.APIGroup,
r.APIResource.Namespaced,
r.APIResource.Kind); err != nil {// 打印拼接的字符串
errs = append(errs, err)
}
}
}
if len(errs) > 0 {
return errors.NewAggregate(errs)
}
return nil
}
//打印头
func printContextHeaders(out io.Writer, output string) error {
columnNames := []string{"NAME", "SHORTNAMES", "APIGROUP", "NAMESPACED", "KIND"}
if output == "wide" {//如果是wide,增加verbs
columnNames = append(columnNames, "VERBS")
}
_, err := fmt.Fprintf(out, "%s\n", strings.Join(columnNames, "\t"))// 打印头
return err
}