Fix for Support selection of datastore for dynamic provisioning in vSphere

This commit is contained in:
Balu Dontu 2017-02-16 16:12:01 -08:00 committed by Ritesh H Shukla
parent b201ac2f8f
commit 12f75f0b86
83 changed files with 8640 additions and 504 deletions

62
Godeps/Godeps.json generated
View File

@ -1,7 +1,7 @@
{
"ImportPath": "k8s.io/kubernetes",
"GoVersion": "go1.7",
"GodepVersion": "v75",
"GodepVersion": "v78",
"Packages": [
"github.com/ugorji/go/codec/codecgen",
"github.com/onsi/ginkgo/ginkgo",
@ -2286,78 +2286,78 @@
},
{
"ImportPath": "github.com/vmware/govmomi",
"Comment": "v0.8.0-9-gb5ee639",
"Rev": "b5ee639d7aa4b8dbb48ab4f75dddc19f71b5c514"
"Comment": "v0.12.1-14-g0a28e59",
"Rev": "0a28e595c8e9e99879e8d2f796e82c5a68202ff0"
},
{
"ImportPath": "github.com/vmware/govmomi/find",
"Comment": "v0.8.0-9-gb5ee639",
"Rev": "b5ee639d7aa4b8dbb48ab4f75dddc19f71b5c514"
"Comment": "v0.12.1-14-g0a28e59",
"Rev": "0a28e595c8e9e99879e8d2f796e82c5a68202ff0"
},
{
"ImportPath": "github.com/vmware/govmomi/list",
"Comment": "v0.8.0-9-gb5ee639",
"Rev": "b5ee639d7aa4b8dbb48ab4f75dddc19f71b5c514"
"Comment": "v0.12.1-14-g0a28e59",
"Rev": "0a28e595c8e9e99879e8d2f796e82c5a68202ff0"
},
{
"ImportPath": "github.com/vmware/govmomi/object",
"Comment": "v0.8.0-9-gb5ee639",
"Rev": "b5ee639d7aa4b8dbb48ab4f75dddc19f71b5c514"
"Comment": "v0.12.1-14-g0a28e59",
"Rev": "0a28e595c8e9e99879e8d2f796e82c5a68202ff0"
},
{
"ImportPath": "github.com/vmware/govmomi/property",
"Comment": "v0.8.0-9-gb5ee639",
"Rev": "b5ee639d7aa4b8dbb48ab4f75dddc19f71b5c514"
"Comment": "v0.12.1-14-g0a28e59",
"Rev": "0a28e595c8e9e99879e8d2f796e82c5a68202ff0"
},
{
"ImportPath": "github.com/vmware/govmomi/session",
"Comment": "v0.8.0-9-gb5ee639",
"Rev": "b5ee639d7aa4b8dbb48ab4f75dddc19f71b5c514"
"Comment": "v0.12.1-14-g0a28e59",
"Rev": "0a28e595c8e9e99879e8d2f796e82c5a68202ff0"
},
{
"ImportPath": "github.com/vmware/govmomi/task",
"Comment": "v0.8.0-9-gb5ee639",
"Rev": "b5ee639d7aa4b8dbb48ab4f75dddc19f71b5c514"
"Comment": "v0.12.1-14-g0a28e59",
"Rev": "0a28e595c8e9e99879e8d2f796e82c5a68202ff0"
},
{
"ImportPath": "github.com/vmware/govmomi/vim25",
"Comment": "v0.8.0-9-gb5ee639",
"Rev": "b5ee639d7aa4b8dbb48ab4f75dddc19f71b5c514"
"Comment": "v0.12.1-14-g0a28e59",
"Rev": "0a28e595c8e9e99879e8d2f796e82c5a68202ff0"
},
{
"ImportPath": "github.com/vmware/govmomi/vim25/debug",
"Comment": "v0.8.0-9-gb5ee639",
"Rev": "b5ee639d7aa4b8dbb48ab4f75dddc19f71b5c514"
"Comment": "v0.12.1-14-g0a28e59",
"Rev": "0a28e595c8e9e99879e8d2f796e82c5a68202ff0"
},
{
"ImportPath": "github.com/vmware/govmomi/vim25/methods",
"Comment": "v0.8.0-9-gb5ee639",
"Rev": "b5ee639d7aa4b8dbb48ab4f75dddc19f71b5c514"
"Comment": "v0.12.1-14-g0a28e59",
"Rev": "0a28e595c8e9e99879e8d2f796e82c5a68202ff0"
},
{
"ImportPath": "github.com/vmware/govmomi/vim25/mo",
"Comment": "v0.8.0-9-gb5ee639",
"Rev": "b5ee639d7aa4b8dbb48ab4f75dddc19f71b5c514"
"Comment": "v0.12.1-14-g0a28e59",
"Rev": "0a28e595c8e9e99879e8d2f796e82c5a68202ff0"
},
{
"ImportPath": "github.com/vmware/govmomi/vim25/progress",
"Comment": "v0.8.0-9-gb5ee639",
"Rev": "b5ee639d7aa4b8dbb48ab4f75dddc19f71b5c514"
"Comment": "v0.12.1-14-g0a28e59",
"Rev": "0a28e595c8e9e99879e8d2f796e82c5a68202ff0"
},
{
"ImportPath": "github.com/vmware/govmomi/vim25/soap",
"Comment": "v0.8.0-9-gb5ee639",
"Rev": "b5ee639d7aa4b8dbb48ab4f75dddc19f71b5c514"
"Comment": "v0.12.1-14-g0a28e59",
"Rev": "0a28e595c8e9e99879e8d2f796e82c5a68202ff0"
},
{
"ImportPath": "github.com/vmware/govmomi/vim25/types",
"Comment": "v0.8.0-9-gb5ee639",
"Rev": "b5ee639d7aa4b8dbb48ab4f75dddc19f71b5c514"
"Comment": "v0.12.1-14-g0a28e59",
"Rev": "0a28e595c8e9e99879e8d2f796e82c5a68202ff0"
},
{
"ImportPath": "github.com/vmware/govmomi/vim25/xml",
"Comment": "v0.8.0-9-gb5ee639",
"Rev": "b5ee639d7aa4b8dbb48ab4f75dddc19f71b5c514"
"Comment": "v0.12.1-14-g0a28e59",
"Rev": "0a28e595c8e9e99879e8d2f796e82c5a68202ff0"
},
{
"ImportPath": "github.com/vmware/photon-controller-go-sdk/photon",

View File

@ -202,7 +202,7 @@
__Note: Here you don't need to create vmdk it is created for you.__
1. Create Storage Class.
See example:
Example 1:
```yaml
kind: StorageClass
@ -216,6 +216,23 @@
[Download example](vsphere-volume-sc-fast.yaml?raw=true)
You can also specify the datastore in the Storageclass as shown in example 2. The volume will be created on the datastore specified in the storage class.
This field is optional. If not specified as shown in example 1, the volume will be created on the datastore specified in the vsphere config file used to initialize the vSphere Cloud Provider.
Example 2:
```yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1beta1
metadata:
name: fast
provisioner: kubernetes.io/vsphere-volume
parameters:
diskformat: zeroedthick
datastore: VSANDatastore
```
[Download example](vsphere-volume-sc-with-datastore.yaml?raw=true)
Creating the storageclass:
``` bash

View File

@ -0,0 +1,8 @@
kind: StorageClass
apiVersion: storage.k8s.io/v1beta1
metadata:
name: fast
provisioner: kubernetes.io/vsphere-volume
parameters:
diskformat: zeroedthick
datastore: vsanDatastore

View File

@ -170,6 +170,7 @@ type VolumeOptions struct {
Tags map[string]string
Name string
DiskFormat string
Datastore string
}
// Generates Valid Options for Diskformat
@ -638,36 +639,30 @@ func (vs *VSphere) ScrubDNS(nameservers, searches []string) (nsOut, srchOut []st
}
// Returns vSphere objects virtual machine, virtual device list, datastore and datacenter.
func getVirtualMachineDevices(ctx context.Context, cfg *VSphereConfig, c *govmomi.Client, name string) (*object.VirtualMachine, object.VirtualDeviceList, *object.Datastore, *object.Datacenter, error) {
func getVirtualMachineDevices(ctx context.Context, cfg *VSphereConfig, c *govmomi.Client, name string) (*object.VirtualMachine, object.VirtualDeviceList, *object.Datacenter, error) {
// Create a new finder
f := find.NewFinder(c.Client, true)
// Fetch and set data center
dc, err := f.Datacenter(ctx, cfg.Global.Datacenter)
if err != nil {
return nil, nil, nil, nil, err
return nil, nil, nil, err
}
f.SetDatacenter(dc)
// Find datastores
ds, err := f.Datastore(ctx, cfg.Global.Datastore)
if err != nil {
return nil, nil, nil, nil, err
}
vmRegex := cfg.Global.WorkingDir + name
vm, err := f.VirtualMachine(ctx, vmRegex)
if err != nil {
return nil, nil, nil, nil, err
return nil, nil, nil, err
}
// Get devices from VM
vmDevices, err := vm.Device(ctx)
if err != nil {
return nil, nil, nil, nil, err
return nil, nil, nil, err
}
return vm, vmDevices, ds, dc, nil
return vm, vmDevices, dc, nil
}
// Removes SCSI controller which is latest attached to VM.
@ -710,7 +705,7 @@ func (vs *VSphere) AttachDisk(vmDiskPath string, nodeName k8stypes.NodeName) (di
}
// Get VM device list
vm, vmDevices, ds, dc, err := getVirtualMachineDevices(ctx, vs.cfg, vs.client, vSphereInstance)
vm, vmDevices, dc, err := getVirtualMachineDevices(ctx, vs.cfg, vs.client, vSphereInstance)
if err != nil {
return "", "", err
}
@ -776,6 +771,23 @@ func (vs *VSphere) AttachDisk(vmDiskPath string, nodeName k8stypes.NodeName) (di
newSCSICreated = true
}
// Create a new finder
f := find.NewFinder(vs.client.Client, true)
// Set data center
f.SetDatacenter(dc)
datastorePathObj := new(object.DatastorePath)
isSuccess := datastorePathObj.FromString(vmDiskPath)
if !isSuccess {
glog.Errorf("Failed to parse vmDiskPath: %+q", vmDiskPath)
return "", "", errors.New("Failed to parse vmDiskPath")
}
ds, err := f.Datastore(ctx, datastorePathObj.Datastore)
if err != nil {
glog.Errorf("Failed while searching for datastore %+q. err %s", datastorePathObj.Datastore, err)
return "", "", err
}
disk := vmDevices.CreateDisk(scsiController, ds.Reference(), vmDiskPath)
unitNumber, err := getNextUnitNumber(vmDevices, scsiController)
if err != nil {
@ -940,7 +952,7 @@ func (vs *VSphere) DiskIsAttached(volPath string, nodeName k8stypes.NodeName) (b
}
// Get VM device list
_, vmDevices, _, dc, err := getVirtualMachineDevices(ctx, vs.cfg, vs.client, vSphereInstance)
_, vmDevices, dc, err := getVirtualMachineDevices(ctx, vs.cfg, vs.client, vSphereInstance)
if err != nil {
glog.Errorf("Failed to get VM devices for VM %#q. err: %s", vSphereInstance, err)
return false, err
@ -992,7 +1004,7 @@ func (vs *VSphere) DisksAreAttached(volPaths []string, nodeName k8stypes.NodeNam
}
// Get VM device list
_, vmDevices, _, dc, err := getVirtualMachineDevices(ctx, vs.cfg, vs.client, vSphereInstance)
_, vmDevices, dc, err := getVirtualMachineDevices(ctx, vs.cfg, vs.client, vSphereInstance)
if err != nil {
glog.Errorf("Failed to get VM devices for VM %#q. err: %s", vSphereInstance, err)
return attached, err
@ -1154,7 +1166,8 @@ func (vs *VSphere) DetachDisk(volPath string, nodeName k8stypes.NodeName) error
vSphereInstance = nodeNameToVMName(nodeName)
}
vm, vmDevices, _, dc, err := getVirtualMachineDevices(ctx, vs.cfg, vs.client, vSphereInstance)
vm, vmDevices, dc, err := getVirtualMachineDevices(ctx, vs.cfg, vs.client, vSphereInstance)
if err != nil {
return err
}
@ -1184,6 +1197,14 @@ func (vs *VSphere) DetachDisk(volPath string, nodeName k8stypes.NodeName) error
func (vs *VSphere) CreateVolume(volumeOptions *VolumeOptions) (volumePath string, err error) {
var diskFormat string
var datastore string
// Default datastore is the datastore in the vSphere config file that is used initialize vSphere cloud provider.
if volumeOptions.Datastore == "" {
datastore = vs.cfg.Global.Datastore
} else {
datastore = volumeOptions.Datastore
}
// Default diskformat as 'thin'
if volumeOptions.DiskFormat == "" {
@ -1215,9 +1236,9 @@ func (vs *VSphere) CreateVolume(volumeOptions *VolumeOptions) (volumePath string
dc, err := f.Datacenter(ctx, vs.cfg.Global.Datacenter)
f.SetDatacenter(dc)
ds, err := f.Datastore(ctx, vs.cfg.Global.Datastore)
ds, err := f.Datastore(ctx, datastore)
if err != nil {
glog.Errorf("Failed while searching for datastore %+q. err %s", vs.cfg.Global.Datastore, err)
glog.Errorf("Failed while searching for datastore %+q. err %s", datastore, err)
return "", err
}

View File

@ -75,6 +75,8 @@ func (util *VsphereDiskUtil) CreateVolume(v *vsphereVolumeProvisioner) (vmDiskPa
switch strings.ToLower(parameter) {
case "diskformat":
volumeOptions.DiskFormat = value
case "datastore":
volumeOptions.Datastore = value
default:
return "", 0, fmt.Errorf("invalid option %q for volume plugin %s", parameter, v.plugin.GetPluginName())
}

17
vendor/BUILD vendored
View File

@ -6742,7 +6742,6 @@ go_library(
"//vendor:github.com/vmware/govmomi/vim25",
"//vendor:github.com/vmware/govmomi/vim25/soap",
"//vendor:github.com/vmware/govmomi/vim25/types",
"//vendor:golang.org/x/net/context",
],
)
@ -6760,7 +6759,6 @@ go_library(
"//vendor:github.com/vmware/govmomi/vim25",
"//vendor:github.com/vmware/govmomi/vim25/mo",
"//vendor:github.com/vmware/govmomi/vim25/types",
"//vendor:golang.org/x/net/context",
],
)
@ -6777,7 +6775,6 @@ go_library(
"//vendor:github.com/vmware/govmomi/vim25/mo",
"//vendor:github.com/vmware/govmomi/vim25/soap",
"//vendor:github.com/vmware/govmomi/vim25/types",
"//vendor:golang.org/x/net/context",
],
)
@ -6792,6 +6789,9 @@ go_library(
"github.com/vmware/govmomi/object/customization_spec_manager.go",
"github.com/vmware/govmomi/object/datacenter.go",
"github.com/vmware/govmomi/object/datastore.go",
"github.com/vmware/govmomi/object/datastore_file.go",
"github.com/vmware/govmomi/object/datastore_path.go",
"github.com/vmware/govmomi/object/diagnostic_log.go",
"github.com/vmware/govmomi/object/diagnostic_manager.go",
"github.com/vmware/govmomi/object/distributed_virtual_portgroup.go",
"github.com/vmware/govmomi/object/distributed_virtual_switch.go",
@ -6800,9 +6800,12 @@ go_library(
"github.com/vmware/govmomi/object/folder.go",
"github.com/vmware/govmomi/object/history_collector.go",
"github.com/vmware/govmomi/object/host_account_manager.go",
"github.com/vmware/govmomi/object/host_certificate_info.go",
"github.com/vmware/govmomi/object/host_certificate_manager.go",
"github.com/vmware/govmomi/object/host_config_manager.go",
"github.com/vmware/govmomi/object/host_datastore_browser.go",
"github.com/vmware/govmomi/object/host_datastore_system.go",
"github.com/vmware/govmomi/object/host_date_time_system.go",
"github.com/vmware/govmomi/object/host_firewall_system.go",
"github.com/vmware/govmomi/object/host_network_system.go",
"github.com/vmware/govmomi/object/host_service_system.go",
@ -6840,7 +6843,6 @@ go_library(
"//vendor:github.com/vmware/govmomi/vim25/progress",
"//vendor:github.com/vmware/govmomi/vim25/soap",
"//vendor:github.com/vmware/govmomi/vim25/types",
"//vendor:golang.org/x/net/context",
],
)
@ -6857,7 +6859,6 @@ go_library(
"//vendor:github.com/vmware/govmomi/vim25/mo",
"//vendor:github.com/vmware/govmomi/vim25/soap",
"//vendor:github.com/vmware/govmomi/vim25/types",
"//vendor:golang.org/x/net/context",
],
)
@ -6875,7 +6876,6 @@ go_library(
"//vendor:github.com/vmware/govmomi/vim25/mo",
"//vendor:github.com/vmware/govmomi/vim25/soap",
"//vendor:github.com/vmware/govmomi/vim25/types",
"//vendor:golang.org/x/net/context",
],
)
@ -6890,7 +6890,6 @@ go_library(
"//vendor:github.com/vmware/govmomi/property",
"//vendor:github.com/vmware/govmomi/vim25/progress",
"//vendor:github.com/vmware/govmomi/vim25/types",
"//vendor:golang.org/x/net/context",
],
)
@ -6906,7 +6905,6 @@ go_library(
"//vendor:github.com/vmware/govmomi/vim25/methods",
"//vendor:github.com/vmware/govmomi/vim25/soap",
"//vendor:github.com/vmware/govmomi/vim25/types",
"//vendor:golang.org/x/net/context",
],
)
@ -6927,7 +6925,6 @@ go_library(
deps = [
"//vendor:github.com/vmware/govmomi/vim25/soap",
"//vendor:github.com/vmware/govmomi/vim25/types",
"//vendor:golang.org/x/net/context",
],
)
@ -6948,7 +6945,6 @@ go_library(
"//vendor:github.com/vmware/govmomi/vim25/methods",
"//vendor:github.com/vmware/govmomi/vim25/soap",
"//vendor:github.com/vmware/govmomi/vim25/types",
"//vendor:golang.org/x/net/context",
],
)
@ -6981,7 +6977,6 @@ go_library(
"//vendor:github.com/vmware/govmomi/vim25/progress",
"//vendor:github.com/vmware/govmomi/vim25/types",
"//vendor:github.com/vmware/govmomi/vim25/xml",
"//vendor:golang.org/x/net/context",
],
)

View File

@ -2,7 +2,7 @@ clone:
tags: true
path: github.com/vmware/govmomi
build:
image: golang:1.6
image: golang:1.7
pull: true
environment:
- GOVC_TEST_URL=$$GOVC_TEST_URL

View File

@ -3,7 +3,7 @@ sudo: false
language: go
go:
- 1.6
- 1.7
before_install:
- make vendor

View File

@ -1,5 +1,69 @@
# changelog
### 0.12.1 (2016-12-19)
* Add DiagnosticLog helper
* Add DatastorePath helper
### 0.12.0 (2016-12-01)
* Disable use of service ticket for datastore HTTP access by default
* Attach context to HTTP requests for cancellations
* Update to vim25/6.5 API
### 0.11.4 (2016-11-15)
* Add object.AuthorizationManager methods: RetrieveRolePermissions, RetrieveAllPermissions, AddRole, RemoveRole, UpdateRole
### 0.11.3 (2016-11-08)
* Allow DatastoreFile.Follow reader to drain current body after stopping
### 0.11.2 (2016-11-01)
* Avoid possible NPE in VirtualMachine.Device method
* Add support for OpaqueNetwork type to Finder
* Add HostConfigManager.AccountManager support for ESX 5.5
### 0.11.1 (2016-10-27)
* Add Finder.ResourcePoolListAll method
### 0.11.0 (2016-10-25)
* Add object.DistributedVirtualPortgroup.Reconfigure method
### 0.10.0 (2016-10-20)
* Add option to set soap.Client.UserAgent
* Add service ticket thumbprint validation
* Update use of http.DefaultTransport fields to 1.7
* Set default locale to en_US (override with GOVMOMI_LOCALE env var)
* Add object.HostCertificateInfo (types.HostCertificateManagerCertificateInfo helpers)
* Add object.HostCertificateManager type and HostConfigManager.CertificateManager method
* Add soap.Client SetRootCAs and SetDialTLS methods
### 0.9.0 (2016-09-09)
* Add object.DatastoreFile helpers for streaming and tailing datastore files
* Add object VirtualMachine.Unregister method
* Add object.ListView methods: Add, Remove, Reset
* Update to Go 1.7 - using stdlib's context package
### 0.8.0 (2016-06-30)
* Add session.Manager.AcquireLocalTicket

View File

@ -3,38 +3,48 @@
# Please keep the list sorted.
#
abrarshivani <abrarshivani@users.noreply.github.com>
Alvaro Miranda <kikitux@gmail.com>
Amit Bathla <abathla@.vmware.com>
Andrew Chin <andrew@andrewtchin.com>
Arran Walker <arran.walker@zopa.com>
Austin Parker <aparker@apprenda.com>
Bob Killen <killen.bob@gmail.com>
Bruce Downs <bdowns@vmware.com>
Brad Fitzpatrick <bradfitz@golang.org>
Bruce Downs <bruceadowns@gmail.com>
Cédric Blomart <cblomart@gmail.com>
Christian Höltje <docwhat@gerf.org>
Clint Greenwood <cgreenwood@vmware.com> <clint.greenwood@gmail.com>
Danny Lockard <danny.lockard@banno.com>
Dave Tucker <dave@dtucker.co.uk>
Davide Agnello <dagnello@hp.com>
David Stark <dave@davidstark.name>
Doug MacEachern <dougm@vmware.com>
Eloy Coto <eloy.coto@gmail.com>
Eric Yutao <eric.yutao@gmail.com>
Fabio Rapposelli <fabio@vmware.com>
Faiyaz Ahmed <ahmedf@vmware.com>
forkbomber <forkbomber@users.noreply.github.com>
Gavin Gray <gavin@infinio.com>
Gavrie Philipson <gavrie@philipson.co.il> <gavrie.philipson@elastifile.com>
George Hicken <ghicken@vmware.com>
Gerrit Renker <Gerrit.Renker@ctl.io>
gthombare <gthombare@vmware.com>
Hasan Mahmood <mahmoodh@vmware.com>
Henrik Hodne <henrik@travis-ci.com>
Isaac Rodman <isaac@eyz.us>
Jason Kincl <jkincl@gmail.com>
Louie Jiang <jiangl@vmware.com>
Mevan Samaratunga <mevansam@gmail.com>
Nicolas Lamirault <nicolas.lamirault@gmail.com>
Pieter Noordhuis <pnoordhuis@vmware.com> <pcnoordhuis@gmail.com>
runner.mei <runner.mei@gmail.com>
S.Çağlar Onur <conur@vmware.com>
Sergey Ignatov <sergey.ignatov@jetbrains.com>
Steve Purcell <steve@sanityinc.com>
Takaaki Furukawa <takaaki.frkw@gmail.com> <takaaki.furukawa@mail.rakuten.com>
Ted Zlatanov <tzz@lifelogs.com>
Vadim Egorov <vegorov@vmware.com>
Yang Yang <yangy@vmware.com>
Yuya Kusakabe <yuya.kusakabe@gmail.com>
Zach Tucker <ztucker@vmware.com>

View File

@ -18,3 +18,6 @@ test:
install:
go install github.com/vmware/govmomi/govc
doc: install
./govc/usage.sh > ./govc/USAGE.md

View File

@ -1,15 +1,15 @@
[![Build Status](https://travis-ci.org/vmware/govmomi.png?branch=master)](https://travis-ci.org/vmware/govmomi)
[![Build Status](https://ci.vmware.run/api/badges/vmware/govmomi/status.svg)](https://ci.vmware.run/vmware/govmomi)
[![Go Report Card](https://goreportcard.com/badge/github.com/vmware/govmomi)](https://goreportcard.com/report/github.com/vmware/govmomi)
# govmomi
A Go library for interacting with VMware vSphere APIs (ESXi and/or vCenter).
For `govc`, a CLI built on top of govmomi, check out the [govc](./govc) directory.
For `govc`, a CLI built on top of govmomi, check out the [govc](./govc) directory and [USAGE](./govc/USAGE.md) document.
## Compatibility
This library is built for and tested against ESXi and vCenter 5.5 and 6.0.
This library is built for and tested against ESXi and vCenter 5.5, 6.0 and 6.5.
If you're able to use it against older versions of ESXi and/or vCenter, please
leave a note and we'll include it in this compatibility list.
@ -37,6 +37,12 @@ To build locally with Drone:
- Install the [Drone command line tools][dronecli].
- Run `drone exec` from within the root directory of the govmomi repository.
## Discussion
Contributors and users are encouraged to collaborate using GitHub issues and/or
[Slack](https://vmwarecode.slack.com/messages/govmomi).
Access to Slack requires a [VMware {code} membership](https://code.vmware.com/join/).
## Status
Changes to the API are subject to [semantic versioning](http://semver.org).
@ -47,8 +53,16 @@ Refer to the [CHANGELOG](CHANGELOG.md) for version to version changes.
* [Docker Machine](https://github.com/docker/machine/tree/master/drivers/vmwarevsphere)
* [Kubernetes](https://github.com/kubernetes/kubernetes/tree/master/pkg/cloudprovider/providers/vsphere)
* [Terraform](https://github.com/hashicorp/terraform/tree/master/builtin/providers/vsphere)
* [VMware VIC Engine](https://github.com/vmware/vic)
* [Travis CI](https://github.com/travis-ci/jupiter-brain)
* [Gru](https://github.com/dnaeon/gru)
## License
govmomi is available under the [Apache 2 license](LICENSE).

View File

@ -57,6 +57,7 @@ are kept outside the object package.
package govmomi
import (
"context"
"crypto/tls"
"net/url"
@ -65,7 +66,6 @@ import (
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type Client struct {

View File

@ -17,6 +17,7 @@ limitations under the License.
package find
import (
"context"
"errors"
"path"
@ -26,7 +27,6 @@ import (
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type Finder struct {
@ -110,6 +110,35 @@ func (f *Finder) datacenter() (*object.Datacenter, error) {
return f.dc, nil
}
// datacenterPath returns the absolute path to the Datacenter containing the given ref
func (f *Finder) datacenterPath(ctx context.Context, ref types.ManagedObjectReference) (string, error) {
mes, err := mo.Ancestors(ctx, f.client, f.client.ServiceContent.PropertyCollector, ref)
if err != nil {
return "", err
}
// Chop leaves under the Datacenter
for i := len(mes) - 1; i > 0; i-- {
if mes[i].Self.Type == "Datacenter" {
break
}
mes = mes[:i]
}
var p string
for _, me := range mes {
// Skip root entity in building inventory path.
if me.Parent == nil {
continue
}
p = p + "/" + me.Name
}
return p, nil
}
func (f *Finder) dcFolders(ctx context.Context) (*object.DatacenterFolders, error) {
if f.folders != nil {
return f.folders, nil
@ -232,6 +261,12 @@ func (f *Finder) ObjectReference(ctx context.Context, ref types.ManagedObjectRef
r.(common).SetInventoryPath(e.Path)
if f.dc != nil {
if ds, ok := r.(*object.Datastore); ok {
ds.DatacenterPath = f.dc.InventoryPath
}
}
return r, nil
}
@ -313,6 +348,16 @@ func (f *Finder) DatastoreList(ctx context.Context, path string) ([]*object.Data
ds := object.NewDatastore(f.client, ref)
ds.InventoryPath = e.Path
if f.dc == nil {
// In this case SetDatacenter was not called and path is absolute
ds.DatacenterPath, err = f.datacenterPath(ctx, ref)
if err != nil {
return nil, err
}
} else {
ds.DatacenterPath = f.dc.InventoryPath
}
dss = append(dss, ds)
}
}
@ -599,7 +644,7 @@ func (f *Finder) NetworkList(ctx context.Context, path string) ([]object.Network
for _, e := range es {
ref := e.Object.Reference()
switch ref.Type {
case "Network":
case "Network", "OpaqueNetwork":
r := object.NewNetwork(f.client, ref)
r.InventoryPath = e.Path
ns = append(ns, r)
@ -714,6 +759,29 @@ func (f *Finder) ResourcePoolOrDefault(ctx context.Context, path string) (*objec
return f.DefaultResourcePool(ctx)
}
// ResourcePoolListAll combines ResourcePoolList and VirtualAppList
// VirtualAppList is only called if ResourcePoolList does not find any pools with the given path.
func (f *Finder) ResourcePoolListAll(ctx context.Context, path string) ([]*object.ResourcePool, error) {
pools, err := f.ResourcePoolList(ctx, path)
if err != nil {
if _, ok := err.(*NotFoundError); !ok {
return nil, err
}
vapps, _ := f.VirtualAppList(ctx, path)
if len(vapps) == 0 {
return nil, err
}
for _, vapp := range vapps {
pools = append(pools, vapp.ResourcePool)
}
}
return pools, nil
}
func (f *Finder) DefaultFolder(ctx context.Context) (*object.Folder, error) {
ref, err := f.vmFolder(ctx)
if err != nil {

View File

@ -17,6 +17,7 @@ limitations under the License.
package list
import (
"context"
"fmt"
"path"
"reflect"
@ -25,7 +26,6 @@ import (
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type Element struct {
@ -79,6 +79,8 @@ func ToElement(r mo.Reference, prefix string) Element {
// Network entity folders on an ESXi host can contain only Network objects.
case mo.Network:
name = m.Name
case mo.OpaqueNetwork:
name = m.Name
case mo.DistributedVirtualSwitch:
name = m.Name
case mo.DistributedVirtualPortgroup:

View File

@ -17,11 +17,11 @@ limitations under the License.
package list
import (
"context"
"path"
"path/filepath"
"github.com/vmware/govmomi/property"
"golang.org/x/net/context"
)
type Recurser struct {

View File

@ -17,11 +17,12 @@ limitations under the License.
package object
import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type AuthorizationManager struct {
@ -106,3 +107,68 @@ func (m AuthorizationManager) SetEntityPermissions(ctx context.Context, entity t
_, err := methods.SetEntityPermissions(ctx, m.Client(), &req)
return err
}
func (m AuthorizationManager) RetrieveRolePermissions(ctx context.Context, id int32) ([]types.Permission, error) {
req := types.RetrieveRolePermissions{
This: m.Reference(),
RoleId: id,
}
res, err := methods.RetrieveRolePermissions(ctx, m.Client(), &req)
if err != nil {
return nil, err
}
return res.Returnval, nil
}
func (m AuthorizationManager) RetrieveAllPermissions(ctx context.Context) ([]types.Permission, error) {
req := types.RetrieveAllPermissions{
This: m.Reference(),
}
res, err := methods.RetrieveAllPermissions(ctx, m.Client(), &req)
if err != nil {
return nil, err
}
return res.Returnval, nil
}
func (m AuthorizationManager) AddRole(ctx context.Context, name string, ids []string) (int32, error) {
req := types.AddAuthorizationRole{
This: m.Reference(),
Name: name,
PrivIds: ids,
}
res, err := methods.AddAuthorizationRole(ctx, m.Client(), &req)
if err != nil {
return -1, err
}
return res.Returnval, nil
}
func (m AuthorizationManager) RemoveRole(ctx context.Context, id int32, failIfUsed bool) error {
req := types.RemoveAuthorizationRole{
This: m.Reference(),
RoleId: id,
FailIfUsed: failIfUsed,
}
_, err := methods.RemoveAuthorizationRole(ctx, m.Client(), &req)
return err
}
func (m AuthorizationManager) UpdateRole(ctx context.Context, id int32, name string, ids []string) error {
req := types.UpdateAuthorizationRole{
This: m.Reference(),
RoleId: id,
NewName: name,
PrivIds: ids,
}
_, err := methods.UpdateAuthorizationRole(ctx, m.Client(), &req)
return err
}

View File

@ -17,10 +17,11 @@ limitations under the License.
package object
import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type ClusterComputeResource struct {

View File

@ -17,6 +17,7 @@ limitations under the License.
package object
import (
"context"
"errors"
"fmt"
"path"
@ -26,11 +27,10 @@ import (
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
var (
ErrNotSupported = errors.New("not supported (vCenter only)")
ErrNotSupported = errors.New("product/version specific feature not supported by target")
)
// Common contains the fields and functions common to all objects.

View File

@ -17,6 +17,7 @@ limitations under the License.
package object
import (
"context"
"path"
"github.com/vmware/govmomi/property"
@ -24,7 +25,6 @@ import (
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type ComputeResource struct {

View File

@ -17,6 +17,7 @@ limitations under the License.
package object
import (
"context"
"errors"
"strconv"
@ -24,7 +25,6 @@ import (
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
var (

View File

@ -17,10 +17,11 @@ limitations under the License.
package object
import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type CustomizationSpecManager struct {

View File

@ -17,13 +17,13 @@ limitations under the License.
package object
import (
"context"
"fmt"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type DatacenterFolders struct {

View File

@ -24,6 +24,7 @@ import (
"path"
"strings"
"context"
"net/http"
"net/url"
@ -33,7 +34,6 @@ import (
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
// DatastoreNoSuchDirectoryError is returned when a directory could not be found.
@ -58,6 +58,8 @@ func (e DatastoreNoSuchFileError) Error() string {
type Datastore struct {
Common
DatacenterPath string
}
func NewDatastore(c *vim25.Client, ref types.ManagedObjectReference) *Datastore {
@ -67,26 +69,14 @@ func NewDatastore(c *vim25.Client, ref types.ManagedObjectReference) *Datastore
}
func (d Datastore) Path(path string) string {
name := d.Name()
if name == "" {
panic("expected non-empty name")
}
return fmt.Sprintf("[%s] %s", name, path)
return (&DatastorePath{
Datastore: d.Name(),
Path: path,
}).String()
}
// URL for datastore access over HTTP
func (d Datastore) URL(ctx context.Context, dc *Datacenter, path string) (*url.URL, error) {
var mdc mo.Datacenter
if err := dc.Properties(ctx, dc.Reference(), []string{"name"}, &mdc); err != nil {
return nil, err
}
var mds mo.Datastore
if err := d.Properties(ctx, d.Reference(), []string{"name"}, &mds); err != nil {
return nil, err
}
// NewURL constructs a url.URL with the given file path for datastore access over HTTP.
func (d Datastore) NewURL(path string) *url.URL {
u := d.c.URL()
return &url.URL{
@ -94,10 +84,15 @@ func (d Datastore) URL(ctx context.Context, dc *Datacenter, path string) (*url.U
Host: u.Host,
Path: fmt.Sprintf("/folder/%s", path),
RawQuery: url.Values{
"dcPath": []string{mdc.Name},
"dsName": []string{mds.Name},
"dcPath": []string{d.DatacenterPath},
"dsName": []string{d.Name()},
}.Encode(),
}, nil
}
}
// URL is deprecated, use NewURL instead.
func (d Datastore) URL(ctx context.Context, dc *Datacenter, path string) (*url.URL, error) {
return d.NewURL(path), nil
}
func (d Datastore) Browser(ctx context.Context) (*HostDatastoreBrowser, error) {
@ -111,6 +106,27 @@ func (d Datastore) Browser(ctx context.Context) (*HostDatastoreBrowser, error) {
return NewHostDatastoreBrowser(d.c, do.Browser), nil
}
func (d Datastore) useServiceTicket() bool {
// If connected to workstation, service ticketing not supported
// If connected to ESX, service ticketing not needed
if !d.c.IsVC() {
return false
}
key := "GOVMOMI_USE_SERVICE_TICKET"
val := d.c.URL().Query().Get(key)
if val == "" {
val = os.Getenv(key)
}
if val == "1" || val == "true" {
return true
}
return false
}
func (d Datastore) useServiceTicketHostName(name string) bool {
// No need if talking directly to ESX.
if !d.c.IsVC() {
@ -147,39 +163,62 @@ func (d Datastore) useServiceTicketHostName(name string) bool {
return false
}
// ServiceTicket obtains a ticket via AcquireGenericServiceTicket and returns it an http.Cookie with the url.URL
// that can be used along with the ticket cookie to access the given path.
func (d Datastore) ServiceTicket(ctx context.Context, path string, method string) (*url.URL, *http.Cookie, error) {
// We are uploading to an ESX host
u := &url.URL{
Scheme: d.c.URL().Scheme,
Host: d.c.URL().Host,
Path: fmt.Sprintf("/folder/%s", path),
RawQuery: url.Values{
"dsName": []string{d.Name()},
}.Encode(),
}
type datastoreServiceTicketHostKey struct{}
// HostContext returns a Context where the given host will be used for datastore HTTP access
// via the ServiceTicket method.
func (d Datastore) HostContext(ctx context.Context, host *HostSystem) context.Context {
return context.WithValue(ctx, datastoreServiceTicketHostKey{}, host)
}
// ServiceTicket obtains a ticket via AcquireGenericServiceTicket and returns it an http.Cookie with the url.URL
// that can be used along with the ticket cookie to access the given path. An host is chosen at random unless the
// the given Context was created with a specific host via the HostContext method.
func (d Datastore) ServiceTicket(ctx context.Context, path string, method string) (*url.URL, *http.Cookie, error) {
u := d.NewURL(path)
host, ok := ctx.Value(datastoreServiceTicketHostKey{}).(*HostSystem)
if !ok {
if !d.useServiceTicket() {
return u, nil, nil
}
// If connected to VC, the ticket request must be for an ESX host.
if d.c.IsVC() {
hosts, err := d.AttachedHosts(ctx)
if err != nil {
return nil, nil, err
}
if len(hosts) == 0 {
return nil, nil, fmt.Errorf("no hosts attached to datastore %#v", d.Reference())
// Fallback to letting vCenter choose a host
return u, nil, nil
}
// Pick a random attached host
host := hosts[rand.Intn(len(hosts))]
name, err := host.ObjectName(ctx)
host = hosts[rand.Intn(len(hosts))]
}
ips, err := host.ManagementIPs(ctx)
if err != nil {
return nil, nil, err
}
if len(ips) > 0 {
// prefer a ManagementIP
u.Host = ips[0].String()
} else {
// fallback to inventory name
u.Host, err = host.ObjectName(ctx)
if err != nil {
return nil, nil, err
}
u.Host = name
}
// VC datacenter path will not be valid against ESX
q := u.Query()
delete(q, "dcPath")
u.RawQuery = q.Encode()
spec := types.SessionManagerHttpServiceRequestSpec{
Url: u.String(),
// See SessionManagerHttpServiceRequestSpecMethod enum
@ -202,6 +241,8 @@ func (d Datastore) ServiceTicket(ctx context.Context, path string, method string
u.Host = ticket.HostName
}
d.Client().SetThumbprint(u.Host, ticket.SslThumbprint)
return u, cookie, nil
}
@ -313,7 +354,7 @@ func (d Datastore) AttachedHosts(ctx context.Context) ([]*HostSystem, error) {
return hosts, nil
}
// AttachedHosts returns hosts that have this Datastore attached, accessible and writable and are members of the given cluster.
// AttachedClusterHosts returns hosts that have this Datastore attached, accessible and writable and are members of the given cluster.
func (d Datastore) AttachedClusterHosts(ctx context.Context, cluster *ComputeResource) ([]*HostSystem, error) {
var hosts []*HostSystem
@ -358,12 +399,12 @@ func (d Datastore) Stat(ctx context.Context, file string) (types.BaseFileInfo, e
}
dsPath := d.Path(path.Dir(file))
task, err := b.SearchDatastore(context.TODO(), dsPath, &spec)
task, err := b.SearchDatastore(ctx, dsPath, &spec)
if err != nil {
return nil, err
}
info, err := task.WaitForResult(context.TODO(), nil)
info, err := task.WaitForResult(ctx, nil)
if err != nil {
if info == nil || info.Error != nil {
_, ok := info.Error.Fault.(*types.FileNotFound)

View File

@ -0,0 +1,399 @@
/*
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package object
import (
"bytes"
"context"
"errors"
"fmt"
"io"
"net/http"
"os"
"path"
"time"
"github.com/vmware/govmomi/vim25/soap"
)
// DatastoreFile implements io.Reader, io.Seeker and io.Closer interfaces for datastore file access.
type DatastoreFile struct {
d Datastore
ctx context.Context
name string
buf io.Reader
body io.ReadCloser
length int64
offset struct {
read, seek int64
}
}
// Open opens the named file relative to the Datastore.
func (d Datastore) Open(ctx context.Context, name string) (*DatastoreFile, error) {
return &DatastoreFile{
d: d,
name: name,
length: -1,
ctx: ctx,
}, nil
}
// Read reads up to len(b) bytes from the DatastoreFile.
func (f *DatastoreFile) Read(b []byte) (int, error) {
if f.offset.read != f.offset.seek {
// A Seek() call changed the offset, we need to issue a new GET
_ = f.Close()
f.offset.read = f.offset.seek
} else if f.buf != nil {
// f.buf + f behaves like an io.MultiReader
n, err := f.buf.Read(b)
if err == io.EOF {
f.buf = nil // buffer has been drained
}
if n > 0 {
return n, nil
}
}
body, err := f.get()
if err != nil {
return 0, err
}
n, err := body.Read(b)
f.offset.read += int64(n)
f.offset.seek += int64(n)
return n, err
}
// Close closes the DatastoreFile.
func (f *DatastoreFile) Close() error {
var err error
if f.body != nil {
err = f.body.Close()
f.body = nil
}
f.buf = nil
return err
}
// Seek sets the offset for the next Read on the DatastoreFile.
func (f *DatastoreFile) Seek(offset int64, whence int) (int64, error) {
switch whence {
case io.SeekStart:
case io.SeekCurrent:
offset += f.offset.seek
case io.SeekEnd:
if f.length < 0 {
_, err := f.Stat()
if err != nil {
return 0, err
}
}
offset += f.length
default:
return 0, errors.New("Seek: invalid whence")
}
// allow negative SeekStart for initial Range request
if offset < 0 {
return 0, errors.New("Seek: invalid offset")
}
f.offset.seek = offset
return offset, nil
}
type fileStat struct {
file *DatastoreFile
header http.Header
}
func (s *fileStat) Name() string {
return path.Base(s.file.name)
}
func (s *fileStat) Size() int64 {
return s.file.length
}
func (s *fileStat) Mode() os.FileMode {
return 0
}
func (s *fileStat) ModTime() time.Time {
return time.Now() // no Last-Modified
}
func (s *fileStat) IsDir() bool {
return false
}
func (s *fileStat) Sys() interface{} {
return s.header
}
func statusError(res *http.Response) error {
if res.StatusCode == http.StatusNotFound {
return os.ErrNotExist
}
return errors.New(res.Status)
}
// Stat returns the os.FileInfo interface describing file.
func (f *DatastoreFile) Stat() (os.FileInfo, error) {
// TODO: consider using Datastore.Stat() instead
u, p, err := f.d.downloadTicket(f.ctx, f.name, &soap.Download{Method: "HEAD"})
if err != nil {
return nil, err
}
res, err := f.d.Client().DownloadRequest(u, p)
if err != nil {
return nil, err
}
if res.StatusCode != http.StatusOK {
return nil, statusError(res)
}
f.length = res.ContentLength
return &fileStat{f, res.Header}, nil
}
func (f *DatastoreFile) get() (io.Reader, error) {
if f.body != nil {
return f.body, nil
}
u, p, err := f.d.downloadTicket(f.ctx, f.name, nil)
if err != nil {
return nil, err
}
if f.offset.read != 0 {
p.Headers = map[string]string{
"Range": fmt.Sprintf("bytes=%d-", f.offset.read),
}
}
res, err := f.d.Client().DownloadRequest(u, p)
if err != nil {
return nil, err
}
switch res.StatusCode {
case http.StatusOK:
f.length = res.ContentLength
case http.StatusPartialContent:
var start, end int
cr := res.Header.Get("Content-Range")
_, err = fmt.Sscanf(cr, "bytes %d-%d/%d", &start, &end, &f.length)
if err != nil {
f.length = -1
}
case http.StatusRequestedRangeNotSatisfiable:
// ok: Read() will return io.EOF
default:
return nil, statusError(res)
}
if f.length < 0 {
_ = res.Body.Close()
return nil, errors.New("unable to determine file size")
}
f.body = res.Body
return f.body, nil
}
func lastIndexLines(s []byte, n *int) int64 {
i := len(s) - 1
for i > 0 {
o := bytes.LastIndexByte(s[:i], '\n')
if o < 0 {
break
}
i = o
*n--
if *n == 0 {
break
}
}
return int64(i)
}
// Tail seeks to the position of the last N lines of the file.
func (f *DatastoreFile) Tail(n int) error {
// Read the file in reverse using bsize chunks
const bsize = int64(1024 * 16)
fsize, err := f.Seek(0, io.SeekEnd)
if err != nil {
return err
}
if n == 0 {
return nil
}
chunk := int64(-1)
buf := bytes.NewBuffer(make([]byte, 0, bsize))
for {
var eof bool
var pos int64
nread := bsize
offset := chunk * bsize
remain := fsize + offset
if remain < 0 {
if pos, err = f.Seek(0, io.SeekStart); err != nil {
return err
}
nread = bsize + remain
eof = true
} else {
if pos, err = f.Seek(offset, io.SeekEnd); err != nil {
return err
}
}
if _, err = io.CopyN(buf, f, nread); err != nil {
if err != io.EOF {
return err
}
}
b := buf.Bytes()
idx := lastIndexLines(b, &n) + 1
if n == 0 {
if chunk == -1 {
// We found all N lines in the last chunk of the file.
// The seek offset is also now at the current end of file.
// Save this buffer to avoid another GET request when Read() is called.
buf.Next(int(idx))
f.buf = buf
return nil
}
if _, err = f.Seek(pos+idx, io.SeekStart); err != nil {
return err
}
break
}
if eof {
if remain < 0 {
// We found < N lines in the entire file, so seek to the start.
_, _ = f.Seek(0, io.SeekStart)
}
break
}
chunk--
buf.Reset()
}
return nil
}
type followDatastoreFile struct {
r *DatastoreFile
c chan struct{}
i time.Duration
}
// Read reads up to len(b) bytes from the DatastoreFile being followed.
// This method will block until data is read, an error other than io.EOF is returned or Close() is called.
func (f *followDatastoreFile) Read(p []byte) (int, error) {
offset := f.r.offset.seek
stop := false
defer f.r.Close()
for {
n, err := f.r.Read(p)
if err != nil && err == io.EOF {
_ = f.r.Close() // GET request body has been drained.
if stop {
return n, err
}
err = nil
}
if n > 0 {
return n, err
}
select {
case <-f.c:
// Wake up and stop polling once the body has been drained
stop = true
case <-time.After(f.i):
}
info, serr := f.r.Stat()
if serr != nil {
// Return EOF rather than 404 if the file goes away
if serr == os.ErrNotExist {
_ = f.r.Close()
return 0, io.EOF
}
return 0, serr
}
if info.Size() < offset {
// assume file has be truncated
offset, err = f.r.Seek(0, io.SeekStart)
if err != nil {
return 0, err
}
}
}
}
// Close will stop Follow polling and close the underlying DatastoreFile.
func (f *followDatastoreFile) Close() error {
close(f.c)
return nil
}
// Follow returns an io.ReadCloser to stream the file contents as data is appended.
func (f *DatastoreFile) Follow(interval time.Duration) io.ReadCloser {
return &followDatastoreFile{f, make(chan struct{}), interval}
}

View File

@ -0,0 +1,65 @@
/*
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package object
import (
"fmt"
"strings"
)
// DatastorePath contains the components of a datastore path.
type DatastorePath struct {
Datastore string
Path string
}
// FromString parses a datastore path.
// Returns true if the path could be parsed, false otherwise.
func (p *DatastorePath) FromString(s string) bool {
if len(s) == 0 {
return false
}
s = strings.TrimSpace(s)
if !strings.HasPrefix(s, "[") {
return false
}
s = s[1:]
ix := strings.Index(s, "]")
if ix < 0 {
return false
}
p.Datastore = s[:ix]
p.Path = strings.TrimSpace(s[ix+1:])
return true
}
// String formats a datastore path.
func (p *DatastorePath) String() string {
s := fmt.Sprintf("[%s]", p.Datastore)
if p.Path == "" {
return s
}
return strings.Join([]string{s, p.Path}, " ")
}

View File

@ -0,0 +1,76 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package object
import (
"context"
"fmt"
"io"
"math"
)
// DiagnosticLog wraps DiagnosticManager.BrowseLog
type DiagnosticLog struct {
m DiagnosticManager
Key string
Host *HostSystem
Start int32
}
// Seek to log position starting at the last nlines of the log
func (l *DiagnosticLog) Seek(ctx context.Context, nlines int32) error {
h, err := l.m.BrowseLog(ctx, l.Host, l.Key, math.MaxInt32, 0)
if err != nil {
return err
}
l.Start = h.LineEnd - nlines
return nil
}
// Copy log starting from l.Start to the given io.Writer
// Returns on error or when end of log is reached.
func (l *DiagnosticLog) Copy(ctx context.Context, w io.Writer) (int, error) {
const max = 500 // VC max == 500, ESX max == 1000
written := 0
for {
h, err := l.m.BrowseLog(ctx, l.Host, l.Key, l.Start, max)
if err != nil {
return 0, err
}
for _, line := range h.LineText {
n, err := fmt.Fprintln(w, line)
written += n
if err != nil {
return written, err
}
}
l.Start += int32(len(h.LineText))
if l.Start >= h.LineEnd {
break
}
}
return written, nil
}

View File

@ -17,10 +17,11 @@ limitations under the License.
package object
import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type DiagnosticManager struct {
@ -35,6 +36,14 @@ func NewDiagnosticManager(c *vim25.Client) *DiagnosticManager {
return &m
}
func (m DiagnosticManager) Log(ctx context.Context, host *HostSystem, key string) *DiagnosticLog {
return &DiagnosticLog{
m: m,
Key: key,
Host: host,
}
}
func (m DiagnosticManager) BrowseLog(ctx context.Context, host *HostSystem, key string, start, lines int32) (*types.DiagnosticManagerLogHeader, error) {
req := types.BrowseDiagnosticLog{
This: m.Reference(),

View File

@ -17,10 +17,12 @@ limitations under the License.
package object
import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type DistributedVirtualPortgroup struct {
@ -55,3 +57,17 @@ func (p DistributedVirtualPortgroup) EthernetCardBackingInfo(ctx context.Context
return backing, nil
}
func (p DistributedVirtualPortgroup) Reconfigure(ctx context.Context, spec types.DVPortgroupConfigSpec) (*Task, error) {
req := types.ReconfigureDVPortgroup_Task{
This: p.Reference(),
Spec: spec,
}
res, err := methods.ReconfigureDVPortgroup_Task(ctx, p.Client(), &req)
if err != nil {
return nil, err
}
return NewTask(p.Client(), res.Returnval), nil
}

View File

@ -17,10 +17,11 @@ limitations under the License.
package object
import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type DistributedVirtualSwitch struct {

View File

@ -17,11 +17,12 @@ limitations under the License.
package object
import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type ExtensionManager struct {

View File

@ -17,10 +17,11 @@ limitations under the License.
package object
import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type FileManager struct {

View File

@ -17,11 +17,12 @@ limitations under the License.
package object
import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type Folder struct {

View File

@ -17,10 +17,11 @@ limitations under the License.
package object
import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type HistoryCollector struct {

View File

@ -17,10 +17,11 @@ limitations under the License.
package object
import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type HostAccountManager struct {

View File

@ -0,0 +1,250 @@
/*
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package object
import (
"crypto/sha256"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/asn1"
"fmt"
"io"
"net/url"
"strings"
"text/tabwriter"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
// HostCertificateInfo provides helpers for types.HostCertificateManagerCertificateInfo
type HostCertificateInfo struct {
types.HostCertificateManagerCertificateInfo
ThumbprintSHA1 string
ThumbprintSHA256 string
Err error
Certificate *x509.Certificate `json:"-"`
subjectName *pkix.Name
issuerName *pkix.Name
}
// FromCertificate converts x509.Certificate to HostCertificateInfo
func (info *HostCertificateInfo) FromCertificate(cert *x509.Certificate) *HostCertificateInfo {
info.Certificate = cert
info.subjectName = &cert.Subject
info.issuerName = &cert.Issuer
info.Issuer = info.fromName(info.issuerName)
info.NotBefore = &cert.NotBefore
info.NotAfter = &cert.NotAfter
info.Subject = info.fromName(info.subjectName)
info.ThumbprintSHA1 = soap.ThumbprintSHA1(cert)
// SHA-256 for info purposes only, API fields all use SHA-1
sum := sha256.Sum256(cert.Raw)
hex := make([]string, len(sum))
for i, b := range sum {
hex[i] = fmt.Sprintf("%02X", b)
}
info.ThumbprintSHA256 = strings.Join(hex, ":")
if info.Status == "" {
info.Status = string(types.HostCertificateManagerCertificateInfoCertificateStatusUnknown)
}
return info
}
// FromURL connects to the given URL.Host via tls.Dial with the given tls.Config and populates the HostCertificateInfo
// via tls.ConnectionState. If the certificate was verified with the given tls.Config, the Err field will be nil.
// Otherwise, Err will be set to the x509.UnknownAuthorityError or x509.HostnameError.
// If tls.Dial returns an error of any other type, that error is returned.
func (info *HostCertificateInfo) FromURL(u *url.URL, config *tls.Config) error {
addr := u.Host
if !(strings.LastIndex(addr, ":") > strings.LastIndex(addr, "]")) {
addr += ":443"
}
conn, err := tls.Dial("tcp", addr, config)
if err != nil {
switch err.(type) {
case x509.UnknownAuthorityError:
case x509.HostnameError:
default:
return err
}
info.Err = err
conn, err = tls.Dial("tcp", addr, &tls.Config{InsecureSkipVerify: true})
if err != nil {
return err
}
} else {
info.Status = string(types.HostCertificateManagerCertificateInfoCertificateStatusGood)
}
state := conn.ConnectionState()
_ = conn.Close()
info.FromCertificate(state.PeerCertificates[0])
return nil
}
var emailAddressOID = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}
func (info *HostCertificateInfo) fromName(name *pkix.Name) string {
var attrs []string
oids := map[string]string{
emailAddressOID.String(): "emailAddress",
}
for _, attr := range name.Names {
if key, ok := oids[attr.Type.String()]; ok {
attrs = append(attrs, fmt.Sprintf("%s=%s", key, attr.Value))
}
}
attrs = append(attrs, fmt.Sprintf("CN=%s", name.CommonName))
add := func(key string, vals []string) {
for _, val := range vals {
attrs = append(attrs, fmt.Sprintf("%s=%s", key, val))
}
}
elts := []struct {
key string
val []string
}{
{"OU", name.OrganizationalUnit},
{"O", name.Organization},
{"L", name.Locality},
{"ST", name.Province},
{"C", name.Country},
}
for _, elt := range elts {
add(elt.key, elt.val)
}
return strings.Join(attrs, ",")
}
func (info *HostCertificateInfo) toName(s string) *pkix.Name {
var name pkix.Name
for _, pair := range strings.Split(s, ",") {
attr := strings.SplitN(pair, "=", 2)
if len(attr) != 2 {
continue
}
v := attr[1]
switch strings.ToLower(attr[0]) {
case "cn":
name.CommonName = v
case "ou":
name.OrganizationalUnit = append(name.OrganizationalUnit, v)
case "o":
name.Organization = append(name.Organization, v)
case "l":
name.Locality = append(name.Locality, v)
case "st":
name.Province = append(name.Province, v)
case "c":
name.Country = append(name.Country, v)
case "emailaddress":
name.Names = append(name.Names, pkix.AttributeTypeAndValue{Type: emailAddressOID, Value: v})
}
}
return &name
}
// SubjectName parses Subject into a pkix.Name
func (info *HostCertificateInfo) SubjectName() *pkix.Name {
if info.subjectName != nil {
return info.subjectName
}
return info.toName(info.Subject)
}
// IssuerName parses Issuer into a pkix.Name
func (info *HostCertificateInfo) IssuerName() *pkix.Name {
if info.issuerName != nil {
return info.issuerName
}
return info.toName(info.Issuer)
}
// Write outputs info similar to the Chrome Certificate Viewer.
func (info *HostCertificateInfo) Write(w io.Writer) error {
tw := tabwriter.NewWriter(w, 2, 0, 2, ' ', 0)
s := func(val string) string {
if val != "" {
return val
}
return "<Not Part Of Certificate>"
}
ss := func(val []string) string {
return s(strings.Join(val, ","))
}
name := func(n *pkix.Name) {
fmt.Fprintf(tw, " Common Name (CN):\t%s\n", s(n.CommonName))
fmt.Fprintf(tw, " Organization (O):\t%s\n", ss(n.Organization))
fmt.Fprintf(tw, " Organizational Unit (OU):\t%s\n", ss(n.OrganizationalUnit))
}
status := info.Status
if info.Err != nil {
status = fmt.Sprintf("ERROR %s", info.Err)
}
fmt.Fprintf(tw, "Certificate Status:\t%s\n", status)
fmt.Fprintln(tw, "Issued To:\t")
name(info.SubjectName())
fmt.Fprintln(tw, "Issued By:\t")
name(info.IssuerName())
fmt.Fprintln(tw, "Validity Period:\t")
fmt.Fprintf(tw, " Issued On:\t%s\n", info.NotBefore)
fmt.Fprintf(tw, " Expires On:\t%s\n", info.NotAfter)
if info.ThumbprintSHA1 != "" {
fmt.Fprintln(tw, "Thumbprints:\t")
if info.ThumbprintSHA256 != "" {
fmt.Fprintf(tw, " SHA-256 Thumbprint:\t%s\n", info.ThumbprintSHA256)
}
fmt.Fprintf(tw, " SHA-1 Thumbprint:\t%s\n", info.ThumbprintSHA1)
}
return tw.Flush()
}

View File

@ -0,0 +1,162 @@
/*
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package object
import (
"context"
"github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
)
// HostCertificateManager provides helper methods around the HostSystem.ConfigManager.CertificateManager
type HostCertificateManager struct {
Common
Host *HostSystem
}
// NewHostCertificateManager creates a new HostCertificateManager helper
func NewHostCertificateManager(c *vim25.Client, ref types.ManagedObjectReference, host types.ManagedObjectReference) *HostCertificateManager {
return &HostCertificateManager{
Common: NewCommon(c, ref),
Host: NewHostSystem(c, host),
}
}
// CertificateInfo wraps the host CertificateManager certificateInfo property with the HostCertificateInfo helper.
// The ThumbprintSHA1 field is set to HostSystem.Summary.Config.SslThumbprint if the host system is managed by a vCenter.
func (m HostCertificateManager) CertificateInfo(ctx context.Context) (*HostCertificateInfo, error) {
var hs mo.HostSystem
var cm mo.HostCertificateManager
pc := property.DefaultCollector(m.Client())
err := pc.RetrieveOne(ctx, m.Reference(), []string{"certificateInfo"}, &cm)
if err != nil {
return nil, err
}
_ = pc.RetrieveOne(ctx, m.Host.Reference(), []string{"summary.config.sslThumbprint"}, &hs)
return &HostCertificateInfo{
HostCertificateManagerCertificateInfo: cm.CertificateInfo,
ThumbprintSHA1: hs.Summary.Config.SslThumbprint,
}, nil
}
// GenerateCertificateSigningRequest requests the host system to generate a certificate-signing request (CSR) for itself.
// The CSR is then typically provided to a Certificate Authority to sign and issue the SSL certificate for the host system.
// Use InstallServerCertificate to import this certificate.
func (m HostCertificateManager) GenerateCertificateSigningRequest(ctx context.Context, useIPAddressAsCommonName bool) (string, error) {
req := types.GenerateCertificateSigningRequest{
This: m.Reference(),
UseIpAddressAsCommonName: useIPAddressAsCommonName,
}
res, err := methods.GenerateCertificateSigningRequest(ctx, m.Client(), &req)
if err != nil {
return "", err
}
return res.Returnval, nil
}
// GenerateCertificateSigningRequestByDn requests the host system to generate a certificate-signing request (CSR) for itself.
// Alternative version similar to GenerateCertificateSigningRequest but takes a Distinguished Name (DN) as a parameter.
func (m HostCertificateManager) GenerateCertificateSigningRequestByDn(ctx context.Context, distinguishedName string) (string, error) {
req := types.GenerateCertificateSigningRequestByDn{
This: m.Reference(),
DistinguishedName: distinguishedName,
}
res, err := methods.GenerateCertificateSigningRequestByDn(ctx, m.Client(), &req)
if err != nil {
return "", err
}
return res.Returnval, nil
}
// InstallServerCertificate imports the given SSL certificate to the host system.
func (m HostCertificateManager) InstallServerCertificate(ctx context.Context, cert string) error {
req := types.InstallServerCertificate{
This: m.Reference(),
Cert: cert,
}
_, err := methods.InstallServerCertificate(ctx, m.Client(), &req)
if err != nil {
return err
}
// NotifyAffectedService is internal, not exposing as we don't have a use case other than with InstallServerCertificate
// Without this call, hostd needs to be restarted to use the updated certificate
// Note: using Refresh as it has the same struct/signature, we just need to use different xml name tags
body := struct {
Req *types.Refresh `xml:"urn:vim25 NotifyAffectedServices,omitempty"`
Res *types.RefreshResponse `xml:"urn:vim25 NotifyAffectedServicesResponse,omitempty"`
methods.RefreshBody
}{
Req: &types.Refresh{This: m.Reference()},
}
return m.Client().RoundTrip(ctx, &body, &body)
}
// ListCACertificateRevocationLists returns the SSL CRLs of Certificate Authorities that are trusted by the host system.
func (m HostCertificateManager) ListCACertificateRevocationLists(ctx context.Context) ([]string, error) {
req := types.ListCACertificateRevocationLists{
This: m.Reference(),
}
res, err := methods.ListCACertificateRevocationLists(ctx, m.Client(), &req)
if err != nil {
return nil, err
}
return res.Returnval, nil
}
// ListCACertificates returns the SSL certificates of Certificate Authorities that are trusted by the host system.
func (m HostCertificateManager) ListCACertificates(ctx context.Context) ([]string, error) {
req := types.ListCACertificates{
This: m.Reference(),
}
res, err := methods.ListCACertificates(ctx, m.Client(), &req)
if err != nil {
return nil, err
}
return res.Returnval, nil
}
// ReplaceCACertificatesAndCRLs replaces the trusted CA certificates and CRL used by the host system.
// These determine whether the server can verify the identity of an external entity.
func (m HostCertificateManager) ReplaceCACertificatesAndCRLs(ctx context.Context, caCert []string, caCrl []string) error {
req := types.ReplaceCACertificatesAndCRLs{
This: m.Reference(),
CaCert: caCert,
CaCrl: caCrl,
}
_, err := methods.ReplaceCACertificatesAndCRLs(ctx, m.Client(), &req)
return err
}

View File

@ -17,10 +17,11 @@ limitations under the License.
package object
import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type HostConfigManager struct {
@ -96,6 +97,11 @@ func (m HostConfigManager) VsanSystem(ctx context.Context) (*HostVsanSystem, err
return nil, err
}
// Added in 5.5
if h.ConfigManager.VsanSystem == nil {
return nil, ErrNotSupported
}
return NewHostVsanSystem(m.c, *h.ConfigManager.VsanSystem), nil
}
@ -107,7 +113,21 @@ func (m HostConfigManager) AccountManager(ctx context.Context) (*HostAccountMana
return nil, err
}
return NewHostAccountManager(m.c, *h.ConfigManager.AccountManager), nil
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
}
}
return NewHostAccountManager(m.c, *ref), nil
}
func (m HostConfigManager) OptionManager(ctx context.Context) (*OptionManager, error) {
@ -131,3 +151,30 @@ func (m HostConfigManager) ServiceSystem(ctx context.Context) (*HostServiceSyste
return NewHostServiceSystem(m.c, *h.ConfigManager.ServiceSystem), nil
}
func (m HostConfigManager) CertificateManager(ctx context.Context) (*HostCertificateManager, error) {
var h mo.HostSystem
err := m.Properties(ctx, m.Reference(), []string{"configManager.certificateManager"}, &h)
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
}
func (m HostConfigManager) DateTimeSystem(ctx context.Context) (*HostDateTimeSystem, error) {
var h mo.HostSystem
err := m.Properties(ctx, m.Reference(), []string{"configManager.dateTimeSystem"}, &h)
if err != nil {
return nil, err
}
return NewHostDateTimeSystem(m.c, *h.ConfigManager.DateTimeSystem), nil
}

View File

@ -17,10 +17,11 @@ limitations under the License.
package object
import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type HostDatastoreBrowser struct {

View File

@ -17,10 +17,11 @@ limitations under the License.
package object
import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type HostDatastoreSystem struct {

View File

@ -0,0 +1,69 @@
/*
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package object
import (
"context"
"time"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/types"
)
type HostDateTimeSystem struct {
Common
}
func NewHostDateTimeSystem(c *vim25.Client, ref types.ManagedObjectReference) *HostDateTimeSystem {
return &HostDateTimeSystem{
Common: NewCommon(c, ref),
}
}
func (s HostDateTimeSystem) UpdateConfig(ctx context.Context, config types.HostDateTimeConfig) error {
req := types.UpdateDateTimeConfig{
This: s.Reference(),
Config: config,
}
_, err := methods.UpdateDateTimeConfig(ctx, s.c, &req)
return err
}
func (s HostDateTimeSystem) Update(ctx context.Context, date time.Time) error {
req := types.UpdateDateTime{
This: s.Reference(),
DateTime: date,
}
_, err := methods.UpdateDateTime(ctx, s.c, &req)
return err
}
func (s HostDateTimeSystem) Query(ctx context.Context) (*time.Time, error) {
req := types.QueryDateTime{
This: s.Reference(),
}
res, err := methods.QueryDateTime(ctx, s.c, &req)
if err != nil {
return nil, err
}
return &res.Returnval, nil
}

View File

@ -17,6 +17,7 @@ limitations under the License.
package object
import (
"context"
"errors"
"fmt"
"strings"
@ -25,7 +26,6 @@ import (
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type HostFirewallSystem struct {

View File

@ -17,10 +17,11 @@ limitations under the License.
package object
import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type HostNetworkSystem struct {

View File

@ -17,11 +17,12 @@ limitations under the License.
package object
import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type HostServiceSystem struct {

View File

@ -17,12 +17,12 @@ limitations under the License.
package object
import (
"context"
"errors"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type HostStorageSystem struct {

View File

@ -17,6 +17,7 @@ limitations under the License.
package object
import (
"context"
"fmt"
"net"
@ -24,7 +25,6 @@ import (
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type HostSystem struct {

View File

@ -17,11 +17,12 @@ limitations under the License.
package object
import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type HostVirtualNicManager struct {

View File

@ -17,11 +17,12 @@ limitations under the License.
package object
import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type HostVsanSystem struct {

View File

@ -17,6 +17,7 @@ limitations under the License.
package object
import (
"context"
"errors"
"fmt"
@ -25,7 +26,6 @@ import (
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type HttpNfcLease struct {

View File

@ -17,10 +17,11 @@ limitations under the License.
package object
import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type ListView struct {
@ -37,7 +38,33 @@ func (v ListView) Destroy(ctx context.Context) error {
req := types.DestroyView{
This: v.Reference(),
}
_, err := methods.DestroyView(ctx, v.c, &req)
return err
}
func (v ListView) Add(ctx context.Context, refs []types.ManagedObjectReference) error {
req := types.ModifyListView{
This: v.Reference(),
Add: refs,
}
_, err := methods.ModifyListView(ctx, v.c, &req)
return err
}
func (v ListView) Remove(ctx context.Context, refs []types.ManagedObjectReference) error {
req := types.ModifyListView{
This: v.Reference(),
Remove: refs,
}
_, err := methods.ModifyListView(ctx, v.c, &req)
return err
}
func (v ListView) Reset(ctx context.Context, refs []types.ManagedObjectReference) error {
req := types.ResetListView{
This: v.Reference(),
Obj: refs,
}
_, err := methods.ResetListView(ctx, v.c, &req)
return err
}

View File

@ -17,10 +17,11 @@ limitations under the License.
package object
import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type DatastoreNamespaceManager struct {

View File

@ -17,9 +17,10 @@ limitations under the License.
package object
import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type Network struct {

View File

@ -17,8 +17,9 @@ limitations under the License.
package object
import (
"context"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
// The NetworkReference interface is implemented by managed objects

View File

@ -17,10 +17,11 @@ limitations under the License.
package object
import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type OptionManager struct {

View File

@ -17,10 +17,11 @@ limitations under the License.
package object
import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type OvfManager struct {

View File

@ -17,10 +17,11 @@ limitations under the License.
package object
import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type ResourcePool struct {

View File

@ -17,10 +17,11 @@ limitations under the License.
package object
import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type SearchIndex struct {

View File

@ -17,10 +17,11 @@ limitations under the License.
package object
import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type StorageResourceManager struct {

View File

@ -17,12 +17,13 @@ limitations under the License.
package object
import (
"context"
"github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/task"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/progress"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
// Task is a convenience wrapper around task.Task that keeps a reference to

View File

@ -47,7 +47,7 @@ func NewReference(c *vim25.Client, e types.ManagedObjectReference) Reference {
return NewClusterComputeResource(c, e)
case "HostSystem":
return NewHostSystem(c, e)
case "Network":
case "Network", "OpaqueNetwork":
return NewNetwork(c, e)
case "ResourcePool":
return NewResourcePool(c, e)

View File

@ -17,7 +17,7 @@ limitations under the License.
package object
import (
"golang.org/x/net/context"
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
@ -34,7 +34,7 @@ func NewVirtualApp(c *vim25.Client, ref types.ManagedObjectReference) *VirtualAp
}
}
func (p VirtualApp) CreateChildVM_Task(ctx context.Context, config types.VirtualMachineConfigSpec, host *HostSystem) (*Task, error) {
func (p VirtualApp) CreateChildVM(ctx context.Context, config types.VirtualMachineConfigSpec, host *HostSystem) (*Task, error) {
req := types.CreateChildVM_Task{
This: p.Reference(),
Config: config,
@ -53,7 +53,7 @@ func (p VirtualApp) CreateChildVM_Task(ctx context.Context, config types.Virtual
return NewTask(p.c, res.Returnval), nil
}
func (p VirtualApp) UpdateVAppConfig(ctx context.Context, spec types.VAppConfigSpec) error {
func (p VirtualApp) UpdateConfig(ctx context.Context, spec types.VAppConfigSpec) error {
req := types.UpdateVAppConfig{
This: p.Reference(),
Spec: spec,
@ -63,7 +63,7 @@ func (p VirtualApp) UpdateVAppConfig(ctx context.Context, spec types.VAppConfigS
return err
}
func (p VirtualApp) PowerOnVApp_Task(ctx context.Context) (*Task, error) {
func (p VirtualApp) PowerOn(ctx context.Context) (*Task, error) {
req := types.PowerOnVApp_Task{
This: p.Reference(),
}
@ -76,7 +76,7 @@ func (p VirtualApp) PowerOnVApp_Task(ctx context.Context) (*Task, error) {
return NewTask(p.c, res.Returnval), nil
}
func (p VirtualApp) PowerOffVApp_Task(ctx context.Context, force bool) (*Task, error) {
func (p VirtualApp) PowerOff(ctx context.Context, force bool) (*Task, error) {
req := types.PowerOffVApp_Task{
This: p.Reference(),
Force: force,
@ -91,7 +91,7 @@ func (p VirtualApp) PowerOffVApp_Task(ctx context.Context, force bool) (*Task, e
}
func (p VirtualApp) SuspendVApp_Task(ctx context.Context) (*Task, error) {
func (p VirtualApp) Suspend(ctx context.Context) (*Task, error) {
req := types.SuspendVApp_Task{
This: p.Reference(),
}

View File

@ -84,6 +84,9 @@ func (l VirtualDeviceList) Select(f func(device types.BaseVirtualDevice) bool) V
// SelectByType returns a new list with devices that are equal to or extend the given type.
func (l VirtualDeviceList) SelectByType(deviceType types.BaseVirtualDevice) VirtualDeviceList {
dtype := reflect.TypeOf(deviceType)
if dtype == nil {
return nil
}
dname := dtype.Elem().Name()
return l.Select(func(device types.BaseVirtualDevice) bool {
@ -242,6 +245,7 @@ func (l VirtualDeviceList) CreateSCSIController(name string) (types.BaseVirtualD
scsi := c.GetVirtualSCSIController()
scsi.BusNumber = l.newSCSIBusNumber()
scsi.Key = l.NewKey()
scsi.ScsiCtlrUnitNumber = 7
return c.(types.BaseVirtualDevice), nil
}
@ -270,6 +274,63 @@ func (l VirtualDeviceList) newSCSIBusNumber() int32 {
return -1
}
// FindNVMEController will find the named NVME controller if given, otherwise will pick an available controller.
// An error is returned if the named controller is not found or not an NVME controller. Or, if name is not
// given and no available controller can be found.
func (l VirtualDeviceList) FindNVMEController(name string) (*types.VirtualNVMEController, error) {
if name != "" {
d := l.Find(name)
if d == nil {
return nil, fmt.Errorf("device '%s' not found", name)
}
if c, ok := d.(*types.VirtualNVMEController); ok {
return c, nil
}
return nil, fmt.Errorf("%s is not an NVME controller", name)
}
c := l.PickController((*types.VirtualNVMEController)(nil))
if c == nil {
return nil, errors.New("no available NVME controller")
}
return c.(*types.VirtualNVMEController), nil
}
// CreateNVMEController creates a new NVMWE controller.
func (l VirtualDeviceList) CreateNVMEController() (types.BaseVirtualDevice, error) {
nvme := &types.VirtualNVMEController{}
nvme.BusNumber = l.newNVMEBusNumber()
nvme.Key = l.NewKey()
return nvme, nil
}
var nvmeBusNumbers = []int{0, 1, 2, 3}
// newNVMEBusNumber returns the bus number to use for adding a new NVME bus device.
// -1 is returned if there are no bus numbers available.
func (l VirtualDeviceList) newNVMEBusNumber() int32 {
var used []int
for _, d := range l.SelectByType((*types.VirtualNVMEController)(nil)) {
num := d.(types.BaseVirtualController).GetVirtualController().BusNumber
if num >= 0 {
used = append(used, int(num))
} // else caller is creating a new vm using NVMEControllerTypes
}
sort.Ints(used)
for i, n := range nvmeBusNumbers {
if i == len(used) || n != used[i] {
return int32(n)
}
}
return -1
}
// FindDiskController will find an existing ide or scsi disk controller.
func (l VirtualDeviceList) FindDiskController(name string) (types.BaseVirtualController, error) {
switch {
@ -277,6 +338,8 @@ func (l VirtualDeviceList) FindDiskController(name string) (types.BaseVirtualCon
return l.FindIDEController("")
case name == "scsi" || name == "":
return l.FindSCSIController("")
case name == "nvme":
return l.FindNVMEController("")
default:
if c, ok := l.Find(name).(types.BaseVirtualController); ok {
return c, nil
@ -296,6 +359,8 @@ func (l VirtualDeviceList) PickController(kind types.BaseVirtualController) type
return num < 15
case *types.VirtualIDEController:
return num < 2
case *types.VirtualNVMEController:
return num < 8
default:
return true
}
@ -310,20 +375,31 @@ func (l VirtualDeviceList) PickController(kind types.BaseVirtualController) type
// newUnitNumber returns the unit number to use for attaching a new device to the given controller.
func (l VirtualDeviceList) newUnitNumber(c types.BaseVirtualController) int32 {
units := make([]bool, 30)
switch sc := c.(type) {
case types.BaseVirtualSCSIController:
// The SCSI controller sits on its own bus
units[sc.GetVirtualSCSIController().ScsiCtlrUnitNumber] = true
}
key := c.GetVirtualController().Key
var max int32 = -1
for _, device := range l {
d := device.GetVirtualDevice()
if d.ControllerKey == key {
if d.UnitNumber != nil && *d.UnitNumber > max {
max = *d.UnitNumber
}
if d.ControllerKey == key && d.UnitNumber != nil {
units[int(*d.UnitNumber)] = true
}
}
return max + 1
for unit, used := range units {
if !used {
return int32(unit)
}
}
return -1
}
// NewKey returns the key to use for adding a new device to the device list.
@ -384,12 +460,14 @@ func (l VirtualDeviceList) CreateDisk(c types.BaseVirtualController, ds types.Ma
func (l VirtualDeviceList) ChildDisk(parent *types.VirtualDisk) *types.VirtualDisk {
disk := *parent
backing := disk.Backing.(*types.VirtualDiskFlatVer2BackingInfo)
ds := strings.SplitN(backing.FileName[1:], "]", 2)
p := new(DatastorePath)
p.FromString(backing.FileName)
p.Path = ""
// Use specified disk as parent backing to a new disk.
disk.Backing = &types.VirtualDiskFlatVer2BackingInfo{
VirtualDeviceFileBackingInfo: types.VirtualDeviceFileBackingInfo{
FileName: fmt.Sprintf("[%s]", ds[0]),
FileName: p.String(),
Datastore: backing.Datastore,
},
Parent: backing,
@ -595,7 +673,17 @@ func (l VirtualDeviceList) CreateSerialPort() (*types.VirtualSerialPort, error)
}
// ConnectSerialPort connects a serial port to a server or client uri.
func (l VirtualDeviceList) ConnectSerialPort(device *types.VirtualSerialPort, uri string, client bool) *types.VirtualSerialPort {
func (l VirtualDeviceList) ConnectSerialPort(device *types.VirtualSerialPort, uri string, client bool, proxyuri string) *types.VirtualSerialPort {
if strings.HasPrefix(uri, "[") {
device.Backing = &types.VirtualSerialPortFileBackingInfo{
VirtualDeviceFileBackingInfo: types.VirtualDeviceFileBackingInfo{
FileName: uri,
},
}
return device
}
direction := types.VirtualDeviceURIBackingOptionDirectionServer
if client {
direction = types.VirtualDeviceURIBackingOptionDirectionClient
@ -605,6 +693,7 @@ func (l VirtualDeviceList) ConnectSerialPort(device *types.VirtualSerialPort, ur
VirtualDeviceURIBackingInfo: types.VirtualDeviceURIBackingInfo{
Direction: string(direction),
ServiceURI: uri,
ProxyURI: proxyuri,
},
}
@ -728,7 +817,11 @@ func (l VirtualDeviceList) SelectBootOrder(order []types.BaseVirtualMachineBootO
// TypeName returns the vmodl type name of the device
func (l VirtualDeviceList) TypeName(device types.BaseVirtualDevice) string {
return reflect.TypeOf(device).Elem().Name()
dtype := reflect.TypeOf(device)
if dtype == nil {
return ""
}
return dtype.Elem().Name()
}
var deviceNameRegexp = regexp.MustCompile(`(?:Virtual)?(?:Machine)?(\w+?)(?:Card|Device|Controller)?$`)
@ -754,6 +847,8 @@ func (l VirtualDeviceList) Type(device types.BaseVirtualDevice) string {
return "pvscsi"
case *types.VirtualLsiLogicSASController:
return "lsilogic-sas"
case *types.VirtualNVMEController:
return "nvme"
default:
return l.deviceName(device)
}

View File

@ -17,10 +17,11 @@ limitations under the License.
package object
import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type VirtualDiskManager struct {

View File

@ -17,15 +17,17 @@ limitations under the License.
package object
import (
"context"
"errors"
"fmt"
"net"
"path"
"github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
const (
@ -227,9 +229,12 @@ func (v VirtualMachine) WaitForIP(ctx context.Context) (string, error) {
// WaitForNetIP waits for the VM guest.net property to report an IP address for all VM NICs.
// Only consider IPv4 addresses if the v4 param is true.
// By default, wait for all NICs to get an IP address, unless 1 or more device is given.
// A device can be specified by the MAC address or the device name, e.g. "ethernet-0".
// Returns a map with MAC address as the key and IP address list as the value.
func (v VirtualMachine) WaitForNetIP(ctx context.Context, v4 bool) (map[string][]string, error) {
func (v VirtualMachine) WaitForNetIP(ctx context.Context, v4 bool, device ...string) (map[string][]string, error) {
macs := make(map[string][]string)
eths := make(map[string]string)
p := property.DefaultCollector(v.c)
@ -240,14 +245,15 @@ func (v VirtualMachine) WaitForNetIP(ctx context.Context, v4 bool) (map[string][
continue
}
devices := c.Val.(types.ArrayOfVirtualDevice).VirtualDevice
for _, device := range devices {
if nic, ok := device.(types.BaseVirtualEthernetCard); ok {
devices := VirtualDeviceList(c.Val.(types.ArrayOfVirtualDevice).VirtualDevice)
for _, d := range devices {
if nic, ok := d.(types.BaseVirtualEthernetCard); ok {
mac := nic.GetVirtualEthernetCard().MacAddress
if mac == "" {
return false
}
macs[mac] = nil
eths[devices.Name(d)] = mac
}
}
}
@ -255,6 +261,17 @@ func (v VirtualMachine) WaitForNetIP(ctx context.Context, v4 bool) (map[string][
return true
})
if len(device) != 0 {
// Only wait for specific NIC(s)
macs = make(map[string][]string)
for _, mac := range device {
if eth, ok := eths[mac]; ok {
mac = eth // device name, e.g. "ethernet-0"
}
macs[mac] = nil
}
}
err = property.Wait(ctx, p, v.Reference(), []string{"guest.net"}, func(pc []types.PropertyChange) bool {
for _, c := range pc {
if c.Op != types.PropertyChangeOpAssign {
@ -300,18 +317,28 @@ func (v VirtualMachine) WaitForNetIP(ctx context.Context, v4 bool) (map[string][
func (v VirtualMachine) Device(ctx context.Context) (VirtualDeviceList, error) {
var o mo.VirtualMachine
err := v.Properties(ctx, v.Reference(), []string{"config.hardware.device"}, &o)
err := v.Properties(ctx, v.Reference(), []string{"config.hardware.device", "summary.runtime.connectionState"}, &o)
if err != nil {
return nil, err
}
// Quoting the SDK doc:
// The virtual machine configuration is not guaranteed to be available.
// For example, the configuration information would be unavailable if the server
// is unable to access the virtual machine files on disk, and is often also unavailable
// during the initial phases of virtual machine creation.
if o.Config == nil {
return nil, fmt.Errorf("%s Config is not available, connectionState=%s",
v.Reference(), o.Summary.Runtime.ConnectionState)
}
return VirtualDeviceList(o.Config.Hardware.Device), nil
}
func (v VirtualMachine) HostSystem(ctx context.Context) (*HostSystem, error) {
var o mo.VirtualMachine
err := v.Properties(ctx, v.Reference(), []string{"summary"}, &o)
err := v.Properties(ctx, v.Reference(), []string{"summary.runtime.host"}, &o)
if err != nil {
return nil, err
}
@ -470,24 +497,102 @@ func (v VirtualMachine) RemoveAllSnapshot(ctx context.Context, consolidate *bool
return NewTask(v.c, res.Returnval), nil
}
// RevertToSnapshot reverts to a named snapshot
func (v VirtualMachine) RevertToSnapshot(ctx context.Context, name string, suppressPowerOn bool) (*Task, error) {
type snapshotMap map[string][]Reference
func (m snapshotMap) add(parent string, tree []types.VirtualMachineSnapshotTree) {
for i, st := range tree {
sname := st.Name
names := []string{sname, st.Snapshot.Value}
if parent != "" {
sname = path.Join(parent, sname)
// Add full path as an option to resolve duplicate names
names = append(names, sname)
}
for _, name := range names {
m[name] = append(m[name], &tree[i].Snapshot)
}
m.add(sname, st.ChildSnapshotList)
}
}
// findSnapshot supports snapshot lookup by name, where name can be:
// 1) snapshot ManagedObjectReference.Value (unique)
// 2) snapshot name (may not be unique)
// 3) snapshot tree path (may not be unique)
func (v VirtualMachine) findSnapshot(ctx context.Context, name string) (Reference, error) {
var o mo.VirtualMachine
err := v.Properties(ctx, v.Reference(), []string{"snapshot"}, &o)
if err != nil {
return nil, err
}
snapshotTree := o.Snapshot.RootSnapshotList
if len(snapshotTree) < 1 {
if o.Snapshot == nil || len(o.Snapshot.RootSnapshotList) == 0 {
return nil, errors.New("No snapshots for this VM")
}
snapshot, err := traverseSnapshotInTree(snapshotTree, name)
m := make(snapshotMap)
m.add("", o.Snapshot.RootSnapshotList)
s := m[name]
switch len(s) {
case 0:
return nil, fmt.Errorf("snapshot %q not found", name)
case 1:
return s[0], nil
default:
return nil, fmt.Errorf("%q resolves to %d snapshots", name, len(s))
}
}
// RemoveSnapshot removes a named snapshot
func (v VirtualMachine) RemoveSnapshot(ctx context.Context, name string, removeChildren bool, consolidate *bool) (*Task, error) {
snapshot, err := v.findSnapshot(ctx, name)
if err != nil {
return nil, err
}
req := types.RemoveSnapshot_Task{
This: snapshot.Reference(),
RemoveChildren: removeChildren,
Consolidate: consolidate,
}
res, err := methods.RemoveSnapshot_Task(ctx, v.c, &req)
if err != nil {
return nil, err
}
return NewTask(v.c, res.Returnval), nil
}
// RevertToCurrentSnapshot reverts to the current snapshot
func (v VirtualMachine) RevertToCurrentSnapshot(ctx context.Context, suppressPowerOn bool) (*Task, error) {
req := types.RevertToCurrentSnapshot_Task{
This: v.Reference(),
SuppressPowerOn: types.NewBool(suppressPowerOn),
}
res, err := methods.RevertToCurrentSnapshot_Task(ctx, v.c, &req)
if err != nil {
return nil, err
}
return NewTask(v.c, res.Returnval), nil
}
// RevertToSnapshot reverts to a named snapshot
func (v VirtualMachine) RevertToSnapshot(ctx context.Context, name string, suppressPowerOn bool) (*Task, error) {
snapshot, err := v.findSnapshot(ctx, name)
if err != nil {
return nil, err
}
req := types.RevertToSnapshot_Task{
This: snapshot,
This: snapshot.Reference(),
SuppressPowerOn: types.NewBool(suppressPowerOn),
}
@ -499,32 +604,6 @@ func (v VirtualMachine) RevertToSnapshot(ctx context.Context, name string, suppr
return NewTask(v.c, res.Returnval), nil
}
// traverseSnapshotInTree is a recursive function that will traverse a snapshot tree to find a given snapshot
func traverseSnapshotInTree(tree []types.VirtualMachineSnapshotTree, name string) (types.ManagedObjectReference, error) {
var o types.ManagedObjectReference
if tree == nil {
return o, errors.New("Snapshot tree is empty")
}
for _, s := range tree {
if s.Name == name {
o = s.Snapshot
break
} else {
childTree := s.ChildSnapshotList
var err error
o, err = traverseSnapshotInTree(childTree, name)
if err != nil {
return o, err
}
}
}
if o.Value == "" {
return o, errors.New("Snapshot not found")
}
return o, nil
}
// IsToolsRunning returns true if VMware Tools is currently running in the guest OS, and false otherwise.
func (v VirtualMachine) IsToolsRunning(ctx context.Context) (bool, error) {
var o mo.VirtualMachine
@ -591,3 +670,58 @@ func (v VirtualMachine) MarkAsVirtualMachine(ctx context.Context, pool ResourceP
return nil
}
func (v VirtualMachine) Migrate(ctx context.Context, pool *ResourcePool, host *HostSystem, priority types.VirtualMachineMovePriority, state types.VirtualMachinePowerState) (*Task, error) {
req := types.MigrateVM_Task{
This: v.Reference(),
Priority: priority,
State: state,
}
if pool != nil {
ref := pool.Reference()
req.Pool = &ref
}
if host != nil {
ref := host.Reference()
req.Host = &ref
}
res, err := methods.MigrateVM_Task(ctx, v.c, &req)
if err != nil {
return nil, err
}
return NewTask(v.c, res.Returnval), nil
}
func (v VirtualMachine) Unregister(ctx context.Context) error {
req := types.UnregisterVM{
This: v.Reference(),
}
_, err := methods.UnregisterVM(ctx, v.Client(), &req)
return err
}
// QueryEnvironmentBrowser is a helper to get the environmentBrowser property.
func (v VirtualMachine) QueryConfigTarget(ctx context.Context) (*types.ConfigTarget, error) {
var vm mo.VirtualMachine
err := v.Properties(ctx, v.Reference(), []string{"environmentBrowser"}, &vm)
if err != nil {
return nil, err
}
req := types.QueryConfigTarget{
This: vm.EnvironmentBrowser,
}
res, err := methods.QueryConfigTarget(ctx, v.Client(), &req)
if err != nil {
return nil, err
}
return res.Returnval, nil
}

View File

@ -17,6 +17,7 @@ limitations under the License.
package property
import (
"context"
"errors"
"github.com/vmware/govmomi/vim25"
@ -24,7 +25,6 @@ import (
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
// Collector models the PropertyCollector managed object.

View File

@ -17,8 +17,9 @@ limitations under the License.
package property
import (
"context"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
// Wait waits for any of the specified properties of the specified managed
@ -60,11 +61,17 @@ func Wait(ctx context.Context, c *Collector, obj types.ManagedObjectReference, p
},
}
if len(ps) == 0 {
req.Spec.PropSet[0].All = types.NewBool(true)
}
err = p.CreateFilter(ctx, req)
if err != nil {
return err
}
return waitLoop(ctx, p, f)
return waitLoop(ctx, p, func(_ types.ManagedObjectReference, pc []types.PropertyChange) bool {
return f(pc)
})
}
// WaitForView waits for any of the specified properties of the managed
@ -81,7 +88,7 @@ func Wait(ctx context.Context, c *Collector, obj types.ManagedObjectReference, p
// in case of success or error).
//
// The code assumes that all objects in the View are the same type
func WaitForView(ctx context.Context, c *Collector, view types.ManagedObjectReference, obj types.ManagedObjectReference, ps []string, f func([]types.PropertyChange) bool) error {
func WaitForView(ctx context.Context, c *Collector, view types.ManagedObjectReference, obj types.ManagedObjectReference, ps []string, f func(types.ManagedObjectReference, []types.PropertyChange) bool) error {
p, err := c.Create(ctx)
if err != nil {
return err
@ -92,7 +99,6 @@ func WaitForView(ctx context.Context, c *Collector, view types.ManagedObjectRefe
defer p.Destroy(context.Background())
req := types.CreateFilter{
Spec: types.PropertyFilterSpec{
ObjectSet: []types.ObjectSpec{
{
@ -107,7 +113,7 @@ func WaitForView(ctx context.Context, c *Collector, view types.ManagedObjectRefe
},
},
PropSet: []types.PropertySpec{
types.PropertySpec{
{
Type: obj.Type,
PathSet: ps,
},
@ -121,7 +127,7 @@ func WaitForView(ctx context.Context, c *Collector, view types.ManagedObjectRefe
return waitLoop(ctx, p, f)
}
func waitLoop(ctx context.Context, c *Collector, f func([]types.PropertyChange) bool) error {
func waitLoop(ctx context.Context, c *Collector, f func(types.ManagedObjectReference, []types.PropertyChange) bool) error {
for version := ""; ; {
res, err := c.WaitForUpdates(ctx, version)
if err != nil {
@ -137,7 +143,7 @@ func waitLoop(ctx context.Context, c *Collector, f func([]types.PropertyChange)
for _, fs := range res.FilterSet {
for _, os := range fs.ObjectSet {
if f(os.ChangeSet) {
if f(os.Obj, os.ChangeSet) {
return nil
}
}

View File

@ -17,12 +17,12 @@ limitations under the License.
package session
import (
"context"
"sync"
"time"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/soap"
"golang.org/x/net/context"
)
type keepAlive struct {

View File

@ -17,16 +17,29 @@ limitations under the License.
package session
import (
"context"
"net/url"
"os"
"github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
// Locale defaults to "en_US" and can be overridden via this var or the GOVMOMI_LOCALE env var.
// A value of "_" uses the server locale setting.
var Locale = os.Getenv("GOVMOMI_LOCALE")
func init() {
if Locale == "_" {
Locale = ""
} else if Locale == "" {
Locale = "en_US"
}
}
type Manager struct {
client *vim25.Client
userSession *types.UserSession
@ -44,9 +57,20 @@ func (sm Manager) Reference() types.ManagedObjectReference {
return *sm.client.ServiceContent.SessionManager
}
func (sm *Manager) SetLocale(ctx context.Context, locale string) error {
req := types.SetLocale{
This: sm.Reference(),
Locale: locale,
}
_, err := methods.SetLocale(ctx, sm.client, &req)
return err
}
func (sm *Manager) Login(ctx context.Context, u *url.Userinfo) error {
req := types.Login{
This: sm.Reference(),
This: sm.Reference(),
Locale: Locale,
}
if u != nil {

View File

@ -17,10 +17,11 @@ limitations under the License.
package task
import (
"context"
"github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/vim25/progress"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type taskProgress struct {

View File

@ -17,12 +17,12 @@ limitations under the License.
package vim25
import (
"context"
"encoding/json"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
// Client is a tiny wrapper around the vim25/soap Client that stores session

View File

@ -17,9 +17,10 @@ limitations under the License.
package methods
import (
"context"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type RetrieveDynamicTypeManagerBody struct {

File diff suppressed because it is too large Load Diff

View File

@ -17,21 +17,21 @@ limitations under the License.
package methods
import (
"context"
"time"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
var serviceInstance = types.ManagedObjectReference{
var ServiceInstance = types.ManagedObjectReference{
Type: "ServiceInstance",
Value: "ServiceInstance",
}
func GetServiceContent(ctx context.Context, r soap.RoundTripper) (types.ServiceContent, error) {
req := types.RetrieveServiceContent{
This: serviceInstance,
This: ServiceInstance,
}
res, err := RetrieveServiceContent(ctx, r, &req)
@ -44,7 +44,7 @@ func GetServiceContent(ctx context.Context, r soap.RoundTripper) (types.ServiceC
func GetCurrentTime(ctx context.Context, r soap.RoundTripper) (*time.Time, error) {
req := types.CurrentTime{
This: serviceInstance,
This: ServiceInstance,
}
res, err := CurrentTime(ctx, r, &req)

View File

@ -17,11 +17,11 @@ limitations under the License.
package mo
import (
"context"
"fmt"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
// Ancestors returns the entire ancestry tree of a specified managed object.
@ -39,13 +39,28 @@ func Ancestors(ctx context.Context, rt soap.RoundTripper, pc, obj types.ManagedO
&types.SelectionSpec{Name: "traverseParent"},
},
},
&types.TraversalSpec{
SelectionSpec: types.SelectionSpec{},
Type: "VirtualMachine",
Path: "parentVApp",
Skip: types.NewBool(false),
SelectSet: []types.BaseSelectionSpec{
&types.SelectionSpec{Name: "traverseParent"},
},
},
},
Skip: types.NewBool(false),
}
pspec := types.PropertySpec{
Type: "ManagedEntity",
PathSet: []string{"name", "parent"},
pspec := []types.PropertySpec{
{
Type: "ManagedEntity",
PathSet: []string{"name", "parent"},
},
{
Type: "VirtualMachine",
PathSet: []string{"parentVApp"},
},
}
req := types.RetrieveProperties{
@ -53,13 +68,12 @@ func Ancestors(ctx context.Context, rt soap.RoundTripper, pc, obj types.ManagedO
SpecSet: []types.PropertyFilterSpec{
{
ObjectSet: []types.ObjectSpec{ospec},
PropSet: []types.PropertySpec{pspec},
PropSet: pspec,
},
},
}
var ifaces []interface{}
err := RetrievePropertiesForRequest(ctx, rt, req, &ifaces)
if err != nil {
return nil, err
@ -96,6 +110,15 @@ func Ancestors(ctx context.Context, rt soap.RoundTripper, pc, obj types.ManagedO
}
}
if me.Parent == nil {
// Special case for VirtualMachine within VirtualApp,
// unlikely to hit this other than via Finder.Element()
switch x := iface.(type) {
case VirtualMachine:
me.Parent = x.ParentVApp
}
}
if me.Parent == nil {
out = append(out, me)
break

View File

@ -984,6 +984,18 @@ func init() {
t["HttpNfcLease"] = reflect.TypeOf((*HttpNfcLease)(nil)).Elem()
}
type InternalDynamicTypeManager struct {
Self types.ManagedObjectReference
}
func (m InternalDynamicTypeManager) Reference() types.ManagedObjectReference {
return m.Self
}
func init() {
t["InternalDynamicTypeManager"] = reflect.TypeOf((*InternalDynamicTypeManager)(nil)).Elem()
}
type InventoryView struct {
ManagedObjectView
}
@ -1290,6 +1302,18 @@ func init() {
t["PropertyFilter"] = reflect.TypeOf((*PropertyFilter)(nil)).Elem()
}
type ReflectManagedMethodExecuter struct {
Self types.ManagedObjectReference
}
func (m ReflectManagedMethodExecuter) Reference() types.ManagedObjectReference {
return m.Self
}
func init() {
t["ReflectManagedMethodExecuter"] = reflect.TypeOf((*ReflectManagedMethodExecuter)(nil)).Elem()
}
type ResourcePlanningManager struct {
Self types.ManagedObjectReference
}
@ -1496,18 +1520,6 @@ func init() {
t["UserDirectory"] = reflect.TypeOf((*UserDirectory)(nil)).Elem()
}
type VRPResourceManager struct {
Self types.ManagedObjectReference
}
func (m VRPResourceManager) Reference() types.ManagedObjectReference {
return m.Self
}
func init() {
t["VRPResourceManager"] = reflect.TypeOf((*VRPResourceManager)(nil)).Elem()
}
type View struct {
Self types.ManagedObjectReference
}

View File

@ -17,12 +17,12 @@ limitations under the License.
package mo
import (
"context"
"reflect"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
func ignoreMissingProperty(ref types.ManagedObjectReference, p types.MissingProperty) bool {

View File

@ -17,12 +17,12 @@ limitations under the License.
package vim25
import (
"context"
"net"
"net/url"
"time"
"github.com/vmware/govmomi/vim25/soap"
"golang.org/x/net/context"
)
type RetryFunc func(err error) (retry bool, delay time.Duration)

View File

@ -17,25 +17,31 @@ limitations under the License.
package soap
import (
"bufio"
"bytes"
"context"
"crypto/sha1"
"crypto/tls"
"crypto/x509"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"net/http/cookiejar"
"net/url"
"os"
"path/filepath"
"regexp"
"strings"
"sync"
"time"
"github.com/vmware/govmomi/vim25/progress"
"github.com/vmware/govmomi/vim25/types"
"github.com/vmware/govmomi/vim25/xml"
"golang.org/x/net/context"
)
type HasFault interface {
@ -46,8 +52,11 @@ type RoundTripper interface {
RoundTrip(ctx context.Context, req, res HasFault) error
}
var DefaultVimNamespace = "urn:vim25"
var DefaultVimVersion = "6.0"
const (
DefaultVimNamespace = "urn:vim25"
DefaultVimVersion = "6.5"
DefaultMinVimVersion = "5.5"
)
type Client struct {
http.Client
@ -58,8 +67,12 @@ type Client struct {
t *http.Transport
p *url.URL
hostsMu sync.Mutex
hosts map[string]string
Namespace string // Vim namespace
Version string // Vim version
UserAgent string
}
var schemeMatch = regexp.MustCompile(`^\w+://`)
@ -101,17 +114,24 @@ func NewClient(u *url.URL, insecure bool) *Client {
}
// Initialize http.RoundTripper on client, so we can customize it below
c.t = &http.Transport{
Proxy: http.ProxyFromEnvironment,
Dial: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).Dial,
if t, ok := http.DefaultTransport.(*http.Transport); ok {
c.t = &http.Transport{
Proxy: t.Proxy,
DialContext: t.DialContext,
MaxIdleConns: t.MaxIdleConns,
IdleConnTimeout: t.IdleConnTimeout,
TLSHandshakeTimeout: t.TLSHandshakeTimeout,
ExpectContinueTimeout: t.ExpectContinueTimeout,
}
} else {
c.t = new(http.Transport)
}
if c.u.Scheme == "https" {
c.t.TLSClientConfig = &tls.Config{InsecureSkipVerify: c.k}
c.t.TLSHandshakeTimeout = 10 * time.Second
c.hosts = make(map[string]string)
c.t.TLSClientConfig = &tls.Config{InsecureSkipVerify: c.k}
// Don't bother setting DialTLS if InsecureSkipVerify=true
if !c.k {
c.t.DialTLS = c.dialTLS
}
c.Client.Transport = c.t
@ -127,6 +147,156 @@ func NewClient(u *url.URL, insecure bool) *Client {
return &c
}
// SetRootCAs defines the set of root certificate authorities
// that clients use when verifying server certificates.
// By default TLS uses the host's root CA set.
//
// See: http.Client.Transport.TLSClientConfig.RootCAs
func (c *Client) SetRootCAs(file string) error {
pool := x509.NewCertPool()
for _, name := range filepath.SplitList(file) {
pem, err := ioutil.ReadFile(name)
if err != nil {
return err
}
pool.AppendCertsFromPEM(pem)
}
c.t.TLSClientConfig.RootCAs = pool
return nil
}
// Add default https port if missing
func hostAddr(addr string) string {
_, port := splitHostPort(addr)
if port == "" {
return addr + ":443"
}
return addr
}
// SetThumbprint sets the known certificate thumbprint for the given host.
// A custom DialTLS function is used to support thumbprint based verification.
// We first try tls.Dial with the default tls.Config, only falling back to thumbprint verification
// if it fails with an x509.UnknownAuthorityError or x509.HostnameError
//
// See: http.Client.Transport.DialTLS
func (c *Client) SetThumbprint(host string, thumbprint string) {
host = hostAddr(host)
c.hostsMu.Lock()
if thumbprint == "" {
delete(c.hosts, host)
} else {
c.hosts[host] = thumbprint
}
c.hostsMu.Unlock()
}
// Thumbprint returns the certificate thumbprint for the given host if known to this client.
func (c *Client) Thumbprint(host string) string {
host = hostAddr(host)
c.hostsMu.Lock()
defer c.hostsMu.Unlock()
return c.hosts[host]
}
// LoadThumbprints from file with the give name.
// If name is empty or name does not exist this function will return nil.
func (c *Client) LoadThumbprints(file string) error {
if file == "" {
return nil
}
for _, name := range filepath.SplitList(file) {
err := c.loadThumbprints(name)
if err != nil {
return err
}
}
return nil
}
func (c *Client) loadThumbprints(name string) error {
f, err := os.Open(name)
if err != nil {
if os.IsNotExist(err) {
return nil
}
return err
}
scanner := bufio.NewScanner(f)
for scanner.Scan() {
e := strings.SplitN(scanner.Text(), " ", 2)
if len(e) != 2 {
continue
}
c.SetThumbprint(e[0], e[1])
}
_ = f.Close()
return scanner.Err()
}
// ThumbprintSHA1 returns the thumbprint of the given cert in the same format used by the SDK and Client.SetThumbprint.
//
// See: SSLVerifyFault.Thumbprint, SessionManagerGenericServiceTicket.Thumbprint, HostConnectSpec.SslThumbprint
func ThumbprintSHA1(cert *x509.Certificate) string {
sum := sha1.Sum(cert.Raw)
hex := make([]string, len(sum))
for i, b := range sum {
hex[i] = fmt.Sprintf("%02X", b)
}
return strings.Join(hex, ":")
}
func (c *Client) dialTLS(network string, addr string) (net.Conn, error) {
// Would be nice if there was a tls.Config.Verify func,
// see tls.clientHandshakeState.doFullHandshake
conn, err := tls.Dial(network, addr, c.t.TLSClientConfig)
if err == nil {
return conn, nil
}
switch err.(type) {
case x509.UnknownAuthorityError:
case x509.HostnameError:
default:
return nil, err
}
thumbprint := c.Thumbprint(addr)
if thumbprint == "" {
return nil, err
}
config := &tls.Config{InsecureSkipVerify: true}
conn, err = tls.Dial(network, addr, config)
if err != nil {
return nil, err
}
cert := conn.ConnectionState().PeerCertificates[0]
peer := ThumbprintSHA1(cert)
if thumbprint != peer {
_ = conn.Close()
return nil, fmt.Errorf("Host %q thumbprint does not match %q", addr, thumbprint)
}
return conn, nil
}
// splitHostPort is similar to net.SplitHostPort,
// but rather than return error if there isn't a ':port',
// return an empty string for the port.
@ -155,7 +325,13 @@ func (c *Client) SetCertificate(cert tls.Certificate) {
host, _ := splitHostPort(c.u.Host)
// Should be no reason to change the default port other than testing
port := os.Getenv("GOVC_TUNNEL_PROXY_PORT")
key := "GOVMOMI_TUNNEL_PROXY_PORT"
port := c.URL().Query().Get(key)
if port == "" {
port = os.Getenv(key)
}
if port != "" {
host += ":" + port
}
@ -212,33 +388,11 @@ func (c *Client) UnmarshalJSON(b []byte) error {
}
func (c *Client) do(ctx context.Context, req *http.Request) (*http.Response, error) {
if nil == ctx || nil == ctx.Done() { // ctx.Done() is for context.TODO()
if nil == ctx || nil == ctx.Done() { // ctx.Done() is for ctx
return c.Client.Do(req)
}
var resc = make(chan *http.Response, 1)
var errc = make(chan error, 1)
// Perform request from separate routine.
go func() {
res, err := c.Client.Do(req)
if err != nil {
errc <- err
} else {
resc <- res
}
}()
// Wait for request completion of context expiry.
select {
case <-ctx.Done():
c.t.CancelRequest(req)
return nil, ctx.Err()
case err := <-errc:
return nil, err
case res := <-resc:
return res, nil
}
return c.Client.Do(req.WithContext(ctx))
}
func (c *Client) RoundTrip(ctx context.Context, reqBody, resBody HasFault) error {
@ -267,6 +421,9 @@ func (c *Client) RoundTrip(ctx context.Context, reqBody, resBody HasFault) error
req.Header.Set(`Content-Type`, `text/xml; charset="utf-8"`)
soapAction := fmt.Sprintf("%s/%s", c.Namespace, c.Version)
req.Header.Set(`SOAPAction`, soapAction)
if c.UserAgent != "" {
req.Header.Set(`User-Agent`, c.UserAgent)
}
if d.enabled() {
d.debugRequest(req)
@ -420,6 +577,7 @@ func (c *Client) UploadFile(file string, u *url.URL, param *Upload) error {
type Download struct {
Method string
Headers map[string]string
Ticket *http.Cookie
Progress progress.Sinker
}
@ -428,19 +586,27 @@ var DefaultDownload = Download{
Method: "GET",
}
// Download GETs the remote file from the given URL
func (c *Client) Download(u *url.URL, param *Download) (io.ReadCloser, int64, error) {
// DownloadRequest wraps http.Client.Do, returning the http.Response without checking its StatusCode
func (c *Client) DownloadRequest(u *url.URL, param *Download) (*http.Response, error) {
req, err := http.NewRequest(param.Method, u.String(), nil)
if err != nil {
return nil, 0, err
return nil, err
}
for k, v := range param.Headers {
req.Header.Add(k, v)
}
if param.Ticket != nil {
req.AddCookie(param.Ticket)
}
res, err := c.Client.Do(req)
return c.Client.Do(req)
}
// Download GETs the remote file from the given URL
func (c *Client) Download(u *url.URL, param *Download) (io.ReadCloser, int64, error) {
res, err := c.DownloadRequest(u, param)
if err != nil {
return nil, 0, err
}
@ -455,9 +621,7 @@ func (c *Client) Download(u *url.URL, param *Download) (io.ReadCloser, int64, er
return nil, 0, err
}
var r io.ReadCloser = res.Body
return r, res.ContentLength, nil
return res.Body, res.ContentLength, nil
}
// DownloadFile GETs the given URL to a local file

View File

@ -39,13 +39,14 @@ func init() {
type ActionType string
const (
ActionTypeMigrationV1 = ActionType("MigrationV1")
ActionTypeVmPowerV1 = ActionType("VmPowerV1")
ActionTypeHostPowerV1 = ActionType("HostPowerV1")
ActionTypeHostMaintenanceV1 = ActionType("HostMaintenanceV1")
ActionTypeStorageMigrationV1 = ActionType("StorageMigrationV1")
ActionTypeStoragePlacementV1 = ActionType("StoragePlacementV1")
ActionTypePlacementV1 = ActionType("PlacementV1")
ActionTypeMigrationV1 = ActionType("MigrationV1")
ActionTypeVmPowerV1 = ActionType("VmPowerV1")
ActionTypeHostPowerV1 = ActionType("HostPowerV1")
ActionTypeHostMaintenanceV1 = ActionType("HostMaintenanceV1")
ActionTypeStorageMigrationV1 = ActionType("StorageMigrationV1")
ActionTypeStoragePlacementV1 = ActionType("StoragePlacementV1")
ActionTypePlacementV1 = ActionType("PlacementV1")
ActionTypeHostInfraUpdateHaV1 = ActionType("HostInfraUpdateHaV1")
)
func init() {
@ -120,6 +121,18 @@ func init() {
t["AutoStartWaitHeartbeatSetting"] = reflect.TypeOf((*AutoStartWaitHeartbeatSetting)(nil)).Elem()
}
type BaseConfigInfoDiskFileBackingInfoProvisioningType string
const (
BaseConfigInfoDiskFileBackingInfoProvisioningTypeThin = BaseConfigInfoDiskFileBackingInfoProvisioningType("thin")
BaseConfigInfoDiskFileBackingInfoProvisioningTypeEagerZeroedThick = BaseConfigInfoDiskFileBackingInfoProvisioningType("eagerZeroedThick")
BaseConfigInfoDiskFileBackingInfoProvisioningTypeLazyZeroedThick = BaseConfigInfoDiskFileBackingInfoProvisioningType("lazyZeroedThick")
)
func init() {
t["BaseConfigInfoDiskFileBackingInfoProvisioningType"] = reflect.TypeOf((*BaseConfigInfoDiskFileBackingInfoProvisioningType)(nil)).Elem()
}
type BatchResultResult string
const (
@ -281,9 +294,11 @@ type ClusterDasVmSettingsRestartPriority string
const (
ClusterDasVmSettingsRestartPriorityDisabled = ClusterDasVmSettingsRestartPriority("disabled")
ClusterDasVmSettingsRestartPriorityLowest = ClusterDasVmSettingsRestartPriority("lowest")
ClusterDasVmSettingsRestartPriorityLow = ClusterDasVmSettingsRestartPriority("low")
ClusterDasVmSettingsRestartPriorityMedium = ClusterDasVmSettingsRestartPriority("medium")
ClusterDasVmSettingsRestartPriorityHigh = ClusterDasVmSettingsRestartPriority("high")
ClusterDasVmSettingsRestartPriorityHighest = ClusterDasVmSettingsRestartPriority("highest")
ClusterDasVmSettingsRestartPriorityClusterRestartPriority = ClusterDasVmSettingsRestartPriority("clusterRestartPriority")
)
@ -291,6 +306,40 @@ func init() {
t["ClusterDasVmSettingsRestartPriority"] = reflect.TypeOf((*ClusterDasVmSettingsRestartPriority)(nil)).Elem()
}
type ClusterHostInfraUpdateHaModeActionOperationType string
const (
ClusterHostInfraUpdateHaModeActionOperationTypeEnterQuarantine = ClusterHostInfraUpdateHaModeActionOperationType("enterQuarantine")
ClusterHostInfraUpdateHaModeActionOperationTypeExitQuarantine = ClusterHostInfraUpdateHaModeActionOperationType("exitQuarantine")
ClusterHostInfraUpdateHaModeActionOperationTypeEnterMaintenance = ClusterHostInfraUpdateHaModeActionOperationType("enterMaintenance")
)
func init() {
t["ClusterHostInfraUpdateHaModeActionOperationType"] = reflect.TypeOf((*ClusterHostInfraUpdateHaModeActionOperationType)(nil)).Elem()
}
type ClusterInfraUpdateHaConfigInfoBehaviorType string
const (
ClusterInfraUpdateHaConfigInfoBehaviorTypeManual = ClusterInfraUpdateHaConfigInfoBehaviorType("Manual")
ClusterInfraUpdateHaConfigInfoBehaviorTypeAutomated = ClusterInfraUpdateHaConfigInfoBehaviorType("Automated")
)
func init() {
t["ClusterInfraUpdateHaConfigInfoBehaviorType"] = reflect.TypeOf((*ClusterInfraUpdateHaConfigInfoBehaviorType)(nil)).Elem()
}
type ClusterInfraUpdateHaConfigInfoRemediationType string
const (
ClusterInfraUpdateHaConfigInfoRemediationTypeQuarantineMode = ClusterInfraUpdateHaConfigInfoRemediationType("QuarantineMode")
ClusterInfraUpdateHaConfigInfoRemediationTypeMaintenanceMode = ClusterInfraUpdateHaConfigInfoRemediationType("MaintenanceMode")
)
func init() {
t["ClusterInfraUpdateHaConfigInfoRemediationType"] = reflect.TypeOf((*ClusterInfraUpdateHaConfigInfoRemediationType)(nil)).Elem()
}
type ClusterPowerOnVmOption string
const (
@ -341,6 +390,20 @@ func init() {
t["ClusterVmComponentProtectionSettingsVmReactionOnAPDCleared"] = reflect.TypeOf((*ClusterVmComponentProtectionSettingsVmReactionOnAPDCleared)(nil)).Elem()
}
type ClusterVmReadinessReadyCondition string
const (
ClusterVmReadinessReadyConditionNone = ClusterVmReadinessReadyCondition("none")
ClusterVmReadinessReadyConditionPoweredOn = ClusterVmReadinessReadyCondition("poweredOn")
ClusterVmReadinessReadyConditionGuestHbStatusGreen = ClusterVmReadinessReadyCondition("guestHbStatusGreen")
ClusterVmReadinessReadyConditionAppHbStatusGreen = ClusterVmReadinessReadyCondition("appHbStatusGreen")
ClusterVmReadinessReadyConditionUseClusterDefault = ClusterVmReadinessReadyCondition("useClusterDefault")
)
func init() {
t["ClusterVmReadinessReadyCondition"] = reflect.TypeOf((*ClusterVmReadinessReadyCondition)(nil)).Elem()
}
type ComplianceResultStatus string
const (
@ -732,6 +795,19 @@ func init() {
t["DrsRecommendationReasonCode"] = reflect.TypeOf((*DrsRecommendationReasonCode)(nil)).Elem()
}
type DvsEventPortBlockState string
const (
DvsEventPortBlockStateUnset = DvsEventPortBlockState("unset")
DvsEventPortBlockStateBlocked = DvsEventPortBlockState("blocked")
DvsEventPortBlockStateUnblocked = DvsEventPortBlockState("unblocked")
DvsEventPortBlockStateUnknown = DvsEventPortBlockState("unknown")
)
func init() {
t["DvsEventPortBlockState"] = reflect.TypeOf((*DvsEventPortBlockState)(nil)).Elem()
}
type DvsFilterOnFailure string
const (
@ -931,6 +1007,20 @@ func init() {
t["GuestRegKeyWowSpec"] = reflect.TypeOf((*GuestRegKeyWowSpec)(nil)).Elem()
}
type HealthUpdateInfoComponentType string
const (
HealthUpdateInfoComponentTypeMemory = HealthUpdateInfoComponentType("Memory")
HealthUpdateInfoComponentTypePower = HealthUpdateInfoComponentType("Power")
HealthUpdateInfoComponentTypeFan = HealthUpdateInfoComponentType("Fan")
HealthUpdateInfoComponentTypeNetwork = HealthUpdateInfoComponentType("Network")
HealthUpdateInfoComponentTypeStorage = HealthUpdateInfoComponentType("Storage")
)
func init() {
t["HealthUpdateInfoComponentType"] = reflect.TypeOf((*HealthUpdateInfoComponentType)(nil)).Elem()
}
type HostAccessMode string
const (
@ -1064,6 +1154,18 @@ func init() {
t["HostCpuPowerManagementInfoPolicyType"] = reflect.TypeOf((*HostCpuPowerManagementInfoPolicyType)(nil)).Elem()
}
type HostCryptoState string
const (
HostCryptoStateIncapable = HostCryptoState("incapable")
HostCryptoStatePrepared = HostCryptoState("prepared")
HostCryptoStateSafe = HostCryptoState("safe")
)
func init() {
t["HostCryptoState"] = reflect.TypeOf((*HostCryptoState)(nil)).Elem()
}
type HostDasErrorEventHostDasErrorReason string
const (
@ -1199,12 +1301,35 @@ func init() {
t["HostFirewallRuleProtocol"] = reflect.TypeOf((*HostFirewallRuleProtocol)(nil)).Elem()
}
type HostGraphicsConfigGraphicsType string
const (
HostGraphicsConfigGraphicsTypeShared = HostGraphicsConfigGraphicsType("shared")
HostGraphicsConfigGraphicsTypeSharedDirect = HostGraphicsConfigGraphicsType("sharedDirect")
)
func init() {
t["HostGraphicsConfigGraphicsType"] = reflect.TypeOf((*HostGraphicsConfigGraphicsType)(nil)).Elem()
}
type HostGraphicsConfigSharedPassthruAssignmentPolicy string
const (
HostGraphicsConfigSharedPassthruAssignmentPolicyPerformance = HostGraphicsConfigSharedPassthruAssignmentPolicy("performance")
HostGraphicsConfigSharedPassthruAssignmentPolicyConsolidation = HostGraphicsConfigSharedPassthruAssignmentPolicy("consolidation")
)
func init() {
t["HostGraphicsConfigSharedPassthruAssignmentPolicy"] = reflect.TypeOf((*HostGraphicsConfigSharedPassthruAssignmentPolicy)(nil)).Elem()
}
type HostGraphicsInfoGraphicsType string
const (
HostGraphicsInfoGraphicsTypeBasic = HostGraphicsInfoGraphicsType("basic")
HostGraphicsInfoGraphicsTypeShared = HostGraphicsInfoGraphicsType("shared")
HostGraphicsInfoGraphicsTypeDirect = HostGraphicsInfoGraphicsType("direct")
HostGraphicsInfoGraphicsTypeBasic = HostGraphicsInfoGraphicsType("basic")
HostGraphicsInfoGraphicsTypeShared = HostGraphicsInfoGraphicsType("shared")
HostGraphicsInfoGraphicsTypeDirect = HostGraphicsInfoGraphicsType("direct")
HostGraphicsInfoGraphicsTypeSharedDirect = HostGraphicsInfoGraphicsType("sharedDirect")
)
func init() {
@ -1451,8 +1576,9 @@ func init() {
type HostNasVolumeSecurityType string
const (
HostNasVolumeSecurityTypeAUTH_SYS = HostNasVolumeSecurityType("AUTH_SYS")
HostNasVolumeSecurityTypeSEC_KRB5 = HostNasVolumeSecurityType("SEC_KRB5")
HostNasVolumeSecurityTypeAUTH_SYS = HostNasVolumeSecurityType("AUTH_SYS")
HostNasVolumeSecurityTypeSEC_KRB5 = HostNasVolumeSecurityType("SEC_KRB5")
HostNasVolumeSecurityTypeSEC_KRB5I = HostNasVolumeSecurityType("SEC_KRB5I")
)
func init() {
@ -1503,6 +1629,14 @@ const (
HostNumericSensorTypeTemperature = HostNumericSensorType("temperature")
HostNumericSensorTypeVoltage = HostNumericSensorType("voltage")
HostNumericSensorTypeOther = HostNumericSensorType("other")
HostNumericSensorTypeProcessor = HostNumericSensorType("processor")
HostNumericSensorTypeMemory = HostNumericSensorType("memory")
HostNumericSensorTypeStorage = HostNumericSensorType("storage")
HostNumericSensorTypeSystemBoard = HostNumericSensorType("systemBoard")
HostNumericSensorTypeBattery = HostNumericSensorType("battery")
HostNumericSensorTypeBios = HostNumericSensorType("bios")
HostNumericSensorTypeCable = HostNumericSensorType("cable")
HostNumericSensorTypeWatchdog = HostNumericSensorType("watchdog")
)
func init() {
@ -1608,6 +1742,18 @@ func init() {
t["HostProtocolEndpointPEType"] = reflect.TypeOf((*HostProtocolEndpointPEType)(nil)).Elem()
}
type HostProtocolEndpointProtocolEndpointType string
const (
HostProtocolEndpointProtocolEndpointTypeScsi = HostProtocolEndpointProtocolEndpointType("scsi")
HostProtocolEndpointProtocolEndpointTypeNfs = HostProtocolEndpointProtocolEndpointType("nfs")
HostProtocolEndpointProtocolEndpointTypeNfs4x = HostProtocolEndpointProtocolEndpointType("nfs4x")
)
func init() {
t["HostProtocolEndpointProtocolEndpointType"] = reflect.TypeOf((*HostProtocolEndpointProtocolEndpointType)(nil)).Elem()
}
type HostReplayUnsupportedReason string
const (
@ -1742,6 +1888,7 @@ const (
HostVirtualNicManagerNicTypeManagement = HostVirtualNicManagerNicType("management")
HostVirtualNicManagerNicTypeVsan = HostVirtualNicManagerNicType("vsan")
HostVirtualNicManagerNicTypeVSphereProvisioning = HostVirtualNicManagerNicType("vSphereProvisioning")
HostVirtualNicManagerNicTypeVsanWitness = HostVirtualNicManagerNicType("vsanWitness")
)
func init() {
@ -1760,6 +1907,17 @@ func init() {
t["HostVmciAccessManagerMode"] = reflect.TypeOf((*HostVmciAccessManagerMode)(nil)).Elem()
}
type HostVmfsVolumeUnmapPriority string
const (
HostVmfsVolumeUnmapPriorityNone = HostVmfsVolumeUnmapPriority("none")
HostVmfsVolumeUnmapPriorityLow = HostVmfsVolumeUnmapPriority("low")
)
func init() {
t["HostVmfsVolumeUnmapPriority"] = reflect.TypeOf((*HostVmfsVolumeUnmapPriority)(nil)).Elem()
}
type HttpNfcLeaseState string
const (
@ -1831,6 +1989,22 @@ func init() {
t["IoFilterOperation"] = reflect.TypeOf((*IoFilterOperation)(nil)).Elem()
}
type IoFilterType string
const (
IoFilterTypeCache = IoFilterType("cache")
IoFilterTypeReplication = IoFilterType("replication")
IoFilterTypeEncryption = IoFilterType("encryption")
IoFilterTypeCompression = IoFilterType("compression")
IoFilterTypeInspection = IoFilterType("inspection")
IoFilterTypeDatastoreIoControl = IoFilterType("datastoreIoControl")
IoFilterTypeDataProvider = IoFilterType("dataProvider")
)
func init() {
t["IoFilterType"] = reflect.TypeOf((*IoFilterType)(nil)).Elem()
}
type IscsiPortInfoPathStatus string
const (
@ -2330,6 +2504,18 @@ func init() {
t["PropertyChangeOp"] = reflect.TypeOf((*PropertyChangeOp)(nil)).Elem()
}
type QuarantineModeFaultFaultType string
const (
QuarantineModeFaultFaultTypeNoCompatibleNonQuarantinedHost = QuarantineModeFaultFaultType("NoCompatibleNonQuarantinedHost")
QuarantineModeFaultFaultTypeCorrectionDisallowed = QuarantineModeFaultFaultType("CorrectionDisallowed")
QuarantineModeFaultFaultTypeCorrectionImpact = QuarantineModeFaultFaultType("CorrectionImpact")
)
func init() {
t["QuarantineModeFaultFaultType"] = reflect.TypeOf((*QuarantineModeFaultFaultType)(nil)).Elem()
}
type QuiesceMode string
const (
@ -2371,6 +2557,10 @@ const (
RecommendationReasonCodeIolbDisabledInternal = RecommendationReasonCode("iolbDisabledInternal")
RecommendationReasonCodeXvmotionPlacement = RecommendationReasonCode("xvmotionPlacement")
RecommendationReasonCodeNetworkBandwidthReservation = RecommendationReasonCode("networkBandwidthReservation")
RecommendationReasonCodeHostInDegradation = RecommendationReasonCode("hostInDegradation")
RecommendationReasonCodeHostExitDegradation = RecommendationReasonCode("hostExitDegradation")
RecommendationReasonCodeMaxVmsConstraint = RecommendationReasonCode("maxVmsConstraint")
RecommendationReasonCodeFtConstraints = RecommendationReasonCode("ftConstraints")
)
func init() {
@ -2420,6 +2610,7 @@ const (
ReplicationVmConfigFaultReasonForFaultInvalidPriorConfiguration = ReplicationVmConfigFaultReasonForFault("invalidPriorConfiguration")
ReplicationVmConfigFaultReasonForFaultReplicationNotEnabled = ReplicationVmConfigFaultReasonForFault("replicationNotEnabled")
ReplicationVmConfigFaultReasonForFaultReplicationConfigurationFailed = ReplicationVmConfigFaultReasonForFault("replicationConfigurationFailed")
ReplicationVmConfigFaultReasonForFaultEncryptedVm = ReplicationVmConfigFaultReasonForFault("encryptedVm")
)
func init() {
@ -2436,6 +2627,7 @@ const (
ReplicationVmFaultReasonForFaultOfflineReplicating = ReplicationVmFaultReasonForFault("offlineReplicating")
ReplicationVmFaultReasonForFaultInvalidState = ReplicationVmFaultReasonForFault("invalidState")
ReplicationVmFaultReasonForFaultInvalidInstanceId = ReplicationVmFaultReasonForFault("invalidInstanceId")
ReplicationVmFaultReasonForFaultCloseDiskError = ReplicationVmFaultReasonForFault("closeDiskError")
)
func init() {
@ -2493,6 +2685,19 @@ func init() {
t["ScheduledHardwareUpgradeInfoHardwareUpgradeStatus"] = reflect.TypeOf((*ScheduledHardwareUpgradeInfoHardwareUpgradeStatus)(nil)).Elem()
}
type ScsiDiskType string
const (
ScsiDiskTypeNative512 = ScsiDiskType("native512")
ScsiDiskTypeEmulated512 = ScsiDiskType("emulated512")
ScsiDiskTypeNative4k = ScsiDiskType("native4k")
ScsiDiskTypeUnknown = ScsiDiskType("unknown")
)
func init() {
t["ScsiDiskType"] = reflect.TypeOf((*ScsiDiskType)(nil)).Elem()
}
type ScsiLunDescriptorQuality string
const (
@ -2612,6 +2817,32 @@ func init() {
t["SlpDiscoveryMethod"] = reflect.TypeOf((*SlpDiscoveryMethod)(nil)).Elem()
}
type SoftwarePackageConstraint string
const (
SoftwarePackageConstraintEquals = SoftwarePackageConstraint("equals")
SoftwarePackageConstraintLessThan = SoftwarePackageConstraint("lessThan")
SoftwarePackageConstraintLessThanEqual = SoftwarePackageConstraint("lessThanEqual")
SoftwarePackageConstraintGreaterThanEqual = SoftwarePackageConstraint("greaterThanEqual")
SoftwarePackageConstraintGreaterThan = SoftwarePackageConstraint("greaterThan")
)
func init() {
t["SoftwarePackageConstraint"] = reflect.TypeOf((*SoftwarePackageConstraint)(nil)).Elem()
}
type SoftwarePackageVibType string
const (
SoftwarePackageVibTypeBootbank = SoftwarePackageVibType("bootbank")
SoftwarePackageVibTypeTools = SoftwarePackageVibType("tools")
SoftwarePackageVibTypeMeta = SoftwarePackageVibType("meta")
)
func init() {
t["SoftwarePackageVibType"] = reflect.TypeOf((*SoftwarePackageVibType)(nil)).Elem()
}
type StateAlarmOperator string
const (
@ -2827,6 +3058,18 @@ func init() {
t["VMwareDVSTeamingMatchStatus"] = reflect.TypeOf((*VMwareDVSTeamingMatchStatus)(nil)).Elem()
}
type VMwareDVSVspanSessionEncapType string
const (
VMwareDVSVspanSessionEncapTypeGre = VMwareDVSVspanSessionEncapType("gre")
VMwareDVSVspanSessionEncapTypeErspan2 = VMwareDVSVspanSessionEncapType("erspan2")
VMwareDVSVspanSessionEncapTypeErspan3 = VMwareDVSVspanSessionEncapType("erspan3")
)
func init() {
t["VMwareDVSVspanSessionEncapType"] = reflect.TypeOf((*VMwareDVSVspanSessionEncapType)(nil)).Elem()
}
type VMwareDVSVspanSessionType string
const (
@ -2903,6 +3146,16 @@ func init() {
t["VMwareUplinkLacpMode"] = reflect.TypeOf((*VMwareUplinkLacpMode)(nil)).Elem()
}
type VStorageObjectConsumptionType string
const (
VStorageObjectConsumptionTypeDisk = VStorageObjectConsumptionType("disk")
)
func init() {
t["VStorageObjectConsumptionType"] = reflect.TypeOf((*VStorageObjectConsumptionType)(nil)).Elem()
}
type ValidateMigrationTestType string
const (
@ -2916,6 +3169,66 @@ func init() {
t["ValidateMigrationTestType"] = reflect.TypeOf((*ValidateMigrationTestType)(nil)).Elem()
}
type VchaClusterMode string
const (
VchaClusterModeEnabled = VchaClusterMode("enabled")
VchaClusterModeDisabled = VchaClusterMode("disabled")
VchaClusterModeMaintenance = VchaClusterMode("maintenance")
)
func init() {
t["VchaClusterMode"] = reflect.TypeOf((*VchaClusterMode)(nil)).Elem()
}
type VchaClusterState string
const (
VchaClusterStateHealthy = VchaClusterState("healthy")
VchaClusterStateDegraded = VchaClusterState("degraded")
VchaClusterStateIsolated = VchaClusterState("isolated")
)
func init() {
t["VchaClusterState"] = reflect.TypeOf((*VchaClusterState)(nil)).Elem()
}
type VchaNodeRole string
const (
VchaNodeRoleActive = VchaNodeRole("active")
VchaNodeRolePassive = VchaNodeRole("passive")
VchaNodeRoleWitness = VchaNodeRole("witness")
)
func init() {
t["VchaNodeRole"] = reflect.TypeOf((*VchaNodeRole)(nil)).Elem()
}
type VchaNodeState string
const (
VchaNodeStateUp = VchaNodeState("up")
VchaNodeStateDown = VchaNodeState("down")
)
func init() {
t["VchaNodeState"] = reflect.TypeOf((*VchaNodeState)(nil)).Elem()
}
type VchaState string
const (
VchaStateConfigured = VchaState("configured")
VchaStateNotConfigured = VchaState("notConfigured")
VchaStateInvalid = VchaState("invalid")
VchaStatePrepared = VchaState("prepared")
)
func init() {
t["VchaState"] = reflect.TypeOf((*VchaState)(nil)).Elem()
}
type VirtualAppVAppState string
const (
@ -3178,6 +3491,18 @@ func init() {
t["VirtualMachineConfigInfoSwapPlacementType"] = reflect.TypeOf((*VirtualMachineConfigInfoSwapPlacementType)(nil)).Elem()
}
type VirtualMachineConfigSpecEncryptedVMotionModes string
const (
VirtualMachineConfigSpecEncryptedVMotionModesDisabled = VirtualMachineConfigSpecEncryptedVMotionModes("disabled")
VirtualMachineConfigSpecEncryptedVMotionModesOpportunistic = VirtualMachineConfigSpecEncryptedVMotionModes("opportunistic")
VirtualMachineConfigSpecEncryptedVMotionModesRequired = VirtualMachineConfigSpecEncryptedVMotionModes("required")
)
func init() {
t["VirtualMachineConfigSpecEncryptedVMotionModes"] = reflect.TypeOf((*VirtualMachineConfigSpecEncryptedVMotionModes)(nil)).Elem()
}
type VirtualMachineConfigSpecNpivWwnOp string
const (
@ -3414,8 +3739,16 @@ const (
VirtualMachineGuestOsIdentifierRhel7_64Guest = VirtualMachineGuestOsIdentifier("rhel7_64Guest")
VirtualMachineGuestOsIdentifierCentosGuest = VirtualMachineGuestOsIdentifier("centosGuest")
VirtualMachineGuestOsIdentifierCentos64Guest = VirtualMachineGuestOsIdentifier("centos64Guest")
VirtualMachineGuestOsIdentifierCentos6Guest = VirtualMachineGuestOsIdentifier("centos6Guest")
VirtualMachineGuestOsIdentifierCentos6_64Guest = VirtualMachineGuestOsIdentifier("centos6_64Guest")
VirtualMachineGuestOsIdentifierCentos7Guest = VirtualMachineGuestOsIdentifier("centos7Guest")
VirtualMachineGuestOsIdentifierCentos7_64Guest = VirtualMachineGuestOsIdentifier("centos7_64Guest")
VirtualMachineGuestOsIdentifierOracleLinuxGuest = VirtualMachineGuestOsIdentifier("oracleLinuxGuest")
VirtualMachineGuestOsIdentifierOracleLinux64Guest = VirtualMachineGuestOsIdentifier("oracleLinux64Guest")
VirtualMachineGuestOsIdentifierOracleLinux6Guest = VirtualMachineGuestOsIdentifier("oracleLinux6Guest")
VirtualMachineGuestOsIdentifierOracleLinux6_64Guest = VirtualMachineGuestOsIdentifier("oracleLinux6_64Guest")
VirtualMachineGuestOsIdentifierOracleLinux7Guest = VirtualMachineGuestOsIdentifier("oracleLinux7Guest")
VirtualMachineGuestOsIdentifierOracleLinux7_64Guest = VirtualMachineGuestOsIdentifier("oracleLinux7_64Guest")
VirtualMachineGuestOsIdentifierSuseGuest = VirtualMachineGuestOsIdentifier("suseGuest")
VirtualMachineGuestOsIdentifierSuse64Guest = VirtualMachineGuestOsIdentifier("suse64Guest")
VirtualMachineGuestOsIdentifierSlesGuest = VirtualMachineGuestOsIdentifier("slesGuest")
@ -3446,16 +3779,22 @@ const (
VirtualMachineGuestOsIdentifierDebian7_64Guest = VirtualMachineGuestOsIdentifier("debian7_64Guest")
VirtualMachineGuestOsIdentifierDebian8Guest = VirtualMachineGuestOsIdentifier("debian8Guest")
VirtualMachineGuestOsIdentifierDebian8_64Guest = VirtualMachineGuestOsIdentifier("debian8_64Guest")
VirtualMachineGuestOsIdentifierDebian9Guest = VirtualMachineGuestOsIdentifier("debian9Guest")
VirtualMachineGuestOsIdentifierDebian9_64Guest = VirtualMachineGuestOsIdentifier("debian9_64Guest")
VirtualMachineGuestOsIdentifierDebian10Guest = VirtualMachineGuestOsIdentifier("debian10Guest")
VirtualMachineGuestOsIdentifierDebian10_64Guest = VirtualMachineGuestOsIdentifier("debian10_64Guest")
VirtualMachineGuestOsIdentifierAsianux3Guest = VirtualMachineGuestOsIdentifier("asianux3Guest")
VirtualMachineGuestOsIdentifierAsianux3_64Guest = VirtualMachineGuestOsIdentifier("asianux3_64Guest")
VirtualMachineGuestOsIdentifierAsianux4Guest = VirtualMachineGuestOsIdentifier("asianux4Guest")
VirtualMachineGuestOsIdentifierAsianux4_64Guest = VirtualMachineGuestOsIdentifier("asianux4_64Guest")
VirtualMachineGuestOsIdentifierAsianux5_64Guest = VirtualMachineGuestOsIdentifier("asianux5_64Guest")
VirtualMachineGuestOsIdentifierAsianux7_64Guest = VirtualMachineGuestOsIdentifier("asianux7_64Guest")
VirtualMachineGuestOsIdentifierOpensuseGuest = VirtualMachineGuestOsIdentifier("opensuseGuest")
VirtualMachineGuestOsIdentifierOpensuse64Guest = VirtualMachineGuestOsIdentifier("opensuse64Guest")
VirtualMachineGuestOsIdentifierFedoraGuest = VirtualMachineGuestOsIdentifier("fedoraGuest")
VirtualMachineGuestOsIdentifierFedora64Guest = VirtualMachineGuestOsIdentifier("fedora64Guest")
VirtualMachineGuestOsIdentifierCoreos64Guest = VirtualMachineGuestOsIdentifier("coreos64Guest")
VirtualMachineGuestOsIdentifierVmwarePhoton64Guest = VirtualMachineGuestOsIdentifier("vmwarePhoton64Guest")
VirtualMachineGuestOsIdentifierOther24xLinuxGuest = VirtualMachineGuestOsIdentifier("other24xLinuxGuest")
VirtualMachineGuestOsIdentifierOther26xLinuxGuest = VirtualMachineGuestOsIdentifier("other26xLinuxGuest")
VirtualMachineGuestOsIdentifierOtherLinuxGuest = VirtualMachineGuestOsIdentifier("otherLinuxGuest")
@ -3490,9 +3829,12 @@ const (
VirtualMachineGuestOsIdentifierDarwin12_64Guest = VirtualMachineGuestOsIdentifier("darwin12_64Guest")
VirtualMachineGuestOsIdentifierDarwin13_64Guest = VirtualMachineGuestOsIdentifier("darwin13_64Guest")
VirtualMachineGuestOsIdentifierDarwin14_64Guest = VirtualMachineGuestOsIdentifier("darwin14_64Guest")
VirtualMachineGuestOsIdentifierDarwin15_64Guest = VirtualMachineGuestOsIdentifier("darwin15_64Guest")
VirtualMachineGuestOsIdentifierDarwin16_64Guest = VirtualMachineGuestOsIdentifier("darwin16_64Guest")
VirtualMachineGuestOsIdentifierVmkernelGuest = VirtualMachineGuestOsIdentifier("vmkernelGuest")
VirtualMachineGuestOsIdentifierVmkernel5Guest = VirtualMachineGuestOsIdentifier("vmkernel5Guest")
VirtualMachineGuestOsIdentifierVmkernel6Guest = VirtualMachineGuestOsIdentifier("vmkernel6Guest")
VirtualMachineGuestOsIdentifierVmkernel65Guest = VirtualMachineGuestOsIdentifier("vmkernel65Guest")
VirtualMachineGuestOsIdentifierOtherGuest = VirtualMachineGuestOsIdentifier("otherGuest")
VirtualMachineGuestOsIdentifierOtherGuest64 = VirtualMachineGuestOsIdentifier("otherGuest64")
)
@ -3719,6 +4061,20 @@ func init() {
t["VirtualMachineTicketType"] = reflect.TypeOf((*VirtualMachineTicketType)(nil)).Elem()
}
type VirtualMachineToolsInstallType string
const (
VirtualMachineToolsInstallTypeGuestToolsTypeUnknown = VirtualMachineToolsInstallType("guestToolsTypeUnknown")
VirtualMachineToolsInstallTypeGuestToolsTypeMSI = VirtualMachineToolsInstallType("guestToolsTypeMSI")
VirtualMachineToolsInstallTypeGuestToolsTypeTar = VirtualMachineToolsInstallType("guestToolsTypeTar")
VirtualMachineToolsInstallTypeGuestToolsTypeOSP = VirtualMachineToolsInstallType("guestToolsTypeOSP")
VirtualMachineToolsInstallTypeGuestToolsTypeOpenVMTools = VirtualMachineToolsInstallType("guestToolsTypeOpenVMTools")
)
func init() {
t["VirtualMachineToolsInstallType"] = reflect.TypeOf((*VirtualMachineToolsInstallType)(nil)).Elem()
}
type VirtualMachineToolsRunningStatus string
const (
@ -3854,6 +4210,18 @@ func init() {
t["VirtualMachineVideoCardUse3dRenderer"] = reflect.TypeOf((*VirtualMachineVideoCardUse3dRenderer)(nil)).Elem()
}
type VirtualMachineWindowsQuiesceSpecVssBackupContext string
const (
VirtualMachineWindowsQuiesceSpecVssBackupContextCtx_auto = VirtualMachineWindowsQuiesceSpecVssBackupContext("ctx_auto")
VirtualMachineWindowsQuiesceSpecVssBackupContextCtx_backup = VirtualMachineWindowsQuiesceSpecVssBackupContext("ctx_backup")
VirtualMachineWindowsQuiesceSpecVssBackupContextCtx_file_share_backup = VirtualMachineWindowsQuiesceSpecVssBackupContext("ctx_file_share_backup")
)
func init() {
t["VirtualMachineWindowsQuiesceSpecVssBackupContext"] = reflect.TypeOf((*VirtualMachineWindowsQuiesceSpecVssBackupContext)(nil)).Elem()
}
type VirtualPointingDeviceHostChoice string
const (

View File

@ -118,6 +118,40 @@ func init() {
t["BaseAuthorizationEvent"] = reflect.TypeOf((*AuthorizationEvent)(nil)).Elem()
}
func (b *BaseConfigInfo) GetBaseConfigInfo() *BaseConfigInfo { return b }
type BaseBaseConfigInfo interface {
GetBaseConfigInfo() *BaseConfigInfo
}
func init() {
t["BaseBaseConfigInfo"] = reflect.TypeOf((*BaseConfigInfo)(nil)).Elem()
}
func (b *BaseConfigInfoBackingInfo) GetBaseConfigInfoBackingInfo() *BaseConfigInfoBackingInfo {
return b
}
type BaseBaseConfigInfoBackingInfo interface {
GetBaseConfigInfoBackingInfo() *BaseConfigInfoBackingInfo
}
func init() {
t["BaseBaseConfigInfoBackingInfo"] = reflect.TypeOf((*BaseConfigInfoBackingInfo)(nil)).Elem()
}
func (b *BaseConfigInfoFileBackingInfo) GetBaseConfigInfoFileBackingInfo() *BaseConfigInfoFileBackingInfo {
return b
}
type BaseBaseConfigInfoFileBackingInfo interface {
GetBaseConfigInfoFileBackingInfo() *BaseConfigInfoFileBackingInfo
}
func init() {
t["BaseBaseConfigInfoFileBackingInfo"] = reflect.TypeOf((*BaseConfigInfoFileBackingInfo)(nil)).Elem()
}
func (b *CannotAccessNetwork) GetCannotAccessNetwork() *CannotAccessNetwork { return b }
type BaseCannotAccessNetwork interface {
@ -376,6 +410,26 @@ func init() {
t["BaseCpuIncompatible"] = reflect.TypeOf((*CpuIncompatible)(nil)).Elem()
}
func (b *CryptoSpec) GetCryptoSpec() *CryptoSpec { return b }
type BaseCryptoSpec interface {
GetCryptoSpec() *CryptoSpec
}
func init() {
t["BaseCryptoSpec"] = reflect.TypeOf((*CryptoSpec)(nil)).Elem()
}
func (b *CryptoSpecNoOp) GetCryptoSpecNoOp() *CryptoSpecNoOp { return b }
type BaseCryptoSpecNoOp interface {
GetCryptoSpecNoOp() *CryptoSpecNoOp
}
func init() {
t["BaseCryptoSpecNoOp"] = reflect.TypeOf((*CryptoSpecNoOp)(nil)).Elem()
}
func (b *CustomFieldDefEvent) GetCustomFieldDefEvent() *CustomFieldDefEvent { return b }
type BaseCustomFieldDefEvent interface {
@ -1388,6 +1442,28 @@ func init() {
t["BaseHostProfileConfigSpec"] = reflect.TypeOf((*HostProfileConfigSpec)(nil)).Elem()
}
func (b *HostProfilesEntityCustomizations) GetHostProfilesEntityCustomizations() *HostProfilesEntityCustomizations {
return b
}
type BaseHostProfilesEntityCustomizations interface {
GetHostProfilesEntityCustomizations() *HostProfilesEntityCustomizations
}
func init() {
t["BaseHostProfilesEntityCustomizations"] = reflect.TypeOf((*HostProfilesEntityCustomizations)(nil)).Elem()
}
func (b *HostSriovDevicePoolInfo) GetHostSriovDevicePoolInfo() *HostSriovDevicePoolInfo { return b }
type BaseHostSriovDevicePoolInfo interface {
GetHostSriovDevicePoolInfo() *HostSriovDevicePoolInfo
}
func init() {
t["BaseHostSriovDevicePoolInfo"] = reflect.TypeOf((*HostSriovDevicePoolInfo)(nil)).Elem()
}
func (b *HostSystemSwapConfigurationSystemSwapOption) GetHostSystemSwapConfigurationSystemSwapOption() *HostSystemSwapConfigurationSystemSwapOption {
return b
}
@ -1798,6 +1874,26 @@ func init() {
t["BaseNoPermission"] = reflect.TypeOf((*NoPermission)(nil)).Elem()
}
func (b *NodeDeploymentSpec) GetNodeDeploymentSpec() *NodeDeploymentSpec { return b }
type BaseNodeDeploymentSpec interface {
GetNodeDeploymentSpec() *NodeDeploymentSpec
}
func init() {
t["BaseNodeDeploymentSpec"] = reflect.TypeOf((*NodeDeploymentSpec)(nil)).Elem()
}
func (b *NodeNetworkSpec) GetNodeNetworkSpec() *NodeNetworkSpec { return b }
type BaseNodeNetworkSpec interface {
GetNodeNetworkSpec() *NodeNetworkSpec
}
func init() {
t["BaseNodeNetworkSpec"] = reflect.TypeOf((*NodeNetworkSpec)(nil)).Elem()
}
func (b *NotEnoughCpus) GetNotEnoughCpus() *NotEnoughCpus { return b }
type BaseNotEnoughCpus interface {
@ -2170,6 +2266,16 @@ func init() {
t["BaseProfileEvent"] = reflect.TypeOf((*ProfileEvent)(nil)).Elem()
}
func (b *ProfileExecuteResult) GetProfileExecuteResult() *ProfileExecuteResult { return b }
type BaseProfileExecuteResult interface {
GetProfileExecuteResult() *ProfileExecuteResult
}
func init() {
t["BaseProfileExecuteResult"] = reflect.TypeOf((*ProfileExecuteResult)(nil)).Elem()
}
func (b *ProfileExpression) GetProfileExpression() *ProfileExpression { return b }
type BaseProfileExpression interface {
@ -2896,6 +3002,18 @@ func init() {
t["BaseVirtualMachineDiskDeviceInfo"] = reflect.TypeOf((*VirtualMachineDiskDeviceInfo)(nil)).Elem()
}
func (b *VirtualMachineGuestQuiesceSpec) GetVirtualMachineGuestQuiesceSpec() *VirtualMachineGuestQuiesceSpec {
return b
}
type BaseVirtualMachineGuestQuiesceSpec interface {
GetVirtualMachineGuestQuiesceSpec() *VirtualMachineGuestQuiesceSpec
}
func init() {
t["BaseVirtualMachineGuestQuiesceSpec"] = reflect.TypeOf((*VirtualMachineGuestQuiesceSpec)(nil)).Elem()
}
func (b *VirtualMachinePciPassthroughInfo) GetVirtualMachinePciPassthroughInfo() *VirtualMachinePciPassthroughInfo {
return b
}
@ -2920,6 +3038,18 @@ func init() {
t["BaseVirtualMachineProfileSpec"] = reflect.TypeOf((*VirtualMachineProfileSpec)(nil)).Elem()
}
func (b *VirtualMachineSriovDevicePoolInfo) GetVirtualMachineSriovDevicePoolInfo() *VirtualMachineSriovDevicePoolInfo {
return b
}
type BaseVirtualMachineSriovDevicePoolInfo interface {
GetVirtualMachineSriovDevicePoolInfo() *VirtualMachineSriovDevicePoolInfo
}
func init() {
t["BaseVirtualMachineSriovDevicePoolInfo"] = reflect.TypeOf((*VirtualMachineSriovDevicePoolInfo)(nil)).Elem()
}
func (b *VirtualMachineTargetInfo) GetVirtualMachineTargetInfo() *VirtualMachineTargetInfo { return b }
type BaseVirtualMachineTargetInfo interface {
@ -3028,6 +3158,26 @@ func init() {
t["BaseVirtualVmxnet"] = reflect.TypeOf((*VirtualVmxnet)(nil)).Elem()
}
func (b *VirtualVmxnet3) GetVirtualVmxnet3() *VirtualVmxnet3 { return b }
type BaseVirtualVmxnet3 interface {
GetVirtualVmxnet3() *VirtualVmxnet3
}
func init() {
t["BaseVirtualVmxnet3"] = reflect.TypeOf((*VirtualVmxnet3)(nil)).Elem()
}
func (b *VirtualVmxnet3Option) GetVirtualVmxnet3Option() *VirtualVmxnet3Option { return b }
type BaseVirtualVmxnet3Option interface {
GetVirtualVmxnet3Option() *VirtualVmxnet3Option
}
func init() {
t["BaseVirtualVmxnet3Option"] = reflect.TypeOf((*VirtualVmxnet3Option)(nil)).Elem()
}
func (b *VirtualVmxnetOption) GetVirtualVmxnetOption() *VirtualVmxnetOption { return b }
type BaseVirtualVmxnetOption interface {
@ -3285,3 +3435,25 @@ type BaseVsanUpgradeSystemUpgradeHistoryItem interface {
func init() {
t["BaseVsanUpgradeSystemUpgradeHistoryItem"] = reflect.TypeOf((*VsanUpgradeSystemUpgradeHistoryItem)(nil)).Elem()
}
func (b *VslmCreateSpecBackingSpec) GetVslmCreateSpecBackingSpec() *VslmCreateSpecBackingSpec {
return b
}
type BaseVslmCreateSpecBackingSpec interface {
GetVslmCreateSpecBackingSpec() *VslmCreateSpecBackingSpec
}
func init() {
t["BaseVslmCreateSpecBackingSpec"] = reflect.TypeOf((*VslmCreateSpecBackingSpec)(nil)).Elem()
}
func (b *VslmMigrateSpec) GetVslmMigrateSpec() *VslmMigrateSpec { return b }
type BaseVslmMigrateSpec interface {
GetVslmMigrateSpec() *VslmMigrateSpec
}
func init() {
t["BaseVslmMigrateSpec"] = reflect.TypeOf((*VslmMigrateSpec)(nil)).Elem()
}

View File

@ -237,6 +237,10 @@ type RetrieveManagedMethodExecuter struct {
This ManagedObjectReference `xml:"_this"`
}
func init() {
t["RetrieveManagedMethodExecuter"] = reflect.TypeOf((*RetrieveManagedMethodExecuter)(nil)).Elem()
}
type RetrieveManagedMethodExecuterResponse struct {
Returnval *ReflectManagedMethodExecuter `xml:"urn:vim25 returnval"`
}

File diff suppressed because it is too large Load Diff

View File

@ -71,7 +71,11 @@ func typeToString(typ reflect.Type) string {
case reflect.Float64:
return "xsd:double"
case reflect.String:
return "xsd:string"
name := typ.Name()
if name == "string" {
return "xsd:string"
}
return name
case reflect.Struct:
if typ == stringToTypeMap["xsd:dateTime"] {
return "xsd:dateTime"