使用Golang开发OpenStack服务的CLI
由于我们需要编写自己服务的客户端,之前参考过magnum的python客户端,编写过一个,整体感受就是: 一件简单的事儿,被他封装的很复杂,而且还有一个关键痛点,部署问题: 1.依赖python环境 2. 蹩脚的二进制打包方式。因此,作为一个产品的CLI,以二进制方式交付会带来诸多方便,比如cloud foundry也用golang重写了他的客户端部分。
Cobra简介
在博客的开篇写过一篇cobra的博客: 如何使用golang编写漂亮的命令行工具, 很多流行的CLI都基于这个库开发,比如kubectl, etcdctl, docker等, 基本的概念和用法请参考之前的博客。
基于RESTful的CLI
打造的这个CLI是RESTful的客户端, 在RESTful里面以资源(Resource)为核心,因此客户端也需要以资源的形式表现, 比如Docker的 Management Commands:
该资源允许的操作:
因此, 轮廓上我们需要打造这样一种风格的RESTful CLI
OpenStack服务 CLI
我们的OpenStack服务是自己开发的, 开发出来的CLI风格想要和Openstack社区风格一致(长相相近), 这东西社区是没有Golang版本的(有的话给我留言, 我真没找到), 因此整个架子需要自己构建, 由于cobra架子比较成熟, 如果只用官方的Flag库来做的话,会有很多重复工作, 因此使用cobra为基础来进行构建。
要做成和Openstack风格类似的CLI, 在cobra的基础上我们需要加入2个组件:
keystone认证: 对每一个资源的访问必须通过keystone认证才能访问, 因此认证部分是全局的。表格输出: OpenstackCLI把资源以Table的方式输出, 这个也需要单独实现。
搭建CLI架子
初始化app, 添加resourceA和resourceB
访问每一个resource都需要经过keystone的认证,因此认证属于一个全局都要执行的逻辑, 必须放在最前面,这里Cobra提供的一组Hook可以解决这个问题
带错误处理的Hook
当处理过程中如果产生了error可以直接return出来, 从而中断命令的继续执行, 因此认证部分我们需要这种带错误处理的Hook, 因为认证失败需要中断请求,
其次,cobra 在命令函数的执行前后分别设置了2组Hook, 执行的顺序如下:
PersistentPreRunE: 无论函数 执不执行 该函数都会运行
PreRunE: 在函数执行前执行
RunE: 执行函数
PostRunE: 函数执行后执行
PersistentPostRunE: 无论函数 执不执行 该函数都会执行
利用cobra提供的PersistentPreRunE来实现验证功能
auth函数实现认证并不难, 关键是auth过后的token 如何传递给后面的子命令使用, 参考etcdctl和docker部分都使用上下文来实现这个需求, cobra里面也没有地方给我存上下文, 因此需要专门用一个模块来保持 全局的上下文, 因此需要手动实现一个common包。
最后在common包里面添加2个子包: keystone, printTable, keystone 用于实现与keystone认证的过程, printTable用于打印最后结果的表格,具体详情请看源码。
添加资源
为每一个资源添加5个基础的操作:get, list, create, delete, update。另起一个resourceA的包,实现这些方法,添加到子命令即可, 比如:
大概效果如下
使用效果
和使用openstack一样,你需要有一个admin_openrc 用于导入环境变量
比如