mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-20 18:31:15 +00:00
godep: update vmware/govmomi
This commit is contained in:
parent
f821a54d39
commit
5c27b98ce0
88
Godeps/Godeps.json
generated
88
Godeps/Godeps.json
generated
@ -2644,113 +2644,113 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi",
|
||||
"Comment": "v0.16.0-5-g5f0f400",
|
||||
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
|
||||
"Comment": "v0.16.0-80-g8174315",
|
||||
"Rev": "81743157fb5ccf548d6bd5088c25ee6156a359ee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/find",
|
||||
"Comment": "v0.16.0-5-g5f0f400",
|
||||
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
|
||||
"Comment": "v0.16.0-80-g8174315",
|
||||
"Rev": "81743157fb5ccf548d6bd5088c25ee6156a359ee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/list",
|
||||
"Comment": "v0.16.0-5-g5f0f400",
|
||||
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
|
||||
"Comment": "v0.16.0-80-g8174315",
|
||||
"Rev": "81743157fb5ccf548d6bd5088c25ee6156a359ee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/nfc",
|
||||
"Comment": "v0.16.0-5-g5f0f400",
|
||||
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
|
||||
"Comment": "v0.16.0-80-g8174315",
|
||||
"Rev": "81743157fb5ccf548d6bd5088c25ee6156a359ee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/object",
|
||||
"Comment": "v0.16.0-5-g5f0f400",
|
||||
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
|
||||
"Comment": "v0.16.0-80-g8174315",
|
||||
"Rev": "81743157fb5ccf548d6bd5088c25ee6156a359ee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/pbm",
|
||||
"Comment": "v0.16.0-5-g5f0f400",
|
||||
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
|
||||
"Comment": "v0.16.0-80-g8174315",
|
||||
"Rev": "81743157fb5ccf548d6bd5088c25ee6156a359ee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/pbm/methods",
|
||||
"Comment": "v0.16.0-5-g5f0f400",
|
||||
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
|
||||
"Comment": "v0.16.0-80-g8174315",
|
||||
"Rev": "81743157fb5ccf548d6bd5088c25ee6156a359ee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/pbm/types",
|
||||
"Comment": "v0.16.0-5-g5f0f400",
|
||||
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
|
||||
"Comment": "v0.16.0-80-g8174315",
|
||||
"Rev": "81743157fb5ccf548d6bd5088c25ee6156a359ee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/property",
|
||||
"Comment": "v0.16.0-5-g5f0f400",
|
||||
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
|
||||
"Comment": "v0.16.0-80-g8174315",
|
||||
"Rev": "81743157fb5ccf548d6bd5088c25ee6156a359ee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/session",
|
||||
"Comment": "v0.16.0-5-g5f0f400",
|
||||
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
|
||||
"Comment": "v0.16.0-80-g8174315",
|
||||
"Rev": "81743157fb5ccf548d6bd5088c25ee6156a359ee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/simulator",
|
||||
"Comment": "v0.16.0-5-g5f0f400",
|
||||
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
|
||||
"Comment": "v0.16.0-80-g8174315",
|
||||
"Rev": "81743157fb5ccf548d6bd5088c25ee6156a359ee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/simulator/esx",
|
||||
"Comment": "v0.16.0-5-g5f0f400",
|
||||
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
|
||||
"Comment": "v0.16.0-80-g8174315",
|
||||
"Rev": "81743157fb5ccf548d6bd5088c25ee6156a359ee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/simulator/vpx",
|
||||
"Comment": "v0.16.0-5-g5f0f400",
|
||||
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
|
||||
"Comment": "v0.16.0-80-g8174315",
|
||||
"Rev": "81743157fb5ccf548d6bd5088c25ee6156a359ee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/task",
|
||||
"Comment": "v0.16.0-5-g5f0f400",
|
||||
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
|
||||
"Comment": "v0.16.0-80-g8174315",
|
||||
"Rev": "81743157fb5ccf548d6bd5088c25ee6156a359ee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/vim25",
|
||||
"Comment": "v0.16.0-5-g5f0f400",
|
||||
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
|
||||
"Comment": "v0.16.0-80-g8174315",
|
||||
"Rev": "81743157fb5ccf548d6bd5088c25ee6156a359ee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/vim25/debug",
|
||||
"Comment": "v0.16.0-5-g5f0f400",
|
||||
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
|
||||
"Comment": "v0.16.0-80-g8174315",
|
||||
"Rev": "81743157fb5ccf548d6bd5088c25ee6156a359ee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/vim25/methods",
|
||||
"Comment": "v0.16.0-5-g5f0f400",
|
||||
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
|
||||
"Comment": "v0.16.0-80-g8174315",
|
||||
"Rev": "81743157fb5ccf548d6bd5088c25ee6156a359ee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/vim25/mo",
|
||||
"Comment": "v0.16.0-5-g5f0f400",
|
||||
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
|
||||
"Comment": "v0.16.0-80-g8174315",
|
||||
"Rev": "81743157fb5ccf548d6bd5088c25ee6156a359ee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/vim25/progress",
|
||||
"Comment": "v0.16.0-5-g5f0f400",
|
||||
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
|
||||
"Comment": "v0.16.0-80-g8174315",
|
||||
"Rev": "81743157fb5ccf548d6bd5088c25ee6156a359ee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/vim25/soap",
|
||||
"Comment": "v0.16.0-5-g5f0f400",
|
||||
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
|
||||
"Comment": "v0.16.0-80-g8174315",
|
||||
"Rev": "81743157fb5ccf548d6bd5088c25ee6156a359ee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/vim25/types",
|
||||
"Comment": "v0.16.0-5-g5f0f400",
|
||||
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
|
||||
"Comment": "v0.16.0-80-g8174315",
|
||||
"Rev": "81743157fb5ccf548d6bd5088c25ee6156a359ee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/govmomi/vim25/xml",
|
||||
"Comment": "v0.16.0-5-g5f0f400",
|
||||
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
|
||||
"Comment": "v0.16.0-80-g8174315",
|
||||
"Rev": "81743157fb5ccf548d6bd5088c25ee6156a359ee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vmware/photon-controller-go-sdk/SSPI",
|
||||
|
2
vendor/github.com/vmware/govmomi/Makefile
generated
vendored
2
vendor/github.com/vmware/govmomi/Makefile
generated
vendored
@ -18,7 +18,7 @@ install:
|
||||
go install -v github.com/vmware/govmomi/vcsim
|
||||
|
||||
go-test:
|
||||
go test -v $(TEST_OPTS) ./...
|
||||
go test -race -v $(TEST_OPTS) ./...
|
||||
|
||||
govc-test: install
|
||||
(cd govc/test && ./vendor/github.com/sstephenson/bats/libexec/bats -t .)
|
||||
|
21
vendor/github.com/vmware/govmomi/find/finder.go
generated
vendored
21
vendor/github.com/vmware/govmomi/find/finder.go
generated
vendored
@ -625,6 +625,15 @@ func (f *Finder) ClusterComputeResourceList(ctx context.Context, path string) ([
|
||||
return ccrs, nil
|
||||
}
|
||||
|
||||
func (f *Finder) DefaultClusterComputeResource(ctx context.Context) (*object.ClusterComputeResource, error) {
|
||||
cr, err := f.ClusterComputeResource(ctx, "*")
|
||||
if err != nil {
|
||||
return nil, toDefaultError(err)
|
||||
}
|
||||
|
||||
return cr, nil
|
||||
}
|
||||
|
||||
func (f *Finder) ClusterComputeResource(ctx context.Context, path string) (*object.ClusterComputeResource, error) {
|
||||
ccrs, err := f.ClusterComputeResourceList(ctx, path)
|
||||
if err != nil {
|
||||
@ -638,6 +647,18 @@ func (f *Finder) ClusterComputeResource(ctx context.Context, path string) (*obje
|
||||
return ccrs[0], nil
|
||||
}
|
||||
|
||||
func (f *Finder) ClusterComputeResourceOrDefault(ctx context.Context, path string) (*object.ClusterComputeResource, error) {
|
||||
if path != "" {
|
||||
cr, err := f.ClusterComputeResource(ctx, path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return cr, nil
|
||||
}
|
||||
|
||||
return f.DefaultClusterComputeResource(ctx)
|
||||
}
|
||||
|
||||
func (f *Finder) HostSystemList(ctx context.Context, path string) ([]*object.HostSystem, error) {
|
||||
s := &spec{
|
||||
Relative: f.hostFolder,
|
||||
|
4
vendor/github.com/vmware/govmomi/nfc/lease.go
generated
vendored
4
vendor/github.com/vmware/govmomi/nfc/lease.go
generated
vendored
@ -224,7 +224,7 @@ func (l *Lease) Upload(ctx context.Context, item FileItem, f io.Reader, opts soa
|
||||
opts.Type = "application/x-vnd.vmware-streamVmdk"
|
||||
}
|
||||
|
||||
return l.c.Upload(f, item.URL, &opts)
|
||||
return l.c.Upload(ctx, f, item.URL, &opts)
|
||||
}
|
||||
|
||||
func (l *Lease) DownloadFile(ctx context.Context, file string, item FileItem, opts soap.Download) error {
|
||||
@ -234,5 +234,5 @@ func (l *Lease) DownloadFile(ctx context.Context, file string, item FileItem, op
|
||||
opts.Progress = progress.Tee(item, opts.Progress)
|
||||
}
|
||||
|
||||
return l.c.DownloadFile(file, item.URL, &opts)
|
||||
return l.c.DownloadFile(ctx, file, item.URL, &opts)
|
||||
}
|
||||
|
26
vendor/github.com/vmware/govmomi/object/cluster_compute_resource.go
generated
vendored
26
vendor/github.com/vmware/govmomi/object/cluster_compute_resource.go
generated
vendored
@ -21,6 +21,7 @@ import (
|
||||
|
||||
"github.com/vmware/govmomi/vim25"
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
@ -34,19 +35,15 @@ func NewClusterComputeResource(c *vim25.Client, ref types.ManagedObjectReference
|
||||
}
|
||||
}
|
||||
|
||||
func (c ClusterComputeResource) ReconfigureCluster(ctx context.Context, spec types.ClusterConfigSpec) (*Task, error) {
|
||||
req := types.ReconfigureCluster_Task{
|
||||
This: c.Reference(),
|
||||
Spec: spec,
|
||||
Modify: true,
|
||||
}
|
||||
func (c ClusterComputeResource) Configuration(ctx context.Context) (*types.ClusterConfigInfoEx, error) {
|
||||
var obj mo.ClusterComputeResource
|
||||
|
||||
res, err := methods.ReconfigureCluster_Task(ctx, c.c, &req)
|
||||
err := c.Properties(ctx, c.Reference(), []string{"configurationEx"}, &obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewTask(c.c, res.Returnval), nil
|
||||
return obj.ConfigurationEx.(*types.ClusterConfigInfoEx), nil
|
||||
}
|
||||
|
||||
func (c ClusterComputeResource) AddHost(ctx context.Context, spec types.HostConnectSpec, asConnected bool, license *string, resourcePool *types.ManagedObjectReference) (*Task, error) {
|
||||
@ -71,16 +68,3 @@ func (c ClusterComputeResource) AddHost(ctx context.Context, spec types.HostConn
|
||||
|
||||
return NewTask(c.c, res.Returnval), nil
|
||||
}
|
||||
|
||||
func (c ClusterComputeResource) Destroy(ctx context.Context) (*Task, error) {
|
||||
req := types.Destroy_Task{
|
||||
This: c.Reference(),
|
||||
}
|
||||
|
||||
res, err := methods.Destroy_Task(ctx, c.c, &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewTask(c.c, res.Returnval), nil
|
||||
}
|
||||
|
13
vendor/github.com/vmware/govmomi/object/compute_resource.go
generated
vendored
13
vendor/github.com/vmware/govmomi/object/compute_resource.go
generated
vendored
@ -109,16 +109,3 @@ func (c ComputeResource) Reconfigure(ctx context.Context, spec types.BaseCompute
|
||||
|
||||
return NewTask(c.c, res.Returnval), nil
|
||||
}
|
||||
|
||||
func (c ComputeResource) Destroy(ctx context.Context) (*Task, error) {
|
||||
req := types.Destroy_Task{
|
||||
This: c.Reference(),
|
||||
}
|
||||
|
||||
res, err := methods.Destroy_Task(ctx, c.c, &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewTask(c.c, res.Returnval), nil
|
||||
}
|
||||
|
17
vendor/github.com/vmware/govmomi/object/datastore.go
generated
vendored
17
vendor/github.com/vmware/govmomi/object/datastore.go
generated
vendored
@ -284,7 +284,7 @@ func (d Datastore) Upload(ctx context.Context, f io.Reader, path string, param *
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return d.Client().Upload(f, u, p)
|
||||
return d.Client().Upload(ctx, f, u, p)
|
||||
}
|
||||
|
||||
// UploadFile via soap.Upload with an http service ticket
|
||||
@ -293,7 +293,7 @@ func (d Datastore) UploadFile(ctx context.Context, file string, path string, par
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return d.Client().UploadFile(file, u, p)
|
||||
return d.Client().UploadFile(ctx, file, u, p)
|
||||
}
|
||||
|
||||
// Download via soap.Download with an http service ticket
|
||||
@ -302,7 +302,7 @@ func (d Datastore) Download(ctx context.Context, path string, param *soap.Downlo
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return d.Client().Download(u, p)
|
||||
return d.Client().Download(ctx, u, p)
|
||||
}
|
||||
|
||||
// DownloadFile via soap.Download with an http service ticket
|
||||
@ -311,7 +311,7 @@ func (d Datastore) DownloadFile(ctx context.Context, path string, file string, p
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return d.Client().DownloadFile(file, u, p)
|
||||
return d.Client().DownloadFile(ctx, file, u, p)
|
||||
}
|
||||
|
||||
// AttachedHosts returns hosts that have this Datastore attached, accessible and writable.
|
||||
@ -406,12 +406,9 @@ func (d Datastore) Stat(ctx context.Context, file string) (types.BaseFileInfo, e
|
||||
|
||||
info, err := task.WaitForResult(ctx, nil)
|
||||
if err != nil {
|
||||
if info == nil || info.Error != nil {
|
||||
_, ok := info.Error.Fault.(*types.FileNotFound)
|
||||
if ok {
|
||||
// FileNotFound means the base path doesn't exist.
|
||||
return nil, DatastoreNoSuchDirectoryError{"stat", dsPath}
|
||||
}
|
||||
if types.IsFileNotFound(err) {
|
||||
// FileNotFound means the base path doesn't exist.
|
||||
return nil, DatastoreNoSuchDirectoryError{"stat", dsPath}
|
||||
}
|
||||
|
||||
return nil, err
|
||||
|
4
vendor/github.com/vmware/govmomi/object/datastore_file.go
generated
vendored
4
vendor/github.com/vmware/govmomi/object/datastore_file.go
generated
vendored
@ -172,7 +172,7 @@ func (f *DatastoreFile) Stat() (os.FileInfo, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res, err := f.d.Client().DownloadRequest(u, p)
|
||||
res, err := f.d.Client().DownloadRequest(f.ctx, u, p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -202,7 +202,7 @@ func (f *DatastoreFile) get() (io.Reader, error) {
|
||||
}
|
||||
}
|
||||
|
||||
res, err := f.d.Client().DownloadRequest(u, p)
|
||||
res, err := f.d.Client().DownloadRequest(f.ctx, u, p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
20
vendor/github.com/vmware/govmomi/object/host_storage_system.go
generated
vendored
20
vendor/github.com/vmware/govmomi/object/host_storage_system.go
generated
vendored
@ -97,6 +97,15 @@ func (s HostStorageSystem) Refresh(ctx context.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (s HostStorageSystem) RescanVmfs(ctx context.Context) error {
|
||||
req := types.RescanVmfs{
|
||||
This: s.Reference(),
|
||||
}
|
||||
|
||||
_, err := methods.RescanVmfs(ctx, s.c, &req)
|
||||
return err
|
||||
}
|
||||
|
||||
func (s HostStorageSystem) MarkAsSsd(ctx context.Context, uuid string) (*Task, error) {
|
||||
req := types.MarkAsSsd_Task{
|
||||
This: s.Reference(),
|
||||
@ -152,3 +161,14 @@ func (s HostStorageSystem) MarkAsNonLocal(ctx context.Context, uuid string) (*Ta
|
||||
|
||||
return NewTask(s.c, res.Returnval), nil
|
||||
}
|
||||
|
||||
func (s HostStorageSystem) AttachScsiLun(ctx context.Context, uuid string) error {
|
||||
req := types.AttachScsiLun{
|
||||
This: s.Reference(),
|
||||
LunUuid: uuid,
|
||||
}
|
||||
|
||||
_, err := methods.AttachScsiLun(ctx, s.c, &req)
|
||||
|
||||
return err
|
||||
}
|
||||
|
41
vendor/github.com/vmware/govmomi/object/virtual_disk_manager.go
generated
vendored
41
vendor/github.com/vmware/govmomi/object/virtual_disk_manager.go
generated
vendored
@ -145,6 +145,47 @@ func (m VirtualDiskManager) DeleteVirtualDisk(ctx context.Context, name string,
|
||||
return NewTask(m.c, res.Returnval), nil
|
||||
}
|
||||
|
||||
// InflateVirtualDisk inflates a virtual disk.
|
||||
func (m VirtualDiskManager) InflateVirtualDisk(ctx context.Context, name string, dc *Datacenter) (*Task, error) {
|
||||
req := types.InflateVirtualDisk_Task{
|
||||
This: m.Reference(),
|
||||
Name: name,
|
||||
}
|
||||
|
||||
if dc != nil {
|
||||
ref := dc.Reference()
|
||||
req.Datacenter = &ref
|
||||
}
|
||||
|
||||
res, err := methods.InflateVirtualDisk_Task(ctx, m.c, &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewTask(m.c, res.Returnval), nil
|
||||
}
|
||||
|
||||
// ShrinkVirtualDisk shrinks a virtual disk.
|
||||
func (m VirtualDiskManager) ShrinkVirtualDisk(ctx context.Context, name string, dc *Datacenter, copy *bool) (*Task, error) {
|
||||
req := types.ShrinkVirtualDisk_Task{
|
||||
This: m.Reference(),
|
||||
Name: name,
|
||||
Copy: copy,
|
||||
}
|
||||
|
||||
if dc != nil {
|
||||
ref := dc.Reference()
|
||||
req.Datacenter = &ref
|
||||
}
|
||||
|
||||
res, err := methods.ShrinkVirtualDisk_Task(ctx, m.c, &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewTask(m.c, res.Returnval), nil
|
||||
}
|
||||
|
||||
// Queries virtual disk uuid
|
||||
func (m VirtualDiskManager) QueryVirtualDiskUuid(ctx context.Context, name string, dc *Datacenter) (string, error) {
|
||||
req := types.QueryVirtualDiskUuid{
|
||||
|
64
vendor/github.com/vmware/govmomi/object/virtual_disk_manager_internal.go
generated
vendored
64
vendor/github.com/vmware/govmomi/object/virtual_disk_manager_internal.go
generated
vendored
@ -95,3 +95,67 @@ func (m VirtualDiskManager) QueryVirtualDiskInfo(ctx context.Context, name strin
|
||||
|
||||
return info.Result.(arrayOfVirtualDiskInfo).VirtualDiskInfo, nil
|
||||
}
|
||||
|
||||
type createChildDiskTaskRequest struct {
|
||||
This types.ManagedObjectReference `xml:"_this"`
|
||||
ChildName string `xml:"childName"`
|
||||
ChildDatacenter *types.ManagedObjectReference `xml:"childDatacenter,omitempty"`
|
||||
ParentName string `xml:"parentName"`
|
||||
ParentDatacenter *types.ManagedObjectReference `xml:"parentDatacenter,omitempty"`
|
||||
IsLinkedClone bool `xml:"isLinkedClone"`
|
||||
}
|
||||
|
||||
type createChildDiskTaskResponse struct {
|
||||
Returnval types.ManagedObjectReference `xml:"returnval"`
|
||||
}
|
||||
|
||||
type createChildDiskTaskBody struct {
|
||||
Req *createChildDiskTaskRequest `xml:"urn:internalvim25 CreateChildDisk_Task,omitempty"`
|
||||
Res *createChildDiskTaskResponse `xml:"urn:vim25 CreateChildDisk_TaskResponse,omitempty"`
|
||||
InternalRes *createChildDiskTaskResponse `xml:"urn:internalvim25 CreateChildDisk_TaskResponse,omitempty"`
|
||||
Err *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *createChildDiskTaskBody) Fault() *soap.Fault { return b.Err }
|
||||
|
||||
func createChildDiskTask(ctx context.Context, r soap.RoundTripper, req *createChildDiskTaskRequest) (*createChildDiskTaskResponse, error) {
|
||||
var reqBody, resBody createChildDiskTaskBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resBody.Res != nil {
|
||||
return resBody.Res, nil // vim-version <= 6.5
|
||||
}
|
||||
|
||||
return resBody.InternalRes, nil // vim-version >= 6.7
|
||||
}
|
||||
|
||||
func (m VirtualDiskManager) CreateChildDisk(ctx context.Context, parent string, pdc *Datacenter, name string, dc *Datacenter, linked bool) (*Task, error) {
|
||||
req := createChildDiskTaskRequest{
|
||||
This: m.Reference(),
|
||||
ChildName: name,
|
||||
ParentName: parent,
|
||||
IsLinkedClone: linked,
|
||||
}
|
||||
|
||||
if dc != nil {
|
||||
ref := dc.Reference()
|
||||
req.ChildDatacenter = &ref
|
||||
}
|
||||
|
||||
if pdc != nil {
|
||||
ref := pdc.Reference()
|
||||
req.ParentDatacenter = &ref
|
||||
}
|
||||
|
||||
res, err := createChildDiskTask(ctx, m.Client(), &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewTask(m.Client(), res.Returnval), nil
|
||||
}
|
||||
|
4
vendor/github.com/vmware/govmomi/property/collector.go
generated
vendored
4
vendor/github.com/vmware/govmomi/property/collector.go
generated
vendored
@ -121,6 +121,10 @@ func (p *Collector) RetrieveProperties(ctx context.Context, req types.RetrievePr
|
||||
// of the specified managed objects, with the relevant properties filled in. If
|
||||
// the properties slice is nil, all properties are loaded.
|
||||
func (p *Collector) Retrieve(ctx context.Context, objs []types.ManagedObjectReference, ps []string, dst interface{}) error {
|
||||
if len(objs) == 0 {
|
||||
return errors.New("object references is empty")
|
||||
}
|
||||
|
||||
var propSpec *types.PropertySpec
|
||||
var objectSet []types.ObjectSpec
|
||||
|
||||
|
2
vendor/github.com/vmware/govmomi/simulator/BUILD
generated
vendored
2
vendor/github.com/vmware/govmomi/simulator/BUILD
generated
vendored
@ -11,12 +11,14 @@ go_library(
|
||||
"doc.go",
|
||||
"dvs.go",
|
||||
"entity.go",
|
||||
"event_manager.go",
|
||||
"file_manager.go",
|
||||
"folder.go",
|
||||
"guest_id.go",
|
||||
"host_datastore_browser.go",
|
||||
"host_datastore_system.go",
|
||||
"host_firewall_system.go",
|
||||
"host_local_account_manager.go",
|
||||
"host_network_system.go",
|
||||
"host_system.go",
|
||||
"ip_pool_manager.go",
|
||||
|
3
vendor/github.com/vmware/govmomi/simulator/authorization_manager.go
generated
vendored
3
vendor/github.com/vmware/govmomi/simulator/authorization_manager.go
generated
vendored
@ -39,7 +39,8 @@ type AuthorizationManager struct {
|
||||
func NewAuthorizationManager(ref types.ManagedObjectReference) object.Reference {
|
||||
m := &AuthorizationManager{}
|
||||
m.Self = ref
|
||||
m.RoleList = esx.RoleList
|
||||
m.RoleList = make([]types.AuthorizationRole, len(esx.RoleList))
|
||||
copy(m.RoleList, esx.RoleList)
|
||||
m.permissions = make(map[types.ManagedObjectReference][]types.Permission)
|
||||
|
||||
l := object.AuthorizationRoleList(m.RoleList)
|
||||
|
238
vendor/github.com/vmware/govmomi/simulator/cluster_compute_resource.go
generated
vendored
238
vendor/github.com/vmware/govmomi/simulator/cluster_compute_resource.go
generated
vendored
@ -17,6 +17,9 @@ limitations under the License.
|
||||
package simulator
|
||||
|
||||
import (
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/vmware/govmomi/simulator/esx"
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
@ -26,6 +29,8 @@ import (
|
||||
|
||||
type ClusterComputeResource struct {
|
||||
mo.ClusterComputeResource
|
||||
|
||||
ruleKey int32
|
||||
}
|
||||
|
||||
type addHost struct {
|
||||
@ -44,18 +49,18 @@ func (add *addHost) Run(task *Task) (types.AnyType, types.BaseMethodFault) {
|
||||
host := NewHostSystem(esx.HostSystem)
|
||||
host.Summary.Config.Name = spec.HostName
|
||||
host.Name = host.Summary.Config.Name
|
||||
host.Runtime.ConnectionState = types.HostSystemConnectionStateDisconnected
|
||||
if add.req.AsConnected {
|
||||
host.Runtime.ConnectionState = types.HostSystemConnectionStateConnected
|
||||
} else {
|
||||
host.Runtime.ConnectionState = types.HostSystemConnectionStateDisconnected
|
||||
}
|
||||
|
||||
cr := add.ClusterComputeResource
|
||||
Map.PutEntity(cr, Map.NewEntity(host))
|
||||
host.Summary.Host = &host.Self
|
||||
|
||||
cr.Host = append(cr.Host, host.Reference())
|
||||
|
||||
if add.req.AsConnected {
|
||||
host.Runtime.ConnectionState = types.HostSystemConnectionStateConnected
|
||||
}
|
||||
|
||||
addComputeResource(add.ClusterComputeResource.Summary.GetComputeResourceSummary(), host)
|
||||
addComputeResource(cr.Summary.GetComputeResourceSummary(), host)
|
||||
|
||||
return host.Reference(), nil
|
||||
}
|
||||
@ -68,6 +73,224 @@ func (c *ClusterComputeResource) AddHostTask(add *types.AddHost_Task) soap.HasFa
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ClusterComputeResource) updateRules(cfg *types.ClusterConfigInfoEx, cspec *types.ClusterConfigSpecEx) types.BaseMethodFault {
|
||||
for _, spec := range cspec.RulesSpec {
|
||||
var i int
|
||||
exists := false
|
||||
|
||||
match := func(info types.BaseClusterRuleInfo) bool {
|
||||
return info.GetClusterRuleInfo().Name == spec.Info.GetClusterRuleInfo().Name
|
||||
}
|
||||
|
||||
if spec.Operation == types.ArrayUpdateOperationRemove {
|
||||
match = func(rule types.BaseClusterRuleInfo) bool {
|
||||
return rule.GetClusterRuleInfo().Key == spec.ArrayUpdateSpec.RemoveKey.(int32)
|
||||
}
|
||||
}
|
||||
|
||||
for i = range cfg.Rule {
|
||||
if match(cfg.Rule[i].GetClusterRuleInfo()) {
|
||||
exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
switch spec.Operation {
|
||||
case types.ArrayUpdateOperationAdd:
|
||||
if exists {
|
||||
return new(types.InvalidArgument)
|
||||
}
|
||||
info := spec.Info.GetClusterRuleInfo()
|
||||
info.Key = atomic.AddInt32(&c.ruleKey, 1)
|
||||
info.RuleUuid = uuid.New().String()
|
||||
cfg.Rule = append(cfg.Rule, spec.Info)
|
||||
case types.ArrayUpdateOperationEdit:
|
||||
if !exists {
|
||||
return new(types.InvalidArgument)
|
||||
}
|
||||
cfg.Rule[i] = spec.Info
|
||||
case types.ArrayUpdateOperationRemove:
|
||||
if !exists {
|
||||
return new(types.InvalidArgument)
|
||||
}
|
||||
cfg.Rule = append(cfg.Rule[:i], cfg.Rule[i+1:]...)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ClusterComputeResource) updateGroups(cfg *types.ClusterConfigInfoEx, cspec *types.ClusterConfigSpecEx) types.BaseMethodFault {
|
||||
for _, spec := range cspec.GroupSpec {
|
||||
var i int
|
||||
exists := false
|
||||
|
||||
match := func(info types.BaseClusterGroupInfo) bool {
|
||||
return info.GetClusterGroupInfo().Name == spec.Info.GetClusterGroupInfo().Name
|
||||
}
|
||||
|
||||
if spec.Operation == types.ArrayUpdateOperationRemove {
|
||||
match = func(info types.BaseClusterGroupInfo) bool {
|
||||
return info.GetClusterGroupInfo().Name == spec.ArrayUpdateSpec.RemoveKey.(string)
|
||||
}
|
||||
}
|
||||
|
||||
for i = range cfg.Group {
|
||||
if match(cfg.Group[i].GetClusterGroupInfo()) {
|
||||
exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
switch spec.Operation {
|
||||
case types.ArrayUpdateOperationAdd:
|
||||
if exists {
|
||||
return new(types.InvalidArgument)
|
||||
}
|
||||
cfg.Group = append(cfg.Group, spec.Info)
|
||||
case types.ArrayUpdateOperationEdit:
|
||||
if !exists {
|
||||
return new(types.InvalidArgument)
|
||||
}
|
||||
cfg.Group[i] = spec.Info
|
||||
case types.ArrayUpdateOperationRemove:
|
||||
if !exists {
|
||||
return new(types.InvalidArgument)
|
||||
}
|
||||
cfg.Group = append(cfg.Group[:i], cfg.Group[i+1:]...)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ClusterComputeResource) updateOverridesDAS(cfg *types.ClusterConfigInfoEx, cspec *types.ClusterConfigSpecEx) types.BaseMethodFault {
|
||||
for _, spec := range cspec.DasVmConfigSpec {
|
||||
var i int
|
||||
var key types.ManagedObjectReference
|
||||
exists := false
|
||||
|
||||
if spec.Operation == types.ArrayUpdateOperationRemove {
|
||||
key = spec.RemoveKey.(types.ManagedObjectReference)
|
||||
} else {
|
||||
key = spec.Info.Key
|
||||
}
|
||||
|
||||
for i = range cfg.DasVmConfig {
|
||||
if cfg.DasVmConfig[i].Key == key {
|
||||
exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
switch spec.Operation {
|
||||
case types.ArrayUpdateOperationAdd:
|
||||
if exists {
|
||||
return new(types.InvalidArgument)
|
||||
}
|
||||
cfg.DasVmConfig = append(cfg.DasVmConfig, *spec.Info)
|
||||
case types.ArrayUpdateOperationEdit:
|
||||
if !exists {
|
||||
return new(types.InvalidArgument)
|
||||
}
|
||||
src := spec.Info.DasSettings
|
||||
if src == nil {
|
||||
return new(types.InvalidArgument)
|
||||
}
|
||||
dst := cfg.DasVmConfig[i].DasSettings
|
||||
if src.RestartPriority != "" {
|
||||
dst.RestartPriority = src.RestartPriority
|
||||
}
|
||||
if src.RestartPriorityTimeout != 0 {
|
||||
dst.RestartPriorityTimeout = src.RestartPriorityTimeout
|
||||
}
|
||||
case types.ArrayUpdateOperationRemove:
|
||||
if !exists {
|
||||
return new(types.InvalidArgument)
|
||||
}
|
||||
cfg.DasVmConfig = append(cfg.DasVmConfig[:i], cfg.DasVmConfig[i+1:]...)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ClusterComputeResource) updateOverridesDRS(cfg *types.ClusterConfigInfoEx, cspec *types.ClusterConfigSpecEx) types.BaseMethodFault {
|
||||
for _, spec := range cspec.DrsVmConfigSpec {
|
||||
var i int
|
||||
var key types.ManagedObjectReference
|
||||
exists := false
|
||||
|
||||
if spec.Operation == types.ArrayUpdateOperationRemove {
|
||||
key = spec.RemoveKey.(types.ManagedObjectReference)
|
||||
} else {
|
||||
key = spec.Info.Key
|
||||
}
|
||||
|
||||
for i = range cfg.DrsVmConfig {
|
||||
if cfg.DrsVmConfig[i].Key == key {
|
||||
exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
switch spec.Operation {
|
||||
case types.ArrayUpdateOperationAdd:
|
||||
if exists {
|
||||
return new(types.InvalidArgument)
|
||||
}
|
||||
cfg.DrsVmConfig = append(cfg.DrsVmConfig, *spec.Info)
|
||||
case types.ArrayUpdateOperationEdit:
|
||||
if !exists {
|
||||
return new(types.InvalidArgument)
|
||||
}
|
||||
if spec.Info.Enabled != nil {
|
||||
cfg.DrsVmConfig[i].Enabled = spec.Info.Enabled
|
||||
}
|
||||
if spec.Info.Behavior != "" {
|
||||
cfg.DrsVmConfig[i].Behavior = spec.Info.Behavior
|
||||
}
|
||||
case types.ArrayUpdateOperationRemove:
|
||||
if !exists {
|
||||
return new(types.InvalidArgument)
|
||||
}
|
||||
cfg.DrsVmConfig = append(cfg.DrsVmConfig[:i], cfg.DrsVmConfig[i+1:]...)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ClusterComputeResource) ReconfigureComputeResourceTask(req *types.ReconfigureComputeResource_Task) soap.HasFault {
|
||||
task := CreateTask(c, "reconfigureCluster", func(*Task) (types.AnyType, types.BaseMethodFault) {
|
||||
spec, ok := req.Spec.(*types.ClusterConfigSpecEx)
|
||||
if !ok {
|
||||
return nil, new(types.InvalidArgument)
|
||||
}
|
||||
|
||||
updates := []func(*types.ClusterConfigInfoEx, *types.ClusterConfigSpecEx) types.BaseMethodFault{
|
||||
c.updateRules,
|
||||
c.updateGroups,
|
||||
c.updateOverridesDAS,
|
||||
c.updateOverridesDRS,
|
||||
}
|
||||
|
||||
for _, update := range updates {
|
||||
if err := update(c.ConfigurationEx.(*types.ClusterConfigInfoEx), spec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
})
|
||||
|
||||
return &methods.ReconfigureComputeResource_TaskBody{
|
||||
Res: &types.ReconfigureComputeResource_TaskResponse{
|
||||
Returnval: task.Run(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func CreateClusterComputeResource(f *Folder, name string, spec types.ClusterConfigSpecEx) (*ClusterComputeResource, types.BaseMethodFault) {
|
||||
if e := Map.FindByName(name, f.ChildEntity); e != nil {
|
||||
return nil, &types.DuplicateName{
|
||||
@ -85,6 +308,7 @@ func CreateClusterComputeResource(f *Folder, name string, spec types.ClusterConf
|
||||
config := &types.ClusterConfigInfoEx{}
|
||||
cluster.ConfigurationEx = config
|
||||
|
||||
config.VmSwapPlacement = string(types.VirtualMachineConfigInfoSwapPlacementTypeVmDirectory)
|
||||
config.DrsConfig.Enabled = types.NewBool(true)
|
||||
|
||||
pool := NewResourcePool()
|
||||
|
8
vendor/github.com/vmware/govmomi/simulator/custom_fields_manager.go
generated
vendored
8
vendor/github.com/vmware/govmomi/simulator/custom_fields_manager.go
generated
vendored
@ -101,9 +101,11 @@ func (c *CustomFieldsManager) SetField(req *types.SetField) soap.HasFault {
|
||||
body := &methods.SetFieldBody{}
|
||||
|
||||
entity := Map.Get(req.Entity).(mo.Entity).Entity()
|
||||
entity.CustomValue = append(entity.CustomValue, &types.CustomFieldStringValue{
|
||||
CustomFieldValue: types.CustomFieldValue{Key: req.Key},
|
||||
Value: req.Value,
|
||||
Map.WithLock(entity, func() {
|
||||
entity.CustomValue = append(entity.CustomValue, &types.CustomFieldStringValue{
|
||||
CustomFieldValue: types.CustomFieldValue{Key: req.Key},
|
||||
Value: req.Value,
|
||||
})
|
||||
})
|
||||
|
||||
body.Res = &types.SetFieldResponse{}
|
||||
|
11
vendor/github.com/vmware/govmomi/simulator/datacenter.go
generated
vendored
11
vendor/github.com/vmware/govmomi/simulator/datacenter.go
generated
vendored
@ -74,3 +74,14 @@ func createDatacenterFolders(dc *mo.Datacenter, isVC bool) {
|
||||
net.putChild(network)
|
||||
}
|
||||
}
|
||||
|
||||
func datacenterEventArgument(obj mo.Entity) *types.DatacenterEventArgument {
|
||||
dc, ok := obj.(*mo.Datacenter)
|
||||
if !ok {
|
||||
dc = Map.getEntityDatacenter(obj)
|
||||
}
|
||||
return &types.DatacenterEventArgument{
|
||||
Datacenter: dc.Self,
|
||||
EntityEventArgument: types.EntityEventArgument{Name: dc.Name},
|
||||
}
|
||||
}
|
||||
|
15
vendor/github.com/vmware/govmomi/simulator/dvs.go
generated
vendored
15
vendor/github.com/vmware/govmomi/simulator/dvs.go
generated
vendored
@ -67,9 +67,10 @@ func (s *DistributedVirtualSwitch) AddDVPortgroupTask(c *types.AddDVPortgroup_Ta
|
||||
s.Summary.PortgroupName = append(s.Summary.PortgroupName, pg.Name)
|
||||
|
||||
for _, h := range s.Summary.HostMember {
|
||||
pg.Host = AddReference(h, pg.Host)
|
||||
pg.Host = append(pg.Host, h)
|
||||
|
||||
host := Map.Get(h).(*HostSystem)
|
||||
host.Network = append(host.Network, pg.Reference())
|
||||
Map.AppendReference(host, &host.Network, pg.Reference())
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,13 +102,13 @@ func (s *DistributedVirtualSwitch) ReconfigureDvsTask(req *types.ReconfigureDvs_
|
||||
return nil, &types.AlreadyExists{Name: host.Name}
|
||||
}
|
||||
|
||||
host.Network = append(host.Network, s.Self)
|
||||
host.Network = append(host.Network, s.Portgroup...)
|
||||
Map.AppendReference(host, &host.Network, s.Self)
|
||||
Map.AppendReference(host, &host.Network, s.Portgroup...)
|
||||
s.Summary.HostMember = append(s.Summary.HostMember, member.Host)
|
||||
|
||||
for _, ref := range s.Portgroup {
|
||||
pg := Map.Get(ref).(*DistributedVirtualPortgroup)
|
||||
pg.Host = AddReference(member.Host, pg.Host)
|
||||
Map.AddReference(pg, &pg.Host, member.Host)
|
||||
}
|
||||
case types.ConfigSpecOperationRemove:
|
||||
if pg := FindReference(host.Network, s.Portgroup...); pg != nil {
|
||||
@ -117,8 +118,8 @@ func (s *DistributedVirtualSwitch) ReconfigureDvsTask(req *types.ReconfigureDvs_
|
||||
}
|
||||
}
|
||||
|
||||
host.Network = RemoveReference(s.Self, host.Network)
|
||||
s.Summary.HostMember = RemoveReference(s.Self, s.Summary.HostMember)
|
||||
Map.RemoveReference(host, &host.Network, s.Self)
|
||||
RemoveReference(&s.Summary.HostMember, s.Self)
|
||||
case types.ConfigSpecOperationEdit:
|
||||
return nil, &types.NotSupported{}
|
||||
}
|
||||
|
1
vendor/github.com/vmware/govmomi/simulator/esx/BUILD
generated
vendored
1
vendor/github.com/vmware/govmomi/simulator/esx/BUILD
generated
vendored
@ -6,6 +6,7 @@ go_library(
|
||||
"authorization_manager.go",
|
||||
"datacenter.go",
|
||||
"doc.go",
|
||||
"event_manager.go",
|
||||
"host_config_info.go",
|
||||
"host_firewall_system.go",
|
||||
"host_hardware_info.go",
|
||||
|
236
vendor/github.com/vmware/govmomi/simulator/esx/event_manager.go
generated
vendored
Normal file
236
vendor/github.com/vmware/govmomi/simulator/esx/event_manager.go
generated
vendored
Normal file
@ -0,0 +1,236 @@
|
||||
/*
|
||||
Copyright (c) 2018 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 esx
|
||||
|
||||
import "github.com/vmware/govmomi/vim25/types"
|
||||
|
||||
// EventInfo is the default template for the EventManager description.eventInfo property.
|
||||
// Capture method:
|
||||
// govc object.collect -s -dump EventManager:ha-eventmgr description.eventInfo
|
||||
// The captured list has been manually pruned and FullFormat fields changed to use Go's template variable syntax.
|
||||
var EventInfo = []types.EventDescriptionEventDetail{
|
||||
{
|
||||
Key: "UserLoginSessionEvent",
|
||||
Description: "User login",
|
||||
Category: "info",
|
||||
FullFormat: "User {{.UserName}}@{{.IpAddress}} logged in as {{.UserAgent}}",
|
||||
},
|
||||
{
|
||||
Key: "UserLogoutSessionEvent",
|
||||
Description: "User logout",
|
||||
Category: "info",
|
||||
FullFormat: "User {{.UserName}}@{{.IpAddress}} logged out (login time: {{.LoginTime}}, number of API invocations: {{.CallCount}}, user agent: {{.UserAgent}})",
|
||||
},
|
||||
{
|
||||
Key: "DatacenterCreatedEvent",
|
||||
Description: "Datacenter created",
|
||||
Category: "info",
|
||||
FullFormat: "Created datacenter {{.Datacenter.Name}} in folder {{.Parent.Name}}",
|
||||
},
|
||||
{
|
||||
Key: "DatastoreFileMovedEvent",
|
||||
Description: "File or directory moved to datastore",
|
||||
Category: "info",
|
||||
FullFormat: "Move of file or directory {{.SourceFile}} from {{.SourceDatastore.Name}} to {{.Datastore.Name}} as {{.TargetFile}}",
|
||||
},
|
||||
{
|
||||
Key: "DatastoreFileCopiedEvent",
|
||||
Description: "File or directory copied to datastore",
|
||||
Category: "info",
|
||||
FullFormat: "Copy of file or directory {{.SourceFile}} from {{.SourceDatastore.Name}} to {{.Datastore.Name}} as {{.TargetFile}}",
|
||||
},
|
||||
{
|
||||
Key: "DatastoreFileDeletedEvent",
|
||||
Description: "File or directory deleted",
|
||||
Category: "info",
|
||||
FullFormat: "Deletion of file or directory {{.TargetFile}} from {{.Datastore.Name}} was initiated",
|
||||
},
|
||||
{
|
||||
Key: "EnteringMaintenanceModeEvent",
|
||||
Description: "Entering maintenance mode",
|
||||
Category: "info",
|
||||
FullFormat: "Host {{.Host.Name}} in {{.Datacenter.Name}} has started to enter maintenance mode",
|
||||
},
|
||||
{
|
||||
Key: "EnteredMaintenanceModeEvent",
|
||||
Description: "Entered maintenance mode",
|
||||
Category: "info",
|
||||
FullFormat: "Host {{.Host.Name}} in {{.Datacenter.Name}} has entered maintenance mode",
|
||||
},
|
||||
{
|
||||
Key: "ExitMaintenanceModeEvent",
|
||||
Description: "Exit maintenance mode",
|
||||
Category: "info",
|
||||
FullFormat: "Host {{.Host.Name}} in {{.Datacenter.Name}} has exited maintenance mode",
|
||||
},
|
||||
{
|
||||
Key: "VmSuspendedEvent",
|
||||
Description: "VM suspended",
|
||||
Category: "info",
|
||||
FullFormat: "{{.Vm.Name}} on {{.Host.Name}} in {{.Datacenter.Name}} is suspended",
|
||||
},
|
||||
{
|
||||
Key: "VmMigratedEvent",
|
||||
Description: "VM migrated",
|
||||
Category: "info",
|
||||
FullFormat: "Migration of virtual machine {{.Vm.Name}} from {{.SourceHost.Name}, {{.SourceDatastore.Name}} to {{.Host.Name}, {{.Ds.Name}} completed",
|
||||
},
|
||||
{
|
||||
Key: "VmBeingMigratedEvent",
|
||||
Description: "VM migrating",
|
||||
Category: "info",
|
||||
FullFormat: "Relocating {{.Vm.Name}} from {{.Host.Name}, {{.Ds.Name}} in {{.Datacenter.Name}} to {{.DestHost.Name}, {{.DestDatastore.Name}} in {{.DestDatacenter.Name}}",
|
||||
},
|
||||
{
|
||||
Key: "VmMacAssignedEvent",
|
||||
Description: "VM MAC assigned",
|
||||
Category: "info",
|
||||
FullFormat: "New MAC address ({{.Mac}}) assigned to adapter {{.Adapter}} for {{.Vm.Name}}",
|
||||
},
|
||||
{
|
||||
Key: "VmRegisteredEvent",
|
||||
Description: "VM registered",
|
||||
Category: "info",
|
||||
FullFormat: "Registered {{.Vm.Name}} on {{.Host.Name}} in {{.Datacenter.Name}}",
|
||||
},
|
||||
{
|
||||
Key: "VmReconfiguredEvent",
|
||||
Description: "VM reconfigured",
|
||||
Category: "info",
|
||||
FullFormat: "Reconfigured {{.Vm.Name}} on {{.Host.Name}} in {{.Datacenter.Name}}",
|
||||
},
|
||||
{
|
||||
Key: "VmGuestRebootEvent",
|
||||
Description: "Guest reboot",
|
||||
Category: "info",
|
||||
FullFormat: "Guest OS reboot for {{.Vm.Name}} on {{.Host.Name}} in {{.Datacenter.Name}}",
|
||||
},
|
||||
{
|
||||
Key: "VmBeingClonedEvent",
|
||||
Description: "VM being cloned",
|
||||
Category: "info",
|
||||
FullFormat: "Cloning {{.Vm.Name}} on host {{.Host.Name}} in {{.Datacenter.Name}} to {{.DestName}} on host {{.DestHost.Name}}",
|
||||
},
|
||||
{
|
||||
Key: "VmClonedEvent",
|
||||
Description: "VM cloned",
|
||||
Category: "info",
|
||||
FullFormat: "Clone of {{.SourceVm.Name}} completed",
|
||||
},
|
||||
{
|
||||
Key: "VmBeingDeployedEvent",
|
||||
Description: "Deploying VM",
|
||||
Category: "info",
|
||||
FullFormat: "Deploying {{.Vm.Name}} on host {{.Host.Name}} in {{.Datacenter.Name}} from template {{.SrcTemplate.Name}}",
|
||||
},
|
||||
{
|
||||
Key: "VmDeployedEvent",
|
||||
Description: "VM deployed",
|
||||
Category: "info",
|
||||
FullFormat: "Template {{.SrcTemplate.Name}} deployed on host {{.Host.Name}}",
|
||||
},
|
||||
{
|
||||
Key: "VmInstanceUuidAssignedEvent",
|
||||
Description: "Assign a new instance UUID",
|
||||
Category: "info",
|
||||
FullFormat: "Assign a new instance UUID ({{.InstanceUuid}}) to {{.Vm.Name}}",
|
||||
},
|
||||
{
|
||||
Key: "VmPoweredOnEvent",
|
||||
Description: "VM powered on",
|
||||
Category: "info",
|
||||
FullFormat: "{{.Vm.Name}} on {{.Host.Name}} in {{.Datacenter.Name}} is powered on",
|
||||
},
|
||||
{
|
||||
Key: "VmStartingEvent",
|
||||
Description: "VM starting",
|
||||
Category: "info",
|
||||
FullFormat: "{{.Vm.Name}} on host {{.Host.Name}} in {{.Datacenter.Name}} is starting",
|
||||
},
|
||||
{
|
||||
Key: "VmSuspendingEvent",
|
||||
Description: "VM being suspended",
|
||||
Category: "info",
|
||||
FullFormat: "{{.Vm.Name}} on {{.Host.Name}} in {{.Datacenter.Name}} is being suspended",
|
||||
},
|
||||
{
|
||||
Key: "VmResumingEvent",
|
||||
Description: "VM resuming",
|
||||
Category: "info",
|
||||
FullFormat: "{{.Vm.Name}} on {{.Host.Name}} in {{.Datacenter.Name}} is resumed",
|
||||
},
|
||||
{
|
||||
Key: "VmBeingCreatedEvent",
|
||||
Description: "Creating VM",
|
||||
Category: "info",
|
||||
FullFormat: "Creating {{.Vm.Name}} on host {{.Host.Name}} in {{.Datacenter.Name}}",
|
||||
},
|
||||
{
|
||||
Key: "VmCreatedEvent",
|
||||
Description: "VM created",
|
||||
Category: "info",
|
||||
FullFormat: "Created virtual machine {{.Vm.Name}} on {{.Host.Name}} in {{.Datacenter.Name}}",
|
||||
},
|
||||
{
|
||||
Key: "VmRemovedEvent",
|
||||
Description: "VM removed",
|
||||
Category: "info",
|
||||
FullFormat: "Removed {{.Vm.Name}} on {{.Host.Name}} from {{.Datacenter.Name}}",
|
||||
},
|
||||
{
|
||||
Key: "VmResettingEvent",
|
||||
Description: "VM resetting",
|
||||
Category: "info",
|
||||
FullFormat: "{{.Vm.Name}} on {{.Host.Name}} in {{.Datacenter.Name}} is reset",
|
||||
},
|
||||
{
|
||||
Key: "VmGuestShutdownEvent",
|
||||
Description: "Guest OS shut down",
|
||||
Category: "info",
|
||||
FullFormat: "Guest OS shut down for {{.Vm.Name}} on {{.Host.Name}} in {{.Datacenter.Name}}",
|
||||
},
|
||||
{
|
||||
Key: "VmUuidAssignedEvent",
|
||||
Description: "VM UUID assigned",
|
||||
Category: "info",
|
||||
FullFormat: "Assigned new BIOS UUID ({{.Uuid}}) to {{.Vm.Name}} on {{.Host.Name}} in {{.Datacenter.Name}}",
|
||||
},
|
||||
{
|
||||
Key: "VmPoweredOffEvent",
|
||||
Description: "VM powered off",
|
||||
Category: "info",
|
||||
FullFormat: "{{.Vm.Name}} on {{.Host.Name}} in {{.Datacenter.Name}} is powered off",
|
||||
},
|
||||
{
|
||||
Key: "VmRelocatedEvent",
|
||||
Description: "VM relocated",
|
||||
Category: "info",
|
||||
FullFormat: "Completed the relocation of the virtual machine",
|
||||
},
|
||||
{
|
||||
Key: "DrsVmMigratedEvent",
|
||||
Description: "DRS VM migrated",
|
||||
Category: "info",
|
||||
FullFormat: "DRS migrated {{.Vm.Name}} from {{.SourceHost.Name}} to {{.Host.Name}} in cluster {{.ComputeResource.Name}} in {{.Datacenter.Name}}",
|
||||
},
|
||||
{
|
||||
Key: "DrsVmPoweredOnEvent",
|
||||
Description: "DRS VM powered on",
|
||||
Category: "info",
|
||||
FullFormat: "DRS powered On {{.Vm.Name}} on {{.Host.Name}} in {{.Datacenter.Name}}",
|
||||
},
|
||||
}
|
386
vendor/github.com/vmware/govmomi/simulator/event_manager.go
generated
vendored
Normal file
386
vendor/github.com/vmware/govmomi/simulator/event_manager.go
generated
vendored
Normal file
@ -0,0 +1,386 @@
|
||||
/*
|
||||
Copyright (c) 2018 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 simulator
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"container/ring"
|
||||
"log"
|
||||
"reflect"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/simulator/esx"
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/soap"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
var (
|
||||
maxPageSize = 1000
|
||||
logEvents = false
|
||||
)
|
||||
|
||||
type EventManager struct {
|
||||
mo.EventManager
|
||||
|
||||
root types.ManagedObjectReference
|
||||
page *ring.Ring
|
||||
key int32
|
||||
collectors map[types.ManagedObjectReference]*EventHistoryCollector
|
||||
templates map[string]*template.Template
|
||||
}
|
||||
|
||||
func NewEventManager(ref types.ManagedObjectReference) object.Reference {
|
||||
return &EventManager{
|
||||
EventManager: mo.EventManager{
|
||||
Self: ref,
|
||||
Description: types.EventDescription{
|
||||
EventInfo: esx.EventInfo,
|
||||
},
|
||||
MaxCollector: 1000,
|
||||
},
|
||||
root: Map.content().RootFolder,
|
||||
page: ring.New(maxPageSize),
|
||||
collectors: make(map[types.ManagedObjectReference]*EventHistoryCollector),
|
||||
templates: make(map[string]*template.Template),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *EventManager) CreateCollectorForEvents(ctx *Context, req *types.CreateCollectorForEvents) soap.HasFault {
|
||||
body := new(methods.CreateCollectorForEventsBody)
|
||||
size, err := validatePageSize(req.Filter.MaxCount)
|
||||
if err != nil {
|
||||
body.Fault_ = err
|
||||
return body
|
||||
}
|
||||
|
||||
if len(m.collectors) >= int(m.MaxCollector) {
|
||||
body.Fault_ = Fault("Too many event collectors to create", new(types.InvalidState))
|
||||
return body
|
||||
}
|
||||
|
||||
collector := &EventHistoryCollector{
|
||||
m: m,
|
||||
page: ring.New(size),
|
||||
}
|
||||
collector.Filter = req.Filter
|
||||
collector.fillPage(size)
|
||||
|
||||
ref := ctx.Session.Put(collector).Reference()
|
||||
m.collectors[ref] = collector
|
||||
|
||||
body.Res = &types.CreateCollectorForEventsResponse{
|
||||
Returnval: ref,
|
||||
}
|
||||
|
||||
return body
|
||||
}
|
||||
|
||||
// formatMessage applies the EventDescriptionEventDetail.FullFormat template to the given event's FullFormattedMessage field.
|
||||
func (m *EventManager) formatMessage(event types.BaseEvent) {
|
||||
id := reflect.ValueOf(event).Elem().Type().Name()
|
||||
e := event.GetEvent()
|
||||
|
||||
t, ok := m.templates[id]
|
||||
if !ok {
|
||||
for _, info := range m.Description.EventInfo {
|
||||
if info.Key == id {
|
||||
t = template.Must(template.New(id).Parse(info.FullFormat))
|
||||
m.templates[id] = t
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
if err := t.Execute(&buf, event); err != nil {
|
||||
log.Print(err)
|
||||
}
|
||||
e.FullFormattedMessage = buf.String()
|
||||
|
||||
if logEvents {
|
||||
log.Printf("[%s] %s", id, e.FullFormattedMessage)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *EventManager) PostEvent(ctx *Context, req *types.PostEvent) soap.HasFault {
|
||||
m.key++
|
||||
event := req.EventToPost.GetEvent()
|
||||
event.Key = m.key
|
||||
event.ChainId = event.Key
|
||||
event.CreatedTime = time.Now()
|
||||
event.UserName = ctx.Session.UserName
|
||||
|
||||
m.page = m.page.Next()
|
||||
m.page.Value = req.EventToPost
|
||||
m.formatMessage(req.EventToPost)
|
||||
|
||||
for _, c := range m.collectors {
|
||||
if c.eventMatches(req.EventToPost) {
|
||||
c.page = c.page.Next()
|
||||
c.page.Value = event
|
||||
}
|
||||
}
|
||||
|
||||
return &methods.PostEventBody{
|
||||
Res: new(types.PostEventResponse),
|
||||
}
|
||||
}
|
||||
|
||||
type EventHistoryCollector struct {
|
||||
mo.EventHistoryCollector
|
||||
|
||||
m *EventManager
|
||||
page *ring.Ring
|
||||
}
|
||||
|
||||
// doEntityEventArgument calls f for each entity argument in the event.
|
||||
// If f returns true, the iteration stops.
|
||||
func doEntityEventArgument(event types.BaseEvent, f func(types.ManagedObjectReference, *types.EntityEventArgument) bool) bool {
|
||||
e := event.GetEvent()
|
||||
|
||||
if arg := e.Vm; arg != nil {
|
||||
if f(arg.Vm, &arg.EntityEventArgument) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if arg := e.Host; arg != nil {
|
||||
if f(arg.Host, &arg.EntityEventArgument) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if arg := e.ComputeResource; arg != nil {
|
||||
if f(arg.ComputeResource, &arg.EntityEventArgument) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if arg := e.Ds; arg != nil {
|
||||
if f(arg.Datastore, &arg.EntityEventArgument) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if arg := e.Net; arg != nil {
|
||||
if f(arg.Network, &arg.EntityEventArgument) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if arg := e.Dvs; arg != nil {
|
||||
if f(arg.Dvs, &arg.EntityEventArgument) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if arg := e.Datacenter; arg != nil {
|
||||
if f(arg.Datacenter, &arg.EntityEventArgument) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// eventFilterSelf returns true if self is one of the entity arguments in the event.
|
||||
func eventFilterSelf(event types.BaseEvent, self types.ManagedObjectReference) bool {
|
||||
return doEntityEventArgument(event, func(ref types.ManagedObjectReference, _ *types.EntityEventArgument) bool {
|
||||
return self == ref
|
||||
})
|
||||
}
|
||||
|
||||
// eventFilterChildren returns true if a child of self is one of the entity arguments in the event.
|
||||
func eventFilterChildren(event types.BaseEvent, self types.ManagedObjectReference) bool {
|
||||
return doEntityEventArgument(event, func(ref types.ManagedObjectReference, _ *types.EntityEventArgument) bool {
|
||||
seen := false
|
||||
|
||||
var match func(types.ManagedObjectReference)
|
||||
|
||||
match = func(child types.ManagedObjectReference) {
|
||||
if child == self {
|
||||
seen = true
|
||||
return
|
||||
}
|
||||
|
||||
walk(child, match)
|
||||
}
|
||||
|
||||
walk(ref, match)
|
||||
|
||||
return seen
|
||||
})
|
||||
}
|
||||
|
||||
// entityMatches returns true if the spec Entity filter matches the event.
|
||||
func (c *EventHistoryCollector) entityMatches(event types.BaseEvent, spec *types.EventFilterSpec) bool {
|
||||
e := spec.Entity
|
||||
if e == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
isRootFolder := c.m.root == e.Entity
|
||||
|
||||
switch e.Recursion {
|
||||
case types.EventFilterSpecRecursionOptionSelf:
|
||||
return isRootFolder || eventFilterSelf(event, e.Entity)
|
||||
case types.EventFilterSpecRecursionOptionChildren:
|
||||
return eventFilterChildren(event, e.Entity)
|
||||
case types.EventFilterSpecRecursionOptionAll:
|
||||
if isRootFolder || eventFilterSelf(event, e.Entity) {
|
||||
return true
|
||||
}
|
||||
return eventFilterChildren(event, e.Entity)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// typeMatches returns true if one of the spec EventTypeId types matches the event.
|
||||
func (c *EventHistoryCollector) typeMatches(event types.BaseEvent, spec *types.EventFilterSpec) bool {
|
||||
if len(spec.EventTypeId) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
matches := func(name string) bool {
|
||||
for _, id := range spec.EventTypeId {
|
||||
if id == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
kind := reflect.ValueOf(event).Elem().Type()
|
||||
|
||||
if matches(kind.Name()) {
|
||||
return true // concrete type
|
||||
}
|
||||
|
||||
field, ok := kind.FieldByNameFunc(matches)
|
||||
if ok {
|
||||
return field.Anonymous // base type (embedded field)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// eventMatches returns true one of the filters matches the event.
|
||||
func (c *EventHistoryCollector) eventMatches(event types.BaseEvent) bool {
|
||||
spec := c.Filter.(types.EventFilterSpec)
|
||||
|
||||
if !c.typeMatches(event, &spec) {
|
||||
return false
|
||||
}
|
||||
|
||||
// TODO: spec.Time, spec.UserName, etc
|
||||
|
||||
return c.entityMatches(event, &spec)
|
||||
}
|
||||
|
||||
// filePage copies the manager's latest events into the collector's page with Filter applied.
|
||||
func (c *EventHistoryCollector) fillPage(size int) {
|
||||
l := c.page.Len()
|
||||
delta := size - l
|
||||
|
||||
if delta < 0 {
|
||||
// Shrink ring size
|
||||
c.page = c.page.Unlink(-delta)
|
||||
return
|
||||
}
|
||||
|
||||
matches := 0
|
||||
mpage := c.m.page
|
||||
page := c.page
|
||||
|
||||
if delta != 0 {
|
||||
// Grow ring size
|
||||
c.page = c.page.Link(ring.New(delta))
|
||||
}
|
||||
|
||||
for i := 0; i < maxPageSize; i++ {
|
||||
event, ok := mpage.Value.(types.BaseEvent)
|
||||
mpage = mpage.Prev()
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
if c.eventMatches(event) {
|
||||
page.Value = event
|
||||
page = page.Prev()
|
||||
matches++
|
||||
if matches == size {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func validatePageSize(count int32) (int, *soap.Fault) {
|
||||
size := int(count)
|
||||
|
||||
if size == 0 {
|
||||
size = 10 // defaultPageSize
|
||||
} else if size < 0 || size > maxPageSize {
|
||||
return -1, Fault("", &types.InvalidArgument{InvalidProperty: "maxCount"})
|
||||
}
|
||||
|
||||
return size, nil
|
||||
}
|
||||
|
||||
func (c *EventHistoryCollector) SetCollectorPageSize(ctx *Context, req *types.SetCollectorPageSize) soap.HasFault {
|
||||
body := new(methods.SetCollectorPageSizeBody)
|
||||
size, err := validatePageSize(req.MaxCount)
|
||||
if err != nil {
|
||||
body.Fault_ = err
|
||||
return body
|
||||
}
|
||||
|
||||
ctx.WithLock(c.m, func() {
|
||||
c.fillPage(size)
|
||||
})
|
||||
|
||||
body.Res = new(types.SetCollectorPageSizeResponse)
|
||||
return body
|
||||
}
|
||||
|
||||
func (c *EventHistoryCollector) DestroyCollector(ctx *Context, req *types.DestroyCollector) soap.HasFault {
|
||||
ctx.Session.Remove(req.This)
|
||||
|
||||
ctx.WithLock(c.m, func() {
|
||||
delete(c.m.collectors, req.This)
|
||||
})
|
||||
|
||||
return &methods.DestroyCollectorBody{
|
||||
Res: new(types.DestroyCollectorResponse),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *EventHistoryCollector) Get() mo.Reference {
|
||||
clone := *c
|
||||
|
||||
c.page.Do(func(val interface{}) {
|
||||
if val == nil {
|
||||
return
|
||||
}
|
||||
clone.LatestPage = append(clone.LatestPage, val.(types.BaseEvent))
|
||||
})
|
||||
|
||||
return &clone
|
||||
}
|
1
vendor/github.com/vmware/govmomi/simulator/file_manager.go
generated
vendored
1
vendor/github.com/vmware/govmomi/simulator/file_manager.go
generated
vendored
@ -160,6 +160,7 @@ func (f *FileManager) MakeDirectory(req *types.MakeDirectory) soap.HasFault {
|
||||
return body
|
||||
}
|
||||
|
||||
body.Res = new(types.MakeDirectoryResponse)
|
||||
return body
|
||||
}
|
||||
|
||||
|
118
vendor/github.com/vmware/govmomi/simulator/folder.go
generated
vendored
118
vendor/github.com/vmware/govmomi/simulator/folder.go
generated
vendored
@ -20,7 +20,6 @@ import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"path"
|
||||
"sync"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
@ -32,12 +31,17 @@ import (
|
||||
|
||||
type Folder struct {
|
||||
mo.Folder
|
||||
}
|
||||
|
||||
m sync.Mutex
|
||||
func (f *Folder) eventArgument() types.FolderEventArgument {
|
||||
return types.FolderEventArgument{
|
||||
Folder: f.Self,
|
||||
EntityEventArgument: types.EntityEventArgument{Name: f.Name},
|
||||
}
|
||||
}
|
||||
|
||||
// update references when objects are added/removed from a Folder
|
||||
func (f *Folder) update(o mo.Reference, u func(types.ManagedObjectReference, []types.ManagedObjectReference) []types.ManagedObjectReference) {
|
||||
func (f *Folder) update(o mo.Reference, u func(mo.Reference, *[]types.ManagedObjectReference, types.ManagedObjectReference)) {
|
||||
ref := o.Reference()
|
||||
|
||||
if f.Parent == nil {
|
||||
@ -53,9 +57,9 @@ func (f *Folder) update(o mo.Reference, u func(types.ManagedObjectReference, []t
|
||||
|
||||
switch ref.Type {
|
||||
case "Network", "DistributedVirtualSwitch", "DistributedVirtualPortgroup":
|
||||
dc.Network = u(ref, dc.Network)
|
||||
u(dc, &dc.Network, ref)
|
||||
case "Datastore":
|
||||
dc.Datastore = u(ref, dc.Datastore)
|
||||
u(dc, &dc.Datastore, ref)
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,12 +74,9 @@ func networkSummary(n *mo.Network) *types.NetworkSummary {
|
||||
func (f *Folder) putChild(o mo.Entity) {
|
||||
Map.PutEntity(f, o)
|
||||
|
||||
f.m.Lock()
|
||||
defer f.m.Unlock()
|
||||
f.ChildEntity = append(f.ChildEntity, o.Reference())
|
||||
|
||||
f.ChildEntity = AddReference(o.Reference(), f.ChildEntity)
|
||||
|
||||
f.update(o, AddReference)
|
||||
f.update(o, Map.AddReference)
|
||||
|
||||
switch e := o.(type) {
|
||||
case *mo.Network:
|
||||
@ -90,12 +91,9 @@ func (f *Folder) putChild(o mo.Entity) {
|
||||
func (f *Folder) removeChild(o mo.Reference) {
|
||||
Map.Remove(o.Reference())
|
||||
|
||||
f.m.Lock()
|
||||
defer f.m.Unlock()
|
||||
RemoveReference(&f.ChildEntity, o.Reference())
|
||||
|
||||
f.ChildEntity = RemoveReference(o.Reference(), f.ChildEntity)
|
||||
|
||||
f.update(o, RemoveReference)
|
||||
f.update(o, Map.RemoveReference)
|
||||
}
|
||||
|
||||
func (f *Folder) hasChildType(kind string) bool {
|
||||
@ -195,7 +193,7 @@ func (p *StoragePod) MoveIntoFolderTask(c *types.MoveIntoFolder_Task) soap.HasFa
|
||||
return (&Folder{Folder: p.Folder}).MoveIntoFolderTask(c)
|
||||
}
|
||||
|
||||
func (f *Folder) CreateDatacenter(c *types.CreateDatacenter) soap.HasFault {
|
||||
func (f *Folder) CreateDatacenter(ctx *Context, c *types.CreateDatacenter) soap.HasFault {
|
||||
r := &methods.CreateDatacenterBody{}
|
||||
|
||||
if f.hasChildType("Datacenter") && f.hasChildType("Folder") {
|
||||
@ -210,6 +208,15 @@ func (f *Folder) CreateDatacenter(c *types.CreateDatacenter) soap.HasFault {
|
||||
r.Res = &types.CreateDatacenterResponse{
|
||||
Returnval: dc.Self,
|
||||
}
|
||||
|
||||
ctx.postEvent(&types.DatacenterCreatedEvent{
|
||||
DatacenterEvent: types.DatacenterEvent{
|
||||
Event: types.Event{
|
||||
Datacenter: datacenterEventArgument(dc),
|
||||
},
|
||||
},
|
||||
Parent: f.eventArgument(),
|
||||
})
|
||||
} else {
|
||||
r.Fault_ = f.typeNotSupported()
|
||||
}
|
||||
@ -240,6 +247,7 @@ func (f *Folder) CreateClusterEx(c *types.CreateClusterEx) soap.HasFault {
|
||||
type createVM struct {
|
||||
*Folder
|
||||
|
||||
ctx *Context
|
||||
req *types.CreateVM_Task
|
||||
|
||||
register bool
|
||||
@ -291,27 +299,50 @@ func (c *createVM) Run(task *Task) (types.AnyType, types.BaseMethodFault) {
|
||||
c.Folder.putChild(vm)
|
||||
|
||||
host := Map.Get(*vm.Runtime.Host).(*HostSystem)
|
||||
host.Vm = append(host.Vm, vm.Self)
|
||||
Map.AppendReference(host, &host.Vm, vm.Self)
|
||||
|
||||
for i := range vm.Datastore {
|
||||
ds := Map.Get(vm.Datastore[i]).(*Datastore)
|
||||
ds.Vm = append(ds.Vm, vm.Self)
|
||||
Map.AppendReference(ds, &ds.Vm, vm.Self)
|
||||
}
|
||||
|
||||
switch rp := Map.Get(*vm.ResourcePool).(type) {
|
||||
case *ResourcePool:
|
||||
rp.Vm = append(rp.Vm, vm.Self)
|
||||
case *VirtualApp:
|
||||
rp.Vm = append(rp.Vm, vm.Self)
|
||||
}
|
||||
pool := Map.Get(*vm.ResourcePool)
|
||||
// This can be an internal call from VirtualApp.CreateChildVMTask, where pool is already locked.
|
||||
c.ctx.WithLock(pool, func() {
|
||||
switch rp := pool.(type) {
|
||||
case *ResourcePool:
|
||||
rp.Vm = append(rp.Vm, vm.Self)
|
||||
case *VirtualApp:
|
||||
rp.Vm = append(rp.Vm, vm.Self)
|
||||
}
|
||||
})
|
||||
|
||||
event := vm.event()
|
||||
c.ctx.postEvent(
|
||||
&types.VmBeingCreatedEvent{
|
||||
VmEvent: event,
|
||||
ConfigSpec: &c.req.Config,
|
||||
},
|
||||
&types.VmInstanceUuidAssignedEvent{
|
||||
VmEvent: event,
|
||||
InstanceUuid: vm.Config.InstanceUuid,
|
||||
},
|
||||
&types.VmUuidAssignedEvent{
|
||||
VmEvent: event,
|
||||
Uuid: vm.Config.Uuid,
|
||||
},
|
||||
&types.VmCreatedEvent{
|
||||
VmEvent: event,
|
||||
},
|
||||
)
|
||||
|
||||
return vm.Reference(), nil
|
||||
}
|
||||
|
||||
func (f *Folder) CreateVMTask(c *types.CreateVM_Task) soap.HasFault {
|
||||
func (f *Folder) CreateVMTask(ctx *Context, c *types.CreateVM_Task) soap.HasFault {
|
||||
return &methods.CreateVM_TaskBody{
|
||||
Res: &types.CreateVM_TaskResponse{
|
||||
Returnval: NewTask(&createVM{f, c, false}).Run(),
|
||||
Returnval: NewTask(&createVM{f, ctx, c, false}).Run(),
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -319,6 +350,7 @@ func (f *Folder) CreateVMTask(c *types.CreateVM_Task) soap.HasFault {
|
||||
type registerVM struct {
|
||||
*Folder
|
||||
|
||||
ctx *Context
|
||||
req *types.RegisterVM_Task
|
||||
}
|
||||
|
||||
@ -367,6 +399,7 @@ func (c *registerVM) Run(task *Task) (types.AnyType, types.BaseMethodFault) {
|
||||
create := NewTask(&createVM{
|
||||
Folder: c.Folder,
|
||||
register: true,
|
||||
ctx: c.ctx,
|
||||
req: &types.CreateVM_Task{
|
||||
This: c.Folder.Reference(),
|
||||
Config: types.VirtualMachineConfigSpec{
|
||||
@ -389,10 +422,12 @@ func (c *registerVM) Run(task *Task) (types.AnyType, types.BaseMethodFault) {
|
||||
return create.Info.Result, nil
|
||||
}
|
||||
|
||||
func (f *Folder) RegisterVMTask(c *types.RegisterVM_Task) soap.HasFault {
|
||||
func (f *Folder) RegisterVMTask(ctx *Context, c *types.RegisterVM_Task) soap.HasFault {
|
||||
ctx.Caller = &f.Self
|
||||
|
||||
return &methods.RegisterVM_TaskBody{
|
||||
Res: &types.RegisterVM_TaskResponse{
|
||||
Returnval: NewTask(®isterVM{f, c}).Run(),
|
||||
Returnval: NewTask(®isterVM{f, ctx, c}).Run(),
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -445,6 +480,33 @@ func (f *Folder) CreateDVSTask(req *types.CreateDVS_Task) soap.HasFault {
|
||||
Description: spec.Description,
|
||||
}
|
||||
|
||||
configInfo := &types.VMwareDVSConfigInfo{
|
||||
DVSConfigInfo: types.DVSConfigInfo{
|
||||
Uuid: dvs.Uuid,
|
||||
Name: spec.Name,
|
||||
ConfigVersion: spec.ConfigVersion,
|
||||
NumStandalonePorts: spec.NumStandalonePorts,
|
||||
MaxPorts: spec.MaxPorts,
|
||||
UplinkPortPolicy: spec.UplinkPortPolicy,
|
||||
UplinkPortgroup: spec.UplinkPortgroup,
|
||||
DefaultPortConfig: spec.DefaultPortConfig,
|
||||
ExtensionKey: spec.ExtensionKey,
|
||||
Description: spec.Description,
|
||||
Policy: spec.Policy,
|
||||
VendorSpecificConfig: spec.VendorSpecificConfig,
|
||||
SwitchIpAddress: spec.SwitchIpAddress,
|
||||
DefaultProxySwitchMaxNumPorts: spec.DefaultProxySwitchMaxNumPorts,
|
||||
InfrastructureTrafficResourceConfig: spec.InfrastructureTrafficResourceConfig,
|
||||
NetworkResourceControlVersion: spec.NetworkResourceControlVersion,
|
||||
},
|
||||
}
|
||||
|
||||
if spec.Contact != nil {
|
||||
configInfo.Contact = *spec.Contact
|
||||
}
|
||||
|
||||
dvs.Config = configInfo
|
||||
|
||||
if dvs.Summary.ProductInfo == nil {
|
||||
product := Map.content().About
|
||||
dvs.Summary.ProductInfo = &types.DistributedVirtualSwitchProductSpec{
|
||||
|
2
vendor/github.com/vmware/govmomi/simulator/host_datastore_system.go
generated
vendored
2
vendor/github.com/vmware/govmomi/simulator/host_datastore_system.go
generated
vendored
@ -72,7 +72,7 @@ func (dss *HostDatastoreSystem) add(ds *Datastore) *soap.Fault {
|
||||
dss.Datastore = append(dss.Datastore, ds.Self)
|
||||
dss.Host.Datastore = dss.Datastore
|
||||
parent := hostParent(dss.Host)
|
||||
parent.Datastore = AddReference(ds.Self, parent.Datastore)
|
||||
Map.AddReference(parent, &parent.Datastore, ds.Self)
|
||||
|
||||
browser := &HostDatastoreBrowser{}
|
||||
browser.Datastore = dss.Datastore
|
||||
|
80
vendor/github.com/vmware/govmomi/simulator/host_local_account_manager.go
generated
vendored
Normal file
80
vendor/github.com/vmware/govmomi/simulator/host_local_account_manager.go
generated
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
Copyright (c) 2017 VMware, Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
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 simulator
|
||||
|
||||
import (
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/soap"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
// As of vSphere API 5.1, local groups operations are deprecated, so it's not supported here.
|
||||
|
||||
type HostLocalAccountManager struct {
|
||||
mo.HostLocalAccountManager
|
||||
}
|
||||
|
||||
func NewHostLocalAccountManager(ref types.ManagedObjectReference) object.Reference {
|
||||
m := &HostLocalAccountManager{}
|
||||
m.Self = ref
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
func (h *HostLocalAccountManager) CreateUser(req *types.CreateUser) soap.HasFault {
|
||||
spec := req.User.GetHostAccountSpec()
|
||||
userDirectory := Map.UserDirectory()
|
||||
|
||||
found := userDirectory.search(true, false, compareFunc(spec.Id, true))
|
||||
if len(found) > 0 {
|
||||
return &methods.CreateUserBody{
|
||||
Fault_: Fault("", &types.AlreadyExists{}),
|
||||
}
|
||||
}
|
||||
|
||||
userDirectory.addUser(spec.Id)
|
||||
|
||||
return &methods.CreateUserBody{
|
||||
Res: &types.CreateUserResponse{},
|
||||
}
|
||||
}
|
||||
|
||||
func (h *HostLocalAccountManager) RemoveUser(req *types.RemoveUser) soap.HasFault {
|
||||
userDirectory := Map.UserDirectory()
|
||||
|
||||
found := userDirectory.search(true, false, compareFunc(req.UserName, true))
|
||||
|
||||
if len(found) == 0 {
|
||||
return &methods.RemoveUserBody{
|
||||
Fault_: Fault("", &types.UserNotFound{}),
|
||||
}
|
||||
}
|
||||
|
||||
userDirectory.removeUser(req.UserName)
|
||||
|
||||
return &methods.RemoveUserBody{
|
||||
Res: &types.RemoveUserResponse{},
|
||||
}
|
||||
}
|
||||
|
||||
func (h *HostLocalAccountManager) UpdateUser(req *types.UpdateUser) soap.HasFault {
|
||||
return &methods.CreateUserBody{
|
||||
Res: &types.CreateUserResponse{},
|
||||
}
|
||||
}
|
24
vendor/github.com/vmware/govmomi/simulator/host_system.go
generated
vendored
24
vendor/github.com/vmware/govmomi/simulator/host_system.go
generated
vendored
@ -71,6 +71,22 @@ func NewHostSystem(host mo.HostSystem) *HostSystem {
|
||||
return hs
|
||||
}
|
||||
|
||||
func (h *HostSystem) eventArgument() *types.HostEventArgument {
|
||||
return &types.HostEventArgument{
|
||||
Host: h.Self,
|
||||
EntityEventArgument: types.EntityEventArgument{Name: h.Name},
|
||||
}
|
||||
}
|
||||
|
||||
func (h *HostSystem) eventArgumentParent() *types.ComputeResourceEventArgument {
|
||||
parent := hostParent(&h.HostSystem)
|
||||
|
||||
return &types.ComputeResourceEventArgument{
|
||||
ComputeResource: parent.Self,
|
||||
EntityEventArgument: types.EntityEventArgument{Name: parent.Name},
|
||||
}
|
||||
}
|
||||
|
||||
func hostParent(host *mo.HostSystem) *mo.ComputeResource {
|
||||
switch parent := Map.Get(*host.Parent).(type) {
|
||||
case *mo.ComputeResource:
|
||||
@ -137,9 +153,15 @@ func CreateStandaloneHost(f *Folder, spec types.HostConnectSpec) (*HostSystem, t
|
||||
summary := new(types.ComputeResourceSummary)
|
||||
addComputeResource(summary, host)
|
||||
|
||||
cr := &mo.ComputeResource{Summary: summary}
|
||||
cr := &mo.ComputeResource{
|
||||
ConfigurationEx: &types.ComputeResourceConfigInfo{
|
||||
VmSwapPlacement: string(types.VirtualMachineConfigInfoSwapPlacementTypeVmDirectory),
|
||||
},
|
||||
Summary: summary,
|
||||
}
|
||||
|
||||
Map.PutEntity(cr, Map.NewEntity(host))
|
||||
host.Summary.Host = &host.Self
|
||||
|
||||
Map.PutEntity(cr, Map.NewEntity(pool))
|
||||
|
||||
|
13
vendor/github.com/vmware/govmomi/simulator/model.go
generated
vendored
13
vendor/github.com/vmware/govmomi/simulator/model.go
generated
vendored
@ -34,13 +34,13 @@ import (
|
||||
// This is a simple helper for tests running against a simulator, to populate an inventory
|
||||
// with commonly used models.
|
||||
type Model struct {
|
||||
Service *Service
|
||||
Service *Service `json:"-"`
|
||||
|
||||
ServiceContent types.ServiceContent
|
||||
RootFolder mo.Folder
|
||||
ServiceContent types.ServiceContent `json:"-"`
|
||||
RootFolder mo.Folder `json:"-"`
|
||||
|
||||
// Autostart will power on Model created VMs when true
|
||||
Autostart bool
|
||||
Autostart bool `json:"-"`
|
||||
|
||||
// Datacenter specifies the number of Datacenter entities to create
|
||||
Datacenter int
|
||||
@ -49,13 +49,13 @@ type Model struct {
|
||||
Portgroup int
|
||||
|
||||
// Host specifies the number of standalone HostSystems entities to create per Datacenter
|
||||
Host int
|
||||
Host int `json:",omitempty"`
|
||||
|
||||
// Cluster specifies the number of ClusterComputeResource entities to create per Datacenter
|
||||
Cluster int
|
||||
|
||||
// ClusterHost specifies the number of HostSystems entities to create within a Cluster
|
||||
ClusterHost int
|
||||
ClusterHost int `json:",omitempty"`
|
||||
|
||||
// Pool specifies the number of ResourcePool entities to create per Cluster
|
||||
Pool int
|
||||
@ -233,6 +233,7 @@ func (m *Model) Create() error {
|
||||
cdrom, _ := devices.CreateCdrom(ide.(*types.VirtualIDEController))
|
||||
disk := devices.CreateDisk(scsi.(types.BaseVirtualController), ds,
|
||||
config.Files.VmPathName+" "+path.Join(name, "disk1.vmdk"))
|
||||
disk.CapacityInKB = 1024
|
||||
|
||||
devices = append(devices, scsi, cdrom, disk, &nic)
|
||||
|
||||
|
39
vendor/github.com/vmware/govmomi/simulator/option_manager.go
generated
vendored
39
vendor/github.com/vmware/govmomi/simulator/option_manager.go
generated
vendored
@ -57,3 +57,42 @@ func (m *OptionManager) QueryOptions(req *types.QueryOptions) soap.HasFault {
|
||||
|
||||
return body
|
||||
}
|
||||
|
||||
func (m *OptionManager) find(key string) *types.OptionValue {
|
||||
for _, opt := range m.Setting {
|
||||
setting := opt.GetOptionValue()
|
||||
if setting.Key == key {
|
||||
return setting
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *OptionManager) UpdateOptions(req *types.UpdateOptions) soap.HasFault {
|
||||
body := new(methods.UpdateOptionsBody)
|
||||
|
||||
for _, change := range req.ChangedValue {
|
||||
setting := change.GetOptionValue()
|
||||
|
||||
// We don't currently include the entire list of default settings for ESX and vCenter,
|
||||
// this prefix is currently used to test the failure path.
|
||||
// Real vCenter seems to only allow new options if Key has a "config." prefix.
|
||||
// TODO: consider behaving the same, which would require including 2 long lists of options in vpx.Setting and esx.Setting
|
||||
if strings.HasPrefix(setting.Key, "ENOENT.") {
|
||||
body.Fault_ = Fault("", &types.InvalidName{Name: setting.Key})
|
||||
return body
|
||||
}
|
||||
|
||||
opt := m.find(setting.Key)
|
||||
if opt != nil {
|
||||
// This is an existing option.
|
||||
opt.Value = setting.Value
|
||||
continue
|
||||
}
|
||||
|
||||
m.Setting = append(m.Setting, change)
|
||||
}
|
||||
|
||||
body.Res = new(types.UpdateOptionsResponse)
|
||||
return body
|
||||
}
|
||||
|
15
vendor/github.com/vmware/govmomi/simulator/portgroup.go
generated
vendored
15
vendor/github.com/vmware/govmomi/simulator/portgroup.go
generated
vendored
@ -53,23 +53,12 @@ func (s *DistributedVirtualPortgroup) ReconfigureDVPortgroupTask(req *types.Reco
|
||||
func (s *DistributedVirtualPortgroup) DestroyTask(req *types.Destroy_Task) soap.HasFault {
|
||||
task := CreateTask(s, "destroy", func(t *Task) (types.AnyType, types.BaseMethodFault) {
|
||||
vswitch := Map.Get(*s.Config.DistributedVirtualSwitch).(*DistributedVirtualSwitch)
|
||||
for i, pg := range vswitch.Portgroup {
|
||||
if pg.Reference() == s.Reference() {
|
||||
vswitch.Portgroup = append(vswitch.Portgroup[:i], vswitch.Portgroup[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
Map.RemoveReference(vswitch, &vswitch.Portgroup, s.Reference())
|
||||
Map.removeString(vswitch, &vswitch.Summary.PortgroupName, s.Name)
|
||||
|
||||
f := Map.getEntityParent(vswitch, "Folder").(*Folder)
|
||||
f.removeChild(s.Reference())
|
||||
|
||||
for i, name := range vswitch.Summary.PortgroupName {
|
||||
if name == s.Name {
|
||||
vswitch.Summary.PortgroupName = append(vswitch.Summary.PortgroupName[:i],
|
||||
vswitch.Summary.PortgroupName[i+1:]...)
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
})
|
||||
|
||||
|
124
vendor/github.com/vmware/govmomi/simulator/property_collector.go
generated
vendored
124
vendor/github.com/vmware/govmomi/simulator/property_collector.go
generated
vendored
@ -43,12 +43,35 @@ func NewPropertyCollector(ref types.ManagedObjectReference) object.Reference {
|
||||
var errMissingField = errors.New("missing field")
|
||||
var errEmptyField = errors.New("empty field")
|
||||
|
||||
func getObject(ref types.ManagedObjectReference) (reflect.Value, bool) {
|
||||
obj := Map.Get(ref)
|
||||
func getObject(ctx *Context, ref types.ManagedObjectReference) (reflect.Value, bool) {
|
||||
var obj mo.Reference
|
||||
if ctx.Session == nil {
|
||||
// Even without permissions to access an object or specific fields, RetrieveProperties
|
||||
// returns an ObjectContent response as long as the object exists. See retrieveResult.add()
|
||||
obj = Map.Get(ref)
|
||||
} else {
|
||||
obj = ctx.Session.Get(ref)
|
||||
}
|
||||
|
||||
if obj == nil {
|
||||
return reflect.Value{}, false
|
||||
}
|
||||
|
||||
if ctx.Session == nil && ref.Type == "SessionManager" {
|
||||
// RetrieveProperties on SessionManager without a session always returns empty,
|
||||
// rather than MissingSet + Fault.NotAuthenticated for each field.
|
||||
obj = &mo.SessionManager{Self: ref}
|
||||
}
|
||||
|
||||
// For objects that use internal types that differ from that of the vim25/mo field types.
|
||||
// See EventHistoryCollector for example.
|
||||
type get interface {
|
||||
Get() mo.Reference
|
||||
}
|
||||
if o, ok := obj.(get); ok {
|
||||
obj = o.Get()
|
||||
}
|
||||
|
||||
rval := reflect.ValueOf(obj).Elem()
|
||||
rtype := rval.Type()
|
||||
|
||||
@ -110,7 +133,6 @@ func fieldValueInterface(f reflect.StructField, rval reflect.Value) interface{}
|
||||
|
||||
func fieldValue(rval reflect.Value, p string) (interface{}, error) {
|
||||
var value interface{}
|
||||
|
||||
fields := strings.Split(p, ".")
|
||||
|
||||
for i, name := range fields {
|
||||
@ -170,7 +192,7 @@ func isEmpty(rval reflect.Value) bool {
|
||||
switch rval.Kind() {
|
||||
case reflect.Ptr:
|
||||
return rval.IsNil()
|
||||
case reflect.String, reflect.Slice:
|
||||
case reflect.String:
|
||||
return rval.Len() == 0
|
||||
}
|
||||
|
||||
@ -200,7 +222,27 @@ type retrieveResult struct {
|
||||
specs map[string]*types.TraversalSpec
|
||||
}
|
||||
|
||||
func (rr *retrieveResult) collectAll(rval reflect.Value, rtype reflect.Type, content *types.ObjectContent) {
|
||||
func (rr *retrieveResult) add(ctx *Context, name string, val types.AnyType, content *types.ObjectContent) {
|
||||
if ctx.Session != nil {
|
||||
content.PropSet = append(content.PropSet, types.DynamicProperty{
|
||||
Name: name,
|
||||
Val: val,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
content.MissingSet = append(content.MissingSet, types.MissingProperty{
|
||||
Path: name,
|
||||
Fault: types.LocalizedMethodFault{Fault: &types.NotAuthenticated{
|
||||
NoPermission: types.NoPermission{
|
||||
Object: content.Obj,
|
||||
PrivilegeId: "System.Read",
|
||||
}},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (rr *retrieveResult) collectAll(ctx *Context, rval reflect.Value, rtype reflect.Type, content *types.ObjectContent) {
|
||||
for i := 0; i < rval.NumField(); i++ {
|
||||
val := rval.Field(i)
|
||||
|
||||
@ -212,18 +254,15 @@ func (rr *retrieveResult) collectAll(rval reflect.Value, rtype reflect.Type, con
|
||||
|
||||
if f.Anonymous {
|
||||
// recurse into embedded field
|
||||
rr.collectAll(val, f.Type, content)
|
||||
rr.collectAll(ctx, val, f.Type, content)
|
||||
continue
|
||||
}
|
||||
|
||||
content.PropSet = append(content.PropSet, types.DynamicProperty{
|
||||
Name: lcFirst(f.Name),
|
||||
Val: fieldValueInterface(f, val),
|
||||
})
|
||||
rr.add(ctx, lcFirst(f.Name), fieldValueInterface(f, val), content)
|
||||
}
|
||||
}
|
||||
|
||||
func (rr *retrieveResult) collectFields(rval reflect.Value, fields []string, content *types.ObjectContent) {
|
||||
func (rr *retrieveResult) collectFields(ctx *Context, rval reflect.Value, fields []string, content *types.ObjectContent) {
|
||||
seen := make(map[string]bool)
|
||||
|
||||
for i := range content.PropSet {
|
||||
@ -240,12 +279,7 @@ func (rr *retrieveResult) collectFields(rval reflect.Value, fields []string, con
|
||||
|
||||
val, err := fieldValue(rval, name)
|
||||
if err == nil {
|
||||
prop := types.DynamicProperty{
|
||||
Name: name,
|
||||
Val: val,
|
||||
}
|
||||
|
||||
content.PropSet = append(content.PropSet, prop)
|
||||
rr.add(ctx, name, val, content)
|
||||
continue
|
||||
}
|
||||
|
||||
@ -263,7 +297,7 @@ func (rr *retrieveResult) collectFields(rval reflect.Value, fields []string, con
|
||||
}
|
||||
}
|
||||
|
||||
func (rr *retrieveResult) collect(ref types.ManagedObjectReference) {
|
||||
func (rr *retrieveResult) collect(ctx *Context, ref types.ManagedObjectReference) {
|
||||
if rr.collected[ref] {
|
||||
return
|
||||
}
|
||||
@ -272,7 +306,7 @@ func (rr *retrieveResult) collect(ref types.ManagedObjectReference) {
|
||||
Obj: ref,
|
||||
}
|
||||
|
||||
rval, ok := getObject(ref)
|
||||
rval, ok := getObject(ctx, ref)
|
||||
if !ok {
|
||||
// Possible if a test uses Map.Remove instead of Destroy_Task
|
||||
log.Printf("object %s no longer exists", ref)
|
||||
@ -293,11 +327,11 @@ func (rr *retrieveResult) collect(ref types.ManagedObjectReference) {
|
||||
}
|
||||
|
||||
if isTrue(p.All) {
|
||||
rr.collectAll(rval, rtype, &content)
|
||||
rr.collectAll(ctx, rval, rtype, &content)
|
||||
continue
|
||||
}
|
||||
|
||||
rr.collectFields(rval, p.PathSet, &content)
|
||||
rr.collectFields(ctx, rval, p.PathSet, &content)
|
||||
}
|
||||
}
|
||||
|
||||
@ -308,10 +342,9 @@ func (rr *retrieveResult) collect(ref types.ManagedObjectReference) {
|
||||
rr.collected[ref] = true
|
||||
}
|
||||
|
||||
func (rr *retrieveResult) selectSet(obj reflect.Value, s []types.BaseSelectionSpec, refs *[]types.ManagedObjectReference) types.BaseMethodFault {
|
||||
func (rr *retrieveResult) selectSet(ctx *Context, obj reflect.Value, s []types.BaseSelectionSpec, refs *[]types.ManagedObjectReference) types.BaseMethodFault {
|
||||
for _, ss := range s {
|
||||
ts, ok := ss.(*types.TraversalSpec)
|
||||
|
||||
if ok {
|
||||
if ts.Name != "" {
|
||||
rr.specs[ts.Name] = ts
|
||||
@ -335,9 +368,9 @@ func (rr *retrieveResult) selectSet(obj reflect.Value, s []types.BaseSelectionSp
|
||||
*refs = append(*refs, ref)
|
||||
}
|
||||
|
||||
rval, ok := getObject(ref)
|
||||
rval, ok := getObject(ctx, ref)
|
||||
if ok {
|
||||
if err := rr.selectSet(rval, ts.SelectSet, refs); err != nil {
|
||||
if err := rr.selectSet(ctx, rval, ts.SelectSet, refs); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -347,7 +380,7 @@ func (rr *retrieveResult) selectSet(obj reflect.Value, s []types.BaseSelectionSp
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pc *PropertyCollector) collect(r *types.RetrievePropertiesEx) (*types.RetrieveResult, types.BaseMethodFault) {
|
||||
func (pc *PropertyCollector) collect(ctx *Context, r *types.RetrievePropertiesEx) (*types.RetrieveResult, types.BaseMethodFault) {
|
||||
var refs []types.ManagedObjectReference
|
||||
|
||||
rr := &retrieveResult{
|
||||
@ -360,8 +393,7 @@ func (pc *PropertyCollector) collect(r *types.RetrievePropertiesEx) (*types.Retr
|
||||
// Select object references
|
||||
for _, spec := range r.SpecSet {
|
||||
for _, o := range spec.ObjectSet {
|
||||
rval, ok := getObject(o.Obj)
|
||||
|
||||
rval, ok := getObject(ctx, o.Obj)
|
||||
if !ok {
|
||||
if isFalse(spec.ReportMissingObjectsInResults) {
|
||||
return nil, &types.ManagedObjectNotFound{Obj: o.Obj}
|
||||
@ -373,27 +405,27 @@ func (pc *PropertyCollector) collect(r *types.RetrievePropertiesEx) (*types.Retr
|
||||
refs = append(refs, o.Obj)
|
||||
}
|
||||
|
||||
if err := rr.selectSet(rval, o.SelectSet, &refs); err != nil {
|
||||
if err := rr.selectSet(ctx, rval, o.SelectSet, &refs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, ref := range refs {
|
||||
rr.collect(ref)
|
||||
rr.collect(ctx, ref)
|
||||
}
|
||||
|
||||
return rr.RetrieveResult, nil
|
||||
}
|
||||
|
||||
func (pc *PropertyCollector) CreateFilter(c *types.CreateFilter) soap.HasFault {
|
||||
func (pc *PropertyCollector) CreateFilter(ctx *Context, c *types.CreateFilter) soap.HasFault {
|
||||
body := &methods.CreateFilterBody{}
|
||||
|
||||
filter := &PropertyFilter{pc: pc}
|
||||
filter.PartialUpdates = c.PartialUpdates
|
||||
filter.Spec = c.Spec
|
||||
|
||||
pc.Filter = append(pc.Filter, Map.Put(filter).Reference())
|
||||
pc.Filter = append(pc.Filter, ctx.Session.Put(filter).Reference())
|
||||
|
||||
body.Res = &types.CreateFilterResponse{
|
||||
Returnval: filter.Self,
|
||||
@ -402,37 +434,37 @@ func (pc *PropertyCollector) CreateFilter(c *types.CreateFilter) soap.HasFault {
|
||||
return body
|
||||
}
|
||||
|
||||
func (pc *PropertyCollector) CreatePropertyCollector(c *types.CreatePropertyCollector) soap.HasFault {
|
||||
func (pc *PropertyCollector) CreatePropertyCollector(ctx *Context, c *types.CreatePropertyCollector) soap.HasFault {
|
||||
body := &methods.CreatePropertyCollectorBody{}
|
||||
|
||||
cpc := &PropertyCollector{}
|
||||
|
||||
body.Res = &types.CreatePropertyCollectorResponse{
|
||||
Returnval: Map.Put(cpc).Reference(),
|
||||
Returnval: ctx.Session.Put(cpc).Reference(),
|
||||
}
|
||||
|
||||
return body
|
||||
}
|
||||
|
||||
func (pc *PropertyCollector) DestroyPropertyCollector(c *types.DestroyPropertyCollector) soap.HasFault {
|
||||
func (pc *PropertyCollector) DestroyPropertyCollector(ctx *Context, c *types.DestroyPropertyCollector) soap.HasFault {
|
||||
body := &methods.DestroyPropertyCollectorBody{}
|
||||
|
||||
for _, ref := range pc.Filter {
|
||||
filter := Map.Get(ref).(*PropertyFilter)
|
||||
filter := ctx.Session.Get(ref).(*PropertyFilter)
|
||||
filter.DestroyPropertyFilter(&types.DestroyPropertyFilter{This: ref})
|
||||
}
|
||||
|
||||
Map.Remove(c.This)
|
||||
ctx.Session.Remove(c.This)
|
||||
|
||||
body.Res = &types.DestroyPropertyCollectorResponse{}
|
||||
|
||||
return body
|
||||
}
|
||||
|
||||
func (pc *PropertyCollector) RetrievePropertiesEx(r *types.RetrievePropertiesEx) soap.HasFault {
|
||||
func (pc *PropertyCollector) RetrievePropertiesEx(ctx *Context, r *types.RetrievePropertiesEx) soap.HasFault {
|
||||
body := &methods.RetrievePropertiesExBody{}
|
||||
|
||||
res, fault := pc.collect(r)
|
||||
res, fault := pc.collect(ctx, r)
|
||||
|
||||
if fault != nil {
|
||||
body.Fault_ = Fault("", fault)
|
||||
@ -446,10 +478,10 @@ func (pc *PropertyCollector) RetrievePropertiesEx(r *types.RetrievePropertiesEx)
|
||||
}
|
||||
|
||||
// RetrieveProperties is deprecated, but govmomi is still using it at the moment.
|
||||
func (pc *PropertyCollector) RetrieveProperties(r *types.RetrieveProperties) soap.HasFault {
|
||||
func (pc *PropertyCollector) RetrieveProperties(ctx *Context, r *types.RetrieveProperties) soap.HasFault {
|
||||
body := &methods.RetrievePropertiesBody{}
|
||||
|
||||
res := pc.RetrievePropertiesEx(&types.RetrievePropertiesEx{
|
||||
res := pc.RetrievePropertiesEx(ctx, &types.RetrievePropertiesEx{
|
||||
This: r.This,
|
||||
SpecSet: r.SpecSet,
|
||||
})
|
||||
@ -469,7 +501,7 @@ func (pc *PropertyCollector) CancelWaitForUpdates(r *types.CancelWaitForUpdates)
|
||||
return &methods.CancelWaitForUpdatesBody{Res: new(types.CancelWaitForUpdatesResponse)}
|
||||
}
|
||||
|
||||
func (pc *PropertyCollector) WaitForUpdatesEx(r *types.WaitForUpdatesEx) soap.HasFault {
|
||||
func (pc *PropertyCollector) WaitForUpdatesEx(ctx *Context, r *types.WaitForUpdatesEx) soap.HasFault {
|
||||
body := &methods.WaitForUpdatesExBody{}
|
||||
|
||||
// At the moment we need to support Task completion. Handlers can simply set the Task
|
||||
@ -485,12 +517,12 @@ func (pc *PropertyCollector) WaitForUpdatesEx(r *types.WaitForUpdatesEx) soap.Ha
|
||||
}
|
||||
|
||||
for _, ref := range pc.Filter {
|
||||
filter := Map.Get(ref).(*PropertyFilter)
|
||||
filter := ctx.Session.Get(ref).(*PropertyFilter)
|
||||
|
||||
r := &types.RetrievePropertiesEx{}
|
||||
r.SpecSet = append(r.SpecSet, filter.Spec)
|
||||
|
||||
res, fault := pc.collect(r)
|
||||
res, fault := pc.collect(ctx, r)
|
||||
if fault != nil {
|
||||
body.Fault_ = Fault("", fault)
|
||||
return body
|
||||
@ -528,10 +560,10 @@ func (pc *PropertyCollector) WaitForUpdatesEx(r *types.WaitForUpdatesEx) soap.Ha
|
||||
}
|
||||
|
||||
// WaitForUpdates is deprecated, but pyvmomi is still using it at the moment.
|
||||
func (pc *PropertyCollector) WaitForUpdates(r *types.WaitForUpdates) soap.HasFault {
|
||||
func (pc *PropertyCollector) WaitForUpdates(ctx *Context, r *types.WaitForUpdates) soap.HasFault {
|
||||
body := &methods.WaitForUpdatesBody{}
|
||||
|
||||
res := pc.WaitForUpdatesEx(&types.WaitForUpdatesEx{
|
||||
res := pc.WaitForUpdatesEx(ctx, &types.WaitForUpdatesEx{
|
||||
This: r.This,
|
||||
Version: r.Version,
|
||||
})
|
||||
|
2
vendor/github.com/vmware/govmomi/simulator/property_filter.go
generated
vendored
2
vendor/github.com/vmware/govmomi/simulator/property_filter.go
generated
vendored
@ -32,7 +32,7 @@ type PropertyFilter struct {
|
||||
func (f *PropertyFilter) DestroyPropertyFilter(c *types.DestroyPropertyFilter) soap.HasFault {
|
||||
body := &methods.DestroyPropertyFilterBody{}
|
||||
|
||||
f.pc.Filter = RemoveReference(c.This, f.pc.Filter)
|
||||
RemoveReference(&f.pc.Filter, c.This)
|
||||
|
||||
Map.Remove(c.This)
|
||||
|
||||
|
133
vendor/github.com/vmware/govmomi/simulator/registry.go
generated
vendored
133
vendor/github.com/vmware/govmomi/simulator/registry.go
generated
vendored
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2017 VMware, Inc. All Rights Reserved.
|
||||
Copyright (c) 2017-2018 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.
|
||||
@ -17,7 +17,9 @@ limitations under the License.
|
||||
package simulator
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
@ -55,6 +57,7 @@ type Registry struct {
|
||||
m sync.Mutex
|
||||
objects map[types.ManagedObjectReference]mo.Reference
|
||||
handlers map[types.ManagedObjectReference]RegisterObject
|
||||
locks map[types.ManagedObjectReference]sync.Locker
|
||||
counter int
|
||||
}
|
||||
|
||||
@ -63,6 +66,7 @@ func NewRegistry() *Registry {
|
||||
r := &Registry{
|
||||
objects: make(map[types.ManagedObjectReference]mo.Reference),
|
||||
handlers: make(map[types.ManagedObjectReference]RegisterObject),
|
||||
locks: make(map[types.ManagedObjectReference]sync.Locker),
|
||||
}
|
||||
|
||||
return r
|
||||
@ -99,6 +103,11 @@ func (r *Registry) newReference(item mo.Reference) types.ManagedObjectReference
|
||||
return ref
|
||||
}
|
||||
|
||||
func (r *Registry) setReference(item mo.Reference, ref types.ManagedObjectReference) {
|
||||
// mo.Reference() returns a value, not a pointer so use reflect to set the Self field
|
||||
reflect.ValueOf(item).Elem().FieldByName("Self").Set(reflect.ValueOf(ref))
|
||||
}
|
||||
|
||||
// AddHandler adds a RegisterObject handler to the Registry.
|
||||
func (r *Registry) AddHandler(h RegisterObject) {
|
||||
r.handlers[h.Reference()] = h
|
||||
@ -156,8 +165,7 @@ func (r *Registry) Put(item mo.Reference) mo.Reference {
|
||||
ref := item.Reference()
|
||||
if ref.Type == "" || ref.Value == "" {
|
||||
ref = r.newReference(item)
|
||||
// mo.Reference() returns a value, not a pointer so use reflect to set the Self field
|
||||
reflect.ValueOf(item).Elem().FieldByName("Self").Set(reflect.ValueOf(ref))
|
||||
r.setReference(item, ref)
|
||||
}
|
||||
|
||||
if me, ok := item.(mo.Entity); ok {
|
||||
@ -186,6 +194,7 @@ func (r *Registry) Remove(item types.ManagedObjectReference) {
|
||||
|
||||
delete(r.objects, item)
|
||||
delete(r.handlers, item)
|
||||
delete(r.locks, item)
|
||||
}
|
||||
|
||||
// getEntityParent traverses up the inventory and returns the first object of type kind.
|
||||
@ -278,29 +287,48 @@ func FindReference(refs []types.ManagedObjectReference, match ...types.ManagedOb
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemoveReference returns a slice with ref removed from refs
|
||||
func RemoveReference(ref types.ManagedObjectReference, refs []types.ManagedObjectReference) []types.ManagedObjectReference {
|
||||
var result []types.ManagedObjectReference
|
||||
|
||||
for i, r := range refs {
|
||||
if r == ref {
|
||||
result = append(result, refs[i+1:]...)
|
||||
break
|
||||
}
|
||||
|
||||
result = append(result, r)
|
||||
}
|
||||
|
||||
return result
|
||||
// AppendReference appends the given refs to field.
|
||||
func (r *Registry) AppendReference(obj mo.Reference, field *[]types.ManagedObjectReference, ref ...types.ManagedObjectReference) {
|
||||
r.WithLock(obj, func() {
|
||||
*field = append(*field, ref...)
|
||||
})
|
||||
}
|
||||
|
||||
// AddReference returns a slice with ref appended if not already in refs.
|
||||
func AddReference(ref types.ManagedObjectReference, refs []types.ManagedObjectReference) []types.ManagedObjectReference {
|
||||
if FindReference(refs, ref) == nil {
|
||||
return append(refs, ref)
|
||||
}
|
||||
// AddReference appends ref to field if not already in the given field.
|
||||
func (r *Registry) AddReference(obj mo.Reference, field *[]types.ManagedObjectReference, ref types.ManagedObjectReference) {
|
||||
r.WithLock(obj, func() {
|
||||
if FindReference(*field, ref) == nil {
|
||||
*field = append(*field, ref)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return refs
|
||||
// RemoveReference removes ref from the given field.
|
||||
func RemoveReference(field *[]types.ManagedObjectReference, ref types.ManagedObjectReference) {
|
||||
for i, r := range *field {
|
||||
if r == ref {
|
||||
*field = append((*field)[:i], (*field)[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// RemoveReference removes ref from the given field.
|
||||
func (r *Registry) RemoveReference(obj mo.Reference, field *[]types.ManagedObjectReference, ref types.ManagedObjectReference) {
|
||||
r.WithLock(obj, func() {
|
||||
RemoveReference(field, ref)
|
||||
})
|
||||
}
|
||||
|
||||
func (r *Registry) removeString(obj mo.Reference, field *[]string, val string) {
|
||||
r.WithLock(obj, func() {
|
||||
for i, name := range *field {
|
||||
if name == val {
|
||||
*field = append((*field)[:i], (*field)[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (r *Registry) content() types.ServiceContent {
|
||||
@ -322,6 +350,11 @@ func (r *Registry) SearchIndex() *SearchIndex {
|
||||
return r.Get(r.content().SearchIndex.Reference()).(*SearchIndex)
|
||||
}
|
||||
|
||||
// EventManager returns the EventManager singleton
|
||||
func (r *Registry) EventManager() *EventManager {
|
||||
return r.Get(r.content().EventManager.Reference()).(*EventManager)
|
||||
}
|
||||
|
||||
// FileManager returns the FileManager singleton
|
||||
func (r *Registry) FileManager() *FileManager {
|
||||
return r.Get(r.content().FileManager.Reference()).(*FileManager)
|
||||
@ -336,3 +369,57 @@ func (r *Registry) VirtualDiskManager() *VirtualDiskManager {
|
||||
func (r *Registry) ViewManager() *ViewManager {
|
||||
return r.Get(r.content().ViewManager.Reference()).(*ViewManager)
|
||||
}
|
||||
|
||||
// UserDirectory returns the UserDirectory singleton
|
||||
func (r *Registry) UserDirectory() *UserDirectory {
|
||||
return r.Get(r.content().UserDirectory.Reference()).(*UserDirectory)
|
||||
}
|
||||
|
||||
// SessionManager returns the SessionManager singleton
|
||||
func (r *Registry) SessionManager() *SessionManager {
|
||||
return r.Get(r.content().SessionManager.Reference()).(*SessionManager)
|
||||
}
|
||||
|
||||
func (r *Registry) MarshalJSON() ([]byte, error) {
|
||||
r.m.Lock()
|
||||
defer r.m.Unlock()
|
||||
|
||||
vars := struct {
|
||||
Objects int
|
||||
Locks int
|
||||
}{
|
||||
len(r.objects),
|
||||
len(r.locks),
|
||||
}
|
||||
|
||||
return json.Marshal(vars)
|
||||
}
|
||||
|
||||
func (r *Registry) locker(obj mo.Reference) sync.Locker {
|
||||
if mu, ok := obj.(sync.Locker); ok {
|
||||
return mu
|
||||
}
|
||||
|
||||
ref := obj.Reference()
|
||||
r.m.Lock()
|
||||
mu, ok := r.locks[ref]
|
||||
if !ok {
|
||||
mu = new(sync.Mutex)
|
||||
r.locks[ref] = mu
|
||||
}
|
||||
r.m.Unlock()
|
||||
|
||||
return mu
|
||||
}
|
||||
|
||||
var enableLocker = os.Getenv("VCSIM_LOCKER") != "false"
|
||||
|
||||
// WithLock holds a lock for the given object while then given function is run.
|
||||
func (r *Registry) WithLock(obj mo.Reference, f func()) {
|
||||
if enableLocker {
|
||||
mu := r.locker(obj)
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
}
|
||||
f()
|
||||
}
|
||||
|
16
vendor/github.com/vmware/govmomi/simulator/resource_pool.go
generated
vendored
16
vendor/github.com/vmware/govmomi/simulator/resource_pool.go
generated
vendored
@ -252,12 +252,13 @@ func (p *ResourcePool) CreateVApp(req *types.CreateVApp) soap.HasFault {
|
||||
return body
|
||||
}
|
||||
|
||||
func (a *VirtualApp) CreateChildVMTask(req *types.CreateChildVM_Task) soap.HasFault {
|
||||
func (a *VirtualApp) CreateChildVMTask(ctx *Context, req *types.CreateChildVM_Task) soap.HasFault {
|
||||
ctx.Caller = &a.Self
|
||||
body := &methods.CreateChildVM_TaskBody{}
|
||||
|
||||
folder := Map.Get(*a.ParentFolder).(*Folder)
|
||||
|
||||
res := folder.CreateVMTask(&types.CreateVM_Task{
|
||||
res := folder.CreateVMTask(ctx, &types.CreateVM_Task{
|
||||
This: folder.Self,
|
||||
Config: req.Config,
|
||||
Host: req.Host,
|
||||
@ -286,18 +287,19 @@ func (p *ResourcePool) DestroyTask(req *types.Destroy_Task) soap.HasFault {
|
||||
|
||||
parent := &pp.ResourcePool
|
||||
// Remove child reference from rp
|
||||
parent.ResourcePool = RemoveReference(req.This, parent.ResourcePool)
|
||||
Map.RemoveReference(parent, &parent.ResourcePool, req.This)
|
||||
|
||||
// The grandchildren become children of the parent (rp)
|
||||
parent.ResourcePool = append(parent.ResourcePool, p.ResourcePool.ResourcePool...)
|
||||
Map.AppendReference(parent, &parent.ResourcePool, p.ResourcePool.ResourcePool...)
|
||||
|
||||
// And VMs move to the parent
|
||||
vms := p.ResourcePool.Vm
|
||||
for _, vm := range vms {
|
||||
Map.Get(vm).(*VirtualMachine).ResourcePool = &parent.Self
|
||||
for _, ref := range vms {
|
||||
vm := Map.Get(ref).(*VirtualMachine)
|
||||
Map.WithLock(vm, func() { vm.ResourcePool = &parent.Self })
|
||||
}
|
||||
|
||||
parent.Vm = append(parent.Vm, vms...)
|
||||
Map.AppendReference(parent, &parent.Vm, vms...)
|
||||
|
||||
Map.Remove(req.This)
|
||||
|
||||
|
5
vendor/github.com/vmware/govmomi/simulator/service_instance.go
generated
vendored
5
vendor/github.com/vmware/govmomi/simulator/service_instance.go
generated
vendored
@ -62,6 +62,7 @@ func NewServiceInstance(content types.ServiceContent, folder mo.Folder) *Service
|
||||
NewLicenseManager(*s.Content.LicenseManager),
|
||||
NewSearchIndex(*s.Content.SearchIndex),
|
||||
NewViewManager(*s.Content.ViewManager),
|
||||
NewEventManager(*s.Content.EventManager),
|
||||
NewTaskManager(*s.Content.TaskManager),
|
||||
NewUserDirectory(*s.Content.UserDirectory),
|
||||
NewOptionManager(s.Content.Setting, setting),
|
||||
@ -75,6 +76,10 @@ func NewServiceInstance(content types.ServiceContent, folder mo.Folder) *Service
|
||||
objects = append(objects, NewIpPoolManager(*s.Content.IpPoolManager))
|
||||
}
|
||||
|
||||
if s.Content.AccountManager != nil {
|
||||
objects = append(objects, NewHostLocalAccountManager(*s.Content.AccountManager))
|
||||
}
|
||||
|
||||
for _, o := range objects {
|
||||
Map.Put(o)
|
||||
}
|
||||
|
210
vendor/github.com/vmware/govmomi/simulator/session_manager.go
generated
vendored
210
vendor/github.com/vmware/govmomi/simulator/session_manager.go
generated
vendored
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2017 VMware, Inc. All Rights Reserved.
|
||||
Copyright (c) 2017-2018 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.
|
||||
@ -17,6 +17,10 @@ limitations under the License.
|
||||
package simulator
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
@ -33,26 +37,30 @@ type SessionManager struct {
|
||||
mo.SessionManager
|
||||
|
||||
ServiceHostName string
|
||||
|
||||
sessions map[string]Session
|
||||
}
|
||||
|
||||
func NewSessionManager(ref types.ManagedObjectReference) object.Reference {
|
||||
s := &SessionManager{}
|
||||
s := &SessionManager{
|
||||
sessions: make(map[string]Session),
|
||||
}
|
||||
s.Self = ref
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *SessionManager) Login(login *types.Login) soap.HasFault {
|
||||
func (s *SessionManager) Login(ctx *Context, login *types.Login) soap.HasFault {
|
||||
body := &methods.LoginBody{}
|
||||
|
||||
if login.Locale == "" {
|
||||
login.Locale = session.Locale
|
||||
}
|
||||
|
||||
if login.UserName == "" || login.Password == "" {
|
||||
body.Fault_ = Fault("Login failure", &types.InvalidLogin{})
|
||||
if login.UserName == "" || login.Password == "" || ctx.Session != nil {
|
||||
body.Fault_ = invalidLogin
|
||||
} else {
|
||||
body.Res = &types.LoginResponse{
|
||||
Returnval: types.UserSession{
|
||||
session := Session{
|
||||
UserSession: types.UserSession{
|
||||
Key: uuid.New().String(),
|
||||
UserName: login.UserName,
|
||||
FullName: login.UserName,
|
||||
@ -61,16 +69,80 @@ func (s *SessionManager) Login(login *types.Login) soap.HasFault {
|
||||
Locale: login.Locale,
|
||||
MessageLocale: login.Locale,
|
||||
},
|
||||
Registry: NewRegistry(),
|
||||
}
|
||||
|
||||
ctx.SetSession(session, true)
|
||||
|
||||
body.Res = &types.LoginResponse{
|
||||
Returnval: session.UserSession,
|
||||
}
|
||||
}
|
||||
|
||||
return body
|
||||
}
|
||||
|
||||
func (s *SessionManager) Logout(*types.Logout) soap.HasFault {
|
||||
func (s *SessionManager) Logout(ctx *Context, _ *types.Logout) soap.HasFault {
|
||||
session := ctx.Session
|
||||
delete(s.sessions, session.Key)
|
||||
|
||||
ctx.postEvent(&types.UserLogoutSessionEvent{
|
||||
IpAddress: session.IpAddress,
|
||||
UserAgent: session.UserAgent,
|
||||
SessionId: session.Key,
|
||||
LoginTime: &session.LoginTime,
|
||||
})
|
||||
|
||||
return &methods.LogoutBody{Res: new(types.LogoutResponse)}
|
||||
}
|
||||
|
||||
func (s *SessionManager) TerminateSession(ctx *Context, req *types.TerminateSession) soap.HasFault {
|
||||
body := new(methods.TerminateSessionBody)
|
||||
|
||||
for _, id := range req.SessionId {
|
||||
if id == ctx.Session.Key {
|
||||
body.Fault_ = Fault("", new(types.InvalidArgument))
|
||||
return body
|
||||
}
|
||||
delete(s.sessions, id)
|
||||
}
|
||||
|
||||
body.Res = new(types.TerminateSessionResponse)
|
||||
return body
|
||||
}
|
||||
|
||||
func (s *SessionManager) AcquireCloneTicket(ctx *Context, _ *types.AcquireCloneTicket) soap.HasFault {
|
||||
session := *ctx.Session
|
||||
session.Key = uuid.New().String()
|
||||
s.sessions[session.Key] = session
|
||||
|
||||
return &methods.AcquireCloneTicketBody{
|
||||
Res: &types.AcquireCloneTicketResponse{
|
||||
Returnval: session.Key,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SessionManager) CloneSession(ctx *Context, ticket *types.CloneSession) soap.HasFault {
|
||||
body := new(methods.CloneSessionBody)
|
||||
|
||||
session, exists := s.sessions[ticket.CloneTicket]
|
||||
|
||||
if exists {
|
||||
delete(s.sessions, ticket.CloneTicket) // A clone ticket can only be used once
|
||||
session.Key = uuid.New().String()
|
||||
ctx.SetSession(session, true)
|
||||
|
||||
body.Res = &types.CloneSessionResponse{
|
||||
Returnval: session.UserSession,
|
||||
}
|
||||
} else {
|
||||
body.Fault_ = invalidLogin
|
||||
}
|
||||
|
||||
return body
|
||||
}
|
||||
|
||||
func (s *SessionManager) AcquireGenericServiceTicket(ticket *types.AcquireGenericServiceTicket) soap.HasFault {
|
||||
return &methods.AcquireGenericServiceTicketBody{
|
||||
Res: &types.AcquireGenericServiceTicketResponse{
|
||||
@ -81,3 +153,125 @@ func (s *SessionManager) AcquireGenericServiceTicket(ticket *types.AcquireGeneri
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// internalContext is the session for use by the in-memory client (Service.RoundTrip)
|
||||
var internalContext = &Context{
|
||||
Context: context.Background(),
|
||||
Session: &Session{
|
||||
UserSession: types.UserSession{
|
||||
Key: uuid.New().String(),
|
||||
},
|
||||
Registry: NewRegistry(),
|
||||
},
|
||||
}
|
||||
|
||||
var invalidLogin = Fault("Login failure", new(types.InvalidLogin))
|
||||
|
||||
// Context provides per-request Session management.
|
||||
type Context struct {
|
||||
req *http.Request
|
||||
res http.ResponseWriter
|
||||
m *SessionManager
|
||||
|
||||
context.Context
|
||||
Session *Session
|
||||
Caller *types.ManagedObjectReference
|
||||
}
|
||||
|
||||
// mapSession maps an HTTP cookie to a Session.
|
||||
func (c *Context) mapSession() {
|
||||
if cookie, err := c.req.Cookie(soap.SessionCookieName); err == nil {
|
||||
if val, ok := c.m.sessions[cookie.Value]; ok {
|
||||
c.SetSession(val, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SetSession should be called after successful authentication.
|
||||
func (c *Context) SetSession(session Session, login bool) {
|
||||
session.UserAgent = c.req.UserAgent()
|
||||
session.IpAddress = strings.Split(c.req.RemoteAddr, ":")[0]
|
||||
session.LastActiveTime = time.Now()
|
||||
|
||||
c.m.sessions[session.Key] = session
|
||||
c.Session = &session
|
||||
|
||||
if login {
|
||||
http.SetCookie(c.res, &http.Cookie{
|
||||
Name: soap.SessionCookieName,
|
||||
Value: session.Key,
|
||||
})
|
||||
|
||||
c.postEvent(&types.UserLoginSessionEvent{
|
||||
SessionId: session.Key,
|
||||
IpAddress: session.IpAddress,
|
||||
UserAgent: session.UserAgent,
|
||||
Locale: session.Locale,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// WithLock holds a lock for the given object while then given function is run.
|
||||
func (c *Context) WithLock(obj mo.Reference, f func()) {
|
||||
if c.Caller != nil && *c.Caller == obj.Reference() {
|
||||
// Internal method invocation, obj is already locked
|
||||
f()
|
||||
return
|
||||
}
|
||||
Map.WithLock(obj, f)
|
||||
}
|
||||
|
||||
// postEvent wraps EventManager.PostEvent for internal use, with a lock on the EventManager.
|
||||
func (c *Context) postEvent(events ...types.BaseEvent) {
|
||||
m := Map.EventManager()
|
||||
c.WithLock(m, func() {
|
||||
for _, event := range events {
|
||||
m.PostEvent(c, &types.PostEvent{EventToPost: event})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Session combines a UserSession and a Registry for per-session managed objects.
|
||||
type Session struct {
|
||||
types.UserSession
|
||||
*Registry
|
||||
}
|
||||
|
||||
// Put wraps Registry.Put, setting the moref value to include the session key.
|
||||
func (s *Session) Put(item mo.Reference) mo.Reference {
|
||||
ref := item.Reference()
|
||||
if ref.Value == "" {
|
||||
ref.Value = fmt.Sprintf("session[%s]%s", s.Key, uuid.New())
|
||||
}
|
||||
s.Registry.setReference(item, ref)
|
||||
return s.Registry.Put(item)
|
||||
}
|
||||
|
||||
// Get wraps Registry.Get, session-izing singleton objects such as SessionManager and the root PropertyCollector.
|
||||
func (s *Session) Get(ref types.ManagedObjectReference) mo.Reference {
|
||||
obj := s.Registry.Get(ref)
|
||||
if obj != nil {
|
||||
return obj
|
||||
}
|
||||
|
||||
// Return a session "view" of certain singleton objects
|
||||
switch ref.Type {
|
||||
case "SessionManager":
|
||||
// Clone SessionManager so the PropertyCollector can properly report CurrentSession
|
||||
m := *Map.SessionManager()
|
||||
m.CurrentSession = &s.UserSession
|
||||
|
||||
// TODO: we could maintain SessionList as part of the SessionManager singleton
|
||||
for _, session := range m.sessions {
|
||||
m.SessionList = append(m.SessionList, session.UserSession)
|
||||
}
|
||||
|
||||
return &m
|
||||
case "PropertyCollector":
|
||||
if ref == Map.content().PropertyCollector {
|
||||
return s.Put(NewPropertyCollector(ref))
|
||||
}
|
||||
}
|
||||
|
||||
return Map.Get(ref)
|
||||
}
|
||||
|
105
vendor/github.com/vmware/govmomi/simulator/simulator.go
generated
vendored
105
vendor/github.com/vmware/govmomi/simulator/simulator.go
generated
vendored
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2017 VMware, Inc. All Rights Reserved.
|
||||
Copyright (c) 2017-2018 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.
|
||||
@ -59,10 +59,12 @@ type Method struct {
|
||||
// Service decodes incoming requests and dispatches to a Handler
|
||||
type Service struct {
|
||||
client *vim25.Client
|
||||
sm *SessionManager
|
||||
|
||||
readAll func(io.Reader) ([]byte, error)
|
||||
|
||||
TLS *tls.Config
|
||||
TLS *tls.Config
|
||||
ServeMux *http.ServeMux
|
||||
}
|
||||
|
||||
// Server provides a simulator Service over HTTP
|
||||
@ -77,6 +79,7 @@ type Server struct {
|
||||
func New(instance *ServiceInstance) *Service {
|
||||
s := &Service{
|
||||
readAll: ioutil.ReadAll,
|
||||
sm: Map.SessionManager(),
|
||||
}
|
||||
|
||||
s.client, _ = vim25.NewClient(context.Background(), s)
|
||||
@ -106,8 +109,29 @@ func Fault(msg string, fault types.BaseMethodFault) *soap.Fault {
|
||||
return f
|
||||
}
|
||||
|
||||
func (s *Service) call(method *Method) soap.HasFault {
|
||||
func (s *Service) call(ctx *Context, method *Method) soap.HasFault {
|
||||
handler := Map.Get(method.This)
|
||||
session := ctx.Session
|
||||
|
||||
if session == nil {
|
||||
switch method.Name {
|
||||
case "RetrieveServiceContent", "Login", "RetrieveProperties", "RetrievePropertiesEx", "CloneSession":
|
||||
// ok for now, TODO: authz
|
||||
default:
|
||||
fault := &types.NotAuthenticated{
|
||||
NoPermission: types.NoPermission{
|
||||
Object: method.This,
|
||||
PrivilegeId: "System.View",
|
||||
},
|
||||
}
|
||||
return &serverFaultBody{Reason: Fault("", fault)}
|
||||
}
|
||||
} else {
|
||||
// Prefer the Session.Registry, ServiceContent.PropertyCollector filter field for example is per-session
|
||||
if h := session.Get(method.This); h != nil {
|
||||
handler = h
|
||||
}
|
||||
}
|
||||
|
||||
if handler == nil {
|
||||
msg := fmt.Sprintf("managed object not found: %s", method.This)
|
||||
@ -141,7 +165,14 @@ func (s *Service) call(method *Method) soap.HasFault {
|
||||
}
|
||||
}
|
||||
|
||||
res := m.Call([]reflect.Value{reflect.ValueOf(method.Body)})
|
||||
var args, res []reflect.Value
|
||||
if m.Type().NumIn() == 2 {
|
||||
args = append(args, reflect.ValueOf(ctx))
|
||||
}
|
||||
args = append(args, reflect.ValueOf(method.Body))
|
||||
Map.WithLock(handler, func() {
|
||||
res = m.Call(args)
|
||||
})
|
||||
|
||||
return res[0].Interface().(soap.HasFault)
|
||||
}
|
||||
@ -165,7 +196,10 @@ func (s *Service) RoundTrip(ctx context.Context, request, response soap.HasFault
|
||||
Body: req.Interface(),
|
||||
}
|
||||
|
||||
res := s.call(method)
|
||||
res := s.call(&Context{
|
||||
Context: ctx,
|
||||
Session: internalContext.Session,
|
||||
}, method)
|
||||
|
||||
if err := res.Fault(); err != nil {
|
||||
return soap.WrapSoapFault(err)
|
||||
@ -226,7 +260,11 @@ func (s *Service) About(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
seen[m.Name] = true
|
||||
|
||||
if m.Type.NumIn() != 2 || m.Type.NumOut() != 1 || m.Type.Out(0) != f {
|
||||
in := m.Type.NumIn()
|
||||
if in < 2 || in > 3 { // at least 2 params (receiver and request), optionally a 3rd param (context)
|
||||
continue
|
||||
}
|
||||
if m.Type.NumOut() != 1 || m.Type.Out(0) != f { // all methods return soap.HasFault
|
||||
continue
|
||||
}
|
||||
|
||||
@ -262,6 +300,15 @@ func (s *Service) ServeSDK(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintf(os.Stderr, "Request: %s\n", string(body))
|
||||
}
|
||||
|
||||
ctx := &Context{
|
||||
req: r,
|
||||
res: w,
|
||||
m: s.sm,
|
||||
|
||||
Context: context.Background(),
|
||||
}
|
||||
Map.WithLock(s.sm, ctx.mapSession)
|
||||
|
||||
var res soap.HasFault
|
||||
var soapBody interface{}
|
||||
|
||||
@ -269,7 +316,7 @@ func (s *Service) ServeSDK(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
res = serverFault(err.Error())
|
||||
} else {
|
||||
res = s.call(method)
|
||||
res = s.call(ctx, method)
|
||||
}
|
||||
|
||||
if f := res.Fault(); f != nil {
|
||||
@ -349,20 +396,10 @@ func (s *Service) ServeDatastore(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
file := strings.TrimPrefix(r.URL.Path, folderPrefix)
|
||||
p := path.Join(ds.Info.GetDatastoreInfo().Url, file)
|
||||
r.URL.Path = strings.TrimPrefix(r.URL.Path, folderPrefix)
|
||||
p := path.Join(ds.Info.GetDatastoreInfo().Url, r.URL.Path)
|
||||
|
||||
switch r.Method {
|
||||
case "GET":
|
||||
f, err := os.Open(p)
|
||||
if err != nil {
|
||||
log.Printf("failed to %s '%s': %s", r.Method, p, err)
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
_, _ = io.Copy(w, f)
|
||||
case "POST":
|
||||
_, err := os.Stat(p)
|
||||
if err == nil {
|
||||
@ -384,7 +421,9 @@ func (s *Service) ServeDatastore(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
_, _ = io.Copy(f, r.Body)
|
||||
default:
|
||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||
fs := http.FileServer(http.Dir(ds.Info.GetDatastoreInfo().Url))
|
||||
|
||||
fs.ServeHTTP(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
@ -408,7 +447,11 @@ func (*Service) ServiceVersions(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// NewServer returns an http Server instance for the given service
|
||||
func (s *Service) NewServer() *Server {
|
||||
mux := http.NewServeMux()
|
||||
mux := s.ServeMux
|
||||
if mux == nil {
|
||||
mux = http.NewServeMux()
|
||||
}
|
||||
|
||||
path := "/sdk"
|
||||
|
||||
mux.HandleFunc(path, s.ServeSDK)
|
||||
@ -428,7 +471,7 @@ func (s *Service) NewServer() *Server {
|
||||
}
|
||||
|
||||
// Redirect clients to this http server, rather than HostSystem.Name
|
||||
Map.Get(*s.client.ServiceContent.SessionManager).(*SessionManager).ServiceHostName = u.Host
|
||||
Map.SessionManager().ServiceHostName = u.Host
|
||||
|
||||
if f := flag.Lookup("httptest.serve"); f != nil {
|
||||
// Avoid the blocking behaviour of httptest.Server.Start() when this flag is set
|
||||
@ -491,7 +534,23 @@ func (s *Server) Close() {
|
||||
}
|
||||
}
|
||||
|
||||
var typeFunc = types.TypeFunc()
|
||||
var (
|
||||
vim25MapType = types.TypeFunc()
|
||||
typeFunc = defaultMapType
|
||||
)
|
||||
|
||||
func defaultMapType(name string) (reflect.Type, bool) {
|
||||
typ, ok := vim25MapType(name)
|
||||
if !ok {
|
||||
// See TestIssue945, in which case Go does not resolve the namespace and name == "ns1:TraversalSpec"
|
||||
// Without this hack, the SelectSet would be all nil's
|
||||
kind := strings.SplitN(name, ":", 2)
|
||||
if len(kind) == 2 {
|
||||
typ, ok = vim25MapType(kind[1])
|
||||
}
|
||||
}
|
||||
return typ, ok
|
||||
}
|
||||
|
||||
// UnmarshalBody extracts the Body from a soap.Envelope and unmarshals to the corresponding govmomi type
|
||||
func UnmarshalBody(data []byte) (*Method, error) {
|
||||
|
16
vendor/github.com/vmware/govmomi/simulator/snapshot.go
generated
vendored
16
vendor/github.com/vmware/govmomi/simulator/snapshot.go
generated
vendored
@ -32,13 +32,14 @@ func (v *VirtualMachineSnapshot) RemoveSnapshotTask(req *types.RemoveSnapshot_Ta
|
||||
Map.Remove(req.This)
|
||||
|
||||
vm := Map.Get(v.Vm).(*VirtualMachine)
|
||||
Map.WithLock(vm, func() {
|
||||
if vm.Snapshot.CurrentSnapshot != nil && *vm.Snapshot.CurrentSnapshot == req.This {
|
||||
parent := findParentSnapshotInTree(vm.Snapshot.RootSnapshotList, req.This)
|
||||
vm.Snapshot.CurrentSnapshot = parent
|
||||
}
|
||||
|
||||
if vm.Snapshot.CurrentSnapshot != nil && *vm.Snapshot.CurrentSnapshot == req.This {
|
||||
parent := findParentSnapshotInTree(vm.Snapshot.RootSnapshotList, req.This)
|
||||
vm.Snapshot.CurrentSnapshot = parent
|
||||
}
|
||||
|
||||
vm.Snapshot.RootSnapshotList = removeSnapshotInTree(vm.Snapshot.RootSnapshotList, req.This, req.RemoveChildren)
|
||||
vm.Snapshot.RootSnapshotList = removeSnapshotInTree(vm.Snapshot.RootSnapshotList, req.This, req.RemoveChildren)
|
||||
})
|
||||
|
||||
return nil, nil
|
||||
})
|
||||
@ -54,8 +55,7 @@ func (v *VirtualMachineSnapshot) RevertToSnapshotTask(req *types.RevertToSnapsho
|
||||
task := CreateTask(v, "revertToSnapshot", func(t *Task) (types.AnyType, types.BaseMethodFault) {
|
||||
vm := Map.Get(v.Vm).(*VirtualMachine)
|
||||
|
||||
ref := v.Reference()
|
||||
vm.Snapshot.CurrentSnapshot = &ref
|
||||
Map.WithLock(vm, func() { vm.Snapshot.CurrentSnapshot = &v.Self })
|
||||
|
||||
return nil, nil
|
||||
})
|
||||
|
48
vendor/github.com/vmware/govmomi/simulator/user_directory.go
generated
vendored
48
vendor/github.com/vmware/govmomi/simulator/user_directory.go
generated
vendored
@ -50,14 +50,7 @@ func NewUserDirectory(ref types.ManagedObjectReference) object.Reference {
|
||||
func (u *UserDirectory) RetrieveUserGroups(req *types.RetrieveUserGroups) soap.HasFault {
|
||||
compare := compareFunc(req.SearchStr, req.ExactMatch)
|
||||
|
||||
var res []types.BaseUserSearchResult
|
||||
for _, ug := range u.userGroup {
|
||||
if req.FindUsers && !ug.Group || req.FindGroups && ug.Group {
|
||||
if compare(ug.Principal) {
|
||||
res = append(res, ug)
|
||||
}
|
||||
}
|
||||
}
|
||||
res := u.search(req.FindUsers, req.FindGroups, compare)
|
||||
|
||||
body := &methods.RetrieveUserGroupsBody{
|
||||
Res: &types.RetrieveUserGroupsResponse{
|
||||
@ -68,6 +61,45 @@ func (u *UserDirectory) RetrieveUserGroups(req *types.RetrieveUserGroups) soap.H
|
||||
return body
|
||||
}
|
||||
|
||||
func (u *UserDirectory) search(findUsers, findGroups bool, compare func(string) bool) (res []types.BaseUserSearchResult) {
|
||||
for _, ug := range u.userGroup {
|
||||
if findUsers && !ug.Group || findGroups && ug.Group {
|
||||
if compare(ug.Principal) {
|
||||
res = append(res, ug)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func (u *UserDirectory) addUser(id string) {
|
||||
u.add(id, false)
|
||||
}
|
||||
|
||||
func (u *UserDirectory) removeUser(id string) {
|
||||
u.remove(id, false)
|
||||
}
|
||||
|
||||
func (u *UserDirectory) add(id string, group bool) {
|
||||
user := &types.UserSearchResult{
|
||||
FullName: id,
|
||||
Group: group,
|
||||
Principal: id,
|
||||
}
|
||||
|
||||
u.userGroup = append(u.userGroup, user)
|
||||
}
|
||||
|
||||
func (u *UserDirectory) remove(id string, group bool) {
|
||||
for i, ug := range u.userGroup {
|
||||
if ug.Group == group && ug.Principal == id {
|
||||
u.userGroup = append(u.userGroup[:i], u.userGroup[i+1:]...)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func compareFunc(compared string, exactly bool) func(string) bool {
|
||||
return func(s string) bool {
|
||||
if exactly {
|
||||
|
26
vendor/github.com/vmware/govmomi/simulator/view_manager.go
generated
vendored
26
vendor/github.com/vmware/govmomi/simulator/view_manager.go
generated
vendored
@ -71,14 +71,14 @@ func NewViewManager(ref types.ManagedObjectReference) object.Reference {
|
||||
func destroyView(ref types.ManagedObjectReference) soap.HasFault {
|
||||
m := Map.ViewManager()
|
||||
|
||||
m.ViewList = RemoveReference(ref, m.ViewList)
|
||||
RemoveReference(&m.ViewList, ref)
|
||||
|
||||
return &methods.DestroyViewBody{
|
||||
Res: &types.DestroyViewResponse{},
|
||||
}
|
||||
}
|
||||
|
||||
func (m *ViewManager) CreateContainerView(req *types.CreateContainerView) soap.HasFault {
|
||||
func (m *ViewManager) CreateContainerView(ctx *Context, req *types.CreateContainerView) soap.HasFault {
|
||||
body := &methods.CreateContainerViewBody{}
|
||||
|
||||
root := Map.Get(req.Container)
|
||||
@ -117,7 +117,7 @@ func (m *ViewManager) CreateContainerView(req *types.CreateContainerView) soap.H
|
||||
}
|
||||
}
|
||||
|
||||
Map.Put(container)
|
||||
ctx.Session.Put(container)
|
||||
|
||||
m.ViewList = append(m.ViewList, container.Reference())
|
||||
|
||||
@ -125,7 +125,8 @@ func (m *ViewManager) CreateContainerView(req *types.CreateContainerView) soap.H
|
||||
Returnval: container.Self,
|
||||
}
|
||||
|
||||
container.add(root)
|
||||
seen := make(map[types.ManagedObjectReference]bool)
|
||||
container.add(root, seen)
|
||||
|
||||
return body
|
||||
}
|
||||
@ -148,7 +149,7 @@ func (v *ContainerView) include(o types.ManagedObjectReference) bool {
|
||||
return v.types[o.Type]
|
||||
}
|
||||
|
||||
func (v *ContainerView) add(root mo.Reference) {
|
||||
func walk(root mo.Reference, f func(child types.ManagedObjectReference)) {
|
||||
var children []types.ManagedObjectReference
|
||||
|
||||
switch e := root.(type) {
|
||||
@ -173,12 +174,21 @@ func (v *ContainerView) add(root mo.Reference) {
|
||||
}
|
||||
|
||||
for _, child := range children {
|
||||
f(child)
|
||||
}
|
||||
}
|
||||
|
||||
func (v *ContainerView) add(root mo.Reference, seen map[types.ManagedObjectReference]bool) {
|
||||
walk(root, func(child types.ManagedObjectReference) {
|
||||
if v.include(child) {
|
||||
v.View = AddReference(child, v.View)
|
||||
if seen[child] == false {
|
||||
seen[child] = true
|
||||
v.View = append(v.View, child)
|
||||
}
|
||||
}
|
||||
|
||||
if v.Recursive {
|
||||
v.add(Map.Get(child))
|
||||
v.add(Map.Get(child), seen)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
17
vendor/github.com/vmware/govmomi/simulator/virtual_disk_manager.go
generated
vendored
17
vendor/github.com/vmware/govmomi/simulator/virtual_disk_manager.go
generated
vendored
@ -45,7 +45,7 @@ func (m *VirtualDiskManager) names(name string) []string {
|
||||
}
|
||||
}
|
||||
|
||||
func (m *VirtualDiskManager) createVirtualDisk(req *types.CreateVirtualDisk_Task) types.BaseMethodFault {
|
||||
func (m *VirtualDiskManager) createVirtualDisk(op types.VirtualDeviceConfigSpecFileOperation, req *types.CreateVirtualDisk_Task) types.BaseMethodFault {
|
||||
fm := Map.FileManager()
|
||||
|
||||
file, fault := fm.resolve(req.Datacenter, req.Name)
|
||||
@ -53,10 +53,23 @@ func (m *VirtualDiskManager) createVirtualDisk(req *types.CreateVirtualDisk_Task
|
||||
return fault
|
||||
}
|
||||
|
||||
shouldReplace := op == types.VirtualDeviceConfigSpecFileOperationReplace
|
||||
shouldExist := op == ""
|
||||
for _, name := range m.names(file) {
|
||||
_, err := os.Stat(name)
|
||||
if err == nil {
|
||||
if shouldExist {
|
||||
return nil
|
||||
}
|
||||
if shouldReplace {
|
||||
if err = os.Truncate(file, 0); err != nil {
|
||||
return fm.fault(name, err, new(types.CannotCreateFile))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return fm.fault(name, nil, new(types.FileAlreadyExists))
|
||||
} else if shouldExist {
|
||||
return fm.fault(name, nil, new(types.FileNotFound))
|
||||
}
|
||||
|
||||
f, err := os.Create(name)
|
||||
@ -72,7 +85,7 @@ func (m *VirtualDiskManager) createVirtualDisk(req *types.CreateVirtualDisk_Task
|
||||
|
||||
func (m *VirtualDiskManager) CreateVirtualDiskTask(req *types.CreateVirtualDisk_Task) soap.HasFault {
|
||||
task := CreateTask(m, "createVirtualDisk", func(*Task) (types.AnyType, types.BaseMethodFault) {
|
||||
return nil, m.createVirtualDisk(req)
|
||||
return nil, m.createVirtualDisk(types.VirtualDeviceConfigSpecFileOperationCreate, req)
|
||||
})
|
||||
|
||||
return &methods.CreateVirtualDisk_TaskBody{
|
||||
|
296
vendor/github.com/vmware/govmomi/simulator/virtual_machine.go
generated
vendored
296
vendor/github.com/vmware/govmomi/simulator/virtual_machine.go
generated
vendored
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2017 VMware, Inc. All Rights Reserved.
|
||||
Copyright (c) 2017-2018 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.
|
||||
@ -18,7 +18,6 @@ package simulator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
@ -40,8 +39,7 @@ import (
|
||||
type VirtualMachine struct {
|
||||
mo.VirtualMachine
|
||||
|
||||
log *log.Logger
|
||||
out io.Closer
|
||||
log string
|
||||
sid int32
|
||||
}
|
||||
|
||||
@ -58,15 +56,22 @@ func NewVirtualMachine(parent types.ManagedObjectReference, spec *types.VirtualM
|
||||
}
|
||||
|
||||
rspec := types.DefaultResourceConfigSpec()
|
||||
vm.Guest = &types.GuestInfo{}
|
||||
vm.Config = &types.VirtualMachineConfigInfo{
|
||||
ExtraConfig: []types.BaseOptionValue{&types.OptionValue{Key: "govcsim", Value: "TRUE"}},
|
||||
Tools: &types.ToolsConfigInfo{},
|
||||
MemoryAllocation: &rspec.MemoryAllocation,
|
||||
CpuAllocation: &rspec.CpuAllocation,
|
||||
}
|
||||
vm.Snapshot = &types.VirtualMachineSnapshotInfo{}
|
||||
vm.Storage = &types.VirtualMachineStorageInfo{
|
||||
Timestamp: time.Now(),
|
||||
}
|
||||
vm.Summary.Guest = &types.VirtualMachineGuestSummary{}
|
||||
vm.Summary.Storage = &types.VirtualMachineStorageSummary{}
|
||||
vm.Summary.Vm = &vm.Self
|
||||
vm.Summary.Storage = &types.VirtualMachineStorageSummary{
|
||||
Timestamp: time.Now(),
|
||||
}
|
||||
|
||||
// Append VM Name as the directory name if not specified
|
||||
if strings.HasSuffix(spec.Files.VmPathName, "]") { // e.g. "[datastore1]"
|
||||
@ -84,6 +89,7 @@ func NewVirtualMachine(parent types.ManagedObjectReference, spec *types.VirtualM
|
||||
NumCoresPerSocket: 1,
|
||||
MemoryMB: 32,
|
||||
Uuid: uuid.New().String(),
|
||||
InstanceUuid: uuid.New().String(),
|
||||
Version: "vmx-11",
|
||||
Files: &types.VirtualMachineFileInfo{
|
||||
SnapshotDirectory: dsPath,
|
||||
@ -111,6 +117,22 @@ func NewVirtualMachine(parent types.ManagedObjectReference, spec *types.VirtualM
|
||||
return vm, nil
|
||||
}
|
||||
|
||||
func (vm *VirtualMachine) event() types.VmEvent {
|
||||
host := Map.Get(*vm.Runtime.Host).(*HostSystem)
|
||||
|
||||
return types.VmEvent{
|
||||
Event: types.Event{
|
||||
Datacenter: datacenterEventArgument(host),
|
||||
ComputeResource: host.eventArgumentParent(),
|
||||
Host: host.eventArgument(),
|
||||
Vm: &types.VmEventArgument{
|
||||
EntityEventArgument: types.EntityEventArgument{Name: vm.Name},
|
||||
Vm: vm.Self,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (vm *VirtualMachine) apply(spec *types.VirtualMachineConfigSpec) {
|
||||
if spec.Files == nil {
|
||||
spec.Files = new(types.VirtualMachineFileInfo)
|
||||
@ -120,6 +142,12 @@ func (vm *VirtualMachine) apply(spec *types.VirtualMachineConfigSpec) {
|
||||
src string
|
||||
dst *string
|
||||
}{
|
||||
{spec.AlternateGuestName, &vm.Config.AlternateGuestName},
|
||||
{spec.Annotation, &vm.Config.Annotation},
|
||||
{spec.Firmware, &vm.Config.Firmware},
|
||||
{spec.InstanceUuid, &vm.Config.InstanceUuid},
|
||||
{spec.LocationId, &vm.Config.LocationId},
|
||||
{spec.NpivWorldWideNameType, &vm.Config.NpivWorldWideNameType},
|
||||
{spec.Name, &vm.Name},
|
||||
{spec.Name, &vm.Config.Name},
|
||||
{spec.Name, &vm.Summary.Config.Name},
|
||||
@ -129,6 +157,9 @@ func (vm *VirtualMachine) apply(spec *types.VirtualMachineConfigSpec) {
|
||||
{spec.GuestId, &vm.Summary.Config.GuestId},
|
||||
{spec.GuestId, &vm.Summary.Config.GuestFullName},
|
||||
{spec.Uuid, &vm.Config.Uuid},
|
||||
{spec.Uuid, &vm.Summary.Config.Uuid},
|
||||
{spec.InstanceUuid, &vm.Config.InstanceUuid},
|
||||
{spec.InstanceUuid, &vm.Summary.Config.InstanceUuid},
|
||||
{spec.Version, &vm.Config.Version},
|
||||
{spec.Files.VmPathName, &vm.Config.Files.VmPathName},
|
||||
{spec.Files.VmPathName, &vm.Summary.Config.VmPathName},
|
||||
@ -142,6 +173,76 @@ func (vm *VirtualMachine) apply(spec *types.VirtualMachineConfigSpec) {
|
||||
}
|
||||
}
|
||||
|
||||
applyb := []struct {
|
||||
src *bool
|
||||
dst **bool
|
||||
}{
|
||||
{spec.NestedHVEnabled, &vm.Config.NestedHVEnabled},
|
||||
{spec.CpuHotAddEnabled, &vm.Config.CpuHotAddEnabled},
|
||||
{spec.CpuHotRemoveEnabled, &vm.Config.CpuHotRemoveEnabled},
|
||||
{spec.GuestAutoLockEnabled, &vm.Config.GuestAutoLockEnabled},
|
||||
{spec.MemoryHotAddEnabled, &vm.Config.MemoryHotAddEnabled},
|
||||
{spec.MemoryReservationLockedToMax, &vm.Config.MemoryReservationLockedToMax},
|
||||
{spec.MessageBusTunnelEnabled, &vm.Config.MessageBusTunnelEnabled},
|
||||
{spec.NpivTemporaryDisabled, &vm.Config.NpivTemporaryDisabled},
|
||||
{spec.NpivOnNonRdmDisks, &vm.Config.NpivOnNonRdmDisks},
|
||||
{spec.ChangeTrackingEnabled, &vm.Config.ChangeTrackingEnabled},
|
||||
}
|
||||
|
||||
for _, f := range applyb {
|
||||
if f.src != nil {
|
||||
*f.dst = f.src
|
||||
}
|
||||
}
|
||||
|
||||
if spec.Flags != nil {
|
||||
vm.Config.Flags = *spec.Flags
|
||||
}
|
||||
|
||||
if spec.LatencySensitivity != nil {
|
||||
vm.Config.LatencySensitivity = spec.LatencySensitivity
|
||||
}
|
||||
|
||||
if spec.ManagedBy != nil {
|
||||
vm.Config.ManagedBy = spec.ManagedBy
|
||||
}
|
||||
|
||||
if spec.BootOptions != nil {
|
||||
vm.Config.BootOptions = spec.BootOptions
|
||||
}
|
||||
|
||||
if spec.RepConfig != nil {
|
||||
vm.Config.RepConfig = spec.RepConfig
|
||||
}
|
||||
|
||||
if spec.Tools != nil {
|
||||
vm.Config.Tools = spec.Tools
|
||||
}
|
||||
|
||||
if spec.ConsolePreferences != nil {
|
||||
vm.Config.ConsolePreferences = spec.ConsolePreferences
|
||||
}
|
||||
|
||||
if spec.CpuAffinity != nil {
|
||||
vm.Config.CpuAffinity = spec.CpuAffinity
|
||||
}
|
||||
|
||||
if spec.CpuAllocation != nil {
|
||||
vm.Config.CpuAllocation = spec.CpuAllocation
|
||||
}
|
||||
|
||||
if spec.MemoryAffinity != nil {
|
||||
vm.Config.MemoryAffinity = spec.MemoryAffinity
|
||||
}
|
||||
|
||||
if spec.MemoryAllocation != nil {
|
||||
vm.Config.MemoryAllocation = spec.MemoryAllocation
|
||||
}
|
||||
|
||||
if spec.LatencySensitivity != nil {
|
||||
vm.Config.LatencySensitivity = spec.LatencySensitivity
|
||||
}
|
||||
|
||||
if spec.MemoryMB != 0 {
|
||||
vm.Config.Hardware.MemoryMB = int32(spec.MemoryMB)
|
||||
vm.Summary.Config.MemorySizeMB = vm.Config.Hardware.MemoryMB
|
||||
@ -152,11 +253,13 @@ func (vm *VirtualMachine) apply(spec *types.VirtualMachineConfigSpec) {
|
||||
vm.Summary.Config.NumCpu = vm.Config.Hardware.NumCPU
|
||||
}
|
||||
|
||||
if spec.NumCoresPerSocket != 0 {
|
||||
vm.Config.Hardware.NumCoresPerSocket = spec.NumCoresPerSocket
|
||||
}
|
||||
|
||||
vm.Config.ExtraConfig = append(vm.Config.ExtraConfig, spec.ExtraConfig...)
|
||||
|
||||
vm.Config.Modified = time.Now()
|
||||
|
||||
vm.Summary.Config.Uuid = vm.Config.Uuid
|
||||
}
|
||||
|
||||
func validateGuestID(id string) types.BaseMethodFault {
|
||||
@ -198,16 +301,13 @@ func (vm *VirtualMachine) useDatastore(name string) *Datastore {
|
||||
|
||||
ds := Map.FindByName(name, host.Datastore).(*Datastore)
|
||||
|
||||
vm.Datastore = AddReference(ds.Self, vm.Datastore)
|
||||
if FindReference(vm.Datastore, ds.Self) == nil {
|
||||
vm.Datastore = append(vm.Datastore, ds.Self)
|
||||
}
|
||||
|
||||
return ds
|
||||
}
|
||||
|
||||
func (vm *VirtualMachine) setLog(w io.WriteCloser) {
|
||||
vm.out = w
|
||||
vm.log = log.New(w, "vmx ", log.Flags())
|
||||
}
|
||||
|
||||
func (vm *VirtualMachine) createFile(spec string, name string, register bool) (*os.File, types.BaseMethodFault) {
|
||||
p, fault := parseDatastorePath(spec)
|
||||
if fault != nil {
|
||||
@ -263,17 +363,29 @@ func (vm *VirtualMachine) createFile(spec string, name string, register bool) (*
|
||||
return f, nil
|
||||
}
|
||||
|
||||
// Rather than keep an fd open for each VM, open/close the log for each messages.
|
||||
// This is ok for now as we do not do any heavy VM logging.
|
||||
func (vm *VirtualMachine) logPrintf(format string, v ...interface{}) {
|
||||
f, err := os.OpenFile(vm.log, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
log.New(f, "vmx ", log.Flags()).Printf(format, v...)
|
||||
_ = f.Close()
|
||||
}
|
||||
|
||||
func (vm *VirtualMachine) create(spec *types.VirtualMachineConfigSpec, register bool) types.BaseMethodFault {
|
||||
vm.apply(spec)
|
||||
|
||||
files := []struct {
|
||||
spec string
|
||||
name string
|
||||
use func(w io.WriteCloser)
|
||||
use *string
|
||||
}{
|
||||
{vm.Config.Files.VmPathName, "", nil},
|
||||
{vm.Config.Files.VmPathName, fmt.Sprintf("%s.nvram", vm.Name), nil},
|
||||
{vm.Config.Files.LogDirectory, "vmware.log", vm.setLog},
|
||||
{vm.Config.Files.LogDirectory, "vmware.log", &vm.log},
|
||||
}
|
||||
|
||||
for _, file := range files {
|
||||
@ -281,15 +393,13 @@ func (vm *VirtualMachine) create(spec *types.VirtualMachineConfigSpec, register
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if file.use != nil {
|
||||
file.use(f)
|
||||
} else {
|
||||
_ = f.Close()
|
||||
*file.use = f.Name()
|
||||
}
|
||||
_ = f.Close()
|
||||
}
|
||||
|
||||
vm.log.Print("created")
|
||||
vm.logPrintf("created")
|
||||
|
||||
return vm.configureDevices(spec)
|
||||
}
|
||||
@ -310,7 +420,8 @@ func (vm *VirtualMachine) generateMAC() string {
|
||||
return mac.String()
|
||||
}
|
||||
|
||||
func (vm *VirtualMachine) configureDevice(devices object.VirtualDeviceList, device types.BaseVirtualDevice) types.BaseMethodFault {
|
||||
func (vm *VirtualMachine) configureDevice(devices object.VirtualDeviceList, spec *types.VirtualDeviceConfigSpec) types.BaseMethodFault {
|
||||
device := spec.Device
|
||||
d := device.GetVirtualDevice()
|
||||
var controller types.BaseVirtualController
|
||||
|
||||
@ -371,7 +482,7 @@ func (vm *VirtualMachine) configureDevice(devices object.VirtualDeviceList, devi
|
||||
info.FileName = filename
|
||||
}
|
||||
|
||||
err := dm.createVirtualDisk(&types.CreateVirtualDisk_Task{
|
||||
err := dm.createVirtualDisk(spec.FileOperation, &types.CreateVirtualDisk_Task{
|
||||
Datacenter: &dc.Self,
|
||||
Name: info.FileName,
|
||||
})
|
||||
@ -381,10 +492,10 @@ func (vm *VirtualMachine) configureDevice(devices object.VirtualDeviceList, devi
|
||||
|
||||
p, _ := parseDatastorePath(info.FileName)
|
||||
|
||||
info.Datastore = &types.ManagedObjectReference{
|
||||
Type: "Datastore",
|
||||
Value: p.Datastore,
|
||||
}
|
||||
host := Map.Get(*vm.Runtime.Host).(*HostSystem)
|
||||
ds := Map.FindByName(p.Datastore, host.Datastore).Reference()
|
||||
|
||||
info.Datastore = &ds
|
||||
}
|
||||
}
|
||||
|
||||
@ -448,6 +559,9 @@ func (vm *VirtualMachine) genVmdkPath() (string, types.BaseMethodFault) {
|
||||
}
|
||||
|
||||
func (vm *VirtualMachine) configureDevices(spec *types.VirtualMachineConfigSpec) types.BaseMethodFault {
|
||||
dc := Map.getEntityDatacenter(Map.Get(*vm.Parent).(mo.Entity))
|
||||
dm := Map.VirtualDiskManager()
|
||||
|
||||
devices := object.VirtualDeviceList(vm.Config.Hardware.Device)
|
||||
|
||||
for i, change := range spec.DeviceChange {
|
||||
@ -466,7 +580,7 @@ func (vm *VirtualMachine) configureDevices(spec *types.VirtualMachineConfigSpec)
|
||||
devices = removeDevice(devices, device)
|
||||
}
|
||||
|
||||
err := vm.configureDevice(devices, dspec.Device)
|
||||
err := vm.configureDevice(devices, dspec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -474,6 +588,23 @@ func (vm *VirtualMachine) configureDevices(spec *types.VirtualMachineConfigSpec)
|
||||
devices = append(devices, dspec.Device)
|
||||
case types.VirtualDeviceConfigSpecOperationRemove:
|
||||
devices = removeDevice(devices, dspec.Device)
|
||||
|
||||
disk, ok := dspec.Device.(*types.VirtualDisk)
|
||||
if ok && dspec.FileOperation == types.VirtualDeviceConfigSpecFileOperationDestroy {
|
||||
var file string
|
||||
|
||||
switch b := disk.Backing.(type) {
|
||||
case types.BaseVirtualDeviceFileBackingInfo:
|
||||
file = b.GetVirtualDeviceFileBackingInfo().FileName
|
||||
}
|
||||
|
||||
if file != "" {
|
||||
dm.DeleteVirtualDiskTask(&types.DeleteVirtualDisk_Task{
|
||||
Name: file,
|
||||
Datacenter: &dc.Self,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -486,10 +617,11 @@ type powerVMTask struct {
|
||||
*VirtualMachine
|
||||
|
||||
state types.VirtualMachinePowerState
|
||||
ctx *Context
|
||||
}
|
||||
|
||||
func (c *powerVMTask) Run(task *Task) (types.AnyType, types.BaseMethodFault) {
|
||||
c.log.Printf("running power task: requesting %s, existing %s",
|
||||
c.logPrintf("running power task: requesting %s, existing %s",
|
||||
c.state, c.VirtualMachine.Runtime.PowerState)
|
||||
|
||||
if c.VirtualMachine.Runtime.PowerState == c.state {
|
||||
@ -510,11 +642,28 @@ func (c *powerVMTask) Run(task *Task) (types.AnyType, types.BaseMethodFault) {
|
||||
*bt = nil
|
||||
}
|
||||
|
||||
event := c.event()
|
||||
switch c.state {
|
||||
case types.VirtualMachinePowerStatePoweredOn:
|
||||
c.ctx.postEvent(
|
||||
&types.VmStartingEvent{VmEvent: event},
|
||||
&types.VmPoweredOnEvent{VmEvent: event},
|
||||
)
|
||||
case types.VirtualMachinePowerStatePoweredOff:
|
||||
c.ctx.postEvent(&types.VmPoweredOffEvent{VmEvent: event})
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (vm *VirtualMachine) PowerOnVMTask(c *types.PowerOnVM_Task) soap.HasFault {
|
||||
runner := &powerVMTask{vm, types.VirtualMachinePowerStatePoweredOn}
|
||||
func (vm *VirtualMachine) PowerOnVMTask(ctx *Context, c *types.PowerOnVM_Task) soap.HasFault {
|
||||
if vm.Config.Template {
|
||||
return &methods.PowerOnVM_TaskBody{
|
||||
Fault_: Fault("cannot powerOn a template", &types.InvalidState{}),
|
||||
}
|
||||
}
|
||||
|
||||
runner := &powerVMTask{vm, types.VirtualMachinePowerStatePoweredOn, ctx}
|
||||
task := CreateTask(runner.Reference(), "powerOn", runner.Run)
|
||||
|
||||
return &methods.PowerOnVM_TaskBody{
|
||||
@ -524,8 +673,8 @@ func (vm *VirtualMachine) PowerOnVMTask(c *types.PowerOnVM_Task) soap.HasFault {
|
||||
}
|
||||
}
|
||||
|
||||
func (vm *VirtualMachine) PowerOffVMTask(c *types.PowerOffVM_Task) soap.HasFault {
|
||||
runner := &powerVMTask{vm, types.VirtualMachinePowerStatePoweredOff}
|
||||
func (vm *VirtualMachine) PowerOffVMTask(ctx *Context, c *types.PowerOffVM_Task) soap.HasFault {
|
||||
runner := &powerVMTask{vm, types.VirtualMachinePowerStatePoweredOff, ctx}
|
||||
task := CreateTask(runner.Reference(), "powerOff", runner.Run)
|
||||
|
||||
return &methods.PowerOffVM_TaskBody{
|
||||
@ -535,13 +684,18 @@ func (vm *VirtualMachine) PowerOffVMTask(c *types.PowerOffVM_Task) soap.HasFault
|
||||
}
|
||||
}
|
||||
|
||||
func (vm *VirtualMachine) ReconfigVMTask(req *types.ReconfigVM_Task) soap.HasFault {
|
||||
func (vm *VirtualMachine) ReconfigVMTask(ctx *Context, req *types.ReconfigVM_Task) soap.HasFault {
|
||||
task := CreateTask(vm, "reconfigVm", func(t *Task) (types.AnyType, types.BaseMethodFault) {
|
||||
err := vm.configure(&req.Spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx.postEvent(&types.VmReconfiguredEvent{
|
||||
VmEvent: vm.event(),
|
||||
ConfigSpec: req.Spec,
|
||||
})
|
||||
|
||||
return nil, nil
|
||||
})
|
||||
|
||||
@ -552,9 +706,9 @@ func (vm *VirtualMachine) ReconfigVMTask(req *types.ReconfigVM_Task) soap.HasFau
|
||||
}
|
||||
}
|
||||
|
||||
func (vm *VirtualMachine) DestroyTask(req *types.Destroy_Task) soap.HasFault {
|
||||
func (vm *VirtualMachine) DestroyTask(ctx *Context, req *types.Destroy_Task) soap.HasFault {
|
||||
task := CreateTask(vm, "destroy", func(t *Task) (types.AnyType, types.BaseMethodFault) {
|
||||
r := vm.UnregisterVM(&types.UnregisterVM{
|
||||
r := vm.UnregisterVM(ctx, &types.UnregisterVM{
|
||||
This: req.This,
|
||||
})
|
||||
|
||||
@ -582,7 +736,7 @@ func (vm *VirtualMachine) DestroyTask(req *types.Destroy_Task) soap.HasFault {
|
||||
}
|
||||
}
|
||||
|
||||
func (vm *VirtualMachine) UnregisterVM(c *types.UnregisterVM) soap.HasFault {
|
||||
func (vm *VirtualMachine) UnregisterVM(ctx *Context, c *types.UnregisterVM) soap.HasFault {
|
||||
r := &methods.UnregisterVMBody{}
|
||||
|
||||
if vm.Runtime.PowerState == types.VirtualMachinePowerStatePoweredOn {
|
||||
@ -594,34 +748,45 @@ func (vm *VirtualMachine) UnregisterVM(c *types.UnregisterVM) soap.HasFault {
|
||||
return r
|
||||
}
|
||||
|
||||
_ = vm.out.Close() // Close log fd
|
||||
|
||||
Map.getEntityParent(vm, "Folder").(*Folder).removeChild(c.This)
|
||||
|
||||
host := Map.Get(*vm.Runtime.Host).(*HostSystem)
|
||||
host.Vm = RemoveReference(vm.Self, host.Vm)
|
||||
Map.RemoveReference(host, &host.Vm, vm.Self)
|
||||
|
||||
switch pool := Map.Get(*vm.ResourcePool).(type) {
|
||||
case *ResourcePool:
|
||||
pool.Vm = RemoveReference(vm.Self, pool.Vm)
|
||||
Map.RemoveReference(pool, &pool.Vm, vm.Self)
|
||||
case *VirtualApp:
|
||||
pool.Vm = RemoveReference(vm.Self, pool.Vm)
|
||||
Map.RemoveReference(pool, &pool.Vm, vm.Self)
|
||||
}
|
||||
|
||||
for i := range vm.Datastore {
|
||||
ds := Map.Get(vm.Datastore[i]).(*Datastore)
|
||||
ds.Vm = RemoveReference(vm.Self, ds.Vm)
|
||||
Map.RemoveReference(ds, &ds.Vm, vm.Self)
|
||||
}
|
||||
|
||||
ctx.postEvent(&types.VmRemovedEvent{VmEvent: vm.event()})
|
||||
Map.getEntityParent(vm, "Folder").(*Folder).removeChild(c.This)
|
||||
|
||||
r.Res = new(types.UnregisterVMResponse)
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func (vm *VirtualMachine) CloneVMTask(req *types.CloneVM_Task) soap.HasFault {
|
||||
task := CreateTask(vm, "cloneVm", func(t *Task) (types.AnyType, types.BaseMethodFault) {
|
||||
folder := Map.Get(req.Folder).(*Folder)
|
||||
func (vm *VirtualMachine) CloneVMTask(ctx *Context, req *types.CloneVM_Task) soap.HasFault {
|
||||
ctx.Caller = &vm.Self
|
||||
folder := Map.Get(req.Folder).(*Folder)
|
||||
host := Map.Get(*vm.Runtime.Host).(*HostSystem)
|
||||
event := vm.event()
|
||||
|
||||
ctx.postEvent(&types.VmBeingClonedEvent{
|
||||
VmCloneEvent: types.VmCloneEvent{
|
||||
VmEvent: event,
|
||||
},
|
||||
DestFolder: folder.eventArgument(),
|
||||
DestName: req.Name,
|
||||
DestHost: *host.eventArgument(),
|
||||
})
|
||||
|
||||
task := CreateTask(vm, "cloneVm", func(t *Task) (types.AnyType, types.BaseMethodFault) {
|
||||
config := types.VirtualMachineConfigSpec{
|
||||
Name: req.Name,
|
||||
GuestId: vm.Config.GuestId,
|
||||
@ -630,10 +795,11 @@ func (vm *VirtualMachine) CloneVMTask(req *types.CloneVM_Task) soap.HasFault {
|
||||
},
|
||||
}
|
||||
|
||||
res := folder.CreateVMTask(&types.CreateVM_Task{
|
||||
res := folder.CreateVMTask(ctx, &types.CreateVM_Task{
|
||||
This: folder.Self,
|
||||
Config: config,
|
||||
Pool: *vm.ResourcePool,
|
||||
Host: vm.Runtime.Host,
|
||||
})
|
||||
|
||||
ctask := Map.Get(res.(*methods.CreateVM_TaskBody).Res.Returnval).(*Task)
|
||||
@ -641,7 +807,15 @@ func (vm *VirtualMachine) CloneVMTask(req *types.CloneVM_Task) soap.HasFault {
|
||||
return nil, ctask.Info.Error.Fault
|
||||
}
|
||||
|
||||
return ctask.Info.Result.(types.ManagedObjectReference), nil
|
||||
ref := ctask.Info.Result.(types.ManagedObjectReference)
|
||||
clone := Map.Get(ref).(*VirtualMachine)
|
||||
|
||||
ctx.postEvent(&types.VmClonedEvent{
|
||||
VmCloneEvent: types.VmCloneEvent{VmEvent: clone.event()},
|
||||
SourceVm: *event.Vm,
|
||||
})
|
||||
|
||||
return ref, nil
|
||||
})
|
||||
|
||||
return &methods.CloneVM_TaskBody{
|
||||
@ -655,7 +829,7 @@ func (vm *VirtualMachine) RelocateVMTask(req *types.RelocateVM_Task) soap.HasFau
|
||||
task := CreateTask(vm, "relocateVm", func(t *Task) (types.AnyType, types.BaseMethodFault) {
|
||||
if ref := req.Spec.Datastore; ref != nil {
|
||||
ds := Map.Get(*ref).(*Datastore)
|
||||
ds.Vm = RemoveReference(*ref, ds.Vm)
|
||||
Map.RemoveReference(ds, &ds.Vm, *ref)
|
||||
|
||||
vm.Datastore = []types.ManagedObjectReference{*ref}
|
||||
|
||||
@ -664,14 +838,14 @@ func (vm *VirtualMachine) RelocateVMTask(req *types.RelocateVM_Task) soap.HasFau
|
||||
|
||||
if ref := req.Spec.Pool; ref != nil {
|
||||
pool := Map.Get(*ref).(*ResourcePool)
|
||||
pool.Vm = RemoveReference(*ref, pool.Vm)
|
||||
Map.RemoveReference(pool, &pool.Vm, *ref)
|
||||
|
||||
vm.ResourcePool = ref
|
||||
}
|
||||
|
||||
if ref := req.Spec.Host; ref != nil {
|
||||
host := Map.Get(*ref).(*HostSystem)
|
||||
host.Vm = RemoveReference(*ref, host.Vm)
|
||||
Map.RemoveReference(host, &host.Vm, *ref)
|
||||
|
||||
vm.Runtime.Host = ref
|
||||
}
|
||||
@ -799,6 +973,24 @@ func (vm *VirtualMachine) ShutdownGuest(c *types.ShutdownGuest) soap.HasFault {
|
||||
return r
|
||||
}
|
||||
|
||||
func (vm *VirtualMachine) MarkAsTemplate(req *types.MarkAsTemplate) soap.HasFault {
|
||||
r := &methods.MarkAsTemplateBody{}
|
||||
|
||||
if vm.Runtime.PowerState != types.VirtualMachinePowerStatePoweredOff {
|
||||
r.Fault_ = Fault("", &types.InvalidPowerState{
|
||||
RequestedState: types.VirtualMachinePowerStatePoweredOff,
|
||||
ExistingState: vm.Runtime.PowerState,
|
||||
})
|
||||
return r
|
||||
}
|
||||
|
||||
vm.Config.Template = true
|
||||
|
||||
r.Res = &types.MarkAsTemplateResponse{}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func findSnapshotInTree(tree []types.VirtualMachineSnapshotTree, ref types.ManagedObjectReference) *types.VirtualMachineSnapshotTree {
|
||||
if tree == nil {
|
||||
return nil
|
||||
|
12
vendor/github.com/vmware/govmomi/simulator/vpx/setting.go
generated
vendored
12
vendor/github.com/vmware/govmomi/simulator/vpx/setting.go
generated
vendored
@ -57,4 +57,16 @@ var Setting = []types.BaseOptionValue{
|
||||
Key: "config.vpxd.sso.admin.uri",
|
||||
Value: "https://127.0.0.1/sso-adminserver/sdk/vsphere.local",
|
||||
},
|
||||
&types.OptionValue{
|
||||
Key: "event.batchsize",
|
||||
Value: int32(2000),
|
||||
},
|
||||
&types.OptionValue{
|
||||
Key: "event.maxAge",
|
||||
Value: int32(30),
|
||||
},
|
||||
&types.OptionValue{
|
||||
Key: "event.maxAgeEnabled",
|
||||
Value: bool(true),
|
||||
},
|
||||
}
|
||||
|
25
vendor/github.com/vmware/govmomi/vim25/progress/reader.go
generated
vendored
25
vendor/github.com/vmware/govmomi/vim25/progress/reader.go
generated
vendored
@ -18,6 +18,7 @@ package progress
|
||||
|
||||
import (
|
||||
"container/list"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"sync/atomic"
|
||||
@ -75,16 +76,16 @@ type reader struct {
|
||||
|
||||
pos int64
|
||||
size int64
|
||||
bps uint64
|
||||
|
||||
bps uint64
|
||||
|
||||
ch chan<- Report
|
||||
ch chan<- Report
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
func NewReader(s Sinker, r io.Reader, size int64) *reader {
|
||||
func NewReader(ctx context.Context, s Sinker, r io.Reader, size int64) *reader {
|
||||
pr := reader{
|
||||
r: r,
|
||||
|
||||
r: r,
|
||||
ctx: ctx,
|
||||
size: size,
|
||||
}
|
||||
|
||||
@ -111,7 +112,10 @@ func (r *reader) Read(b []byte) (int, error) {
|
||||
bps: &r.bps,
|
||||
}
|
||||
|
||||
r.ch <- q
|
||||
select {
|
||||
case r.ch <- q:
|
||||
case <-r.ctx.Done():
|
||||
}
|
||||
|
||||
return n, err
|
||||
}
|
||||
@ -127,8 +131,11 @@ func (r *reader) Done(err error) {
|
||||
err: err,
|
||||
}
|
||||
|
||||
r.ch <- q
|
||||
close(r.ch)
|
||||
select {
|
||||
case r.ch <- q:
|
||||
close(r.ch)
|
||||
case <-r.ctx.Done():
|
||||
}
|
||||
}
|
||||
|
||||
// newBpsLoop returns a sink that monitors and stores throughput.
|
||||
|
35
vendor/github.com/vmware/govmomi/vim25/soap/client.go
generated
vendored
35
vendor/github.com/vmware/govmomi/vim25/soap/client.go
generated
vendored
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2014-2017 VMware, Inc. All Rights Reserved.
|
||||
Copyright (c) 2014-2018 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.
|
||||
@ -56,6 +56,7 @@ const (
|
||||
DefaultVimNamespace = "urn:vim25"
|
||||
DefaultVimVersion = "6.5"
|
||||
DefaultMinVimVersion = "5.5"
|
||||
SessionCookieName = "vmware_soap_session"
|
||||
)
|
||||
|
||||
type header struct {
|
||||
@ -168,7 +169,7 @@ func (c *Client) NewServiceClient(path string, namespace string) *Client {
|
||||
|
||||
// Set SOAP Header cookie
|
||||
for _, cookie := range client.Jar.Cookies(u) {
|
||||
if cookie.Name == "vmware_soap_session" {
|
||||
if cookie.Name == SessionCookieName {
|
||||
client.cookie = cookie.Value
|
||||
break
|
||||
}
|
||||
@ -458,6 +459,8 @@ func (c *Client) RoundTrip(ctx context.Context, reqBody, resBody HasFault) error
|
||||
panic(err)
|
||||
}
|
||||
|
||||
req = req.WithContext(ctx)
|
||||
|
||||
req.Header.Set(`Content-Type`, `text/xml; charset="utf-8"`)
|
||||
soapAction := fmt.Sprintf("%s/%s", c.Namespace, c.Version)
|
||||
req.Header.Set(`SOAPAction`, soapAction)
|
||||
@ -548,11 +551,11 @@ var DefaultUpload = Upload{
|
||||
}
|
||||
|
||||
// Upload PUTs the local file to the given URL
|
||||
func (c *Client) Upload(f io.Reader, u *url.URL, param *Upload) error {
|
||||
func (c *Client) Upload(ctx context.Context, f io.Reader, u *url.URL, param *Upload) error {
|
||||
var err error
|
||||
|
||||
if param.Progress != nil {
|
||||
pr := progress.NewReader(param.Progress, f, param.ContentLength)
|
||||
pr := progress.NewReader(ctx, param.Progress, f, param.ContentLength)
|
||||
f = pr
|
||||
|
||||
// Mark progress reader as done when returning from this function.
|
||||
@ -566,6 +569,8 @@ func (c *Client) Upload(f io.Reader, u *url.URL, param *Upload) error {
|
||||
return err
|
||||
}
|
||||
|
||||
req = req.WithContext(ctx)
|
||||
|
||||
req.ContentLength = param.ContentLength
|
||||
req.Header.Set("Content-Type", param.Type)
|
||||
|
||||
@ -593,7 +598,7 @@ func (c *Client) Upload(f io.Reader, u *url.URL, param *Upload) error {
|
||||
}
|
||||
|
||||
// UploadFile PUTs the local file to the given URL
|
||||
func (c *Client) UploadFile(file string, u *url.URL, param *Upload) error {
|
||||
func (c *Client) UploadFile(ctx context.Context, file string, u *url.URL, param *Upload) error {
|
||||
if param == nil {
|
||||
p := DefaultUpload // Copy since we set ContentLength
|
||||
param = &p
|
||||
@ -612,7 +617,7 @@ func (c *Client) UploadFile(file string, u *url.URL, param *Upload) error {
|
||||
|
||||
param.ContentLength = s.Size()
|
||||
|
||||
return c.Upload(f, u, param)
|
||||
return c.Upload(ctx, f, u, param)
|
||||
}
|
||||
|
||||
type Download struct {
|
||||
@ -628,12 +633,14 @@ var DefaultDownload = Download{
|
||||
}
|
||||
|
||||
// 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) {
|
||||
func (c *Client) DownloadRequest(ctx context.Context, u *url.URL, param *Download) (*http.Response, error) {
|
||||
req, err := http.NewRequest(param.Method, u.String(), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req = req.WithContext(ctx)
|
||||
|
||||
for k, v := range param.Headers {
|
||||
req.Header.Add(k, v)
|
||||
}
|
||||
@ -646,8 +653,8 @@ func (c *Client) DownloadRequest(u *url.URL, param *Download) (*http.Response, e
|
||||
}
|
||||
|
||||
// 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)
|
||||
func (c *Client) Download(ctx context.Context, u *url.URL, param *Download) (io.ReadCloser, int64, error) {
|
||||
res, err := c.DownloadRequest(ctx, u, param)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
@ -667,7 +674,7 @@ func (c *Client) Download(u *url.URL, param *Download) (io.ReadCloser, int64, er
|
||||
return r, res.ContentLength, nil
|
||||
}
|
||||
|
||||
func (c *Client) WriteFile(file string, src io.Reader, size int64, s progress.Sinker, w io.Writer) error {
|
||||
func (c *Client) WriteFile(ctx context.Context, file string, src io.Reader, size int64, s progress.Sinker, w io.Writer) error {
|
||||
var err error
|
||||
|
||||
r := src
|
||||
@ -678,7 +685,7 @@ func (c *Client) WriteFile(file string, src io.Reader, size int64, s progress.Si
|
||||
}
|
||||
|
||||
if s != nil {
|
||||
pr := progress.NewReader(s, src, size)
|
||||
pr := progress.NewReader(ctx, s, src, size)
|
||||
src = pr
|
||||
|
||||
// Mark progress reader as done when returning from this function.
|
||||
@ -705,16 +712,16 @@ func (c *Client) WriteFile(file string, src io.Reader, size int64, s progress.Si
|
||||
}
|
||||
|
||||
// DownloadFile GETs the given URL to a local file
|
||||
func (c *Client) DownloadFile(file string, u *url.URL, param *Download) error {
|
||||
func (c *Client) DownloadFile(ctx context.Context, file string, u *url.URL, param *Download) error {
|
||||
var err error
|
||||
if param == nil {
|
||||
param = &DefaultDownload
|
||||
}
|
||||
|
||||
rc, contentLength, err := c.Download(u, param)
|
||||
rc, contentLength, err := c.Download(ctx, u, param)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.WriteFile(file, rc, contentLength, param.Progress, param.Writer)
|
||||
return c.WriteFile(ctx, file, rc, contentLength, param.Progress, param.Writer)
|
||||
}
|
||||
|
7
vendor/github.com/vmware/govmomi/vim25/types/helpers.go
generated
vendored
7
vendor/github.com/vmware/govmomi/vim25/types/helpers.go
generated
vendored
@ -17,6 +17,7 @@ limitations under the License.
|
||||
package types
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
@ -86,3 +87,9 @@ func DefaultResourceConfigSpec() ResourceConfigSpec {
|
||||
MemoryAllocation: defaultResourceAllocationInfo(),
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
// Known 6.5 issue where this event type is sent even though it is internal.
|
||||
// This workaround allows us to unmarshal and avoid NPEs.
|
||||
t["HostSubSpecificationUpdateEvent"] = reflect.TypeOf((*HostEvent)(nil)).Elem()
|
||||
}
|
||||
|
2
vendor/github.com/vmware/govmomi/vim25/types/types.go
generated
vendored
2
vendor/github.com/vmware/govmomi/vim25/types/types.go
generated
vendored
@ -48188,7 +48188,7 @@ func init() {
|
||||
type VirtualMachineAffinityInfo struct {
|
||||
DynamicData
|
||||
|
||||
AffinitySet []int32 `xml:"affinitySet,omitempty"`
|
||||
AffinitySet []int32 `xml:"affinitySet"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
Loading…
Reference in New Issue
Block a user