使用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 用于導入環境變量
比如