2017年4月17日月曜日

govmomi で指定のフォルダ配下の VM を取得する方法

概要

vSphpere 上のあるデータセンター配下に作成されたフォルダ配下に存在する VM の情報を取得してみました
今回は VM の名前と IP アドレスを取得するサンプルを紹介します

環境

  • Ubuntu 16.04
  • golang 1.8
  • govmomi 0.14.0

ソースコード

  • vim find_vm_sample.go
package main

import (
        "context"
        "flag"
        "fmt"
        "net/url"
        "os"
        "github.com/vmware/govmomi"
        "github.com/vmware/govmomi/find"
        "github.com/vmware/govmomi/object"
        "github.com/vmware/govmomi/property"
        "github.com/vmware/govmomi/vim25/mo"
        "github.com/vmware/govmomi/vim25/types"
)

type MyVCenter struct {
        URL           string
        User          string
        Pass          string
        Insecure      bool
        URLFlag       *string
        InsecureFlag  *bool
        Network       string
        GovmomiClient *govmomi.Client
        Finder        *find.Finder
        DC            *object.Datacenter
}

func NewMyVC() (myvc *MyVCenter) {
        myvc = new(MyVCenter)
        myvc.URL = "https://192.168.100.101/sdk"
        myvc.User = "vcenter-username"
        myvc.Pass = "vcenter-password"
        myvc.Insecure = true
        myvc.URLFlag = flag.String("url", myvc.URL, "")
        myvc.InsecureFlag = flag.Bool("insecure", myvc.Insecure, "")
        myvc.Network = "VM Network"
        flag.Parse()
        return myvc
}

func (myvc *MyVCenter) Init() (err error) {
        ctx, cancel := context.WithCancel(context.Background())
        defer cancel()
        u, err := url.Parse(*myvc.URLFlag)
        if err != nil {
                return err
        }
        u.User = url.UserPassword(myvc.User, myvc.Pass)
        c, err := govmomi.NewClient(ctx, u, *myvc.InsecureFlag)
        if err != nil {
                return err
        }
        f := find.NewFinder(c.Client, true) // true にするとディレクトリの場合も再帰的に検索してくれる
        dc, err := f.DefaultDatacenter(ctx)
        if err != nil {
                return err
        }
        f.SetDatacenter(dc)
        myvc.GovmomiClient = c
        myvc.Finder = f
        myvc.DC = dc
        return nil
}

func (myvc *MyVCenter) FindVMs(folder string) (err error) {
        ctx, cancel := context.WithCancel(context.Background())
        defer cancel()
        dci := myvc.DC.Common.InventoryPath
        path := fmt.Sprintf("%s/vm/%s/*", dci, folder) // フォルダは /dc/vm/folder という構造になっている
        vss, err := myvc.Finder.VirtualMachineList(ctx, path)
        if err != nil {
                return err
        }
        refs := []types.ManagedObjectReference{}
        for _, vs := range vss {
                refs = append(refs, vs.Reference())
        }
        vdst := []mo.VirtualMachine{}
        pc := property.DefaultCollector(myvc.GovmomiClient.Client)
        err = pc.Retrieve(ctx, refs, nil, &vdst)
        if err != nil {
                return err
        }
        for _, vs := range vdst {
                fmt.Println(vs.Summary.Config.Name)
                for _, n := range vs.Guest.Net {
                        if n.Network == myvc.Network {
                                fmt.Println(n.IpAddress)
                        }
                }
        }
        return nil
}

func main() {
        myvc := NewMyVC()
        err := myvc.Init()
        if err != nil {
                fmt.Println(err)
                os.Exit(1)
        }
        err = myvc.FindVMs("your-folder-name")
        if err != nil {
                fmt.Println(err)
                os.Exit(1)
        }
}
  • go fmt find_vm_sample.go
  • go run find_vm_sample.go

解説

ちょっと長いですが、流れは簡単です
まず NewMyVC で必要なデータをセットします
変更する箇所は VCenter の IP とユーザ名/パスワードかなと思います

次に Init してます
Init では VCenter への接続確認と検索するための必要な変数を MyVCenter 構造体に保存しています

そして取得したい VM の一覧があるフォルダを指定して FindVM を実行します
今回は VM 名と VM が接続しているネットワーク (VM Network) に割り振られた IP アドレスを表示するだけになります
ネットワークに接続されていない VM は VM だけ表示されると思います

最後に

govmomi を使ってフォルダ指定のフォルダ配下の VM を取得してみました
pager や limit のような機能が現状ないので、必要に応じて実装する必要があります
詳しく調べないと何ともですが、VirtualMachineList の引数にそういった指定ができなさそうなので、基本は全件取得かもしれません

VirtualMachine から取得できるプロパティは govmomi の godoc と types.go のコードを直接見るのがわかりやすいと思います

0 件のコメント:

コメントを投稿