はじめに
govmomiは、vCenterやESXiを操作するAPI (主に vSphere Web Services API
) のSDKです。
Web Client上の操作の自動化等で重宝します。
VMwareが開発しているOSSで、名前の通りGo言語製です1。
表現力が高く便利な一方、少し使い方にコツがいるライブラリなので、本記事では備忘録として使い方と内部構成をまとめてみました。
ディレクトリ構成
たくさんありますが、かいつまんで紹介すると以下の役割を持っています。
-
find
: managed object取得用ファインダー -
govc
: CLIツール govc の実装 -
object
: managed objectをgovmomi上で扱いやすくしたラッパー -
property
: プロパティ取得関数 -
simulator
: vSphereのシミュレーター vcsim の実装 -
vapi
: vSphere Automation API (REST API)のSDK (このパッケージ以外は vSphere Web Services API のSDK) -
vcsim
: vcsim の実装 -
vim25
: Web Services API のリクエスト、レスポンスのスキーマ定義-
mo
: managed object(管理対象オブジェクト)を表す構造体2 -
methods
: リクエスト(managed objectに対する操作)を表す構造体 -
types
: ↑のプロパティを表す構造体
-
オブジェクト構成は以下のようになっています。

mo
, methods
, types
の3パッケージは、vSphere Web Services API
のリクエスト、レスポンスのスキーマ3を表す構造体を定義しています。操作用のメソッドは生えておらず、単純に値の入れ物として使用します。
type VirtualMachine struct {
ManagedEntity
Capability types.VirtualMachineCapability `mo:"capability"`
Config *types.VirtualMachineConfigInfo `mo:"config"`
Layout *types.VirtualMachineFileLayout `mo:"layout"`
LayoutEx *types.VirtualMachineFileLayoutEx `mo:"layoutEx"`
Storage *types.VirtualMachineStorageInfo `mo:"storage"`
EnvironmentBrowser types.ManagedObjectReference `mo:"environmentBrowser"`
ResourcePool *types.ManagedObjectReference `mo:"resourcePool"`
ParentVApp *types.ManagedObjectReference `mo:"parentVApp"`
ResourceConfig *types.ResourceConfigSpec `mo:"resourceConfig"`
Runtime types.VirtualMachineRuntimeInfo `mo:"runtime"`
Guest *types.GuestInfo `mo:"guest"`
Summary types.VirtualMachineSummary `mo:"summary"`
Datastore []types.ManagedObjectReference `mo:"datastore"`
Network []types.ManagedObjectReference `mo:"network"`
Snapshot *types.VirtualMachineSnapshotInfo `mo:"snapshot"`
RootSnapshot []types.ManagedObjectReference `mo:"rootSnapshot"`
GuestHeartbeatStatus types.ManagedEntityStatus `mo:"guestHeartbeatStatus"`
}
対応するレスポンス
このままでは少し使いづらいですが、govmomiにはmanaged objectを扱いやすくした構造体が定義されています。これが object
パッケージです。object
パッケージには操作用のメソッドが生えているので、裏のAPI構造を意識することなく実装できます。
メソッド一覧
objectとmo,methodsの使い分け
可能な限りobjectを使い、できないことがあった場合のみmo/methodsを使うのが良いと思います。
objectで事足りる例
- VMのパワーオン
// クライアント生成(今回はデモとしてvcsimを使用)
u, _ := url.Parse("https://user:pass@127.0.0.1:8989/sdk")
c, _ := govmomi.NewClient(ctx, u, true)
// VMを取得
finder := find.NewFinder(c.Client)
vm, err := finder.VirtualMachine(ctx, "DC0_H0_VM0") // vmは *object.VirtualMachine型
if err != nil {
return fmt.Errorf("vm取得失敗: %w", err)
}
task, err := vm.PowerOn(ctx) // taskは *object.Task型
if err != nil {
return fmt.Errorf("vmパワーオン失敗: %w", err)
}
err = task.Wait(ctx) // タスクの完了を待機
if err != nil {
return fmt.Errorf("パワーオンタスク失敗: %w", err)
}
- VMのデバイス一覧取得
// VMを取得
finder := find.NewFinder(c.Client)
vm, err := finder.VirtualMachine(ctx, "DC0_H0_VM0") // vmは *object.VirtualMachine型
if err != nil {
return fmt.Errorf("vm取得失敗: %w", err)
}
devices, err := vm.Device(ctx) // devicesは object.DeviceList ([]*types.BaseVirtualDevice)型
if err != nil {
return fmt.Errorf("device取得失敗: %w", err)
}
for _, d := range devices {
fmt.Printf("device summary: %s\n", d.GetVirtualDevice().DeviceInfo.GetDescription().Summary)
}
moが必要な例
レスポンス中の特定の要素を取得する場合にはmoを使う必要があります。
// VMを取得
finder := find.NewFinder(c.Client)
vm, err := finder.VirtualMachine(ctx, "DC0_H0_VM0") // vmは *object.VirtualMachine型
if err != nil {
return fmt.Errorf("vm取得失敗: %w", err)
}
// VMの特定の属性を取得
pc := property.DefaultCollector(c.Client)
var moVM mo.VirtualMachine
props := []string{"summary.config"} // mo中の取得したい属性(フィールド)のパス
err = pc.RetrieveOne(ctx, vm.Reference(), props, &moVM) // propsに対応する属性を取得し、結果をmoVMに書き込み
if err != nil {
return fmt.Errorf("mo取得失敗: %w", err)
}
fmt.Printf("path: %s\n", moVM.Summary.Config.VmPathName) // path: [LocalDS_0] DC0_H0_VM0/DC0_H0_VM0.vmx
pc.RetrieveXXX
を使い、props
で指定した属性を取得します。以下利用の際の注意点です。
- moが戻り値で返るわけではなく、引数にポインタを渡してフィールドに書き込む (
json.Unmarshal
と同じイメージ) - moのうち
props
で指定していないフィールドはゼロ値のまま
おわりに
以上、駆け足でしたがgovmomiの内部構成の紹介でした。
今回は紹介しきれませんでしたが、実際に操作系のメソッドを扱う際にはobjectパッケージとtypesパッケージを組み合わせて使うことが多いです。
利用の際には、以下の公式実装が参考になると思います。