k8s学习之cobra命令库学习
1.前言
打开k8s代码的时候,我发现基本上那几个核心服务都是使用cobra库作为命令行处理的能力。因此,为了对代码之后的代码学习的有比较深入的理解,因此先基于这个库写个demo,加深对这个库的一些理解吧
2.cobra库的基本简介
Github:GitHub - spf13/cobra: A Commander for modern Go CLI interactions 在这里了,Cobra是一个用Go语言实现的命令行工具。并且现在正在被很多项目使用,例如:Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速的创建命令行工具,特别适合写 测试脚本
,各种服务的 Admin CLI
等。
因为命令行参数,golang本身自带了"flag" 库,使用flag库呢
flag.Parse()
args := flag.Args()
解析完之后,需要每个命令去判断,十分的麻烦。
但是我们在使用到时候,需要针对命令行进行各种解析判断,但是有了这个库,我们就可以减少这段冗余的代码了
3 cobra的使用demo
话不多说,我们直接给出怎么用这个项目。我的环境是在macos上。
3.1 首先下载依赖库
命令行执行
go get -u github.com/spf13/cobra@latest
3.2 命令行CLI工具
$ go install github.com/spf13/cobra-cli@latest
因为我本身我的golang代码路径已经建好了bin目录,因此,执行完该命令后,如下
我们看到了cobra-cli的可执行文件。
这边是我们可以在命令用这个东西,进行初始化了。集体步骤如下
xxx@MBP src % mkdir greet
xxx@MBP src % cd greet
xxx@MBP test % ls
xxx@MBP greet % cobra-cli init
Error: Please run `go mod init <MODNAME>` before `cobra-cli init`
xxx@MBP greet % go mod init greet
go: creating new go.mod: module greet
xxx@MBP greet % ls
go.mod
xxx@MBP greet % cobra-cli init
Your Cobra application is ready at
/Users/XXX/workspace/golang/src/greet
xxx@MBP greet % ls
LICENSE cmd go.mod go.sum main.go
xxx@MBP greet %
第一步先建好一个test目录,然后执行go mod init test,然后再执行cobra-cli init的命令行,就会生成了脚手架文件了。
目录中会产生一下文件:
main.go cmd LICENSE go.mod go.sum
├── LICENSE
├── cmd
│ └── root.go
└── main.gogo.mod go.sum
3.3 编写代码文件
刚刚生成的文件,因为没有加具体的命令选项,可能用处不大,因此我们继续执行,添加一个命令字
cobra-cli add [command]
这样,他就会又生成了一个文件。
比如执行
cobra-cli add greet
// Package cmd /*
package cmd
import ("fmt"
"github.com/spf13/cobra"
)
// greetCmd represents the greet command
var greetCmd = &cobra.Command{Use: "greet",Short: "A brief description of your command",Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:
Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,Run: func(cmd *cobra.Command, args []string) {// 这段代码是我加的。if len(args) < 1 {cmd.Help()return}name := args[0]fmt.Println("greet called:", name)},
}
func init() {rootCmd.AddCommand(greetCmd)
// Here you will define your flags and configuration settings.
// Cobra supports Persistent Flags which will work for this command// and all subcommands, e.g.:// greetCmd.PersistentFlags().String("foo", "", "A help for foo")
// Cobra supports local flags which will only run when this command// is called directly, e.g.:greetCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}
因此,我们可以看到,新增了greet的命令。
然后我们编译一下,生成目标文件,后我们执行以下
./greetA longer description that spans multiple lines and likely contains
examples and usage of using your application. For example:
Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.
Usage:greet [command]
Available Commands:completion Generate the autocompletion script for the specified shellgreet A brief description of your commandhelp Help about any commandmockMsg A brief description of your command
Flags:-h, --help help for greet-t, --toggle Help message for toggle
Use "greet [command] --help" for more information about a command.
以上我们通过返回的内容,可以看出多了一个gree的子命令。
并且可以加flag,比如-h
上边的Run 就可以放我们想要处理的业务逻辑了。
如果我们想增加一些flag 值,只需要能够在run里边添加如下代码即可
g, _ := cmd.Flags().GetInt32("goroutine")p, _ := cmd.Flags().GetInt32("packet")fmt.Println("mockmsg called,flags:g=", g, ",p=", p, ",args:", args)
比如我们实现如下:
Run: func(cmd *cobra.Command, args []string) {if len(args) < 1 {cmd.Help()return}name := args[0]fmt.Println("greet called:", name)
g, _ := cmd.Flags().GetInt32("goroutine")p, _ := cmd.Flags().GetInt32("packet")fmt.Println("mockmsg called,flags:g=", g, ",p=", p, ",args:", args)},
这样,问可以这样使用了
./greet greet xx -p 10 -g 100
greet called: xx
greetCmd called,flags:g= 100 ,p= 10 ,args: [xx]
4 K8s中如何使用
我主要是看了kubctl模块的代码,我发现这个模块对cmd这块又进行了更丰富的封装,用以支持更加复杂的场景。
其中我们从kubectl的main开始
一个入口方法
// NewDefaultKubectlCommand creates the `kubectl` command with default arguments
func NewDefaultKubectlCommand() *cobra.Command {ioStreams := genericiooptions.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr}return NewDefaultKubectlCommandWithArgs(KubectlOptions{PluginHandler: NewDefaultPluginHandler(plugin.ValidPluginFilenamePrefixes),Arguments: os.Args,ConfigFlags: defaultConfigFlags().WithWarningPrinter(ioStreams),IOStreams: ioStreams,})
}
因为kubectl是可以对文件,以及flag进行处理使用的,因此,需要针对这种情况各种设置参数,我们发现已经充分利用了cmd结构体的内各个字段
其中 这两个方法是核心方法,基本上是初始化并赋值给command的结构了
// NewDefaultKubectlCommandWithArgs creates the `kubectl` command with arguments
func NewDefaultKubectlCommandWithArgs(o KubectlOptions) *cobra.Command {cmd := NewKubectlCommand(o)
其中在NewKubectlCommand 就是用来new cmd实例的。
func NewKubectlCommand(o KubectlOptions) *cobra.Command {warningHandler := rest.NewWarningWriter(o.IOStreams.ErrOut, rest.WarningWriterOptions{Deduplicate: true, Color: term.AllowsColorOutput(o.IOStreams.ErrOut)})warningsAsErrors := false// Parent command to which all subcommands are added.cmds := &cobra.Command{Use: "kubectl",
这个就是 我么看到的kubectl的命令的使用地方了,因为本文主要是讲command的使用,因此k8s的其他get命令等先不赘述,下一篇在讲
下面是具体贴一下Command具体的相关的字段了意思了
以下是对 `Command` 结构体中每个字段的详细解释:
1. `Use`:这是一个字符串,用于描述命令的基本使用方式。它规定了命令所需的参数和可选参数的格式,为用户提供了简洁明了的使用指导。- 例如:`"add [-F file | -D dir]... [-f format] profile"` 表示 `add` 命令可以有可选的 `-F` 和 `-D` 参数,其中 `-F` 后跟一个文件,`-D` 后跟一个目录,这两个参数是互斥的,并且可以多次出现,还有一个可选的 `-f` 参数后跟格式信息,最后需要一个 `profile` 参数。
2. `Aliases`:一个字符串切片,存储了该命令的别名。这使得用户可以通过不同的名称来调用同一个命令,增加了命令使用的灵活性。- 比如:`["add_item", "insert"]` 是 `add` 命令的别名。
3. `SuggestFor`:也是一个字符串切片,其中包含了此命令可能被建议替代的其他命令名称。这有助于在用户输入类似但不完全准确的命令时提供相关的建议。
4. `Short`:一个简短的字符串,用于在帮助输出中提供命令的简短描述,让用户快速了解命令的主要功能。- 例如:"添加新的项目"
5. `GroupID`:指定该子命令在其父命令的“帮助”输出中所属的组标识,便于对命令进行分组展示和管理。
6. `Long`:详细的长字符串,在“帮助 <此命令>”输出中提供更全面和深入的命令描述,包括更多的功能细节、使用示例、注意事项等。
7. `Example`:包含命令使用的示例字符串,通过实际的例子帮助用户更好地理解如何正确使用该命令。
8. `ValidArgs`:一个字符串切片,列出了在外壳自动补全中所有有效的非标志参数。
9. `ValidArgsFunction`:一个函数,动态地提供有效的非标志参数用于外壳自动补全,是一种更灵活的参数提供方式。
10. `Args`:定义了预期的参数的相关规则和处理方式。
11. `ArgAliases`:一个字符串切片,列出了有效参数的别名,这些别名不会在外壳自动补全中被提示,但手动输入时会被接受。
12. `BashCompletionFunction`:用于传统 Bash 自动补全生成器的自定义 Bash 函数,为特定的 Bash 环境提供定制的自动补全功能。
13. `Deprecated`:如果命令已被弃用,存储了使用该命令时将显示的提示信息,告知用户该命令不应再被使用。
14. `Annotations`:一个键值对映射,允许应用程序为命令添加自定义的标识、分组或特殊选项等元数据。
15. `Version`:存储命令的版本信息,用于版本控制和显示。
16. 各种 `Run` 函数:- `PersistentPreRun` 和 `PersistentPreRunE`:在命令执行前被调用,且子命令会继承并执行,用于进行一些持久的预处理操作。- `PreRun` 和 `PreRunE`:在命令执行前被调用,但子命令不会继承,用于特定于当前命令的预处理。- `Run` 和 `RunE`:实际的工作函数,实现命令的主要逻辑。- `PostRun` 和 `PostRunE`:在 `Run` 函数执行后被调用,用于进行后续的处理操作。
17. `commandgroups`:一个指针切片,指向子命令所属的组对象。
18. `args`:实际从标志解析得到的参数切片。
19. `flagErrorBuf`:一个字节缓冲区,用于存储来自 `pflag` 的错误消息。
20. `flags`:一个 `flag.FlagSet` 对象,包含了所有的标志。
21. `pflags`:存储持久的标志。
22. `lflags`:本地标志的缓存,用于优化 `LocalFlags` 函数调用。
23. `iflags`:继承的标志的缓存,用于优化相关函数调用。
24. `parentsPflags`:父命令的所有持久标志。
25. `globNormFunc`:一个全局的标准化函数,用于处理标志名称的标准化。
26. `usageFunc`:用户定义的使用函数,用于自定义命令的使用说明。
27. `usageTemplate`:用户定义的使用模板。
28. `flagErrorFunc`:用户定义的标志错误处理函数。
29. `helpTemplate`:用户定义的帮助模板。
30. `helpFunc`:用户定义的帮助函数。
31. `helpCommand`:具有“帮助”用途的命令,如果用户未定义,则使用默认的帮助命令。
32. `helpCommandGroupID`:帮助命令所属的组标识。
33. `completionCommandGroupID`:自动完成命令所属的组标识。
34. `versionTemplate`:用户定义的版本模板。
35. `errPrefix`:用户定义的错误消息前缀。
36. `inReader`:用户定义的输入读取器,替代标准输入。
37. `outWriter`:用户定义的输出写入器,替代标准输出。
38. `errWriter`:用户定义的错误输出写入器,替代标准错误输出。
39. `FParseErrWhitelist`:要忽略的标志解析错误的列表。
40. `CompletionOptions`:用于控制外壳自动完成的选项。
41. `commandsAreSorted`:一个布尔值,指示命令切片是否已排序。
42. `commandCalledAs`:一个结构体,记录命令被调用时的名称和是否被调用的状态。
43. `ctx`:上下文对象,用于传递和管理命令执行的上下文信息。
44. `commands`:一个指针切片,包含此命令支持的子命令。
45. `parent`:指向该命令的父命令的指针。
46. `Max lengths` 相关字段:记录命令相关字符串的最大长度,用于格式化和展示。
47. `TraverseChildren`:一个布尔值,决定是否在执行子命令之前解析所有父命令的标志。
48. `Hidden`:如果为真,该命令将在可用命令列表中隐藏,不向用户显示。
49. `SilenceErrors`:一个布尔值,用于控制是否静默处理错误。
50. `SilenceUsage`:一个布尔值,用于控制在发生错误时是否静默使用信息。
51. `DisableFlagParsing`:如果为真,将禁用标志解析,所有标志将作为参数传递给命令。
52. `DisableAutoGenTag`:如果为真,在生成文档时将禁用自动生成的标签。
53. `DisableFlagsInUseLine`:如果为真,将在使用行中禁用标志的添加。
54. `DisableSuggestions`:如果为真,将禁用基于编辑距离的建议功能。
55. `SuggestionsMinimumDistance`:定义显示建议的最小编辑距离,必须大于 0 。
5 总结
本篇文章主要是一步步的吧cobra这个库如何使用等进行了详细的解释,我们在使用这个库的时候,比较能够理解他工作的原理,然后再根据具体的k8s如何使用以及具体字段的使用来充分发挥cmd的能力和价值
相关文章:

k8s学习之cobra命令库学习
1.前言 打开k8s代码的时候,我发现基本上那几个核心服务都是使用cobra库作为命令行处理的能力。因此,为了对代码之后的代码学习的有比较深入的理解,因此先基于这个库写个demo,加深对这个库的一些理解吧 2.cobra库的基本简介 Git…...

Spring框架的学习SpringMVC(1)
1.什么是MVC (1)MVC其实就是软件架构的一种设计模式,它将软件的系统分为,(视图,模型,控制器)三个部分 1.1View(视图) 视图也就是,在浏览器显示的那一个部分,是后端数据的呈现 1.…...

赋值运算符重载和const成员函数和 const函数
文章目录 1.运算符重载(1)(2)运算符重载的语法:(3)运算符重载的注意事项:(4)前置和后置重载区别 2.const成员函数3.取地址及const取地址操作符重载4.总结 1.运算符重载 (1) 我们知道内置类型(整形,字符型,浮点型…)可以进行一系…...

VSCode设置字体大小
方法1:Ctrl 和 Ctrl -,可以控制整个VSCode界面的整体缩放,但是不会调整字体大小 方法2:该方法只能设置编辑器界面的字号,无法改变窗口界面的字号。 (1)点开左下角如下图标,进入…...

Excel中按列的首行字母顺序,重新排列(VBA脚本)
排序前 要求对4列数据按照第一行abcd的顺序排列 VB脚本如下: 要使用这个脚本,请按照以下步骤操作: 打开Excel,然后按下 Alt F11 打开VBA编辑器。在VBA编辑器中,选择“插入” > “模块”,在打开的模块…...
多线程爬虫技术详解
🎀引言❤❤ 在当今信息爆炸的时代,网络爬虫(Web Crawler)作为一种自动获取网页内容的程序,已经成为数据挖掘和信息检索不可或缺的工具。多线程爬虫作为提高爬虫效率的重要手段,通过并行处理技术大幅度提升…...

项目一单机安装基于LNMP结构的WordPress网站 web与数据库服务分离
网站的类型: Jave:LNMT PHP:LNMP Python: LNMU 项目部署: 1.项目的类型(项目的开发语言) 2.项目运营平台的技术选择 3.尽快让项目运行起来 all in one部署 4. 架构的优化 配置ansible管理环境 配置nginx 配置数据库服务…...

vue事件处理v-on或@
事件处理v-on或 我们可以使用v-on指令(简写)来监听DOM事件,并在事件触发时执行对应的Javascript。用法:v-on:click"methodName"或click"hander" 事件处理器的值可以是: 内敛事件处理器࿱…...

使用OpenCV与PySide(PyQt)的视觉检测小项目练习
OpenCV 提供了丰富的图像处理和计算机视觉功能,可以实现各种复杂的图像处理任务,如目标检测、人脸识别、图像分割等。 PyQt(或PySide)是一个创建GUI应用程序的工具包,它是Python编程语言和Qt库的成功融合。Qt库是最强大的GUI库之一。Qt的快速…...

通信协议_C#实现自定义ModbusRTU主站
背景知识:modbus协议介绍 相关工具 mbslave:充当从站。虚拟串口工具:虚拟出一对串口。VS2022。 实现过程以及Demo 打开虚拟串口工具: 打开mbslave: 此处从站连接COM1口。 Demo实现 创建DLL库,创建ModbusRTU类,进行实现: using Syste…...

【C语言】 —— 编译和链接
【C语言】 —— 编译和链接 一、编译环境和运行环境二、翻译环境2.1、 预处理2.2、 编译(1)词法分析(2)语法分析(3)语义分析 2.3、 汇编2.4、链接 三、运行环境 一、编译环境和运行环境 平时我们说写 C语言…...

DNS正向解析与反向解析实验
正向解析 安装bind软件 [rootlocalhost ~]# dnf install bind bind-utils -y修改主配置文件/etc/named.conf [rootlocalhost ~]# vim /etc/named.conf重启DNS服务(named) [rootlocalhost ~]# systemctl restart named编辑数据配置文件。在/var/named…...

机器学习简介--NLP(二)
机器学习简介 机器学习简介机器学习例子机器学习分类有监督学习有监督学习的应用 无监督学习 机器学习常见概念数据集k折交叉验证过拟合欠拟合评价指标 机器学习简介 机器学习例子 问题: 2,4,6,8,?&#…...

Winform中使用HttpClient实现调用http的post接口并设置传参content-type为application/json示例
场景 Winform中怎样使用HttpClient调用http的get和post接口并将接口返回json数据解析为实体类: Winform中怎样使用HttpClient调用http的get和post接口并将接口返回json数据解析为实体类_winform解析json-CSDN博客 上面使用HttpClient调用post接口时使用的HttpCon…...

【RAG探索第3讲】LlamaIndex的API调用与本地部署实战
原文链接:【RAG探索第3讲】LlamaIndex的API调用与本地部署实战 今天是2024年7月5日,星期五,天气晴,北京。 RAG的文章也看不少了,今天给大家带来一个llamaindex的实战。分为两个部分,调用ChatGLM的API来用l…...
C# —— 日期对象
DateTime 时间类 存储时间对象 可以获取当前时间 DateTime now DateTime.Now;// 获取当前时间 Console.WriteLine("年:" now.Year);//2023 Console.WriteLine("月:" now.Month);//9 Console.WriteLine("日:" now.Day);//12 Console.WriteLi…...

【MySQL04】【 redo 日志】
文章目录 一、前言二、redo 日志1. redo 日志格式2. Mini-Transaction2.1 以组的形式写入 redo 日志2.2 Mini-Transaction (MTR)概念 3. redo 日志写入过程3.1 redo 日志缓冲区3.3 redo 日志写入 log buffer 4. redo 日志文件4.1 redo 日志刷盘机制4.2 r…...

Android线性布局的概念与属性
线性布局(LinearLayout)是Android中最简单的布局方式,线性布局方式会使得所有在其内部的控件或子布局按一条水平或垂直的线排列。如图所示,图a是纵向线性布局示意图,图b是横向线性布局示意图。 a)纵向线性布局示意图 …...

java反射介绍
Java反射API允许你在运行时检查和修改程序的行为。这意味着你可以动态地创建对象、查看类的字段、方法和构造函数,甚至调用它们。这是一个强大的特性,但也应该谨慎使用,因为它可以破坏封装性。 以下是使用Java反射的一些常见用途:…...
Spring中@Transactional的实现和原理
这篇文章写的很详细了,引自脚本之家 Java中SpringBoot的Transactional原理_java_脚本之家...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...

dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...

2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...

接口自动化测试:HttpRunner基础
相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具,支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议,涵盖接口测试、性能测试、数字体验监测等测试类型…...