2017年4月25日火曜日

vic-machine ls コマンドをコードからライブラリとして使う方法

概要

VMware VIC は vic-machine というコマンドを提供しておりこれを使って vch を操作します
プログラムから vch を操作したい場合、コードから os.Exec などを使って CLI を実行する方法があります
が、CLI の場合結果をパースしたりエラーハンドリングをしたりするのが大変です
なので、vic-machine コマンドがやっていることをコードから同じように実行してみました

環境

  • Ubuntu 16.04
  • golang 1.8.1
  • vic 0.9.0

vic のインストール

ライブラリ形式で提供されていないため go get が使えません
なので、GOPATH に git clone して無理矢理ライブラリとして利用します

ls を実行するコードの作成

  • mkdir /path/to/work
  • cd /path/to/work
  • vim my_vic_ls.go
package main

import (
        "context"
        "fmt"
        "github.com/vmware/vic/lib/install/data"
        "github.com/vmware/vic/lib/install/management"
        "github.com/vmware/vic/lib/install/validate"
        "net/url"
)

type List struct {
        Data     *data.Data
        executor *management.Dispatcher
}

func NewList() (l *List, err error) {
        l = new(List)
        l.Data = data.NewData()
        u, err := url.Parse("https://192.168.100.101/dc")
        if err != nil {
                return l, err
        }
        l.Data.Target.URL = u
        l.Data.Target.User = "vcenter_username"
        p := "vcenter_password"
        l.Data.Target.Password = &p
        l.Data.Target.Thumbprint = "F9:xx:xx:..."
        l.Data.Force = true
        err = l.Data.Target.HasCredentials()
        if err != nil {
                return l, err
        }
        return l, nil
}

func (l *List) Run() (err error) {
        ctx, cancel := context.WithTimeout(context.Background(), l.Data.Timeout)
        defer cancel()
        validator, err := validate.NewValidator(ctx, l.Data)
        if err != nil {
                return err
        }
        validator.AllowEmptyDC()
        executor := management.NewDispatcher(validator.Context, validator.Session, nil, false)
        vchs, err := executor.SearchVCHs(validator.ClusterPath)
        if err != nil {
                return err
        }
        fmt.Println(vchs)
        return nil
}

func main() {
        l, err := NewList()
        if err != nil {
                fmt.Println(err)
        }
        err = l.Run()
        if err != nil {
                fmt.Println(err)
        }
}
  • go fmt my_vic_ls.go
  • go run my_vic_ls.go

でとりあえず vch の一覧を取得できると思います
vCenter の情報は適宜書き換えて使用してください

解説

流れ的には config して実行しているだけです

まず、NewList 関数で vCenter の認証情報を設定します
ここで一つポイントなのが HasCredentials を呼ばないと vCenter の認証でエラーとなります
なので、必ず呼んでください
vCenter の URL を設定するときにデータセンター名まで指定するとそのデータセンター配下にある vch を取得してくれます

実際に取得している関数は executor.SearchVCHs になります
これが VIC 内で定義されている関数になりライブラリとしてコールしている感じになります
あとは executor.SearchVCHs をコールするために必要な変数などを定義しているだけです

実際に参考したコードは vic-machine の list.go になります

最後に

VMware VIC の CLI 用のコードをライブラリっぽく使ってみました
そもそも godoc にすらなっていないのでコードを見ながら理解しなければいけないのが辛いです

CLI が実装していることと同じようなことをしてるので車輪の再発明的な感じがありますが、ライブラリを使ってクライアントコードを実装していると思えば割りと当たり前のことかなと言う気がします

本来であれば vmware/vic のコードをライブラリ用のコードとして書き換えて go get で取得できるようにして使うのが定石だとは思います
現状はそうなっていないので、無理矢理使ってみました

他のコマンドに関しては同じような実装をしていけば同様にコードから使えるようになると思います
ただ、あくまでも内部では CLI 用のコードとして書かれているのでロギングなどの出力は CLI ベースになってしまいます

参考サイト

0 件のコメント:

コメントを投稿