kubectl源码分析之api-resources

你。 提交于 2020-07-27 22:28:34

发布一个k8s部署视频:https://edu.csdn.net/course/detail/26967

课程内容:各种k8s部署方式。包括minikube部署,kubeadm部署,kubeasz部署,rancher部署,k3s部署。包括开发测试环境部署k8s,和生产环境部署k8s。

腾讯课堂连接地址https://ke.qq.com/course/478827?taid=4373109931462251&tuin=ba64518

第二个视频发布  https://edu.csdn.net/course/detail/27109

腾讯课堂连接地址https://ke.qq.com/course/484107?tuin=ba64518

介绍主要的k8s资源的使用配置和命令。包括configmap,pod,service,replicaset,namespace,deployment,daemonset,ingress,pv,pvc,sc,role,rolebinding,clusterrole,clusterrolebinding,secret,serviceaccount,statefulset,job,cronjob,podDisruptionbudget,podSecurityPolicy,networkPolicy,resourceQuota,limitrange,endpoint,event,conponentstatus,node,apiservice,controllerRevision等。

第三个视频发布:https://edu.csdn.net/course/detail/27574

详细介绍helm命令,学习helm chart语法,编写helm chart。深入分析各项目源码,学习编写helm插件

第四个课程发布:https://edu.csdn.net/course/detail/28488

本课程将详细介绍k8s所有命令,以及命令的go源码分析,学习知其然,知其所以然
————————————————

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
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!