2017年4月13日木曜日

govmomi を試してみた

概要

vSphere の API を golang でコールするのに govmomi というライブラリがあります
今回はこれを使って vCenter から情報を取得したりしてみました

環境

  • Ubuntu 16.04
  • golang 1.8
  • govmomi 0.14.0

ライブラリインストール

  • go get github.com/vmware/govmomi

とりあえず vCenter に接続する

  • vim connect.go
package main

import (
        "context"
        "flag"
        "fmt"
        "net/url"
        "os"

        "github.com/vmware/govmomi"
)

var envURL = "https://192.168.100.101/sdk"
var urlDescription = fmt.Sprintf("ESX or vCenter URL [%s]", envURL)
var urlFlag = flag.String("url", envURL, urlDescription)

var envInsecure = true
var insecureDescription = fmt.Sprintf("Don't verify the server's certificate chain [%s]", envInsecure)
var insecureFlag = flag.Bool("insecure", envInsecure, insecureDescription)

func main() {
        ctx, cancel := context.WithCancel(context.Background())
        defer cancel()
        flag.Parse()
        u, err := url.Parse(*urlFlag)
        if err != nil {
                fmt.Println(err)
                os.Exit(1)
        }
        u.User = url.UserPassword("vcenter_user", "vcenter_pass")
        c, err := govmomi.NewClient(ctx, u, *insecureFlag)
        if err != nil {
                fmt.Println(err)
                os.Exit(1)
        }
        fmt.Println(c.Client.Client.Version)
}

設定する箇所は envURL の部分と url.UserPassword の部分です
それぞれ vCenter の IP とユーザ名、パスワードを設定してください

とりあえずこれでエラーにならなければ vCenter には接続できています

データセンターの情報を取得する

import に以下を追加してください

"github.com/vmware/govmomi/find"

main の部分に以下を追記してください

f := find.NewFinder(c.Client, true)
dc, err := f.DefaultDatacenter(ctx)
if err != nil {
        fmt.Println(err)
        os.Exit(1)
}
f.SetDatacenter(dc)
fmt.Println(dc)

これでデータセンターの情報を取得できます

データストアのリストを取得する

import に以下を追加してください

"github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types'

main の部分に以下を追記します

dss, err := f.DatastoreList(ctx, "*")
if err != nil {
        fmt.Println(err)
        os.Exit(1)
}
pc := property.DefaultCollector(c.Client)
var refs []types.ManagedObjectReference
for _, ds := range dss {
        fmt.Println(ds.Common.InventoryPath)
        refs = append(refs, ds.Reference())
}
var dst []mo.Datastore
err = pc.Retrieve(ctx, refs, nil, &dst)
if err != nil {
        fmt.Println(err)
        os.Exit(1)
}
for _, ds := range dst {
        fmt.Println(ds.Summary.Name)
        fmt.Println(ds.Summary.Type)
        fmt.Println(ds.Summary.Capacity)
        fmt.Println(ds.Summary.FreeSpace)
}

いきなりややこしくなった感があります
まず f.DatastoreList でデータストアのリストを取得します
このままだと InventoryPath しか取得できないので一旦ループさせて types.ManagedObjectReference の配列を作成します

さらにその配列をループさせて mo.Datastore の配列を作成します
この配列の中にデータストアのいろいろな情報が詰め込まれています
その詰め込むための関数が用意されていて property.DefaultCollector -> pc.Retrieve をコールします
これの 3 番目の引数に今回は nil を指定していますが、ここに ManagedObjectReference で設定したい値だけ設定することができます
例えば []string{"summary"} と指定すると summary の情報だけ設定することができます

設定した値はポインタで渡した dst に設定されるので、これを参照することでデータストアの詳細なデータにアクセスできます
dst から参照できるフィールドは mo の godoc を見ながらやるとわかりやすいと思います
更にその配下の構造体にさわる場合は godoc がなかったのどんなフィールドがあるかは直接ソースを見るしかなさそうです

VM のリストを取得する

main の部分に以下を追記します

refs = []types.ManagedObjectReference{}
vss, err := f.VirtualMachineList(ctx, "*")
if err != nil {
        fmt.Println(err)
        os.Exit(1)
}
for _, vs := range vss {
        fmt.Println(vs.Common.InventoryPath)
        refs = append(refs, vs.Reference())
}
var vdst []mo.VirtualMachine
err = pc.Retrieve(ctx, refs, nil, &vdst)
if err != nil {
        fmt.Println(err)
        os.Exit(1)
}
for _, vs := range vdst {
        fmt.Println(vs.Summary.Guest.GuestId)
        fmt.Println(vs.Summary.Guest.GuestFullName)
        fmt.Println(vs.Summary.Guest.HostName)
        fmt.Println(vs.Summary.Guest.IpAddress)
        fmt.Println(vs.Summary.Config.Name)
        fmt.Println(vs.Summary.Config.VmPathName)
        fmt.Println(vs.Summary.Config.MemorySizeMB)
        fmt.Println(vs.Summary.Config.NumCpu)
}

refs は設定し直します
f.VirtualMachineList を代わりにコールします
あとは pc.Retrieve を使って []mo.VirtualMachine に値を設定します

設定した dst のフィールドの値を参照することで VM の値を取得します

最後に

とりあえず取得系だけ試してみました
結構クセがある感じはしましたが、慣れればそれほど難しくはなさそうです

あとは update や post 系の処理がどんな感じかも試してみたいなと思います

参考サイト

0 件のコメント:

コメントを投稿