Merge pull request #9391 from hashicorp/fix_8656
Update vmware/govmomi to v0.22.2
This commit is contained in:
commit
c984f71786
2
go.mod
2
go.mod
|
@ -137,7 +137,7 @@ require (
|
|||
github.com/ufilesdk-dev/ufile-gosdk v0.0.0-20190830075812-b4dbc4ef43a6
|
||||
github.com/ugorji/go v0.0.0-20151218193438-646ae4a518c1
|
||||
github.com/ulikunitz/xz v0.5.5
|
||||
github.com/vmware/govmomi v0.21.0
|
||||
github.com/vmware/govmomi v0.22.2
|
||||
github.com/xanzy/go-cloudstack v0.0.0-20190526095453-42f262b63ed0
|
||||
github.com/yandex-cloud/go-genproto v0.0.0-20190916101622-7617782d381e
|
||||
github.com/yandex-cloud/go-sdk v0.0.0-20190916101744-c781afa45829
|
||||
|
|
5
go.sum
5
go.sum
|
@ -607,6 +607,11 @@ github.com/vmihailenco/msgpack v3.3.3+incompatible h1:wapg9xDUZDzGCNFlwc5SqI1rvc
|
|||
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
|
||||
github.com/vmware/govmomi v0.21.0 h1:jc8uMuxpcV2xMAA/cnEDlnsIjvqcMra5Y8onh/U3VuY=
|
||||
github.com/vmware/govmomi v0.21.0/go.mod h1:zbnFoBQ9GIjs2RVETy8CNEpb+L+Lwkjs3XZUL0B3/m0=
|
||||
github.com/vmware/govmomi v0.22.0 h1:fIg5KkUxu4b/y1BmmtNFO9pyN10CkVzvriaJyynAdE8=
|
||||
github.com/vmware/govmomi v0.22.0/go.mod h1:Y+Wq4lst78L85Ge/F8+ORXIWiKYqaro1vhAulACy9Lc=
|
||||
github.com/vmware/govmomi v0.22.1/go.mod h1:Y+Wq4lst78L85Ge/F8+ORXIWiKYqaro1vhAulACy9Lc=
|
||||
github.com/vmware/govmomi v0.22.2 h1:hmLv4f+RMTTseqtJRijjOWzwELiaLMIoHv2D6H3bF4I=
|
||||
github.com/vmware/govmomi v0.22.2/go.mod h1:Y+Wq4lst78L85Ge/F8+ORXIWiKYqaro1vhAulACy9Lc=
|
||||
github.com/vmware/vmw-guestinfo v0.0.0-20170707015358-25eff159a728/go.mod h1:x9oS4Wk2s2u4tS29nEaDLdzvuHdB19CvSGJjPgkZJNk=
|
||||
github.com/xanzy/go-cloudstack v0.0.0-20190526095453-42f262b63ed0 h1:NJrcIkdzq0C3I8ypAZwFE9RHtGbfp+mJvqIcoFATZuk=
|
||||
github.com/xanzy/go-cloudstack v0.0.0-20190526095453-42f262b63ed0/go.mod h1:sBh287mCRwCz6zyXHMmw7sSZGPohVpnx+o+OY4M+i3A=
|
||||
|
|
|
@ -27,3 +27,4 @@ Zee Yang <zeey@vmware.com> <zee.yang@gmail.com>
|
|||
Jiatong Wang <wjiatong@vmware.com> jiatongw <wjiatong@vmware.com>
|
||||
Uwe Bessle <Uwe.Bessle@iteratec.de> Uwe Bessle <u.bessle.extern@eos-ts.com>
|
||||
Uwe Bessle <Uwe.Bessle@iteratec.de> Uwe Bessle <uwe.bessle@web.de>
|
||||
Lintong Jiang <lintongj@vmware.com> lintongj <55512168+lintongj@users.noreply.github.com>
|
||||
|
|
|
@ -12,7 +12,7 @@ services: false
|
|||
|
||||
# Set the version of Go.
|
||||
language: go
|
||||
go: 1.12
|
||||
go: 1.13
|
||||
|
||||
# Always set the project's Go import path to ensure that forked
|
||||
# builds get cloned to the correct location.
|
||||
|
@ -35,7 +35,7 @@ jobs:
|
|||
- <<: *lint-stage
|
||||
env: LINTER=goimports
|
||||
|
||||
# The "build" stage verifies the program can be built against the
|
||||
# The "build" stage verifies the program can be built against the
|
||||
# various GOOS and GOARCH combinations found in the Go releaser
|
||||
# config file, ".goreleaser.yml".
|
||||
- &build-stage
|
||||
|
|
|
@ -1,5 +1,57 @@
|
|||
# changelog
|
||||
|
||||
### 0.22.1 (2020-01-13)
|
||||
|
||||
* Fix SAML token auth using Holder-of-Key with delegated Bearer identity against 6.7 U3b+
|
||||
|
||||
### 0.22.0 (2020-01-10)
|
||||
|
||||
* Add OVF properties to library.Deploy method
|
||||
|
||||
* Add retry support for HTTP status codes
|
||||
|
||||
* Use cs.identity service type for sts endpoint lookups
|
||||
|
||||
* Add Content Library VM template APIs
|
||||
|
||||
* Add SearchIndex FindAllByDnsName and FindAllByIp methods
|
||||
|
||||
* Fix HostSystem.ManagementIPs to use SelectedVnic
|
||||
|
||||
* Change generated ResourceReductionToToleratePercent to pointer type
|
||||
|
||||
* Add DistributedVirtualSwitch.ReconfigureDVPort method
|
||||
|
||||
* Add VirtualMachine.IsTemplate method
|
||||
|
||||
* Add GetInventoryPath to NetworkReference interface
|
||||
|
||||
* Support HoK tokens with Interactive Users
|
||||
|
||||
* Replace mo.LoadRetrievePropertiesResponse with mo.LoadObjectContent
|
||||
|
||||
* Add VirtualHardwareSection.StorageItem
|
||||
|
||||
* Add ResourcePool.Owner method
|
||||
|
||||
* Add VirtualMachine.QueryChangedDiskAreas method
|
||||
|
||||
* Update generated code to vSphere 6.7u3
|
||||
|
||||
* Add option to propagate MissingSet faults in property.WaitForUpdates
|
||||
|
||||
* Add content library subscription support
|
||||
|
||||
* Fix deadlock for keep alive handlers that attempt log in
|
||||
|
||||
* Add CNS API bindings
|
||||
|
||||
* Add FetchCapabilityMetadata method to Pbm client
|
||||
|
||||
* Add v4 option to VirtualMachine.WaitForIP
|
||||
|
||||
* Add VirtualHardwareSection.StorageItem
|
||||
|
||||
### 0.21.0 (2019-07-24)
|
||||
|
||||
* Add vsan package
|
||||
|
|
|
@ -22,10 +22,12 @@ Anfernee Yongkun Gui <agui@vmware.com>
|
|||
angystardust <angystardust@users.noreply.github.com>
|
||||
aniketGslab <aniket.shinde@gslab.com>
|
||||
Arran Walker <arran.walker@zopa.com>
|
||||
Artem Anisimov <aanisimov@inbox.ru>
|
||||
Aryeh Weinreb <aryehweinreb@gmail.com>
|
||||
Austin Parker <aparker@apprenda.com>
|
||||
Balu Dontu <bdontu@vmware.com>
|
||||
bastienbc <bastien.barbe.creuly@gmail.com>
|
||||
Ben Corrie <bcorrie@vmware.com>
|
||||
Benjamin Peterson <benjamin@python.org>
|
||||
Bob Killen <killen.bob@gmail.com>
|
||||
Brad Fitzpatrick <bradfitz@golang.org>
|
||||
|
@ -35,15 +37,21 @@ Chris Marchesi <chrism@vancluevertech.com>
|
|||
Christian Höltje <docwhat@gerf.org>
|
||||
Clint Greenwood <cgreenwood@vmware.com>
|
||||
CuiHaozhi <cuihaozhi@chinacloud.com.cn>
|
||||
Daniel Mueller <deso@posteo.net>
|
||||
Danny Lockard <danny.lockard@banno.com>
|
||||
Dave Gress <gressd@vmware.com>
|
||||
Dave Smith-Uchida <dsmithuchida@vmware.com>
|
||||
Dave Tucker <dave@dtucker.co.uk>
|
||||
Davide Agnello <dagnello@hp.com>
|
||||
David Stark <dave@davidstark.name>
|
||||
Davinder Kumar <davinderk@vmware.com>
|
||||
dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
|
||||
Deric Crago <deric.crago@gmail.com>
|
||||
Divyen Patel <divyenp@vmware.com>
|
||||
Doug MacEachern <dougm@vmware.com>
|
||||
Eloy Coto <eloy.coto@gmail.com>
|
||||
Eric Edens <ericedens@google.com>
|
||||
Eric Graham <16710890+Pheric@users.noreply.github.com>
|
||||
Eric Gray <egray@vmware.com>
|
||||
Eric Yutao <eric.yutao@gmail.com>
|
||||
Erik Hollensbe <github@hollensbe.org>
|
||||
|
@ -51,6 +59,7 @@ Ethan Kaley <ethan.kaley@emc.com>
|
|||
Fabio Rapposelli <fabio@vmware.com>
|
||||
Faiyaz Ahmed <ahmedf@vmware.com>
|
||||
forkbomber <forkbomber@users.noreply.github.com>
|
||||
François Rigault <rigault.francois@gmail.com>
|
||||
freebsdly <qinhuajun@outlook.com>
|
||||
Gavin Gray <gavin@infinio.com>
|
||||
Gavrie Philipson <gavrie.philipson@elastifile.com>
|
||||
|
@ -59,23 +68,29 @@ Gerrit Renker <Gerrit.Renker@ctl.io>
|
|||
gthombare <gthombare@vmware.com>
|
||||
Hasan Mahmood <mahmoodh@vmware.com>
|
||||
Henrik Hodne <henrik@travis-ci.com>
|
||||
hkumar <hkumar@vmware.com>
|
||||
hui luo <luoh@vmware.com>
|
||||
Isaac Rodman <isaac@eyz.us>
|
||||
Ivan Mikushin <imikushin@vmware.com>
|
||||
Ivan Porto Carrero <icarrero@vmware.com>
|
||||
James King <james.king@emc.com>
|
||||
Jason Kincl <jkincl@gmail.com>
|
||||
Jeremy Canady <jcanady@jackhenry.com>
|
||||
jeremy-clerc <jeremy@clerc.io>
|
||||
Jiatong Wang <wjiatong@vmware.com>
|
||||
jingyizPensando <jingyiz@pensando.io>
|
||||
João Pereira <joaodrp@gmail.com>
|
||||
Jonas Ausevicius <jonas.ausevicius@virtustream.com>
|
||||
Jorge Sevilla <jorge.sevilla@rstor.io>
|
||||
kayrus <kay.diam@gmail.com>
|
||||
Kevin George <georgek@vmware.com>
|
||||
leslie-qiwa <leslie.qiwa@gmail.com>
|
||||
Lintong Jiang <lintongj@vmware.com>
|
||||
Louie Jiang <jiangl@vmware.com>
|
||||
Luther Monson <luther.monson@gmail.com>
|
||||
maplain <fangyuanl@vmware.com>
|
||||
Marc Carmier <mcarmier@gmail.com>
|
||||
Marcus Tan <marcus.tan@rubrik.com>
|
||||
Maria Ntalla <maria.ntalla@gmail.com>
|
||||
Marin Atanasov Nikolov <mnikolov@vmware.com>
|
||||
Mario Trangoni <mjtrangoni@gmail.com>
|
||||
|
@ -97,6 +112,9 @@ Rowan Jacobs <rojacobs@pivotal.io>
|
|||
runner.mei <runner.mei@gmail.com>
|
||||
S.Çağlar Onur <conur@vmware.com>
|
||||
Sergey Ignatov <sergey.ignatov@jetbrains.com>
|
||||
serokles <timbo.alexander@gmail.com>
|
||||
Shawn Neal <sneal@sneal.net>
|
||||
sky-joker <sky.jokerxx@gmail.com>
|
||||
Sten Feldman <exile@chamber.ee>
|
||||
Stepan Mazurov <smazurov@gmail.com>
|
||||
Steve Purcell <steve@sanityinc.com>
|
||||
|
@ -104,9 +122,11 @@ Takaaki Furukawa <takaaki.frkw@gmail.com>
|
|||
Tamas Eger <tamas.eger@bitrise.io>
|
||||
tanishi <tanishi503@gmail.com>
|
||||
Ted Zlatanov <tzz@lifelogs.com>
|
||||
Thad Craft <tcraft@pivotal.io>
|
||||
Thibaut Ackermann <thibaut.ackermann@alcatel-lucent.com>
|
||||
Tim McNamara <tim.mcnamara@canonical.com>
|
||||
Tjeu Kayim <15987676+TjeuKayim@users.noreply.github.com>
|
||||
Toomas Pelberg <toomas.pelberg@playtech.com>
|
||||
Trevor Dawe <trevor.dawe@gmail.com>
|
||||
Uwe Bessle <Uwe.Bessle@iteratec.de>
|
||||
Vadim Egorov <vegorov@vmware.com>
|
||||
|
|
|
@ -28,7 +28,7 @@ The code in the `govmomi` package is a wrapper for the code that is generated fr
|
|||
It primarily provides convenience functions for working with the vSphere API.
|
||||
See [godoc.org][godoc] for documentation.
|
||||
|
||||
[apiref]:http://pubs.vmware.com/vsphere-6-5/index.jsp#com.vmware.wssdk.apiref.doc/right-pane.html
|
||||
[apiref]:https://code.vmware.com/apis/196/vsphere
|
||||
[godoc]:http://godoc.org/github.com/vmware/govmomi
|
||||
|
||||
## Installation
|
||||
|
|
|
@ -11,3 +11,5 @@ require (
|
|||
github.com/kr/text v0.1.0 // indirect
|
||||
github.com/vmware/vmw-guestinfo v0.0.0-20170707015358-25eff159a728
|
||||
)
|
||||
|
||||
go 1.13
|
||||
|
|
|
@ -87,3 +87,17 @@ func (c ClusterComputeResource) MoveInto(ctx context.Context, hosts ...*HostSyst
|
|||
|
||||
return NewTask(c.c, res.Returnval), nil
|
||||
}
|
||||
|
||||
func (c ClusterComputeResource) PlaceVm(ctx context.Context, spec types.PlacementSpec) (*types.PlacementResult, error) {
|
||||
req := types.PlaceVm{
|
||||
This: c.Reference(),
|
||||
PlacementSpec: spec,
|
||||
}
|
||||
|
||||
res, err := methods.PlaceVm(ctx, c.c, &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &res.Returnval, nil
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
|
||||
"github.com/vmware/govmomi/vim25"
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
|
@ -36,6 +37,12 @@ func NewCustomizationSpecManager(c *vim25.Client) *CustomizationSpecManager {
|
|||
return &cs
|
||||
}
|
||||
|
||||
func (cs CustomizationSpecManager) Info(ctx context.Context) ([]types.CustomizationSpecInfo, error) {
|
||||
var m mo.CustomizationSpecManager
|
||||
err := cs.Properties(ctx, cs.Reference(), []string{"info"}, &m)
|
||||
return m.Info, err
|
||||
}
|
||||
|
||||
func (cs CustomizationSpecManager) DoesCustomizationSpecExist(ctx context.Context, name string) (bool, error) {
|
||||
req := types.DoesCustomizationSpecExist{
|
||||
This: cs.Reference(),
|
||||
|
|
|
@ -36,6 +36,10 @@ func NewDistributedVirtualPortgroup(c *vim25.Client, ref types.ManagedObjectRefe
|
|||
}
|
||||
}
|
||||
|
||||
func (p DistributedVirtualPortgroup) GetInventoryPath() string {
|
||||
return p.InventoryPath
|
||||
}
|
||||
|
||||
// EthernetCardBackingInfo returns the VirtualDeviceBackingInfo for this DistributedVirtualPortgroup
|
||||
func (p DistributedVirtualPortgroup) EthernetCardBackingInfo(ctx context.Context) (types.BaseVirtualDeviceBackingInfo, error) {
|
||||
var dvp mo.DistributedVirtualPortgroup
|
||||
|
@ -46,9 +50,15 @@ func (p DistributedVirtualPortgroup) EthernetCardBackingInfo(ctx context.Context
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// From the docs at https://code.vmware.com/apis/196/vsphere/doc/vim.dvs.DistributedVirtualPortgroup.ConfigInfo.html:
|
||||
// "This property should always be set unless the user's setting does not have System.Read privilege on the object referred to by this property."
|
||||
// Note that "the object" refers to the Switch, not the PortGroup.
|
||||
if dvp.Config.DistributedVirtualSwitch == nil {
|
||||
return nil, fmt.Errorf("no System.Read privilege on: %s.%s", p.Reference(), prop)
|
||||
name := p.InventoryPath
|
||||
if name == "" {
|
||||
name = p.Reference().String()
|
||||
}
|
||||
return nil, fmt.Errorf("failed to create EthernetCardBackingInfo for %s: System.Read privilege required for %s", name, prop)
|
||||
}
|
||||
|
||||
if err := p.Properties(ctx, *dvp.Config.DistributedVirtualSwitch, []string{"uuid"}, &dvs); err != nil {
|
||||
|
|
|
@ -18,6 +18,7 @@ package object
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/vmware/govmomi/vim25"
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
|
@ -34,8 +35,17 @@ func NewDistributedVirtualSwitch(c *vim25.Client, ref types.ManagedObjectReferen
|
|||
}
|
||||
}
|
||||
|
||||
func (s DistributedVirtualSwitch) GetInventoryPath() string {
|
||||
return s.InventoryPath
|
||||
}
|
||||
|
||||
func (s DistributedVirtualSwitch) EthernetCardBackingInfo(ctx context.Context) (types.BaseVirtualDeviceBackingInfo, error) {
|
||||
return nil, ErrNotSupported // TODO: just to satisfy NetworkReference interface for the finder
|
||||
ref := s.Reference()
|
||||
name := s.InventoryPath
|
||||
if name == "" {
|
||||
name = ref.String()
|
||||
}
|
||||
return nil, fmt.Errorf("type %s (%s) cannot be used for EthernetCardBackingInfo", ref.Type, name)
|
||||
}
|
||||
|
||||
func (s DistributedVirtualSwitch) Reconfigure(ctx context.Context, spec types.BaseDVSConfigSpec) (*Task, error) {
|
||||
|
@ -78,3 +88,17 @@ func (s DistributedVirtualSwitch) FetchDVPorts(ctx context.Context, criteria *ty
|
|||
}
|
||||
return res.Returnval, nil
|
||||
}
|
||||
|
||||
func (s DistributedVirtualSwitch) ReconfigureDVPort(ctx context.Context, spec []types.DVPortConfigSpec) (*Task, error) {
|
||||
req := types.ReconfigureDVPort_Task{
|
||||
This: s.Reference(),
|
||||
Port: spec,
|
||||
}
|
||||
|
||||
res, err := methods.ReconfigureDVPort_Task(ctx, s.Client(), &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewTask(s.Client(), res.Returnval), nil
|
||||
}
|
||||
|
|
|
@ -18,9 +18,9 @@ package object
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/vmware/govmomi/vim25"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
|
@ -34,163 +34,138 @@ func NewHostConfigManager(c *vim25.Client, ref types.ManagedObjectReference) *Ho
|
|||
}
|
||||
}
|
||||
|
||||
func (m HostConfigManager) DatastoreSystem(ctx context.Context) (*HostDatastoreSystem, error) {
|
||||
var h mo.HostSystem
|
||||
// reference returns the ManagedObjectReference for the given HostConfigManager property name.
|
||||
// An error is returned if the field is nil, of type ErrNotSupported if versioned is true.
|
||||
func (m HostConfigManager) reference(ctx context.Context, name string, versioned ...bool) (types.ManagedObjectReference, error) {
|
||||
prop := "configManager." + name
|
||||
var content []types.ObjectContent
|
||||
|
||||
err := m.Properties(ctx, m.Reference(), []string{"configManager.datastoreSystem"}, &h)
|
||||
err := m.Properties(ctx, m.Reference(), []string{prop}, &content)
|
||||
if err != nil {
|
||||
return types.ManagedObjectReference{}, err
|
||||
}
|
||||
|
||||
for _, c := range content {
|
||||
for _, p := range c.PropSet {
|
||||
if p.Name != prop {
|
||||
continue
|
||||
}
|
||||
if ref, ok := p.Val.(types.ManagedObjectReference); ok {
|
||||
return ref, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = fmt.Errorf("%s %s is nil", m.Reference(), prop)
|
||||
if len(versioned) == 1 && versioned[0] {
|
||||
err = ErrNotSupported
|
||||
}
|
||||
return types.ManagedObjectReference{}, err
|
||||
}
|
||||
|
||||
func (m HostConfigManager) DatastoreSystem(ctx context.Context) (*HostDatastoreSystem, error) {
|
||||
ref, err := m.reference(ctx, "datastoreSystem")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewHostDatastoreSystem(m.c, *h.ConfigManager.DatastoreSystem), nil
|
||||
return NewHostDatastoreSystem(m.c, ref), nil
|
||||
}
|
||||
|
||||
func (m HostConfigManager) NetworkSystem(ctx context.Context) (*HostNetworkSystem, error) {
|
||||
var h mo.HostSystem
|
||||
|
||||
err := m.Properties(ctx, m.Reference(), []string{"configManager.networkSystem"}, &h)
|
||||
ref, err := m.reference(ctx, "networkSystem")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewHostNetworkSystem(m.c, *h.ConfigManager.NetworkSystem), nil
|
||||
return NewHostNetworkSystem(m.c, ref), nil
|
||||
}
|
||||
|
||||
func (m HostConfigManager) FirewallSystem(ctx context.Context) (*HostFirewallSystem, error) {
|
||||
var h mo.HostSystem
|
||||
|
||||
err := m.Properties(ctx, m.Reference(), []string{"configManager.firewallSystem"}, &h)
|
||||
ref, err := m.reference(ctx, "firewallSystem")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewHostFirewallSystem(m.c, *h.ConfigManager.FirewallSystem), nil
|
||||
return NewHostFirewallSystem(m.c, ref), nil
|
||||
}
|
||||
|
||||
func (m HostConfigManager) StorageSystem(ctx context.Context) (*HostStorageSystem, error) {
|
||||
var h mo.HostSystem
|
||||
|
||||
err := m.Properties(ctx, m.Reference(), []string{"configManager.storageSystem"}, &h)
|
||||
ref, err := m.reference(ctx, "storageSystem")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewHostStorageSystem(m.c, *h.ConfigManager.StorageSystem), nil
|
||||
return NewHostStorageSystem(m.c, ref), nil
|
||||
}
|
||||
|
||||
func (m HostConfigManager) VirtualNicManager(ctx context.Context) (*HostVirtualNicManager, error) {
|
||||
var h mo.HostSystem
|
||||
|
||||
err := m.Properties(ctx, m.Reference(), []string{"configManager.virtualNicManager"}, &h)
|
||||
ref, err := m.reference(ctx, "virtualNicManager")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewHostVirtualNicManager(m.c, *h.ConfigManager.VirtualNicManager, m.Reference()), nil
|
||||
return NewHostVirtualNicManager(m.c, ref, m.Reference()), nil
|
||||
}
|
||||
|
||||
func (m HostConfigManager) VsanSystem(ctx context.Context) (*HostVsanSystem, error) {
|
||||
var h mo.HostSystem
|
||||
|
||||
err := m.Properties(ctx, m.Reference(), []string{"configManager.vsanSystem"}, &h)
|
||||
ref, err := m.reference(ctx, "vsanSystem", true) // Added in 5.5
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Added in 5.5
|
||||
if h.ConfigManager.VsanSystem == nil {
|
||||
return nil, ErrNotSupported
|
||||
}
|
||||
|
||||
return NewHostVsanSystem(m.c, *h.ConfigManager.VsanSystem), nil
|
||||
return NewHostVsanSystem(m.c, ref), nil
|
||||
}
|
||||
|
||||
func (m HostConfigManager) VsanInternalSystem(ctx context.Context) (*HostVsanInternalSystem, error) {
|
||||
var h mo.HostSystem
|
||||
|
||||
err := m.Properties(ctx, m.Reference(), []string{"configManager.vsanInternalSystem"}, &h)
|
||||
ref, err := m.reference(ctx, "vsanInternalSystem", true) // Added in 5.5
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Added in 5.5
|
||||
if h.ConfigManager.VsanInternalSystem == nil {
|
||||
return nil, ErrNotSupported
|
||||
}
|
||||
|
||||
return NewHostVsanInternalSystem(m.c, *h.ConfigManager.VsanInternalSystem), nil
|
||||
return NewHostVsanInternalSystem(m.c, ref), nil
|
||||
}
|
||||
|
||||
func (m HostConfigManager) AccountManager(ctx context.Context) (*HostAccountManager, error) {
|
||||
var h mo.HostSystem
|
||||
|
||||
err := m.Properties(ctx, m.Reference(), []string{"configManager.accountManager"}, &h)
|
||||
ref, err := m.reference(ctx, "accountManager", true) // Added in 5.5
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ref := h.ConfigManager.AccountManager // Added in 6.0
|
||||
if ref == nil {
|
||||
// Versions < 5.5 can use the ServiceContent ref,
|
||||
// but we can only use it when connected directly to ESX.
|
||||
c := m.Client()
|
||||
if !c.IsVC() {
|
||||
ref = c.ServiceContent.AccountManager
|
||||
}
|
||||
|
||||
if ref == nil {
|
||||
return nil, ErrNotSupported
|
||||
if err == ErrNotSupported {
|
||||
// Versions < 5.5 can use the ServiceContent ref,
|
||||
// but only when connected directly to ESX.
|
||||
if m.c.ServiceContent.AccountManager == nil {
|
||||
return nil, err
|
||||
}
|
||||
ref = *m.c.ServiceContent.AccountManager
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return NewHostAccountManager(m.c, *ref), nil
|
||||
return NewHostAccountManager(m.c, ref), nil
|
||||
}
|
||||
|
||||
func (m HostConfigManager) OptionManager(ctx context.Context) (*OptionManager, error) {
|
||||
var h mo.HostSystem
|
||||
|
||||
err := m.Properties(ctx, m.Reference(), []string{"configManager.advancedOption"}, &h)
|
||||
ref, err := m.reference(ctx, "advancedOption")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewOptionManager(m.c, *h.ConfigManager.AdvancedOption), nil
|
||||
return NewOptionManager(m.c, ref), nil
|
||||
}
|
||||
|
||||
func (m HostConfigManager) ServiceSystem(ctx context.Context) (*HostServiceSystem, error) {
|
||||
var h mo.HostSystem
|
||||
|
||||
err := m.Properties(ctx, m.Reference(), []string{"configManager.serviceSystem"}, &h)
|
||||
ref, err := m.reference(ctx, "serviceSystem")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewHostServiceSystem(m.c, *h.ConfigManager.ServiceSystem), nil
|
||||
return NewHostServiceSystem(m.c, ref), nil
|
||||
}
|
||||
|
||||
func (m HostConfigManager) CertificateManager(ctx context.Context) (*HostCertificateManager, error) {
|
||||
var h mo.HostSystem
|
||||
|
||||
err := m.Properties(ctx, m.Reference(), []string{"configManager.certificateManager"}, &h)
|
||||
ref, err := m.reference(ctx, "certificateManager", true) // Added in 6.0
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Added in 6.0
|
||||
if h.ConfigManager.CertificateManager == nil {
|
||||
return nil, ErrNotSupported
|
||||
}
|
||||
|
||||
return NewHostCertificateManager(m.c, *h.ConfigManager.CertificateManager, m.Reference()), nil
|
||||
return NewHostCertificateManager(m.c, ref, m.Reference()), nil
|
||||
}
|
||||
|
||||
func (m HostConfigManager) DateTimeSystem(ctx context.Context) (*HostDateTimeSystem, error) {
|
||||
var h mo.HostSystem
|
||||
|
||||
err := m.Properties(ctx, m.Reference(), []string{"configManager.dateTimeSystem"}, &h)
|
||||
ref, err := m.reference(ctx, "dateTimeSystem")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewHostDateTimeSystem(m.c, *h.ConfigManager.DateTimeSystem), nil
|
||||
return NewHostDateTimeSystem(m.c, ref), nil
|
||||
}
|
||||
|
|
|
@ -83,14 +83,21 @@ func (h HostSystem) ManagementIPs(ctx context.Context) ([]net.IP, error) {
|
|||
|
||||
var ips []net.IP
|
||||
for _, nc := range mh.Config.VirtualNicManagerInfo.NetConfig {
|
||||
if nc.NicType == "management" && len(nc.CandidateVnic) > 0 {
|
||||
ip := net.ParseIP(nc.CandidateVnic[0].Spec.Ip.IpAddress)
|
||||
if ip != nil {
|
||||
ips = append(ips, ip)
|
||||
if nc.NicType != string(types.HostVirtualNicManagerNicTypeManagement) {
|
||||
continue
|
||||
}
|
||||
for ix := range nc.CandidateVnic {
|
||||
for _, selectedVnicKey := range nc.SelectedVnic {
|
||||
if nc.CandidateVnic[ix].Key != selectedVnicKey {
|
||||
continue
|
||||
}
|
||||
ip := net.ParseIP(nc.CandidateVnic[ix].Spec.Ip.IpAddress)
|
||||
if ip != nil {
|
||||
ips = append(ips, ip)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ips, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,10 @@ func NewNetwork(c *vim25.Client, ref types.ManagedObjectReference) *Network {
|
|||
}
|
||||
}
|
||||
|
||||
func (n Network) GetInventoryPath() string {
|
||||
return n.InventoryPath
|
||||
}
|
||||
|
||||
// EthernetCardBackingInfo returns the VirtualDeviceBackingInfo for this Network
|
||||
func (n Network) EthernetCardBackingInfo(ctx context.Context) (types.BaseVirtualDeviceBackingInfo, error) {
|
||||
var e mo.Network
|
||||
|
|
|
@ -26,6 +26,6 @@ import (
|
|||
// which can be used as the backing for a VirtualEthernetCard.
|
||||
type NetworkReference interface {
|
||||
Reference
|
||||
|
||||
GetInventoryPath() string
|
||||
EthernetCardBackingInfo(ctx context.Context) (types.BaseVirtualDeviceBackingInfo, error)
|
||||
}
|
||||
|
|
|
@ -35,6 +35,10 @@ func NewOpaqueNetwork(c *vim25.Client, ref types.ManagedObjectReference) *Opaque
|
|||
}
|
||||
}
|
||||
|
||||
func (n OpaqueNetwork) GetInventoryPath() string {
|
||||
return n.InventoryPath
|
||||
}
|
||||
|
||||
// EthernetCardBackingInfo returns the VirtualDeviceBackingInfo for this Network
|
||||
func (n OpaqueNetwork) EthernetCardBackingInfo(ctx context.Context) (types.BaseVirtualDeviceBackingInfo, error) {
|
||||
var net mo.OpaqueNetwork
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
"github.com/vmware/govmomi/nfc"
|
||||
"github.com/vmware/govmomi/vim25"
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
|
@ -35,6 +36,18 @@ func NewResourcePool(c *vim25.Client, ref types.ManagedObjectReference) *Resourc
|
|||
}
|
||||
}
|
||||
|
||||
// Owner returns the ResourcePool owner as a ClusterComputeResource or ComputeResource.
|
||||
func (p ResourcePool) Owner(ctx context.Context) (Reference, error) {
|
||||
var pool mo.ResourcePool
|
||||
|
||||
err := p.Properties(ctx, p.Reference(), []string{"owner"}, &pool)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewReference(p.Client(), pool.Owner), nil
|
||||
}
|
||||
|
||||
func (p ResourcePool) ImportVApp(ctx context.Context, spec types.BaseImportSpec, folder *Folder, host *HostSystem) (*nfc.Lease, error) {
|
||||
req := types.ImportVApp{
|
||||
This: p.Reference(),
|
||||
|
|
|
@ -161,3 +161,88 @@ func (s SearchIndex) FindChild(ctx context.Context, entity Reference, name strin
|
|||
}
|
||||
return NewReference(s.c, *res.Returnval), nil
|
||||
}
|
||||
|
||||
// FindAllByDnsName finds all virtual machines or hosts by DNS name.
|
||||
func (s SearchIndex) FindAllByDnsName(ctx context.Context, dc *Datacenter, dnsName string, vmSearch bool) ([]Reference, error) {
|
||||
req := types.FindAllByDnsName{
|
||||
This: s.Reference(),
|
||||
DnsName: dnsName,
|
||||
VmSearch: vmSearch,
|
||||
}
|
||||
if dc != nil {
|
||||
ref := dc.Reference()
|
||||
req.Datacenter = &ref
|
||||
}
|
||||
|
||||
res, err := methods.FindAllByDnsName(ctx, s.c, &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(res.Returnval) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var references []Reference
|
||||
for _, returnval := range res.Returnval {
|
||||
references = append(references, NewReference(s.c, returnval))
|
||||
}
|
||||
return references, nil
|
||||
}
|
||||
|
||||
// FindAllByIp finds all virtual machines or hosts by IP address.
|
||||
func (s SearchIndex) FindAllByIp(ctx context.Context, dc *Datacenter, ip string, vmSearch bool) ([]Reference, error) {
|
||||
req := types.FindAllByIp{
|
||||
This: s.Reference(),
|
||||
Ip: ip,
|
||||
VmSearch: vmSearch,
|
||||
}
|
||||
if dc != nil {
|
||||
ref := dc.Reference()
|
||||
req.Datacenter = &ref
|
||||
}
|
||||
|
||||
res, err := methods.FindAllByIp(ctx, s.c, &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(res.Returnval) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var references []Reference
|
||||
for _, returnval := range res.Returnval {
|
||||
references = append(references, NewReference(s.c, returnval))
|
||||
}
|
||||
return references, nil
|
||||
}
|
||||
|
||||
// FindAllByUuid finds all virtual machines or hosts by UUID.
|
||||
func (s SearchIndex) FindAllByUuid(ctx context.Context, dc *Datacenter, uuid string, vmSearch bool, instanceUuid *bool) ([]Reference, error) {
|
||||
req := types.FindAllByUuid{
|
||||
This: s.Reference(),
|
||||
Uuid: uuid,
|
||||
VmSearch: vmSearch,
|
||||
InstanceUuid: instanceUuid,
|
||||
}
|
||||
if dc != nil {
|
||||
ref := dc.Reference()
|
||||
req.Datacenter = &ref
|
||||
}
|
||||
|
||||
res, err := methods.FindAllByUuid(ctx, s.c, &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(res.Returnval) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var references []Reference
|
||||
for _, returnval := range res.Returnval {
|
||||
references = append(references, NewReference(s.c, returnval))
|
||||
}
|
||||
return references, nil
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import (
|
|||
|
||||
const (
|
||||
PropRuntimePowerState = "summary.runtime.powerState"
|
||||
PropConfigTemplate = "summary.config.template"
|
||||
)
|
||||
|
||||
type VirtualMachine struct {
|
||||
|
@ -56,6 +57,17 @@ func (v VirtualMachine) PowerState(ctx context.Context) (types.VirtualMachinePow
|
|||
return o.Summary.Runtime.PowerState, nil
|
||||
}
|
||||
|
||||
func (v VirtualMachine) IsTemplate(ctx context.Context) (bool, error) {
|
||||
var o mo.VirtualMachine
|
||||
|
||||
err := v.Properties(ctx, v.Reference(), []string{PropConfigTemplate}, &o)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return o.Summary.Config.Template, nil
|
||||
}
|
||||
|
||||
func (v VirtualMachine) PowerOn(ctx context.Context) (*Task, error) {
|
||||
req := types.PowerOnVM_Task{
|
||||
This: v.Reference(),
|
||||
|
@ -221,7 +233,9 @@ func (v VirtualMachine) RefreshStorageInfo(ctx context.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
func (v VirtualMachine) WaitForIP(ctx context.Context) (string, error) {
|
||||
// WaitForIP waits for the VM guest.ipAddress property to report an IP address.
|
||||
// Waits for an IPv4 address if the v4 param is true.
|
||||
func (v VirtualMachine) WaitForIP(ctx context.Context, v4 ...bool) (string, error) {
|
||||
var ip string
|
||||
|
||||
p := property.DefaultCollector(v.c)
|
||||
|
@ -238,6 +252,11 @@ func (v VirtualMachine) WaitForIP(ctx context.Context) (string, error) {
|
|||
}
|
||||
|
||||
ip = c.Val.(string)
|
||||
if len(v4) == 1 && v4[0] {
|
||||
if net.ParseIP(ip).To4() == nil {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -839,3 +858,67 @@ func (v VirtualMachine) UUID(ctx context.Context) string {
|
|||
|
||||
return o.Config.Uuid
|
||||
}
|
||||
|
||||
func (v VirtualMachine) QueryChangedDiskAreas(ctx context.Context, baseSnapshot, curSnapshot *types.ManagedObjectReference, disk *types.VirtualDisk, offset int64) (types.DiskChangeInfo, error) {
|
||||
var noChange types.DiskChangeInfo
|
||||
var err error
|
||||
|
||||
if offset > disk.CapacityInBytes {
|
||||
return noChange, fmt.Errorf("offset is greater than the disk size (%#x and %#x)", offset, disk.CapacityInBytes)
|
||||
} else if offset == disk.CapacityInBytes {
|
||||
return types.DiskChangeInfo{StartOffset: offset, Length: 0}, nil
|
||||
}
|
||||
|
||||
var b mo.VirtualMachineSnapshot
|
||||
err = v.Properties(ctx, baseSnapshot.Reference(), []string{"config.hardware"}, &b)
|
||||
if err != nil {
|
||||
return noChange, fmt.Errorf("failed to fetch config.hardware of snapshot %s: %s", baseSnapshot, err)
|
||||
}
|
||||
|
||||
var changeId *string
|
||||
for _, vd := range b.Config.Hardware.Device {
|
||||
d := vd.GetVirtualDevice()
|
||||
if d.Key != disk.Key {
|
||||
continue
|
||||
}
|
||||
|
||||
// As per VDDK programming guide, these are the four types of disks
|
||||
// that support CBT, see "Gathering Changed Block Information".
|
||||
if b, ok := d.Backing.(*types.VirtualDiskFlatVer2BackingInfo); ok {
|
||||
changeId = &b.ChangeId
|
||||
break
|
||||
}
|
||||
if b, ok := d.Backing.(*types.VirtualDiskSparseVer2BackingInfo); ok {
|
||||
changeId = &b.ChangeId
|
||||
break
|
||||
}
|
||||
if b, ok := d.Backing.(*types.VirtualDiskRawDiskMappingVer1BackingInfo); ok {
|
||||
changeId = &b.ChangeId
|
||||
break
|
||||
}
|
||||
if b, ok := d.Backing.(*types.VirtualDiskRawDiskVer2BackingInfo); ok {
|
||||
changeId = &b.ChangeId
|
||||
break
|
||||
}
|
||||
|
||||
return noChange, fmt.Errorf("disk %d has backing info without .ChangeId: %t", disk.Key, d.Backing)
|
||||
}
|
||||
if changeId == nil || *changeId == "" {
|
||||
return noChange, fmt.Errorf("CBT is not enabled on disk %d", disk.Key)
|
||||
}
|
||||
|
||||
req := types.QueryChangedDiskAreas{
|
||||
This: v.Reference(),
|
||||
Snapshot: curSnapshot,
|
||||
DeviceKey: disk.Key,
|
||||
StartOffset: offset,
|
||||
ChangeId: *changeId,
|
||||
}
|
||||
|
||||
res, err := methods.QueryChangedDiskAreas(ctx, v.Client(), &req)
|
||||
if err != nil {
|
||||
return noChange, err
|
||||
}
|
||||
|
||||
return res.Returnval, nil
|
||||
}
|
||||
|
|
|
@ -19,3 +19,7 @@ package object
|
|||
type VmwareDistributedVirtualSwitch struct {
|
||||
DistributedVirtualSwitch
|
||||
}
|
||||
|
||||
func (s VmwareDistributedVirtualSwitch) GetInventoryPath() string {
|
||||
return s.InventoryPath
|
||||
}
|
||||
|
|
|
@ -16,6 +16,10 @@ limitations under the License.
|
|||
|
||||
package ovf
|
||||
|
||||
import (
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
/*
|
||||
Source: http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2.24.0/CIM_VirtualSystemSettingData.xsd
|
||||
*/
|
||||
|
@ -76,3 +80,49 @@ type CIMResourceAllocationSettingData struct {
|
|||
VirtualQuantityUnits *string `xml:"VirtualQuantityUnits"`
|
||||
Weight *uint `xml:"Weight"`
|
||||
}
|
||||
|
||||
/*
|
||||
Source: http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2.24.0/CIM_StorageAllocationSettingData.xsd
|
||||
*/
|
||||
type CIMStorageAllocationSettingData struct {
|
||||
ElementName string `xml:"ElementName"`
|
||||
InstanceID string `xml:"InstanceID"`
|
||||
|
||||
ResourceType *uint16 `xml:"ResourceType"`
|
||||
OtherResourceType *string `xml:"OtherResourceType"`
|
||||
ResourceSubType *string `xml:"ResourceSubType"`
|
||||
|
||||
Access *uint16 `xml:"Access"`
|
||||
Address *string `xml:"Address"`
|
||||
AddressOnParent *string `xml:"AddressOnParent"`
|
||||
AllocationUnits *string `xml:"AllocationUnits"`
|
||||
AutomaticAllocation *bool `xml:"AutomaticAllocation"`
|
||||
AutomaticDeallocation *bool `xml:"AutomaticDeallocation"`
|
||||
Caption *string `xml:"Caption"`
|
||||
ChangeableType *uint16 `xml:"ChangeableType"`
|
||||
ComponentSetting []types.AnyType `xml:"ComponentSetting"`
|
||||
ConfigurationName *string `xml:"ConfigurationName"`
|
||||
Connection []string `xml:"Connection"`
|
||||
ConsumerVisibility *uint16 `xml:"ConsumerVisibility"`
|
||||
Description *string `xml:"Description"`
|
||||
Generation *uint64 `xml:"Generation"`
|
||||
HostExtentName *string `xml:"HostExtentName"`
|
||||
HostExtentNameFormat *uint16 `xml:"HostExtentNameFormat"`
|
||||
HostExtentNameNamespace *uint16 `xml:"HostExtentNameNamespace"`
|
||||
HostExtentStartingAddress *uint64 `xml:"HostExtentStartingAddress"`
|
||||
HostResource []string `xml:"HostResource"`
|
||||
HostResourceBlockSize *uint64 `xml:"HostResourceBlockSize"`
|
||||
Limit *uint64 `xml:"Limit"`
|
||||
MappingBehavior *uint `xml:"MappingBehavior"`
|
||||
OtherHostExtentNameFormat *string `xml:"OtherHostExtentNameFormat"`
|
||||
OtherHostExtentNameNamespace *string `xml:"OtherHostExtentNameNamespace"`
|
||||
Parent *string `xml:"Parent"`
|
||||
PoolID *string `xml:"PoolID"`
|
||||
Reservation *uint64 `xml:"Reservation"`
|
||||
SoID *string `xml:"SoID"`
|
||||
SoOrgID *string `xml:"SoOrgID"`
|
||||
VirtualQuantity *uint `xml:"VirtualQuantity"`
|
||||
VirtualQuantityUnits *string `xml:"VirtualQuantityUnits"`
|
||||
VirtualResourceBlockSize *uint64 `xml:"VirtualResourceBlockSize"`
|
||||
Weight *uint `xml:"Weight"`
|
||||
}
|
||||
|
|
|
@ -154,8 +154,9 @@ type VirtualHardwareSection struct {
|
|||
ID *string `xml:"id,attr"`
|
||||
Transport *string `xml:"transport,attr"`
|
||||
|
||||
System *VirtualSystemSettingData `xml:"System"`
|
||||
Item []ResourceAllocationSettingData `xml:"Item"`
|
||||
System *VirtualSystemSettingData `xml:"System"`
|
||||
Item []ResourceAllocationSettingData `xml:"Item"`
|
||||
StorageItem []StorageAllocationSettingData `xml:"StorageItem"`
|
||||
}
|
||||
|
||||
type VirtualSystemSettingData struct {
|
||||
|
@ -170,6 +171,14 @@ type ResourceAllocationSettingData struct {
|
|||
Bound *string `xml:"bound,attr"`
|
||||
}
|
||||
|
||||
type StorageAllocationSettingData struct {
|
||||
CIMStorageAllocationSettingData
|
||||
|
||||
Required *bool `xml:"required,attr"`
|
||||
Configuration *string `xml:"configuration,attr"`
|
||||
Bound *string `xml:"bound,attr"`
|
||||
}
|
||||
|
||||
type ResourceAllocationSection struct {
|
||||
Section
|
||||
|
||||
|
|
|
@ -179,7 +179,7 @@ func (p *Collector) Retrieve(ctx context.Context, objs []types.ManagedObjectRefe
|
|||
return nil
|
||||
}
|
||||
|
||||
return mo.LoadRetrievePropertiesResponse(res, dst)
|
||||
return mo.LoadObjectContent(res.Returnval, dst)
|
||||
}
|
||||
|
||||
// RetrieveWithFilter populates dst as Retrieve does, but only for entities matching the given filter.
|
||||
|
|
|
@ -20,13 +20,15 @@ import (
|
|||
"context"
|
||||
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/vim25/soap"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
// WaitFilter provides helpers to construct a types.CreateFilter for use with property.Wait
|
||||
type WaitFilter struct {
|
||||
types.CreateFilter
|
||||
Options *types.WaitOptions
|
||||
Options *types.WaitOptions
|
||||
PropagateMissing bool
|
||||
}
|
||||
|
||||
// Add a new ObjectSpec and PropertySpec to the WaitFilter
|
||||
|
@ -81,6 +83,8 @@ func Wait(ctx context.Context, c *Collector, obj types.ManagedObjectReference, p
|
|||
// The newly created collector is destroyed before this function returns (both
|
||||
// in case of success or error).
|
||||
//
|
||||
// By default, ObjectUpdate.MissingSet faults are not propagated to the returned error,
|
||||
// set WaitFilter.PropagateMissing=true to enable MissingSet fault propagation.
|
||||
func WaitForUpdates(ctx context.Context, c *Collector, filter *WaitFilter, f func([]types.ObjectUpdate) bool) error {
|
||||
p, err := c.Create(ctx)
|
||||
if err != nil {
|
||||
|
@ -125,6 +129,15 @@ func WaitForUpdates(ctx context.Context, c *Collector, filter *WaitFilter, f fun
|
|||
req.Version = set.Version
|
||||
|
||||
for _, fs := range set.FilterSet {
|
||||
if filter.PropagateMissing {
|
||||
for i := range fs.ObjectSet {
|
||||
for _, p := range fs.ObjectSet[i].MissingSet {
|
||||
// Same behavior as mo.ObjectContentToType()
|
||||
return soap.WrapVimFault(p.Fault.Fault)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if f(fs.ObjectSet) {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
|
||||
Copyright (c) 2015,2019 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.
|
||||
|
@ -80,17 +80,18 @@ func (k *keepAlive) start() {
|
|||
k.notifyWaitGroup.Add(1)
|
||||
|
||||
go func() {
|
||||
defer k.notifyWaitGroup.Done()
|
||||
|
||||
for t := time.NewTimer(k.idleTime); ; {
|
||||
select {
|
||||
case <-k.notifyStop:
|
||||
k.notifyWaitGroup.Done()
|
||||
return
|
||||
case <-k.notifyRequest:
|
||||
t.Reset(k.idleTime)
|
||||
case <-t.C:
|
||||
if err := k.keepAlive(k.roundTripper); err != nil {
|
||||
k.notifyWaitGroup.Done()
|
||||
k.stop()
|
||||
return
|
||||
}
|
||||
t = time.NewTimer(k.idleTime)
|
||||
}
|
||||
|
@ -110,17 +111,21 @@ func (k *keepAlive) stop() {
|
|||
}
|
||||
|
||||
func (k *keepAlive) RoundTrip(ctx context.Context, req, res soap.HasFault) error {
|
||||
err := k.roundTripper.RoundTrip(ctx, req, res)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Start ticker on login, stop ticker on logout.
|
||||
// Stop ticker on logout.
|
||||
switch req.(type) {
|
||||
case *methods.LoginBody, *methods.LoginExtensionByCertificateBody, *methods.LoginByTokenBody:
|
||||
k.start()
|
||||
case *methods.LogoutBody:
|
||||
k.stop()
|
||||
}
|
||||
|
||||
err := k.roundTripper.RoundTrip(ctx, req, res)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Start ticker on login.
|
||||
switch req.(type) {
|
||||
case *methods.LoginBody, *methods.LoginExtensionByCertificateBody, *methods.LoginByTokenBody:
|
||||
k.start()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -50,10 +50,10 @@ func Secret(value string) (string, error) {
|
|||
}
|
||||
contents, err := ioutil.ReadFile(value)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return value, nil
|
||||
if os.IsPermission(err) {
|
||||
return "", err
|
||||
}
|
||||
return "", err
|
||||
return value, nil
|
||||
}
|
||||
return strings.TrimSpace(string(contents)), nil
|
||||
}
|
||||
|
|
|
@ -123,7 +123,18 @@ func Wait(ctx context.Context, ref types.ManagedObjectReference, pc *property.Co
|
|||
defer close(cb.ch)
|
||||
}
|
||||
|
||||
err := property.Wait(ctx, pc, ref, []string{"info"}, cb.fn)
|
||||
filter := &property.WaitFilter{PropagateMissing: true}
|
||||
filter.Add(ref, ref.Type, []string{"info"})
|
||||
|
||||
err := property.WaitForUpdates(ctx, pc, filter, func(updates []types.ObjectUpdate) bool {
|
||||
for _, update := range updates {
|
||||
if cb.fn(update.ChangeSet) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -18,8 +18,7 @@ package debug
|
|||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
// Provider specified the interface types must implement to be used as a
|
||||
|
@ -31,6 +30,7 @@ type Provider interface {
|
|||
}
|
||||
|
||||
var currentProvider Provider = nil
|
||||
var scrubPassword = regexp.MustCompile(`<password>(.*)</password>`)
|
||||
|
||||
func SetProvider(p Provider) {
|
||||
if currentProvider != nil {
|
||||
|
@ -54,28 +54,9 @@ func Flush() {
|
|||
currentProvider.Flush()
|
||||
}
|
||||
|
||||
// FileProvider implements a debugging provider that creates a real file for
|
||||
// every call to NewFile. It maintains a list of all files that it creates,
|
||||
// such that it can close them when its Flush function is called.
|
||||
type FileProvider struct {
|
||||
Path string
|
||||
func Scrub(in []byte) []byte {
|
||||
out := string(in)
|
||||
out = scrubPassword.ReplaceAllString(out, `<password>********</password>`)
|
||||
|
||||
files []*os.File
|
||||
}
|
||||
|
||||
func (fp *FileProvider) NewFile(p string) io.WriteCloser {
|
||||
f, err := os.Create(path.Join(fp.Path, p))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fp.files = append(fp.files, f)
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
func (fp *FileProvider) Flush() {
|
||||
for _, f := range fp.files {
|
||||
f.Close()
|
||||
}
|
||||
return []byte(out)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
Copyright (c) 2014 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 debug
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
)
|
||||
|
||||
// FileProvider implements a debugging provider that creates a real file for
|
||||
// every call to NewFile. It maintains a list of all files that it creates,
|
||||
// such that it can close them when its Flush function is called.
|
||||
type FileProvider struct {
|
||||
Path string
|
||||
files []*os.File
|
||||
}
|
||||
|
||||
func (fp *FileProvider) NewFile(p string) io.WriteCloser {
|
||||
f, err := os.Create(path.Join(fp.Path, p))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fp.files = append(fp.files, f)
|
||||
|
||||
return NewFileWriterCloser(f, p)
|
||||
}
|
||||
|
||||
func (fp *FileProvider) Flush() {
|
||||
for _, f := range fp.files {
|
||||
f.Close()
|
||||
}
|
||||
}
|
||||
|
||||
type FileWriterCloser struct {
|
||||
f *os.File
|
||||
p string
|
||||
}
|
||||
|
||||
func NewFileWriterCloser(f *os.File, p string) *FileWriterCloser {
|
||||
return &FileWriterCloser{
|
||||
f,
|
||||
p,
|
||||
}
|
||||
}
|
||||
|
||||
func (fwc *FileWriterCloser) Write(p []byte) (n int, err error) {
|
||||
return fwc.f.Write(Scrub(p))
|
||||
}
|
||||
|
||||
func (fwc *FileWriterCloser) Close() error {
|
||||
return fwc.f.Close()
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
Copyright (c) 2014 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 debug
|
||||
|
||||
import (
|
||||
"io"
|
||||
"log"
|
||||
)
|
||||
|
||||
type LogWriterCloser struct {
|
||||
}
|
||||
|
||||
func NewLogWriterCloser() *LogWriterCloser {
|
||||
return &LogWriterCloser{}
|
||||
}
|
||||
|
||||
func (lwc *LogWriterCloser) Write(p []byte) (n int, err error) {
|
||||
log.Print(string(Scrub(p)))
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func (lwc *LogWriterCloser) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type LogProvider struct {
|
||||
}
|
||||
|
||||
func (s *LogProvider) NewFile(p string) io.WriteCloser {
|
||||
log.Print(p)
|
||||
return NewLogWriterCloser()
|
||||
}
|
||||
|
||||
func (s *LogProvider) Flush() {
|
||||
}
|
|
@ -79,12 +79,13 @@ func init() {
|
|||
type ClusterComputeResource struct {
|
||||
ComputeResource
|
||||
|
||||
Configuration types.ClusterConfigInfo `mo:"configuration"`
|
||||
Recommendation []types.ClusterRecommendation `mo:"recommendation"`
|
||||
DrsRecommendation []types.ClusterDrsRecommendation `mo:"drsRecommendation"`
|
||||
MigrationHistory []types.ClusterDrsMigration `mo:"migrationHistory"`
|
||||
ActionHistory []types.ClusterActionHistory `mo:"actionHistory"`
|
||||
DrsFault []types.ClusterDrsFaults `mo:"drsFault"`
|
||||
Configuration types.ClusterConfigInfo `mo:"configuration"`
|
||||
Recommendation []types.ClusterRecommendation `mo:"recommendation"`
|
||||
DrsRecommendation []types.ClusterDrsRecommendation `mo:"drsRecommendation"`
|
||||
HciConfig *types.ClusterComputeResourceHCIConfigInfo `mo:"hciConfig"`
|
||||
MigrationHistory []types.ClusterDrsMigration `mo:"migrationHistory"`
|
||||
ActionHistory []types.ClusterActionHistory `mo:"actionHistory"`
|
||||
DrsFault []types.ClusterDrsFaults `mo:"drsFault"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
|
@ -46,7 +46,7 @@ func ignoreMissingProperty(ref types.ManagedObjectReference, p types.MissingProp
|
|||
// it returns the first fault it finds there as error. If the 'MissingSet'
|
||||
// field is empty, it returns a pointer to a reflect.Value. It handles contain
|
||||
// nested properties, such as 'guest.ipAddress' or 'config.hardware'.
|
||||
func ObjectContentToType(o types.ObjectContent) (interface{}, error) {
|
||||
func ObjectContentToType(o types.ObjectContent, ptr ...bool) (interface{}, error) {
|
||||
// Expect no properties in the missing set
|
||||
for _, p := range o.MissingSet {
|
||||
if ignoreMissingProperty(o.Obj, p) {
|
||||
|
@ -62,6 +62,9 @@ func ObjectContentToType(o types.ObjectContent) (interface{}, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if len(ptr) == 1 && ptr[0] {
|
||||
return v.Interface(), nil
|
||||
}
|
||||
return v.Elem().Interface(), nil
|
||||
}
|
||||
|
||||
|
@ -81,9 +84,9 @@ func ApplyPropertyChange(obj Reference, changes []types.PropertyChange) {
|
|||
}
|
||||
}
|
||||
|
||||
// LoadRetrievePropertiesResponse converts the response of a call to
|
||||
// RetrieveProperties to one or more managed objects.
|
||||
func LoadRetrievePropertiesResponse(res *types.RetrievePropertiesResponse, dst interface{}) error {
|
||||
// LoadObjectContent converts the response of a call to
|
||||
// RetrieveProperties{Ex} to one or more managed objects.
|
||||
func LoadObjectContent(content []types.ObjectContent, dst interface{}) error {
|
||||
rt := reflect.TypeOf(dst)
|
||||
if rt == nil || rt.Kind() != reflect.Ptr {
|
||||
panic("need pointer")
|
||||
|
@ -104,7 +107,7 @@ func LoadRetrievePropertiesResponse(res *types.RetrievePropertiesResponse, dst i
|
|||
}
|
||||
|
||||
if isSlice {
|
||||
for _, p := range res.Returnval {
|
||||
for _, p := range content {
|
||||
v, err := ObjectContentToType(p)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -123,10 +126,10 @@ func LoadRetrievePropertiesResponse(res *types.RetrievePropertiesResponse, dst i
|
|||
rv.Set(reflect.Append(rv, reflect.ValueOf(v)))
|
||||
}
|
||||
} else {
|
||||
switch len(res.Returnval) {
|
||||
switch len(content) {
|
||||
case 0:
|
||||
case 1:
|
||||
v, err := ObjectContentToType(res.Returnval[0])
|
||||
v, err := ObjectContentToType(content[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -160,7 +163,7 @@ func RetrievePropertiesForRequest(ctx context.Context, r soap.RoundTripper, req
|
|||
return err
|
||||
}
|
||||
|
||||
return LoadRetrievePropertiesResponse(res, dst)
|
||||
return LoadObjectContent(res.Returnval, dst)
|
||||
}
|
||||
|
||||
// RetrieveProperties retrieves the properties of the managed object specified
|
||||
|
@ -188,3 +191,65 @@ func RetrieveProperties(ctx context.Context, r soap.RoundTripper, pc, obj types.
|
|||
|
||||
return RetrievePropertiesForRequest(ctx, r, req, dst)
|
||||
}
|
||||
|
||||
var morType = reflect.TypeOf((*types.ManagedObjectReference)(nil)).Elem()
|
||||
|
||||
// References returns all non-nil moref field values in the given struct.
|
||||
// Only Anonymous struct fields are followed by default. The optional follow
|
||||
// param will follow any struct fields when true.
|
||||
func References(s interface{}, follow ...bool) []types.ManagedObjectReference {
|
||||
var refs []types.ManagedObjectReference
|
||||
rval := reflect.ValueOf(s)
|
||||
rtype := rval.Type()
|
||||
|
||||
if rval.Kind() == reflect.Ptr {
|
||||
rval = rval.Elem()
|
||||
rtype = rval.Type()
|
||||
}
|
||||
|
||||
for i := 0; i < rval.NumField(); i++ {
|
||||
val := rval.Field(i)
|
||||
finfo := rtype.Field(i)
|
||||
|
||||
if finfo.Anonymous {
|
||||
refs = append(refs, References(val.Interface(), follow...)...)
|
||||
continue
|
||||
}
|
||||
if finfo.Name == "Self" {
|
||||
continue
|
||||
}
|
||||
|
||||
ftype := val.Type()
|
||||
|
||||
if ftype.Kind() == reflect.Slice {
|
||||
if ftype.Elem() == morType {
|
||||
s := val.Interface().([]types.ManagedObjectReference)
|
||||
for i := range s {
|
||||
refs = append(refs, s[i])
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if ftype.Kind() == reflect.Ptr {
|
||||
if val.IsNil() {
|
||||
continue
|
||||
}
|
||||
val = val.Elem()
|
||||
ftype = val.Type()
|
||||
}
|
||||
|
||||
if ftype == morType {
|
||||
refs = append(refs, val.Interface().(types.ManagedObjectReference))
|
||||
continue
|
||||
}
|
||||
|
||||
if len(follow) != 0 && follow[0] {
|
||||
if ftype.Kind() == reflect.Struct && val.CanSet() {
|
||||
refs = append(refs, References(val.Interface(), follow...)...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return refs
|
||||
}
|
||||
|
|
|
@ -18,8 +18,6 @@ package vim25
|
|||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/vmware/govmomi/vim25/soap"
|
||||
|
@ -32,22 +30,18 @@ type RetryFunc func(err error) (retry bool, delay time.Duration)
|
|||
// network error (for example: a connect timeout).
|
||||
func TemporaryNetworkError(n int) RetryFunc {
|
||||
return func(err error) (retry bool, delay time.Duration) {
|
||||
var nerr net.Error
|
||||
var ok bool
|
||||
|
||||
// Never retry if this is not a network error.
|
||||
switch rerr := err.(type) {
|
||||
case *url.Error:
|
||||
if nerr, ok = rerr.Err.(net.Error); !ok {
|
||||
return false, 0
|
||||
}
|
||||
case net.Error:
|
||||
nerr = rerr
|
||||
default:
|
||||
t, ok := err.(interface {
|
||||
// Temporary is implemented by url.Error and net.Error
|
||||
Temporary() bool
|
||||
})
|
||||
if !ok {
|
||||
// Never retry if this is not a Temporary error.
|
||||
return false, 0
|
||||
}
|
||||
|
||||
if !nerr.Temporary() {
|
||||
if !t.Temporary() {
|
||||
return false, 0
|
||||
}
|
||||
|
||||
|
|
|
@ -532,6 +532,32 @@ func (c *Client) WithHeader(ctx context.Context, header Header) context.Context
|
|||
return context.WithValue(ctx, headerContext{}, header)
|
||||
}
|
||||
|
||||
type statusError struct {
|
||||
res *http.Response
|
||||
}
|
||||
|
||||
// Temporary returns true for HTTP response codes that can be retried
|
||||
// See vim25.TemporaryNetworkError
|
||||
func (e *statusError) Temporary() bool {
|
||||
switch e.res.StatusCode {
|
||||
case http.StatusBadGateway:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (e *statusError) Error() string {
|
||||
return e.res.Status
|
||||
}
|
||||
|
||||
func newStatusError(res *http.Response) error {
|
||||
return &url.Error{
|
||||
Op: res.Request.Method,
|
||||
URL: res.Request.URL.Path,
|
||||
Err: &statusError{res},
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) RoundTrip(ctx context.Context, reqBody, resBody HasFault) error {
|
||||
var err error
|
||||
var b []byte
|
||||
|
@ -587,7 +613,7 @@ func (c *Client) RoundTrip(ctx context.Context, reqBody, resBody HasFault) error
|
|||
case http.StatusInternalServerError:
|
||||
// Error, but typically includes a body explaining the error
|
||||
default:
|
||||
return errors.New(res.Status)
|
||||
return newStatusError(res)
|
||||
}
|
||||
|
||||
dec := xml.NewDecoder(res.Body)
|
||||
|
@ -755,7 +781,7 @@ func (c *Client) Download(ctx context.Context, u *url.URL, param *Download) (io.
|
|||
switch res.StatusCode {
|
||||
case http.StatusOK:
|
||||
default:
|
||||
err = errors.New(res.Status)
|
||||
err = fmt.Errorf("download(%s): %s", u, res.Status)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
|
|
@ -8231,7 +8231,7 @@ func init() {
|
|||
type ClusterDasAdmissionControlPolicy struct {
|
||||
DynamicData
|
||||
|
||||
ResourceReductionToToleratePercent int32 `xml:"resourceReductionToToleratePercent,omitempty"`
|
||||
ResourceReductionToToleratePercent *int32 `xml:"resourceReductionToToleratePercent"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
@ -49027,6 +49027,17 @@ type VStorageObjectCreateSnapshot_TaskResponse struct {
|
|||
Returnval ManagedObjectReference `xml:"returnval"`
|
||||
}
|
||||
|
||||
type VStorageObjectSnapshotDetails struct {
|
||||
DynamicData
|
||||
|
||||
Path string `xml:"path,omitempty"`
|
||||
ChangedBlockTrackingId string `xml:"changedBlockTrackingId,omitempty"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
t["VStorageObjectSnapshotDetails"] = reflect.TypeOf((*VStorageObjectSnapshotDetails)(nil)).Elem()
|
||||
}
|
||||
|
||||
type VStorageObjectSnapshotInfo struct {
|
||||
DynamicData
|
||||
|
||||
|
|
|
@ -571,7 +571,7 @@ github.com/ulikunitz/xz
|
|||
github.com/ulikunitz/xz/internal/hash
|
||||
github.com/ulikunitz/xz/internal/xlog
|
||||
github.com/ulikunitz/xz/lzma
|
||||
# github.com/vmware/govmomi v0.21.0
|
||||
# github.com/vmware/govmomi v0.22.2
|
||||
github.com/vmware/govmomi
|
||||
github.com/vmware/govmomi/find
|
||||
github.com/vmware/govmomi/list
|
||||
|
|
Loading…
Reference in New Issue