Update vmware/govmomi godeps

This commit is contained in:
Doug MacEachern
2017-11-16 20:13:29 -08:00
parent 8a9954d471
commit 09da53c8e9
125 changed files with 26926 additions and 934 deletions

View File

@@ -38,13 +38,11 @@ go_library(
"host_virtual_nic_manager.go",
"host_vsan_internal_system.go",
"host_vsan_system.go",
"http_nfc_lease.go",
"namespace_manager.go",
"network.go",
"network_reference.go",
"opaque_network.go",
"option_manager.go",
"ovf_manager.go",
"resource_pool.go",
"search_index.go",
"storage_pod.go",
@@ -61,6 +59,7 @@ go_library(
importpath = "github.com/vmware/govmomi/object",
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/vmware/govmomi/nfc:go_default_library",
"//vendor/github.com/vmware/govmomi/property:go_default_library",
"//vendor/github.com/vmware/govmomi/session:go_default_library",
"//vendor/github.com/vmware/govmomi/task:go_default_library",

View File

@@ -80,17 +80,24 @@ func (c *Common) SetInventoryPath(p string) {
func (c Common) ObjectName(ctx context.Context) (string, error) {
var o mo.ManagedEntity
name := c.Name()
if name != "" {
return name, nil
}
err := c.Properties(ctx, c.Reference(), []string{"name"}, &o)
if err != nil {
return "", err
}
return o.Name, nil
if o.Name != "" {
return o.Name, nil
}
// Network has its own "name" field...
var n mo.Network
err = c.Properties(ctx, c.Reference(), []string{"name"}, &n)
if err != nil {
return "", err
}
return n.Name, nil
}
func (c Common) Properties(ctx context.Context, r types.ManagedObjectReference, ps []string, dst interface{}) error {

View File

@@ -102,7 +102,9 @@ func (m CustomFieldsManager) Set(ctx context.Context, entity types.ManagedObject
return err
}
func (m CustomFieldsManager) Field(ctx context.Context) ([]types.CustomFieldDef, error) {
type CustomFieldDefList []types.CustomFieldDef
func (m CustomFieldsManager) Field(ctx context.Context) (CustomFieldDefList, error) {
var fm mo.CustomFieldsManager
err := m.Properties(ctx, m.Reference(), []string{"field"}, &fm)
@@ -113,19 +115,19 @@ func (m CustomFieldsManager) Field(ctx context.Context) ([]types.CustomFieldDef,
return fm.Field, nil
}
func (m CustomFieldsManager) FindKey(ctx context.Context, key string) (int32, error) {
func (m CustomFieldsManager) FindKey(ctx context.Context, name string) (int32, error) {
field, err := m.Field(ctx)
if err != nil {
return -1, err
}
for _, def := range field {
if def.Name == key {
if def.Name == name {
return def.Key, nil
}
}
k, err := strconv.Atoi(key)
k, err := strconv.Atoi(name)
if err == nil {
// assume literal int key
return int32(k), nil
@@ -133,3 +135,12 @@ func (m CustomFieldsManager) FindKey(ctx context.Context, key string) (int32, er
return -1, ErrKeyNameNotFound
}
func (l CustomFieldDefList) ByKey(key int32) *types.CustomFieldDef {
for _, def := range l {
if def.Key == key {
return &def
}
}
return nil
}

View File

@@ -1,5 +1,5 @@
/*
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
Copyright (c) 2016-2017 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@ import (
"net/http"
"os"
"path"
"sync"
"time"
"github.com/vmware/govmomi/vim25/soap"
@@ -232,8 +233,9 @@ func (f *DatastoreFile) get() (io.Reader, error) {
return f.body, nil
}
func lastIndexLines(s []byte, n *int) int64 {
func lastIndexLines(s []byte, line *int, include func(l int, m string) bool) (int64, bool) {
i := len(s) - 1
done := false
for i > 0 {
o := bytes.LastIndexByte(s[:i], '\n')
@@ -241,18 +243,27 @@ func lastIndexLines(s []byte, n *int) int64 {
break
}
i = o
*n--
if *n == 0 {
msg := string(s[o+1 : i+1])
if !include(*line, msg) {
done = true
break
} else {
i = o
*line++
}
}
return int64(i)
return int64(i), done
}
// Tail seeks to the position of the last N lines of the file.
func (f *DatastoreFile) Tail(n int) error {
return f.TailFunc(n, func(line int, _ string) bool { return n > line })
}
// TailFunc will seek backwards in the datastore file until it hits a line that does
// not satisfy the supplied `include` function.
func (f *DatastoreFile) TailFunc(lines int, include func(line int, message string) bool) error {
// Read the file in reverse using bsize chunks
const bsize = int64(1024 * 16)
@@ -261,13 +272,14 @@ func (f *DatastoreFile) Tail(n int) error {
return err
}
if n == 0 {
if lines == 0 {
return nil
}
chunk := int64(-1)
buf := bytes.NewBuffer(make([]byte, 0, bsize))
line := 0
for {
var eof bool
@@ -298,19 +310,19 @@ func (f *DatastoreFile) Tail(n int) error {
}
b := buf.Bytes()
idx := lastIndexLines(b, &n) + 1
idx, done := lastIndexLines(b, &line, include)
if n == 0 {
if done {
if chunk == -1 {
// We found all N lines in the last chunk of the file.
// The seek offset is also now at the current end of file.
// Save this buffer to avoid another GET request when Read() is called.
buf.Next(int(idx))
buf.Next(int(idx + 1))
f.buf = buf
return nil
}
if _, err = f.Seek(pos+idx, io.SeekStart); err != nil {
if _, err = f.Seek(pos+idx+1, io.SeekStart); err != nil {
return err
}
@@ -336,6 +348,7 @@ type followDatastoreFile struct {
r *DatastoreFile
c chan struct{}
i time.Duration
o sync.Once
}
// Read reads up to len(b) bytes from the DatastoreFile being followed.
@@ -387,11 +400,15 @@ func (f *followDatastoreFile) Read(p []byte) (int, error) {
// Close will stop Follow polling and close the underlying DatastoreFile.
func (f *followDatastoreFile) Close() error {
close(f.c)
f.o.Do(func() { close(f.c) })
return nil
}
// Follow returns an io.ReadCloser to stream the file contents as data is appended.
func (f *DatastoreFile) Follow(interval time.Duration) io.ReadCloser {
return &followDatastoreFile{f, make(chan struct{}), interval}
return &followDatastoreFile{
r: f,
c: make(chan struct{}),
i: interval,
}
}

View File

@@ -97,6 +97,25 @@ func (m *DatastoreFileManager) DeleteVirtualDisk(ctx context.Context, name strin
return task.Wait(ctx)
}
// Move dispatches to the appropriate Move method based on file name extension
func (m *DatastoreFileManager) Move(ctx context.Context, src string, dst string) error {
srcp := m.Path(src)
dstp := m.Path(dst)
f := m.FileManager.MoveDatastoreFile
if srcp.IsVMDK() {
f = m.VirtualDiskManager.MoveVirtualDisk
}
task, err := f(ctx, srcp.String(), m.Datacenter, dstp.String(), m.Datacenter, m.Force)
if err != nil {
return err
}
return task.Wait(ctx)
}
// Path converts path name to a DatastorePath
func (m *DatastoreFileManager) Path(name string) *DatastorePath {
var p DatastorePath

View File

@@ -18,6 +18,7 @@ package object
import (
"fmt"
"path"
"strings"
)
@@ -63,3 +64,8 @@ func (p *DatastorePath) String() string {
return strings.Join([]string{s, p.Path}, " ")
}
// IsVMDK returns true if Path has a ".vmdk" extension
func (p *DatastorePath) IsVMDK() bool {
return path.Ext(p.Path) == ".vmdk"
}

View File

@@ -38,7 +38,7 @@ func NewDistributedVirtualPortgroup(c *vim25.Client, ref types.ManagedObjectRefe
// EthernetCardBackingInfo returns the VirtualDeviceBackingInfo for this DistributedVirtualPortgroup
func (p DistributedVirtualPortgroup) EthernetCardBackingInfo(ctx context.Context) (types.BaseVirtualDeviceBackingInfo, error) {
var dvp mo.DistributedVirtualPortgroup
var dvs mo.VmwareDistributedVirtualSwitch // TODO: should be mo.BaseDistributedVirtualSwitch
var dvs mo.DistributedVirtualSwitch
if err := p.Properties(ctx, p.Reference(), []string{"key", "config.distributedVirtualSwitch"}, &dvp); err != nil {
return nil, err

View File

@@ -65,3 +65,15 @@ func (s DistributedVirtualSwitch) AddPortgroup(ctx context.Context, spec []types
return NewTask(s.Client(), res.Returnval), nil
}
func (s DistributedVirtualSwitch) FetchDVPorts(ctx context.Context) ([]types.DistributedVirtualPort, error) {
req := &types.FetchDVPorts{
This: s.Reference(),
}
res, err := methods.FetchDVPorts(ctx, s.Client(), req)
if err != nil {
return nil, err
}
return res.Returnval, nil
}

View File

@@ -88,6 +88,15 @@ func (s HostStorageSystem) RescanAllHba(ctx context.Context) error {
return err
}
func (s HostStorageSystem) Refresh(ctx context.Context) error {
req := types.RefreshStorageSystem{
This: s.Reference(),
}
_, err := methods.RefreshStorageSystem(ctx, s.c, &req)
return err
}
func (s HostStorageSystem) MarkAsSsd(ctx context.Context, uuid string) (*Task, error) {
req := types.MarkAsSsd_Task{
This: s.Reference(),

View File

@@ -42,7 +42,7 @@ func (m HostVsanInternalSystem) QueryVsanObjectUuidsByFilter(ctx context.Context
req := types.QueryVsanObjectUuidsByFilter{
This: m.Reference(),
Uuids: uuids,
Limit: limit,
Limit: &limit,
Version: version,
}

View File

@@ -1,143 +0,0 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package object
import (
"context"
"errors"
"fmt"
"github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
)
type HttpNfcLease struct {
Common
}
func NewHttpNfcLease(c *vim25.Client, ref types.ManagedObjectReference) *HttpNfcLease {
return &HttpNfcLease{
Common: NewCommon(c, ref),
}
}
// HttpNfcLeaseAbort wraps methods.HttpNfcLeaseAbort
func (o HttpNfcLease) HttpNfcLeaseAbort(ctx context.Context, fault *types.LocalizedMethodFault) error {
req := types.HttpNfcLeaseAbort{
This: o.Reference(),
Fault: fault,
}
_, err := methods.HttpNfcLeaseAbort(ctx, o.c, &req)
if err != nil {
return err
}
return nil
}
// HttpNfcLeaseComplete wraps methods.HttpNfcLeaseComplete
func (o HttpNfcLease) HttpNfcLeaseComplete(ctx context.Context) error {
req := types.HttpNfcLeaseComplete{
This: o.Reference(),
}
_, err := methods.HttpNfcLeaseComplete(ctx, o.c, &req)
if err != nil {
return err
}
return nil
}
// HttpNfcLeaseGetManifest wraps methods.HttpNfcLeaseGetManifest
func (o HttpNfcLease) HttpNfcLeaseGetManifest(ctx context.Context) error {
req := types.HttpNfcLeaseGetManifest{
This: o.Reference(),
}
_, err := methods.HttpNfcLeaseGetManifest(ctx, o.c, &req)
if err != nil {
return err
}
return nil
}
// HttpNfcLeaseProgress wraps methods.HttpNfcLeaseProgress
func (o HttpNfcLease) HttpNfcLeaseProgress(ctx context.Context, percent int32) error {
req := types.HttpNfcLeaseProgress{
This: o.Reference(),
Percent: percent,
}
_, err := methods.HttpNfcLeaseProgress(ctx, o.c, &req)
if err != nil {
return err
}
return nil
}
func (o HttpNfcLease) Wait(ctx context.Context) (*types.HttpNfcLeaseInfo, error) {
var lease mo.HttpNfcLease
pc := property.DefaultCollector(o.c)
err := property.Wait(ctx, pc, o.Reference(), []string{"state", "info", "error"}, func(pc []types.PropertyChange) bool {
done := false
for _, c := range pc {
if c.Val == nil {
continue
}
switch c.Name {
case "error":
val := c.Val.(types.LocalizedMethodFault)
lease.Error = &val
done = true
case "info":
val := c.Val.(types.HttpNfcLeaseInfo)
lease.Info = &val
case "state":
lease.State = c.Val.(types.HttpNfcLeaseState)
if lease.State != types.HttpNfcLeaseStateInitializing {
done = true
}
}
}
return done
})
if err != nil {
return nil, err
}
if lease.State == types.HttpNfcLeaseStateReady {
return lease.Info, nil
}
if lease.Error != nil {
return nil, errors.New(lease.Error.LocalizedMessage)
}
return nil, fmt.Errorf("unexpected nfc lease state: %s", lease.State)
}

View File

@@ -20,6 +20,7 @@ import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
)
@@ -34,12 +35,20 @@ func NewNetwork(c *vim25.Client, ref types.ManagedObjectReference) *Network {
}
// EthernetCardBackingInfo returns the VirtualDeviceBackingInfo for this Network
func (n Network) EthernetCardBackingInfo(_ context.Context) (types.BaseVirtualDeviceBackingInfo, error) {
name := n.Name()
func (n Network) EthernetCardBackingInfo(ctx context.Context) (types.BaseVirtualDeviceBackingInfo, error) {
var e mo.Network
// Use Network.Name rather than Common.Name as the latter does not return the complete name if it contains a '/'
// We can't use Common.ObjectName here either as we need the ManagedEntity.Name field is not set since mo.Network
// has its own Name field.
err := n.Properties(ctx, n.Reference(), []string{"name"}, &e)
if err != nil {
return nil, err
}
backing := &types.VirtualEthernetCardNetworkBackingInfo{
VirtualDeviceDeviceBackingInfo: types.VirtualDeviceDeviceBackingInfo{
DeviceName: name,
DeviceName: e.Name,
},
}

View File

@@ -1,104 +0,0 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package object
import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/types"
)
type OvfManager struct {
Common
}
func NewOvfManager(c *vim25.Client) *OvfManager {
o := OvfManager{
Common: NewCommon(c, *c.ServiceContent.OvfManager),
}
return &o
}
// CreateDescriptor wraps methods.CreateDescriptor
func (o OvfManager) CreateDescriptor(ctx context.Context, obj Reference, cdp types.OvfCreateDescriptorParams) (*types.OvfCreateDescriptorResult, error) {
req := types.CreateDescriptor{
This: o.Reference(),
Obj: obj.Reference(),
Cdp: cdp,
}
res, err := methods.CreateDescriptor(ctx, o.c, &req)
if err != nil {
return nil, err
}
return &res.Returnval, nil
}
// CreateImportSpec wraps methods.CreateImportSpec
func (o OvfManager) CreateImportSpec(ctx context.Context, ovfDescriptor string, resourcePool Reference, datastore Reference, cisp types.OvfCreateImportSpecParams) (*types.OvfCreateImportSpecResult, error) {
req := types.CreateImportSpec{
This: o.Reference(),
OvfDescriptor: ovfDescriptor,
ResourcePool: resourcePool.Reference(),
Datastore: datastore.Reference(),
Cisp: cisp,
}
res, err := methods.CreateImportSpec(ctx, o.c, &req)
if err != nil {
return nil, err
}
return &res.Returnval, nil
}
// ParseDescriptor wraps methods.ParseDescriptor
func (o OvfManager) ParseDescriptor(ctx context.Context, ovfDescriptor string, pdp types.OvfParseDescriptorParams) (*types.OvfParseDescriptorResult, error) {
req := types.ParseDescriptor{
This: o.Reference(),
OvfDescriptor: ovfDescriptor,
Pdp: pdp,
}
res, err := methods.ParseDescriptor(ctx, o.c, &req)
if err != nil {
return nil, err
}
return &res.Returnval, nil
}
// ValidateHost wraps methods.ValidateHost
func (o OvfManager) ValidateHost(ctx context.Context, ovfDescriptor string, host Reference, vhp types.OvfValidateHostParams) (*types.OvfValidateHostResult, error) {
req := types.ValidateHost{
This: o.Reference(),
OvfDescriptor: ovfDescriptor,
Host: host.Reference(),
Vhp: vhp,
}
res, err := methods.ValidateHost(ctx, o.c, &req)
if err != nil {
return nil, err
}
return &res.Returnval, nil
}

View File

@@ -19,6 +19,7 @@ package object
import (
"context"
"github.com/vmware/govmomi/nfc"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/types"
@@ -34,7 +35,7 @@ func NewResourcePool(c *vim25.Client, ref types.ManagedObjectReference) *Resourc
}
}
func (p ResourcePool) ImportVApp(ctx context.Context, spec types.BaseImportSpec, folder *Folder, host *HostSystem) (*HttpNfcLease, error) {
func (p ResourcePool) ImportVApp(ctx context.Context, spec types.BaseImportSpec, folder *Folder, host *HostSystem) (*nfc.Lease, error) {
req := types.ImportVApp{
This: p.Reference(),
Spec: spec,
@@ -55,7 +56,7 @@ func (p ResourcePool) ImportVApp(ctx context.Context, spec types.BaseImportSpec,
return nil, err
}
return NewHttpNfcLease(p.c, res.Returnval), nil
return nfc.NewLease(p.c, res.Returnval), nil
}
func (p ResourcePool) Create(ctx context.Context, name string, spec types.ResourceConfigSpec) (*ResourcePool, error) {

View File

@@ -22,6 +22,7 @@ import (
"github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/task"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/progress"
"github.com/vmware/govmomi/vim25/types"
)
@@ -51,3 +52,11 @@ func (t *Task) WaitForResult(ctx context.Context, s progress.Sinker) (*types.Tas
p := property.DefaultCollector(t.c)
return task.Wait(ctx, t.Reference(), p, s)
}
func (t *Task) Cancel(ctx context.Context) error {
_, err := methods.CancelTask(ctx, t.Client(), &types.CancelTask{
This: t.Reference(),
})
return err
}

View File

@@ -1,5 +1,5 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Copyright (c) 2015-2017 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -30,6 +30,7 @@ import (
// Type values for use in BootOrder
const (
DeviceTypeNone = "-"
DeviceTypeCdrom = "cdrom"
DeviceTypeDisk = "disk"
DeviceTypeEthernet = "ethernet"
@@ -754,6 +755,9 @@ func (l VirtualDeviceList) PrimaryMacAddress() string {
// convert a BaseVirtualDevice to a BaseVirtualMachineBootOptionsBootableDevice
var bootableDevices = map[string]func(device types.BaseVirtualDevice) types.BaseVirtualMachineBootOptionsBootableDevice{
DeviceTypeNone: func(types.BaseVirtualDevice) types.BaseVirtualMachineBootOptionsBootableDevice {
return &types.VirtualMachineBootOptionsBootableDevice{}
},
DeviceTypeCdrom: func(types.BaseVirtualDevice) types.BaseVirtualMachineBootOptionsBootableDevice {
return &types.VirtualMachineBootOptionsBootableCdromDevice{}
},
@@ -773,17 +777,23 @@ var bootableDevices = map[string]func(device types.BaseVirtualDevice) types.Base
}
// BootOrder returns a list of devices which can be used to set boot order via VirtualMachine.SetBootOptions.
// The order can any of "ethernet", "cdrom", "floppy" or "disk" or by specific device name.
// The order can be any of "ethernet", "cdrom", "floppy" or "disk" or by specific device name.
// A value of "-" will clear the existing boot order on the VC/ESX side.
func (l VirtualDeviceList) BootOrder(order []string) []types.BaseVirtualMachineBootOptionsBootableDevice {
var devices []types.BaseVirtualMachineBootOptionsBootableDevice
for _, name := range order {
if kind, ok := bootableDevices[name]; ok {
if name == DeviceTypeNone {
// Not covered in the API docs, nor obvious, but this clears the boot order on the VC/ESX side.
devices = append(devices, new(types.VirtualMachineBootOptionsBootableDevice))
continue
}
for _, device := range l {
if l.Type(device) == name {
devices = append(devices, kind(device))
}
}
continue
}

View File

@@ -1,5 +1,5 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Copyright (c) 2015-2017 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@ import (
"net"
"path"
"github.com/vmware/govmomi/nfc"
"github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
@@ -464,6 +465,20 @@ func (v VirtualMachine) Answer(ctx context.Context, id, answer string) error {
return nil
}
func (v VirtualMachine) AcquireTicket(ctx context.Context, kind string) (*types.VirtualMachineTicket, error) {
req := types.AcquireTicket{
This: v.Reference(),
TicketType: kind,
}
res, err := methods.AcquireTicket(ctx, v.c, &req)
if err != nil {
return nil, err
}
return &res.Returnval, nil
}
// CreateSnapshot creates a new snapshot of a virtual machine.
func (v VirtualMachine) CreateSnapshot(ctx context.Context, name string, description string, memory bool, quiesce bool) (*Task, error) {
req := types.CreateSnapshot_Task{
@@ -497,7 +512,7 @@ func (v VirtualMachine) RemoveAllSnapshot(ctx context.Context, consolidate *bool
return NewTask(v.c, res.Returnval), nil
}
type snapshotMap map[string][]Reference
type snapshotMap map[string][]types.ManagedObjectReference
func (m snapshotMap) add(parent string, tree []types.VirtualMachineSnapshotTree) {
for i, st := range tree {
@@ -511,18 +526,18 @@ func (m snapshotMap) add(parent string, tree []types.VirtualMachineSnapshotTree)
}
for _, name := range names {
m[name] = append(m[name], &tree[i].Snapshot)
m[name] = append(m[name], tree[i].Snapshot)
}
m.add(sname, st.ChildSnapshotList)
}
}
// findSnapshot supports snapshot lookup by name, where name can be:
// FindSnapshot supports snapshot lookup by name, where name can be:
// 1) snapshot ManagedObjectReference.Value (unique)
// 2) snapshot name (may not be unique)
// 3) snapshot tree path (may not be unique)
func (v VirtualMachine) findSnapshot(ctx context.Context, name string) (Reference, error) {
func (v VirtualMachine) FindSnapshot(ctx context.Context, name string) (*types.ManagedObjectReference, error) {
var o mo.VirtualMachine
err := v.Properties(ctx, v.Reference(), []string{"snapshot"}, &o)
@@ -542,7 +557,7 @@ func (v VirtualMachine) findSnapshot(ctx context.Context, name string) (Referenc
case 0:
return nil, fmt.Errorf("snapshot %q not found", name)
case 1:
return s[0], nil
return &s[0], nil
default:
return nil, fmt.Errorf("%q resolves to %d snapshots", name, len(s))
}
@@ -550,7 +565,7 @@ func (v VirtualMachine) findSnapshot(ctx context.Context, name string) (Referenc
// RemoveSnapshot removes a named snapshot
func (v VirtualMachine) RemoveSnapshot(ctx context.Context, name string, removeChildren bool, consolidate *bool) (*Task, error) {
snapshot, err := v.findSnapshot(ctx, name)
snapshot, err := v.FindSnapshot(ctx, name)
if err != nil {
return nil, err
}
@@ -586,7 +601,7 @@ func (v VirtualMachine) RevertToCurrentSnapshot(ctx context.Context, suppressPow
// RevertToSnapshot reverts to a named snapshot
func (v VirtualMachine) RevertToSnapshot(ctx context.Context, name string, suppressPowerOn bool) (*Task, error) {
snapshot, err := v.findSnapshot(ctx, name)
snapshot, err := v.FindSnapshot(ctx, name)
if err != nil {
return nil, err
}
@@ -757,3 +772,30 @@ func (v VirtualMachine) UpgradeTools(ctx context.Context, options string) (*Task
return NewTask(v.c, res.Returnval), nil
}
func (v VirtualMachine) Export(ctx context.Context) (*nfc.Lease, error) {
req := types.ExportVm{
This: v.Reference(),
}
res, err := methods.ExportVm(ctx, v.Client(), &req)
if err != nil {
return nil, err
}
return nfc.NewLease(v.c, res.Returnval), nil
}
func (v VirtualMachine) UpgradeVM(ctx context.Context, version string) (*Task, error) {
req := types.UpgradeVM_Task{
This: v.Reference(),
Version: version,
}
res, err := methods.UpgradeVM_Task(ctx, v.Client(), &req)
if err != nil {
return nil, err
}
return NewTask(v.c, res.Returnval), nil
}