Merge pull request #9391 from hashicorp/fix_8656

Update vmware/govmomi to v0.22.2
This commit is contained in:
Megan Marsh 2020-06-10 11:04:55 -07:00 committed by GitHub
commit c984f71786
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 768 additions and 175 deletions

2
go.mod
View File

@ -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
View File

@ -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=

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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(),

View File

@ -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 {

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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

View File

@ -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)
}

View File

@ -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

View File

@ -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(),

View File

@ -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
}

View File

@ -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
}

View File

@ -19,3 +19,7 @@ package object
type VmwareDistributedVirtualSwitch struct {
DistributedVirtualSwitch
}
func (s VmwareDistributedVirtualSwitch) GetInventoryPath() string {
return s.InventoryPath
}

View File

@ -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"`
}

View File

@ -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

View File

@ -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.

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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)
}

68
vendor/github.com/vmware/govmomi/vim25/debug/file.go generated vendored Normal file
View File

@ -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()
}

49
vendor/github.com/vmware/govmomi/vim25/debug/log.go generated vendored Normal file
View File

@ -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() {
}

View File

@ -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() {

View File

@ -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
}

View File

@ -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
}

View File

@ -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 {

View File

@ -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

2
vendor/modules.txt vendored
View File

@ -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