govmomiを使ってManagement ObjectのMethodを実行しようとしたところ、findで取得したオブジェクトにMethodが実装されてたりされていなかったりというのに気づきました。
ちなみに、今回はCluster ObjectのGetResourceUsage Methodを実行したかったのですが、findで返ってくるオブジェクトには実装されていなかったのでmethodsに定義されているものを直接使って見ました。
pyvmomiの例
まずは、pyvmomiでやった時の例です。
実装部分(一部)はこんな感じ。
(snip)
def get_mob_info(content, mob, target=''):
r = content.viewManager.CreateContainerView(content.rootFolder,
[mob],
True)
# 返すmobを名前で指定する場合
if(target):
for i in r.view:
if(i.name == target):
r = i
return r
(snip)
if __name__ == '__main__':
(snip)
cluster = get_mob_info(content, vim.ClusterComputeResource, "")
for i in cluster.view:
r = i.GetResourceUsage()
print(r)
これを実行すると、以下のように表示されます。
vim.cluster.ResourceUsageSummary) {
dynamicType = <unset>,
dynamicProperty = (vmodl.DynamicProperty) [],
cpuUsedMHz = 124,
cpuCapacityMHz = 49600,
memUsedMB = 4048,
memCapacityMB = 64945,
storageUsedMB = 270712,
storageCapacityMB = 3268352
}
こんなイメージでgovmomiもできるかな?と思ったのですができませんでした。
govmomiでのMethodを実行する方法
とりあえず、どのように実行しているかを確認してみました。
ここで参考にしたのは PowerOnVM_Task です。
(snip)
func (v VirtualMachine) PowerOn(ctx context.Context) (*Task, error) {
req := types.PowerOnVM_Task{
This: v.Reference(),
}
res, err := methods.PowerOnVM_Task(ctx, v.c, &req)
if err != nil {
return nil, err
}
return NewTask(v.c, res.Returnval), nil
}
(snip)
処理を見てみると
- typesでMethodに渡す構造体を作る、ここでは構造体にオブジェクトリファレンスを格納
- 実行するMethodに必要な引数を渡す
のような流れだったので、実際にクラスタでもやってみました。
govmomiでクラスタオブジェクトのGetResourceUsageを実行
package main
import (
"context"
"fmt"
"net/url"
"os"
"github.com/vmware/govmomi"
"github.com/vmware/govmomi/find"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/types"
)
const (
URL = "https://vCenterIP/sdk" // ESXi or vCenter URL
UserName = "administrator@vsphere.local" // ログインユーザー
Password = "password" // ログインパスワード
Insecure = true // 自己証明書の許可 `true`
)
func exit(err error) {
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
os.Exit(1)
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// 接続先のURLをパース
u, err := url.Parse(URL)
if err != nil {
exit(err)
}
// ログインユーザーとパスワードをセット
u.User = url.UserPassword(UserName, Password)
// ログイン
c, err := govmomi.NewClient(ctx, u, Insecure)
if err != nil {
exit(err)
}
f := find.NewFinder(c.Client, true)
// データセンターを検索
dc, err := f.DefaultDatacenter(ctx)
if err != nil {
exit(err)
}
// 見つけたデータセンターのローカルコールを使う
f.SetDatacenter(dc)
// データセンター内のクラスタリストを取得
cls, err := f.ClusterComputeResourceList(ctx, "*")
if err != nil {
exit(err)
}
// クラスタのGetResourceUsageメソッドを実行する
for _, i := range cls {
// GetResourceUsageに渡す構造体を作成
// https://godoc.org/github.com/vmware/govmomi/vim25/types#GetResourceUsage
req := types.GetResourceUsage{
This: i.Reference(),
}
// GetResourceUsageメソッドを実行
// https://godoc.org/github.com/vmware/govmomi/vim25/methods#GetResourceUsage
r, _ := methods.GetResourceUsage(ctx, c.Client, &req)
// 結果を出力
fmt.Println("CapacityMHz :", r.Returnval.CpuCapacityMHz)
fmt.Println("CpuUsedMHz :", r.Returnval.CpuUsedMHz)
fmt.Println("MemCapacityMB :", r.Returnval.MemCapacityMB)
fmt.Println("MemUsedMB :", r.Returnval.MemUsedMB)
fmt.Println("StorageCapacityMB :", r.Returnval.StorageCapacityMB)
fmt.Println("StorageUsedMB :", r.Returnval.StorageUsedMB)
}
}
実行結果
$ go run get_cluster_resource.go
CapacityMHz : 49600
CpuUsedMHz : 126
MemCapacityMB : 64945
MemUsedMB : 4047
StorageCapacityMB : 3268352
StorageUsedMB : 270712
pyvmomiで取得した情報と同じものが取れました :-)
govmomiでMethodを実行する場合は、ちょっとだけ手間かもしれません。