From 9b3f1ce2e473aea68e46e821c3319cb583fe3b9b Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Thu, 21 Dec 2017 14:14:33 -0800 Subject: [PATCH 1/3] Update govmomi --- .../vmware/govmomi/event/manager.go | 8 +- .../vmware/govmomi/event/processor.go | 19 +- .../github.com/vmware/govmomi/find/finder.go | 21 ++ .../vmware/govmomi/govc/cluster/add.go | 18 +- .../govmomi/govc/cluster/group/change.go | 75 +++++++ .../govmomi/govc/cluster/group/create.go | 86 ++++++++ .../govmomi/govc/cluster/group/info_flag.go | 121 ++++++++++++ .../vmware/govmomi/govc/cluster/group/ls.go | 92 +++++++++ .../govmomi/govc/cluster/group/remove.go | 61 ++++++ .../govmomi/govc/cluster/rule/change.go | 93 +++++++++ .../govmomi/govc/cluster/rule/create.go | 118 +++++++++++ .../govmomi/govc/cluster/rule/info_flag.go | 135 +++++++++++++ .../vmware/govmomi/govc/cluster/rule/ls.go | 96 +++++++++ .../govmomi/govc/cluster/rule/remove.go | 66 +++++++ .../govmomi/govc/datastore/disk/create.go | 12 +- .../govmomi/govc/datastore/disk/inflate.go | 80 ++++++++ .../govmomi/govc/datastore/disk/shrink.go | 84 ++++++++ .../github.com/vmware/govmomi/govc/dvs/add.go | 2 +- .../vmware/govmomi/govc/events/command.go | 33 +++- .../vmware/govmomi/govc/flags/client.go | 14 +- .../vmware/govmomi/govc/flags/cluster.go | 184 ++++++++++++++++++ .../govc/flags/resource_allocation_info.go | 85 ++++++++ .../vmware/govmomi/govc/flags/version.go | 2 +- .../vmware/govmomi/govc/host/shutdown.go | 4 + .../vmware/govmomi/govc/host/storage/info.go | 17 +- vendor/github.com/vmware/govmomi/govc/main.go | 2 + .../govmomi/govc/pool/resource_config_spec.go | 48 +---- .../vmware/govmomi/govc/session/ls.go | 11 +- .../vmware/govmomi/govc/vm/change.go | 34 ++++ .../vmware/govmomi/govc/vm/guest/auth.go | 2 +- .../github.com/vmware/govmomi/govc/vm/info.go | 13 ++ .../vmware/govmomi/govc/vm/upgrade.go | 81 ++++++++ .../object/cluster_compute_resource.go | 26 +-- .../vmware/govmomi/object/compute_resource.go | 13 -- .../vmware/govmomi/object/datastore.go | 9 +- .../govmomi/object/host_storage_system.go | 9 + .../govmomi/object/virtual_disk_manager.go | 41 ++++ .../object/virtual_disk_manager_internal.go | 64 ++++++ .../vmware/govmomi/object/virtual_machine.go | 14 ++ .../vmware/govmomi/property/collector.go | 4 + .../simulator/authorization_manager.go | 3 +- .../simulator/cluster_compute_resource.go | 125 ++++++++++++ .../govmomi/simulator/esx/service_content.go | 88 +++++---- .../vmware/govmomi/simulator/file_manager.go | 1 + .../vmware/govmomi/simulator/folder.go | 27 +++ .../vmware/govmomi/simulator/guest_id.go | 171 ++++++++++++++++ .../simulator/host_local_account_manager.go | 80 ++++++++ .../vmware/govmomi/simulator/host_system.go | 7 +- .../vmware/govmomi/simulator/registry.go | 5 + .../vmware/govmomi/simulator/resource_pool.go | 24 +-- .../govmomi/simulator/service_instance.go | 4 + .../vmware/govmomi/simulator/simulator.go | 18 +- .../govmomi/simulator/user_directory.go | 46 ++++- .../govmomi/simulator/virtual_disk_manager.go | 26 +++ .../govmomi/simulator/virtual_machine.go | 124 +++++++++++- .../govmomi/simulator/vpx/service_content.go | 93 +++++---- .../vmware/govmomi/toolbox/command.go | 7 +- vendor/manifest | 2 +- 58 files changed, 2510 insertions(+), 238 deletions(-) create mode 100644 vendor/github.com/vmware/govmomi/govc/cluster/group/change.go create mode 100644 vendor/github.com/vmware/govmomi/govc/cluster/group/create.go create mode 100644 vendor/github.com/vmware/govmomi/govc/cluster/group/info_flag.go create mode 100644 vendor/github.com/vmware/govmomi/govc/cluster/group/ls.go create mode 100644 vendor/github.com/vmware/govmomi/govc/cluster/group/remove.go create mode 100644 vendor/github.com/vmware/govmomi/govc/cluster/rule/change.go create mode 100644 vendor/github.com/vmware/govmomi/govc/cluster/rule/create.go create mode 100644 vendor/github.com/vmware/govmomi/govc/cluster/rule/info_flag.go create mode 100644 vendor/github.com/vmware/govmomi/govc/cluster/rule/ls.go create mode 100644 vendor/github.com/vmware/govmomi/govc/cluster/rule/remove.go create mode 100644 vendor/github.com/vmware/govmomi/govc/datastore/disk/inflate.go create mode 100644 vendor/github.com/vmware/govmomi/govc/datastore/disk/shrink.go create mode 100644 vendor/github.com/vmware/govmomi/govc/flags/cluster.go create mode 100644 vendor/github.com/vmware/govmomi/govc/flags/resource_allocation_info.go create mode 100644 vendor/github.com/vmware/govmomi/govc/vm/upgrade.go create mode 100644 vendor/github.com/vmware/govmomi/simulator/guest_id.go create mode 100644 vendor/github.com/vmware/govmomi/simulator/host_local_account_manager.go diff --git a/vendor/github.com/vmware/govmomi/event/manager.go b/vendor/github.com/vmware/govmomi/event/manager.go index 3feede10ec..72cc343503 100644 --- a/vendor/github.com/vmware/govmomi/event/manager.go +++ b/vendor/github.com/vmware/govmomi/event/manager.go @@ -169,16 +169,18 @@ func (m Manager) EventCategory(ctx context.Context, event types.BaseEvent) (stri } // Get the events from the specified object(s) and optionanlly tail the event stream -func (m Manager) Events(ctx context.Context, objects []types.ManagedObjectReference, pageSize int32, tail bool, force bool, f func(types.ManagedObjectReference, []types.BaseEvent) error) error { - +func (m Manager) Events(ctx context.Context, objects []types.ManagedObjectReference, pageSize int32, tail bool, force bool, f func(types.ManagedObjectReference, []types.BaseEvent) error, kind ...string) error { + // TODO: deprecated this method and add one that uses a single config struct, so we can extend further without breaking the method signature. if len(objects) >= m.maxObjects && !force { return fmt.Errorf("Maximum number of objects to monitor (%d) exceeded, refine search", m.maxObjects) } - proc := newEventProcessor(m, pageSize, f) + proc := newEventProcessor(m, pageSize, f, kind) for _, o := range objects { proc.addObject(ctx, o) } + defer proc.destroy() + return proc.run(ctx, tail) } diff --git a/vendor/github.com/vmware/govmomi/event/processor.go b/vendor/github.com/vmware/govmomi/event/processor.go index 18084d4895..b8760a8e49 100644 --- a/vendor/github.com/vmware/govmomi/event/processor.go +++ b/vendor/github.com/vmware/govmomi/event/processor.go @@ -28,22 +28,24 @@ import ( type tailInfo struct { t *eventTailer obj types.ManagedObjectReference - collector types.ManagedObjectReference + collector *HistoryCollector } type eventProcessor struct { mgr Manager pageSize int32 + kind []string tailers map[types.ManagedObjectReference]*tailInfo // tailers by collector ref callback func(types.ManagedObjectReference, []types.BaseEvent) error } -func newEventProcessor(mgr Manager, pageSize int32, callback func(types.ManagedObjectReference, []types.BaseEvent) error) *eventProcessor { +func newEventProcessor(mgr Manager, pageSize int32, callback func(types.ManagedObjectReference, []types.BaseEvent) error, kind []string) *eventProcessor { return &eventProcessor{ mgr: mgr, tailers: make(map[types.ManagedObjectReference]*tailInfo), callback: callback, pageSize: pageSize, + kind: kind, } } @@ -53,6 +55,7 @@ func (p *eventProcessor) addObject(ctx context.Context, obj types.ManagedObjectR Entity: obj, Recursion: types.EventFilterSpecRecursionOptionAll, }, + EventTypeId: p.kind, } collector, err := p.mgr.CreateCollectorForEvents(ctx, filter) @@ -68,20 +71,26 @@ func (p *eventProcessor) addObject(ctx context.Context, obj types.ManagedObjectR p.tailers[collector.Reference()] = &tailInfo{ t: newEventTailer(), obj: obj, - collector: collector.Reference(), + collector: collector, } return nil } +func (p *eventProcessor) destroy() { + for _, info := range p.tailers { + _ = info.collector.Destroy(context.Background()) + } +} + func (p *eventProcessor) run(ctx context.Context, tail bool) error { if len(p.tailers) == 0 { return nil } var collectors []types.ManagedObjectReference - for _, t := range p.tailers { - collectors = append(collectors, t.collector) + for ref := range p.tailers { + collectors = append(collectors, ref) } c := property.DefaultCollector(p.mgr.Client()) diff --git a/vendor/github.com/vmware/govmomi/find/finder.go b/vendor/github.com/vmware/govmomi/find/finder.go index 04d0e891a9..2e9727e484 100644 --- a/vendor/github.com/vmware/govmomi/find/finder.go +++ b/vendor/github.com/vmware/govmomi/find/finder.go @@ -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, diff --git a/vendor/github.com/vmware/govmomi/govc/cluster/add.go b/vendor/github.com/vmware/govmomi/govc/cluster/add.go index e29af5ab80..3b8f7d78ac 100644 --- a/vendor/github.com/vmware/govmomi/govc/cluster/add.go +++ b/vendor/github.com/vmware/govmomi/govc/cluster/add.go @@ -27,10 +27,9 @@ import ( ) type add struct { - *flags.DatacenterFlag + *flags.ClusterFlag *flags.HostConnectFlag - cluster string connect bool license string } @@ -40,21 +39,19 @@ func init() { } func (cmd *add) Register(ctx context.Context, f *flag.FlagSet) { - cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx) - cmd.DatacenterFlag.Register(ctx, f) + cmd.ClusterFlag, ctx = flags.NewClusterFlag(ctx) + cmd.ClusterFlag.Register(ctx, f) cmd.HostConnectFlag, ctx = flags.NewHostConnectFlag(ctx) cmd.HostConnectFlag.Register(ctx, f) - f.StringVar(&cmd.cluster, "cluster", "*", "Path to cluster") - f.StringVar(&cmd.license, "license", "", "Assign license key") f.BoolVar(&cmd.connect, "connect", true, "Immediately connect to host") } func (cmd *add) Process(ctx context.Context) error { - if err := cmd.DatacenterFlag.Process(ctx); err != nil { + if err := cmd.ClusterFlag.Process(ctx); err != nil { return err } if err := cmd.HostConnectFlag.Process(ctx); err != nil { @@ -108,12 +105,7 @@ func (cmd *add) Run(ctx context.Context, f *flag.FlagSet) error { return flag.ErrHelp } - finder, err := cmd.Finder() - if err != nil { - return err - } - - cluster, err := finder.ClusterComputeResource(ctx, cmd.cluster) + cluster, err := cmd.Cluster() if err != nil { return err } diff --git a/vendor/github.com/vmware/govmomi/govc/cluster/group/change.go b/vendor/github.com/vmware/govmomi/govc/cluster/group/change.go new file mode 100644 index 0000000000..ddaffce523 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/cluster/group/change.go @@ -0,0 +1,75 @@ +/* +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 group + +import ( + "context" + "flag" + + "github.com/vmware/govmomi/govc/cli" + "github.com/vmware/govmomi/vim25/types" +) + +type change struct { + *InfoFlag +} + +func init() { + cli.Register("cluster.group.change", &change{}) +} + +func (cmd *change) Register(ctx context.Context, f *flag.FlagSet) { + cmd.InfoFlag, ctx = NewInfoFlag(ctx) + cmd.InfoFlag.Register(ctx, f) +} + +func (cmd *change) Process(ctx context.Context) error { + if cmd.name == "" { + return flag.ErrHelp + } + return cmd.InfoFlag.Process(ctx) +} + +func (cmd *change) Usage() string { + return `NAME...` +} + +func (cmd *change) Description() string { + return `Set cluster group members. + +Examples: + govc cluster.group.change -name my_group vm_a vm_b vm_c # set + govc cluster.group.change -name my_group vm_a vm_b vm_c $(govc cluster.group.ls -name my_group) vm_d # add + govc cluster.group.ls -name my_group | grep -v vm_b | xargs govc cluster.group.change -name my_group vm_a vm_b vm_c # remove` +} + +func (cmd *change) Run(ctx context.Context, f *flag.FlagSet) error { + update := types.ArrayUpdateSpec{Operation: types.ArrayUpdateOperationEdit} + group, err := cmd.Group(ctx) + if err != nil { + return err + } + + refs, err := cmd.ObjectList(ctx, group.kind, f.Args()) + if err != nil { + return err + } + + *group.refs = refs + + return cmd.Apply(ctx, update, group.info) +} diff --git a/vendor/github.com/vmware/govmomi/govc/cluster/group/create.go b/vendor/github.com/vmware/govmomi/govc/cluster/group/create.go new file mode 100644 index 0000000000..ef20e0ed56 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/cluster/group/create.go @@ -0,0 +1,86 @@ +/* +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 group + +import ( + "context" + "flag" + + "github.com/vmware/govmomi/govc/cli" + "github.com/vmware/govmomi/vim25/types" +) + +type create struct { + *InfoFlag + + vm bool + host bool +} + +func init() { + cli.Register("cluster.group.create", &create{}) +} + +func (cmd *create) Register(ctx context.Context, f *flag.FlagSet) { + cmd.InfoFlag, ctx = NewInfoFlag(ctx) + cmd.InfoFlag.Register(ctx, f) + + f.BoolVar(&cmd.vm, "vm", false, "Create cluster VM group") + f.BoolVar(&cmd.host, "host", false, "Create cluster Host group") +} + +func (cmd *create) Process(ctx context.Context) error { + if cmd.name == "" { + return flag.ErrHelp + } + return cmd.InfoFlag.Process(ctx) +} + +func (cmd *create) Description() string { + return `Create cluster group. + +One of '-vm' or '-host' must be provided to specify the group type. + +Examples: + govc cluster.group.create -name my_vm_group -vm vm_a vm_b vm_c + govc cluster.group.create -name my_host_group -host host_a host_b host_c` +} + +func (cmd *create) Run(ctx context.Context, f *flag.FlagSet) error { + update := types.ArrayUpdateSpec{Operation: types.ArrayUpdateOperationAdd} + var info types.BaseClusterGroupInfo + var err error + + switch { + case cmd.vm: + info = new(types.ClusterVmGroup) + case cmd.host: + info = new(types.ClusterHostGroup) + default: + return flag.ErrHelp + } + + info.GetClusterGroupInfo().Name = cmd.name + + group := newGroupInfo(info) + *group.refs, err = cmd.ObjectList(ctx, group.kind, f.Args()) + if err != nil { + return err + } + + return cmd.Apply(ctx, update, info) +} diff --git a/vendor/github.com/vmware/govmomi/govc/cluster/group/info_flag.go b/vendor/github.com/vmware/govmomi/govc/cluster/group/info_flag.go new file mode 100644 index 0000000000..1efc2f7532 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/cluster/group/info_flag.go @@ -0,0 +1,121 @@ +/* +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 group + +import ( + "context" + "flag" + "fmt" + + "github.com/vmware/govmomi/govc/flags" + "github.com/vmware/govmomi/vim25/types" +) + +type InfoFlag struct { + *flags.ClusterFlag + + groups []types.BaseClusterGroupInfo + + name string +} + +func NewInfoFlag(ctx context.Context) (*InfoFlag, context.Context) { + f := &InfoFlag{} + f.ClusterFlag, ctx = flags.NewClusterFlag(ctx) + return f, ctx +} + +func (f *InfoFlag) Register(ctx context.Context, fs *flag.FlagSet) { + f.ClusterFlag.Register(ctx, fs) + + fs.StringVar(&f.name, "name", "", "Cluster group name") +} + +func (f *InfoFlag) Process(ctx context.Context) error { + return f.ClusterFlag.Process(ctx) +} + +func (f *InfoFlag) Groups(ctx context.Context) ([]types.BaseClusterGroupInfo, error) { + if f.groups != nil { + return f.groups, nil + } + + cluster, err := f.Cluster() + if err != nil { + return nil, err + } + + config, err := cluster.Configuration(ctx) + if err != nil { + return nil, err + } + + f.groups = config.Group + + return f.groups, nil +} + +type ClusterGroupInfo struct { + info types.BaseClusterGroupInfo + + refs *[]types.ManagedObjectReference + + kind string +} + +func newGroupInfo(info types.BaseClusterGroupInfo) *ClusterGroupInfo { + group := &ClusterGroupInfo{info: info} + + switch info := info.(type) { + case *types.ClusterHostGroup: + group.refs = &info.Host + group.kind = "HostSystem" + case *types.ClusterVmGroup: + group.refs = &info.Vm + group.kind = "VirtualMachine" + } + + return group +} + +func (f *InfoFlag) Group(ctx context.Context) (*ClusterGroupInfo, error) { + groups, err := f.Groups(ctx) + if err != nil { + return nil, err + } + + for _, group := range groups { + if group.GetClusterGroupInfo().Name == f.name { + return newGroupInfo(group), nil + } + } + + return nil, fmt.Errorf("group %q not found", f.name) +} + +func (f *InfoFlag) Apply(ctx context.Context, update types.ArrayUpdateSpec, info types.BaseClusterGroupInfo) error { + spec := &types.ClusterConfigSpecEx{ + GroupSpec: []types.ClusterGroupSpec{ + { + ArrayUpdateSpec: update, + Info: info, + }, + }, + } + + return f.Reconfigure(ctx, spec) +} diff --git a/vendor/github.com/vmware/govmomi/govc/cluster/group/ls.go b/vendor/github.com/vmware/govmomi/govc/cluster/group/ls.go new file mode 100644 index 0000000000..1dbe5e07a6 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/cluster/group/ls.go @@ -0,0 +1,92 @@ +/* +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 group + +import ( + "context" + "flag" + "fmt" + "io" + + "github.com/vmware/govmomi/govc/cli" +) + +type ls struct { + *InfoFlag +} + +func init() { + cli.Register("cluster.group.ls", &ls{}) +} + +func (cmd *ls) Register(ctx context.Context, f *flag.FlagSet) { + cmd.InfoFlag, ctx = NewInfoFlag(ctx) + cmd.InfoFlag.Register(ctx, f) +} + +func (cmd *ls) Process(ctx context.Context) error { + return cmd.InfoFlag.Process(ctx) +} + +func (cmd *ls) Description() string { + return `List cluster groups and group members. + +Examples: + govc cluster.group.ls -cluster my_cluster + govc cluster.group.ls -cluster my_cluster -name my_group` +} + +type groupResult []string + +func (r groupResult) Write(w io.Writer) error { + for i := range r { + fmt.Fprintln(w, r[i]) + } + + return nil +} + +func (cmd *ls) Run(ctx context.Context, f *flag.FlagSet) error { + var res groupResult + + if cmd.name == "" { + groups, err := cmd.Groups(ctx) + if err != nil { + return err + } + + for _, g := range groups { + res = append(res, g.GetClusterGroupInfo().Name) + } + } else { + group, err := cmd.Group(ctx) + if err != nil { + return err + } + + names, err := cmd.Names(ctx, *group.refs) + if err != nil { + return err + } + + for _, ref := range *group.refs { + res = append(res, names[ref]) + } + } + + return cmd.WriteResult(res) +} diff --git a/vendor/github.com/vmware/govmomi/govc/cluster/group/remove.go b/vendor/github.com/vmware/govmomi/govc/cluster/group/remove.go new file mode 100644 index 0000000000..f864771035 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/cluster/group/remove.go @@ -0,0 +1,61 @@ +/* +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 group + +import ( + "context" + "flag" + + "github.com/vmware/govmomi/govc/cli" + "github.com/vmware/govmomi/vim25/types" +) + +type remove struct { + *InfoFlag +} + +func init() { + cli.Register("cluster.group.remove", &remove{}) +} + +func (cmd *remove) Register(ctx context.Context, f *flag.FlagSet) { + cmd.InfoFlag, ctx = NewInfoFlag(ctx) + cmd.InfoFlag.Register(ctx, f) +} + +func (cmd *remove) Process(ctx context.Context) error { + if cmd.name == "" { + return flag.ErrHelp + } + return cmd.InfoFlag.Process(ctx) +} + +func (cmd *remove) Description() string { + return `Remove cluster group. + +Examples: + govc cluster.group.remove -cluster my_cluster -name my_group` +} + +func (cmd *remove) Run(ctx context.Context, f *flag.FlagSet) error { + update := types.ArrayUpdateSpec{ + Operation: types.ArrayUpdateOperationRemove, + RemoveKey: cmd.name, + } + + return cmd.Apply(ctx, update, nil) +} diff --git a/vendor/github.com/vmware/govmomi/govc/cluster/rule/change.go b/vendor/github.com/vmware/govmomi/govc/cluster/rule/change.go new file mode 100644 index 0000000000..092efa6893 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/cluster/rule/change.go @@ -0,0 +1,93 @@ +/* +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 rule + +import ( + "context" + "flag" + + "github.com/vmware/govmomi/govc/cli" + "github.com/vmware/govmomi/vim25/types" +) + +type change struct { + *SpecFlag + *InfoFlag +} + +func init() { + cli.Register("cluster.rule.change", &change{}) +} + +func (cmd *change) Register(ctx context.Context, f *flag.FlagSet) { + cmd.SpecFlag = new(SpecFlag) + cmd.SpecFlag.Register(ctx, f) + + cmd.InfoFlag, ctx = NewInfoFlag(ctx) + cmd.InfoFlag.Register(ctx, f) +} + +func (cmd *change) Process(ctx context.Context) error { + if cmd.name == "" { + return flag.ErrHelp + } + return cmd.InfoFlag.Process(ctx) +} + +func (cmd *change) Usage() string { + return `NAME...` +} + +func (cmd *change) Description() string { + return `Change cluster rule. + +Examples: + govc cluster.rule.change -cluster my_cluster -name my_rule -enable=false` +} + +func (cmd *change) Run(ctx context.Context, f *flag.FlagSet) error { + update := types.ArrayUpdateSpec{Operation: types.ArrayUpdateOperationEdit} + rule, err := cmd.Rule(ctx) + if err != nil { + return err + } + + var vms *[]types.ManagedObjectReference + + switch r := rule.info.(type) { + case *types.ClusterAffinityRuleSpec: + vms = &r.Vm + case *types.ClusterAntiAffinityRuleSpec: + vms = &r.Vm + } + + if vms != nil && f.NArg() != 0 { + refs, err := cmd.ObjectList(ctx, rule.kind, f.Args()) + if err != nil { + return err + } + + *vms = refs + } + + info := rule.info.GetClusterRuleInfo() + info.Name = cmd.name + info.Enabled = cmd.Enabled + info.Mandatory = cmd.Mandatory + + return cmd.Apply(ctx, update, rule.info) +} diff --git a/vendor/github.com/vmware/govmomi/govc/cluster/rule/create.go b/vendor/github.com/vmware/govmomi/govc/cluster/rule/create.go new file mode 100644 index 0000000000..f9590090d6 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/cluster/rule/create.go @@ -0,0 +1,118 @@ +/* +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 rule + +import ( + "context" + "flag" + + "github.com/vmware/govmomi/govc/cli" + "github.com/vmware/govmomi/vim25/types" +) + +type create struct { + *SpecFlag + *InfoFlag + + vmhost bool + affinity bool + antiaffinity bool +} + +func init() { + cli.Register("cluster.rule.create", &create{}) +} + +func (cmd *create) Register(ctx context.Context, f *flag.FlagSet) { + cmd.SpecFlag = new(SpecFlag) + cmd.SpecFlag.Register(ctx, f) + + cmd.InfoFlag, ctx = NewInfoFlag(ctx) + cmd.InfoFlag.Register(ctx, f) + + f.BoolVar(&cmd.vmhost, "vm-host", false, "Virtual Machines to Hosts") + f.BoolVar(&cmd.affinity, "affinity", false, "Keep Virtual Machines Together") + f.BoolVar(&cmd.antiaffinity, "anti-affinity", false, "Separate Virtual Machines") +} + +func (cmd *create) Process(ctx context.Context) error { + if cmd.name == "" { + return flag.ErrHelp + } + return cmd.InfoFlag.Process(ctx) +} + +func (cmd *create) Usage() string { + return "NAME..." +} + +func (cmd *create) Description() string { + return `Create cluster rule. + +Rules are not enabled by default, use the 'enable' flag to enable upon creation or cluster.rule.change after creation. + +One of '-affinity', '-anti-affinity' or '-vm-host' must be provided to specify the rule type. + +With '-affinity' or '-anti-affinity', at least 2 vm NAME arguments must be specified. + +With '-vm-host', use the '-vm-group' flag combined with the '-host-affine-group' and/or '-host-anti-affine-group' flags. + +Examples: + govc cluster.rule.create -name pod1 -enable -affinity vm_a vm_b vm_c + govc cluster.rule.create -name pod2 -enable -anti-affinity vm_d vm_e vm_f + govc cluster.rule.create -name pod3 -enable -mandatory -vm-host -vm-group my_vms -host-affine-group my_hosts` +} + +func (cmd *create) Run(ctx context.Context, f *flag.FlagSet) error { + args := f.Args() + update := types.ArrayUpdateSpec{Operation: types.ArrayUpdateOperationAdd} + var rule types.BaseClusterRuleInfo + var err error + + switch { + case cmd.vmhost: + rule = &cmd.ClusterVmHostRuleInfo + case cmd.affinity: + rule = &cmd.ClusterAffinityRuleSpec + if len(args) < 2 { + return flag.ErrHelp // can't create this rule without 2 or more hosts + } + cmd.ClusterAffinityRuleSpec.Vm, err = cmd.ObjectList(ctx, "VirtualMachine", args) + if err != nil { + return err + } + case cmd.antiaffinity: + rule = &cmd.ClusterAntiAffinityRuleSpec + if len(args) < 2 { + return flag.ErrHelp // can't create this rule without 2 or more hosts + } + cmd.ClusterAntiAffinityRuleSpec.Vm, err = cmd.ObjectList(ctx, "VirtualMachine", args) + if err != nil { + return err + } + default: + return flag.ErrHelp + } + + info := rule.GetClusterRuleInfo() + info.Name = cmd.name + info.Enabled = cmd.Enabled + info.Mandatory = cmd.Mandatory + info.UserCreated = types.NewBool(true) + + return cmd.Apply(ctx, update, rule) +} diff --git a/vendor/github.com/vmware/govmomi/govc/cluster/rule/info_flag.go b/vendor/github.com/vmware/govmomi/govc/cluster/rule/info_flag.go new file mode 100644 index 0000000000..74caad0061 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/cluster/rule/info_flag.go @@ -0,0 +1,135 @@ +/* +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 rule + +import ( + "context" + "flag" + "fmt" + + "github.com/vmware/govmomi/govc/flags" + "github.com/vmware/govmomi/vim25/types" +) + +type InfoFlag struct { + *flags.ClusterFlag + + rules []types.BaseClusterRuleInfo + + name string +} + +func NewInfoFlag(ctx context.Context) (*InfoFlag, context.Context) { + f := &InfoFlag{} + f.ClusterFlag, ctx = flags.NewClusterFlag(ctx) + return f, ctx +} + +func (f *InfoFlag) Register(ctx context.Context, fs *flag.FlagSet) { + f.ClusterFlag.Register(ctx, fs) + + fs.StringVar(&f.name, "name", "", "Cluster rule name") +} + +func (f *InfoFlag) Process(ctx context.Context) error { + return f.ClusterFlag.Process(ctx) +} + +func (f *InfoFlag) Rules(ctx context.Context) ([]types.BaseClusterRuleInfo, error) { + if f.rules != nil { + return f.rules, nil + } + + cluster, err := f.Cluster() + if err != nil { + return nil, err + } + + config, err := cluster.Configuration(ctx) + if err != nil { + return nil, err + } + + f.rules = config.Rule + + return f.rules, nil +} + +type ClusterRuleInfo struct { + info types.BaseClusterRuleInfo + + refs *[]types.ManagedObjectReference + + kind string +} + +func (f *InfoFlag) Rule(ctx context.Context) (*ClusterRuleInfo, error) { + rules, err := f.Rules(ctx) + if err != nil { + return nil, err + } + + for _, rule := range rules { + if rule.GetClusterRuleInfo().Name != f.name { + continue + } + + r := &ClusterRuleInfo{info: rule} + + switch info := rule.(type) { + case *types.ClusterAffinityRuleSpec: + r.refs = &info.Vm + r.kind = "VirtualMachine" + case *types.ClusterAntiAffinityRuleSpec: + r.refs = &info.Vm + r.kind = "VirtualMachine" + } + + return r, nil + } + + return nil, fmt.Errorf("rule %q not found", f.name) +} + +func (f *InfoFlag) Apply(ctx context.Context, update types.ArrayUpdateSpec, info types.BaseClusterRuleInfo) error { + spec := &types.ClusterConfigSpecEx{ + RulesSpec: []types.ClusterRuleSpec{ + { + ArrayUpdateSpec: update, + Info: info, + }, + }, + } + + return f.Reconfigure(ctx, spec) +} + +type SpecFlag struct { + types.ClusterRuleInfo + types.ClusterVmHostRuleInfo + types.ClusterAffinityRuleSpec + types.ClusterAntiAffinityRuleSpec +} + +func (s *SpecFlag) Register(ctx context.Context, f *flag.FlagSet) { + f.Var(flags.NewOptionalBool(&s.Enabled), "enable", "Enable rule") + f.Var(flags.NewOptionalBool(&s.Mandatory), "mandatory", "Enforce rule compliance") + + f.StringVar(&s.VmGroupName, "vm-group", "", "VM group name") + f.StringVar(&s.AffineHostGroupName, "host-affine-group", "", "Host affine group name") + f.StringVar(&s.AntiAffineHostGroupName, "host-anti-affine-group", "", "Host anti-affine group name") +} diff --git a/vendor/github.com/vmware/govmomi/govc/cluster/rule/ls.go b/vendor/github.com/vmware/govmomi/govc/cluster/rule/ls.go new file mode 100644 index 0000000000..71fafc5a40 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/cluster/rule/ls.go @@ -0,0 +1,96 @@ +/* +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 rule + +import ( + "context" + "flag" + "fmt" + "io" + + "github.com/vmware/govmomi/govc/cli" +) + +type ls struct { + *InfoFlag +} + +func init() { + cli.Register("cluster.rule.ls", &ls{}) +} + +func (cmd *ls) Register(ctx context.Context, f *flag.FlagSet) { + cmd.InfoFlag, ctx = NewInfoFlag(ctx) + cmd.InfoFlag.Register(ctx, f) +} + +func (cmd *ls) Process(ctx context.Context) error { + return cmd.InfoFlag.Process(ctx) +} + +func (cmd *ls) Description() string { + return `List cluster rules and rule members. + +Examples: + govc cluster.rule.ls -cluster my_cluster + govc cluster.rule.ls -cluster my_cluster -name my_rule` +} + +type ruleResult []string + +func (r ruleResult) Write(w io.Writer) error { + for i := range r { + fmt.Fprintln(w, r[i]) + } + + return nil +} + +func (cmd *ls) Run(ctx context.Context, f *flag.FlagSet) error { + var res ruleResult + + if cmd.name == "" { + rules, err := cmd.Rules(ctx) + if err != nil { + return err + } + + for _, g := range rules { + res = append(res, g.GetClusterRuleInfo().Name) + } + } else { + rule, err := cmd.Rule(ctx) + if err != nil { + return err + } + + if rule.refs == nil { + return nil + } + + names, err := cmd.Names(ctx, *rule.refs) + if err != nil { + return err + } + + for _, ref := range *rule.refs { + res = append(res, names[ref]) + } + } + + return cmd.WriteResult(res) +} diff --git a/vendor/github.com/vmware/govmomi/govc/cluster/rule/remove.go b/vendor/github.com/vmware/govmomi/govc/cluster/rule/remove.go new file mode 100644 index 0000000000..a38b96b396 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/cluster/rule/remove.go @@ -0,0 +1,66 @@ +/* +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 rule + +import ( + "context" + "flag" + + "github.com/vmware/govmomi/govc/cli" + "github.com/vmware/govmomi/vim25/types" +) + +type remove struct { + *InfoFlag +} + +func init() { + cli.Register("cluster.rule.remove", &remove{}) +} + +func (cmd *remove) Register(ctx context.Context, f *flag.FlagSet) { + cmd.InfoFlag, ctx = NewInfoFlag(ctx) + cmd.InfoFlag.Register(ctx, f) +} + +func (cmd *remove) Process(ctx context.Context) error { + if cmd.name == "" { + return flag.ErrHelp + } + return cmd.InfoFlag.Process(ctx) +} + +func (cmd *remove) Description() string { + return `Remove cluster rule. + +Examples: + govc cluster.group.remove -cluster my_cluster -name my_rule` +} + +func (cmd *remove) Run(ctx context.Context, f *flag.FlagSet) error { + rule, err := cmd.Rule(ctx) + if err != nil { + return err + } + + update := types.ArrayUpdateSpec{ + Operation: types.ArrayUpdateOperationRemove, + RemoveKey: rule.info.GetClusterRuleInfo().Key, + } + + return cmd.Apply(ctx, update, nil) +} diff --git a/vendor/github.com/vmware/govmomi/govc/datastore/disk/create.go b/vendor/github.com/vmware/govmomi/govc/datastore/disk/create.go index c629c2a2ce..b0a1eaffa2 100644 --- a/vendor/github.com/vmware/govmomi/govc/datastore/disk/create.go +++ b/vendor/github.com/vmware/govmomi/govc/datastore/disk/create.go @@ -61,7 +61,8 @@ func (cmd *create) Description() string { Examples: govc datastore.mkdir disks - govc datastore.disk.create -size 24G disks/disk1.vmdk` + govc datastore.disk.create -size 24G disks/disk1.vmdk + govc datastore.disk.create disks/parent.vmdk disk/child.vmdk` } func (cmd *create) Run(ctx context.Context, f *flag.FlagSet) error { @@ -81,6 +82,8 @@ func (cmd *create) Run(ctx context.Context, f *flag.FlagSet) error { m := object.NewVirtualDiskManager(ds.Client()) + var task *object.Task + spec := &types.FileBackedVirtualDiskSpec{ VirtualDiskSpec: types.VirtualDiskSpec{ AdapterType: string(types.VirtualDiskAdapterTypeLsiLogic), @@ -89,7 +92,12 @@ func (cmd *create) Run(ctx context.Context, f *flag.FlagSet) error { CapacityKb: int64(cmd.Bytes) / 1024, } - task, err := m.CreateVirtualDisk(ctx, ds.Path(f.Arg(0)), dc, spec) + if f.NArg() == 1 { + task, err = m.CreateVirtualDisk(ctx, ds.Path(f.Arg(0)), dc, spec) + } else { + task, err = m.CreateChildDisk(ctx, ds.Path(f.Arg(0)), dc, ds.Path(f.Arg(1)), dc, true) + } + if err != nil { return err } diff --git a/vendor/github.com/vmware/govmomi/govc/datastore/disk/inflate.go b/vendor/github.com/vmware/govmomi/govc/datastore/disk/inflate.go new file mode 100644 index 0000000000..67a1ae0bd6 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/datastore/disk/inflate.go @@ -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 disk + +import ( + "context" + "flag" + "fmt" + + "github.com/vmware/govmomi/govc/cli" + "github.com/vmware/govmomi/govc/flags" + "github.com/vmware/govmomi/object" +) + +type inflate struct { + *flags.DatastoreFlag +} + +func init() { + cli.Register("datastore.disk.inflate", &inflate{}) +} + +func (cmd *inflate) Register(ctx context.Context, f *flag.FlagSet) { + cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx) + cmd.DatastoreFlag.Register(ctx, f) +} + +func (cmd *inflate) Process(ctx context.Context) error { + return cmd.DatastoreFlag.Process(ctx) +} + +func (cmd *inflate) Usage() string { + return "VMDK" +} + +func (cmd *inflate) Description() string { + return `Inflate VMDK on DS. + +Examples: + govc datastore.disk.inflate disks/disk1.vmdk` +} + +func (cmd *inflate) Run(ctx context.Context, f *flag.FlagSet) error { + dc, err := cmd.Datacenter() + if err != nil { + return err + } + + ds, err := cmd.Datastore() + if err != nil { + return err + } + + m := object.NewVirtualDiskManager(ds.Client()) + path := ds.Path(f.Arg(0)) + task, err := m.InflateVirtualDisk(ctx, path, dc) + if err != nil { + return err + } + + logger := cmd.ProgressLogger(fmt.Sprintf("Inflating %s...", path)) + defer logger.Wait() + + _, err = task.WaitForResult(ctx, logger) + return err +} diff --git a/vendor/github.com/vmware/govmomi/govc/datastore/disk/shrink.go b/vendor/github.com/vmware/govmomi/govc/datastore/disk/shrink.go new file mode 100644 index 0000000000..0a76a52770 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/datastore/disk/shrink.go @@ -0,0 +1,84 @@ +/* +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 disk + +import ( + "context" + "flag" + "fmt" + + "github.com/vmware/govmomi/govc/cli" + "github.com/vmware/govmomi/govc/flags" + "github.com/vmware/govmomi/object" +) + +type shrink struct { + *flags.DatastoreFlag + + copy *bool +} + +func init() { + cli.Register("datastore.disk.shrink", &shrink{}) +} + +func (cmd *shrink) Register(ctx context.Context, f *flag.FlagSet) { + cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx) + cmd.DatastoreFlag.Register(ctx, f) + + f.Var(flags.NewOptionalBool(&cmd.copy), "copy", "Perform shrink in-place mode if false, copy-shrink mode otherwise") +} + +func (cmd *shrink) Process(ctx context.Context) error { + return cmd.DatastoreFlag.Process(ctx) +} + +func (cmd *shrink) Usage() string { + return "VMDK" +} + +func (cmd *shrink) Description() string { + return `Shrink VMDK on DS. + +Examples: + govc datastore.disk.shrink disks/disk1.vmdk` +} + +func (cmd *shrink) Run(ctx context.Context, f *flag.FlagSet) error { + dc, err := cmd.Datacenter() + if err != nil { + return err + } + + ds, err := cmd.Datastore() + if err != nil { + return err + } + + m := object.NewVirtualDiskManager(ds.Client()) + path := ds.Path(f.Arg(0)) + task, err := m.ShrinkVirtualDisk(ctx, path, dc, cmd.copy) + if err != nil { + return err + } + + logger := cmd.ProgressLogger(fmt.Sprintf("Shrinking %s...", path)) + defer logger.Wait() + + _, err = task.WaitForResult(ctx, logger) + return err +} diff --git a/vendor/github.com/vmware/govmomi/govc/dvs/add.go b/vendor/github.com/vmware/govmomi/govc/dvs/add.go index f51ded6507..511e252876 100644 --- a/vendor/github.com/vmware/govmomi/govc/dvs/add.go +++ b/vendor/github.com/vmware/govmomi/govc/dvs/add.go @@ -87,7 +87,7 @@ func (cmd *add) Run(ctx context.Context, f *flag.FlagSet) error { return fmt.Errorf("%s (%T) is not of type %T", cmd.path, net, dvs) } - var s mo.VmwareDistributedVirtualSwitch + var s mo.DistributedVirtualSwitch err = dvs.Properties(ctx, dvs.Reference(), []string{"config"}, &s) if err != nil { return err diff --git a/vendor/github.com/vmware/govmomi/govc/events/command.go b/vendor/github.com/vmware/govmomi/govc/events/command.go index e57112b859..a96c83454b 100644 --- a/vendor/github.com/vmware/govmomi/govc/events/command.go +++ b/vendor/github.com/vmware/govmomi/govc/events/command.go @@ -1,5 +1,5 @@ /* -Copyright (c) 2015 VMware, Inc. All Rights Reserved. +Copyright (c) 2015-2017 VMware, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import ( "fmt" "io" "os" + "reflect" "strings" "time" @@ -40,6 +41,19 @@ type events struct { Max int32 Tail bool Force bool + Long bool + Kind kinds +} + +type kinds []string + +func (e *kinds) String() string { + return fmt.Sprint(*e) +} + +func (e *kinds) Set(value string) error { + *e = append(*e, value) + return nil } func init() { @@ -55,6 +69,8 @@ func (cmd *events) Register(ctx context.Context, f *flag.FlagSet) { f.Var(flags.NewInt32(&cmd.Max), "n", "Output the last N events") f.BoolVar(&cmd.Tail, "f", false, "Follow event stream") f.BoolVar(&cmd.Force, "force", false, "Disable number objects to monitor limit") + f.BoolVar(&cmd.Long, "l", false, "Long listing format") + f.Var(&cmd.Kind, "type", "Include only the specified event types") } func (cmd *events) Description() string { @@ -63,6 +79,7 @@ func (cmd *events) Description() string { Examples: govc events vm/my-vm1 vm/my-vm2 govc events /dc1/vm/* /dc2/vm/* + govc events -type VmPoweredOffEvent -type VmPoweredOnEvent govc ls -t HostSystem host/* | xargs govc events | grep -i vsan` } @@ -101,6 +118,10 @@ func (cmd *events) printEvents(ctx context.Context, obj *types.ManagedObjectRefe Message: strings.TrimSpace(event.FullFormattedMessage), } + if cmd.Long { + r.Type = reflect.TypeOf(e).Elem().Name() + } + // if this is a TaskEvent gather a little more information if t, ok := e.(*types.TaskEvent); ok { // some tasks won't have this information, so just use the event message @@ -118,6 +139,7 @@ func (cmd *events) printEvents(ctx context.Context, obj *types.ManagedObjectRefe type record struct { Object string `json:",omitempty"` + Type string `json:",omitempty"` CreatedTime time.Time Category string Message string @@ -129,8 +151,11 @@ func writeEventAsJSON(w io.Writer, r *record) error { func writeEvent(w io.Writer, r *record) error { when := r.CreatedTime.Local().Format(time.ANSIC) - - _, err := fmt.Fprintf(w, "[%s] [%s] %s\n", when, r.Category, r.Message) + var kind string + if r.Type != "" { + kind = fmt.Sprintf(" [%s]", r.Type) + } + _, err := fmt.Fprintf(w, "[%s] [%s]%s %s\n", when, r.Category, kind, r.Message) return err } @@ -166,7 +191,7 @@ func (cmd *events) Run(ctx context.Context, f *flag.FlagSet) error { return err } return nil - }) + }, cmd.Kind...) if err != nil { return err diff --git a/vendor/github.com/vmware/govmomi/govc/flags/client.go b/vendor/github.com/vmware/govmomi/govc/flags/client.go index 8722ce3fcb..f1a5384d61 100644 --- a/vendor/github.com/vmware/govmomi/govc/flags/client.go +++ b/vendor/github.com/vmware/govmomi/govc/flags/client.go @@ -428,11 +428,15 @@ func (flag *ClientFlag) newClient() (*vim25.Client, error) { m := session.NewManager(c) u := flag.url.User - if u.Username() == "" { - // Assume we are running on an ESX or Workstation host if no username is provided - u, err = flag.localTicket(ctx, m) - if err != nil { - return nil, err + if u.Username() == "" && !c.IsVC() { + // If no username is provided, try to acquire a local ticket. + // When invoked remotely, ESX returns an InvalidRequestFault. + // So, rather than return an error here, fallthrough to Login() with the original User to + // to avoid what would be a confusing error message. + luser, lerr := flag.localTicket(ctx, m) + if lerr == nil { + // We are running directly on an ESX or Workstation host and can use the ticket with Login() + u = luser } } diff --git a/vendor/github.com/vmware/govmomi/govc/flags/cluster.go b/vendor/github.com/vmware/govmomi/govc/flags/cluster.go new file mode 100644 index 0000000000..618e386665 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/flags/cluster.go @@ -0,0 +1,184 @@ +/* +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 flags + +import ( + "context" + "flag" + "fmt" + "os" + + "github.com/vmware/govmomi/object" + "github.com/vmware/govmomi/property" + "github.com/vmware/govmomi/view" + "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/types" +) + +type ClusterFlag struct { + common + + *DatacenterFlag + + Name string + + cluster *object.ClusterComputeResource + pc *property.Collector +} + +var clusterFlagKey = flagKey("cluster") + +func NewClusterFlag(ctx context.Context) (*ClusterFlag, context.Context) { + if v := ctx.Value(clusterFlagKey); v != nil { + return v.(*ClusterFlag), ctx + } + + v := &ClusterFlag{} + v.DatacenterFlag, ctx = NewDatacenterFlag(ctx) + ctx = context.WithValue(ctx, clusterFlagKey, v) + return v, ctx +} + +func (f *ClusterFlag) Register(ctx context.Context, fs *flag.FlagSet) { + f.RegisterOnce(func() { + f.DatacenterFlag.Register(ctx, fs) + + env := "GOVC_CLUSTER" + value := os.Getenv(env) + usage := fmt.Sprintf("Cluster [%s]", env) + fs.StringVar(&f.Name, "cluster", value, usage) + }) +} + +func (f *ClusterFlag) Process(ctx context.Context) error { + return f.ProcessOnce(func() error { + if err := f.DatacenterFlag.Process(ctx); err != nil { + return err + } + return nil + }) +} + +func (f *ClusterFlag) Cluster() (*object.ClusterComputeResource, error) { + if f.cluster != nil { + return f.cluster, nil + } + + finder, err := f.Finder() + if err != nil { + return nil, err + } + + if f.cluster, err = finder.ClusterComputeResourceOrDefault(context.TODO(), f.Name); err != nil { + return nil, err + } + + f.pc = property.DefaultCollector(f.cluster.Client()) + + return f.cluster, nil +} + +func (f *ClusterFlag) Reconfigure(ctx context.Context, spec types.BaseComputeResourceConfigSpec) error { + cluster, err := f.Cluster() + if err != nil { + return err + } + + task, err := cluster.Reconfigure(ctx, spec, true) + if err != nil { + return err + } + + logger := f.ProgressLogger(fmt.Sprintf("Reconfigure %s...", cluster.InventoryPath)) + defer logger.Wait() + + _, err = task.WaitForResult(ctx, logger) + return err +} + +func (f *ClusterFlag) objectMap(ctx context.Context, kind string, names []string) (map[string]types.ManagedObjectReference, error) { + cluster, err := f.Cluster() + if err != nil { + return nil, err + } + + objects := make(map[string]types.ManagedObjectReference, len(names)) + for _, name := range names { + objects[name] = types.ManagedObjectReference{} + } + + m := view.NewManager(cluster.Client()) + v, err := m.CreateContainerView(ctx, cluster.Reference(), []string{kind}, true) + if err != nil { + return nil, err + } + defer v.Destroy(ctx) + + var entities []mo.ManagedEntity + + err = v.Retrieve(ctx, []string{"ManagedEntity"}, []string{"name"}, &entities) + if err != nil { + return nil, err + } + + for _, e := range entities { + if _, ok := objects[e.Name]; ok { + objects[e.Name] = e.Self + } + } + + for name, ref := range objects { + if ref.Value == "" { + return nil, fmt.Errorf("%s %q not found", kind, name) + } + } + + return objects, nil +} + +func (f *ClusterFlag) ObjectList(ctx context.Context, kind string, names []string) ([]types.ManagedObjectReference, error) { + objs, err := f.objectMap(ctx, kind, names) + if err != nil { + return nil, err + } + + var refs []types.ManagedObjectReference + + for _, name := range names { // preserve order + refs = append(refs, objs[name]) + } + + return refs, nil +} + +func (f *ClusterFlag) Names(ctx context.Context, refs []types.ManagedObjectReference) (map[types.ManagedObjectReference]string, error) { + names := make(map[types.ManagedObjectReference]string, len(refs)) + + if len(refs) != 0 { + var objs []mo.ManagedEntity + err := f.pc.Retrieve(ctx, refs, []string{"name"}, &objs) + if err != nil { + return nil, err + } + + for _, obj := range objs { + names[obj.Self] = obj.Name + } + } + + return names, nil +} diff --git a/vendor/github.com/vmware/govmomi/govc/flags/resource_allocation_info.go b/vendor/github.com/vmware/govmomi/govc/flags/resource_allocation_info.go new file mode 100644 index 0000000000..99a262ec45 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/flags/resource_allocation_info.go @@ -0,0 +1,85 @@ +/* +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 flags + +import ( + "context" + "flag" + "strconv" + "strings" + + "github.com/vmware/govmomi/vim25/types" +) + +type sharesInfo types.SharesInfo + +func (s *sharesInfo) String() string { + return string(s.Level) +} + +func (s *sharesInfo) Set(val string) error { + switch val { + case string(types.SharesLevelNormal), string(types.SharesLevelLow), string(types.SharesLevelHigh): + s.Level = types.SharesLevel(val) + default: + n, err := strconv.Atoi(val) + if err != nil { + return err + } + + s.Level = types.SharesLevelCustom + s.Shares = int32(n) + } + + return nil +} + +type ResourceAllocationFlag struct { + cpu, mem *types.ResourceAllocationInfo + ExpandableReservation bool +} + +func NewResourceAllocationFlag(cpu, mem *types.ResourceAllocationInfo) *ResourceAllocationFlag { + return &ResourceAllocationFlag{cpu, mem, true} +} + +func (r *ResourceAllocationFlag) Register(ctx context.Context, f *flag.FlagSet) { + opts := []struct { + name string + units string + *types.ResourceAllocationInfo + }{ + {"CPU", "MHz", r.cpu}, + {"Memory", "MB", r.mem}, + } + + for _, opt := range opts { + prefix := strings.ToLower(opt.name)[:3] + shares := (*sharesInfo)(opt.Shares) + + f.Var(NewOptionalInt64(&opt.Limit), prefix+".limit", opt.name+" limit in "+opt.units) + f.Var(NewOptionalInt64(&opt.Reservation), prefix+".reservation", opt.name+" reservation in "+opt.units) + if r.ExpandableReservation { + f.Var(NewOptionalBool(&opt.ExpandableReservation), prefix+".expandable", opt.name+" expandable reservation") + } + f.Var(shares, prefix+".shares", opt.name+" shares level or number") + } +} + +func (s *ResourceAllocationFlag) Process(ctx context.Context) error { + return nil +} diff --git a/vendor/github.com/vmware/govmomi/govc/flags/version.go b/vendor/github.com/vmware/govmomi/govc/flags/version.go index f1ea204d03..6333e6622b 100644 --- a/vendor/github.com/vmware/govmomi/govc/flags/version.go +++ b/vendor/github.com/vmware/govmomi/govc/flags/version.go @@ -21,7 +21,7 @@ import ( "strings" ) -const Version = "0.16.0" +const Version = "0.16.1" type version []int diff --git a/vendor/github.com/vmware/govmomi/govc/host/shutdown.go b/vendor/github.com/vmware/govmomi/govc/host/shutdown.go index 97d1b01a1b..f40a7ee802 100644 --- a/vendor/github.com/vmware/govmomi/govc/host/shutdown.go +++ b/vendor/github.com/vmware/govmomi/govc/host/shutdown.go @@ -53,6 +53,10 @@ func (cmd *shutdown) Process(ctx context.Context) error { return nil } +func (cmd *shutdown) Usage() string { + return `HOST...` +} + func (cmd *shutdown) Description() string { return `Shutdown HOST.` } diff --git a/vendor/github.com/vmware/govmomi/govc/host/storage/info.go b/vendor/github.com/vmware/govmomi/govc/host/storage/info.go index 799a055183..e2fa2cf93d 100644 --- a/vendor/github.com/vmware/govmomi/govc/host/storage/info.go +++ b/vendor/github.com/vmware/govmomi/govc/host/storage/info.go @@ -67,10 +67,11 @@ type info struct { *flags.HostSystemFlag *flags.OutputFlag - typ infoType - rescan bool - refresh bool - unclaimed bool + typ infoType + rescan bool + refresh bool + rescanvmfs bool + unclaimed bool } func init() { @@ -92,6 +93,7 @@ func (cmd *info) Register(ctx context.Context, f *flag.FlagSet) { f.BoolVar(&cmd.rescan, "rescan", false, "Rescan all host bus adapters") f.BoolVar(&cmd.refresh, "refresh", false, "Refresh the storage system provider") + f.BoolVar(&cmd.rescanvmfs, "rescan-vmfs", false, "Rescan for new VMFSs") f.BoolVar(&cmd.unclaimed, "unclaimed", false, "Only show disks that can be used as new VMFS datastores") } @@ -137,6 +139,13 @@ func (cmd *info) Run(ctx context.Context, f *flag.FlagSet) error { } } + if cmd.rescanvmfs { + err = ss.RescanVmfs(ctx) + if err != nil { + return err + } + } + var hss mo.HostStorageSystem err = ss.Properties(ctx, ss.Reference(), nil, &hss) if err != nil { diff --git a/vendor/github.com/vmware/govmomi/govc/main.go b/vendor/github.com/vmware/govmomi/govc/main.go index 6df93034b1..236499dbaf 100644 --- a/vendor/github.com/vmware/govmomi/govc/main.go +++ b/vendor/github.com/vmware/govmomi/govc/main.go @@ -23,6 +23,8 @@ import ( _ "github.com/vmware/govmomi/govc/about" _ "github.com/vmware/govmomi/govc/cluster" + _ "github.com/vmware/govmomi/govc/cluster/group" + _ "github.com/vmware/govmomi/govc/cluster/rule" _ "github.com/vmware/govmomi/govc/datacenter" _ "github.com/vmware/govmomi/govc/datastore" _ "github.com/vmware/govmomi/govc/datastore/disk" diff --git a/vendor/github.com/vmware/govmomi/govc/pool/resource_config_spec.go b/vendor/github.com/vmware/govmomi/govc/pool/resource_config_spec.go index 45522ae7fd..c4e933ccd2 100644 --- a/vendor/github.com/vmware/govmomi/govc/pool/resource_config_spec.go +++ b/vendor/github.com/vmware/govmomi/govc/pool/resource_config_spec.go @@ -19,63 +19,23 @@ package pool import ( "context" "flag" - "strconv" - "strings" "github.com/vmware/govmomi/govc/flags" "github.com/vmware/govmomi/vim25/types" ) -type sharesInfo types.SharesInfo - -func (s *sharesInfo) String() string { - return string(s.Level) -} - -func (s *sharesInfo) Set(val string) error { - switch val { - case string(types.SharesLevelNormal), string(types.SharesLevelLow), string(types.SharesLevelHigh): - s.Level = types.SharesLevel(val) - default: - n, err := strconv.Atoi(val) - if err != nil { - return err - } - - s.Level = types.SharesLevelCustom - s.Shares = int32(n) - } - - return nil -} - func NewResourceConfigSpecFlag() *ResourceConfigSpecFlag { - return &ResourceConfigSpecFlag{types.DefaultResourceConfigSpec()} + return &ResourceConfigSpecFlag{types.DefaultResourceConfigSpec(), nil} } type ResourceConfigSpecFlag struct { types.ResourceConfigSpec + *flags.ResourceAllocationFlag } func (s *ResourceConfigSpecFlag) Register(ctx context.Context, f *flag.FlagSet) { - opts := []struct { - name string - units string - *types.ResourceAllocationInfo - }{ - {"CPU", "MHz", &s.CpuAllocation}, - {"Memory", "MB", &s.MemoryAllocation}, - } - - for _, opt := range opts { - prefix := strings.ToLower(opt.name)[:3] - shares := (*sharesInfo)(opt.Shares) - - f.Var(flags.NewOptionalInt64(&opt.Limit), prefix+".limit", opt.name+" limit in "+opt.units) - f.Var(flags.NewOptionalInt64(&opt.Reservation), prefix+".reservation", opt.name+" reservation in "+opt.units) - f.Var(flags.NewOptionalBool(&opt.ExpandableReservation), prefix+".expandable", opt.name+" expandable reservation") - f.Var(shares, prefix+".shares", opt.name+" shares level or number") - } + s.ResourceAllocationFlag = flags.NewResourceAllocationFlag(&s.CpuAllocation, &s.MemoryAllocation) + s.ResourceAllocationFlag.Register(ctx, f) } func (s *ResourceConfigSpecFlag) Process(ctx context.Context) error { diff --git a/vendor/github.com/vmware/govmomi/govc/session/ls.go b/vendor/github.com/vmware/govmomi/govc/session/ls.go index ae077decec..d87aee8c77 100644 --- a/vendor/github.com/vmware/govmomi/govc/session/ls.go +++ b/vendor/github.com/vmware/govmomi/govc/session/ls.go @@ -27,6 +27,7 @@ import ( "github.com/vmware/govmomi/govc/cli" "github.com/vmware/govmomi/govc/flags" "github.com/vmware/govmomi/property" + "github.com/vmware/govmomi/vim25/methods" "github.com/vmware/govmomi/vim25/mo" ) @@ -67,6 +68,7 @@ func (cmd *ls) Process(ctx context.Context) error { type sessionInfo struct { cmd *ls + now *time.Time mo.SessionManager } @@ -85,7 +87,7 @@ func (s *sessionInfo) Write(w io.Writer) error { for _, v := range s.SessionList { idle := " ." if v.Key != s.CurrentSession.Key { - since := time.Since(v.LastActiveTime) + since := s.now.Sub(v.LastActiveTime) if since > time.Hour { idle = "old" } else { @@ -117,5 +119,10 @@ func (cmd *ls) Run(ctx context.Context, f *flag.FlagSet) error { return nil } - return cmd.WriteResult(&sessionInfo{cmd, m}) + now, err := methods.GetCurrentTime(ctx, c) + if err != nil { + return err + } + + return cmd.WriteResult(&sessionInfo{cmd, now, m}) } diff --git a/vendor/github.com/vmware/govmomi/govc/vm/change.go b/vendor/github.com/vmware/govmomi/govc/vm/change.go index af00b36c9d..6b4bea2dff 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/change.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/change.go @@ -44,6 +44,7 @@ func (e *extraConfig) Set(v string) error { type change struct { *flags.VirtualMachineFlag + *flags.ResourceAllocationFlag types.VirtualMachineConfigSpec extraConfig extraConfig @@ -53,10 +54,39 @@ func init() { cli.Register("vm.change", &change{}) } +// setAllocation sets *info=nil if none of the fields have been set. +// We need non-nil fields for use with flag.FlagSet, but we want the +// VirtualMachineConfigSpec fields to be nil if none of the related flags were given. +func setAllocation(info **types.ResourceAllocationInfo) { + r := *info + + if r.Shares.Level == "" { + r.Shares = nil + } else { + return + } + + if r.Limit != nil { + return + } + + if r.Reservation != nil { + return + } + + *info = nil +} + func (cmd *change) Register(ctx context.Context, f *flag.FlagSet) { cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx) cmd.VirtualMachineFlag.Register(ctx, f) + cmd.CpuAllocation = &types.ResourceAllocationInfo{Shares: new(types.SharesInfo)} + cmd.MemoryAllocation = &types.ResourceAllocationInfo{Shares: new(types.SharesInfo)} + cmd.ResourceAllocationFlag = flags.NewResourceAllocationFlag(cmd.CpuAllocation, cmd.MemoryAllocation) + cmd.ResourceAllocationFlag.ExpandableReservation = false + cmd.ResourceAllocationFlag.Register(ctx, f) + f.Int64Var(&cmd.MemoryMB, "m", 0, "Size in MB of memory") f.Var(flags.NewInt32(&cmd.NumCPUs), "c", "Number of CPUs") f.StringVar(&cmd.GuestId, "g", "", "Guest OS") @@ -74,6 +104,7 @@ func (cmd *change) Description() string { To add ExtraConfig variables that can read within the guest, use the 'guestinfo.' prefix. Examples: + govc vm.change -vm $vm -mem.reservation 2048 govc vm.change -vm $vm -e smc.present=TRUE -e ich7m.present=TRUE govc vm.change -vm $vm -e guestinfo.vmname $vm # Read the variable set above inside the guest: @@ -101,6 +132,9 @@ func (cmd *change) Run(ctx context.Context, f *flag.FlagSet) error { cmd.VirtualMachineConfigSpec.ExtraConfig = cmd.extraConfig } + setAllocation(&cmd.CpuAllocation) + setAllocation(&cmd.MemoryAllocation) + task, err := vm.Reconfigure(ctx, cmd.VirtualMachineConfigSpec) if err != nil { return err diff --git a/vendor/github.com/vmware/govmomi/govc/vm/guest/auth.go b/vendor/github.com/vmware/govmomi/govc/vm/guest/auth.go index c392eab14b..8393537101 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/guest/auth.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/guest/auth.go @@ -39,7 +39,7 @@ func (flag *AuthFlag) String() string { } func (flag *AuthFlag) Set(s string) error { - c := strings.Split(s, ":") + c := strings.SplitN(s, ":", 2) if len(c) > 0 { flag.auth.Username = c[0] if len(c) > 1 { diff --git a/vendor/github.com/vmware/govmomi/govc/vm/info.go b/vendor/github.com/vmware/govmomi/govc/vm/info.go index 1b37378cd1..cc219355df 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/info.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/info.go @@ -83,6 +83,19 @@ func (cmd *info) Process(ctx context.Context) error { return nil } +func (cmd *info) Usage() string { + return `VM...` +} + +func (cmd *info) Description() string { + return `Display info for VM. + +Examples: + govc vm.info $vm + govc vm.info -json $vm + govc find . -type m -runtime.powerState poweredOn | xargs govc vm.info` +} + func (cmd *info) Run(ctx context.Context, f *flag.FlagSet) error { c, err := cmd.Client() if err != nil { diff --git a/vendor/github.com/vmware/govmomi/govc/vm/upgrade.go b/vendor/github.com/vmware/govmomi/govc/vm/upgrade.go new file mode 100644 index 0000000000..e4f4ec8af8 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/vm/upgrade.go @@ -0,0 +1,81 @@ +package vm + +import ( + "context" + "flag" + + "fmt" + + "github.com/vmware/govmomi/govc/cli" + "github.com/vmware/govmomi/govc/flags" + "github.com/vmware/govmomi/task" + "github.com/vmware/govmomi/vim25/types" +) + +type upgrade struct { + *flags.VirtualMachineFlag + version int +} + +func init() { + cli.Register("vm.upgrade", &upgrade{}) +} + +func isAlreadyUpgraded(err error) bool { + if fault, ok := err.(task.Error); ok { + _, ok = fault.Fault().(*types.AlreadyUpgraded) + return ok + } + + return false +} + +func (cmd *upgrade) Register(ctx context.Context, f *flag.FlagSet) { + cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx) + cmd.VirtualMachineFlag.Register(ctx, f) + + f.IntVar(&cmd.version, "version", 0, "Target vm hardware version, by default -- latest available") +} + +func (cmd *upgrade) Process(ctx context.Context) error { + if err := cmd.VirtualMachineFlag.Process(ctx); err != nil { + return err + } + return nil +} + +func (cmd *upgrade) Description() string { + return `Upgrade VMs to latest hardware version + +Examples: + govc vm.upgrade -vm $vm_name + govc vm.upgrade -version=$version -vm $vm_name + govc vm.upgrade -version=$version -vm.uuid $vm_uuid` +} + +func (cmd *upgrade) Run(ctx context.Context, f *flag.FlagSet) error { + vm, err := cmd.VirtualMachine() + if err != nil { + return err + } + + var version = "" + if cmd.version != 0 { + version = fmt.Sprintf("vmx-%02d", cmd.version) + } + + task, err := vm.UpgradeVM(ctx, version) + if err != nil { + return err + } + err = task.Wait(ctx) + if err != nil { + if isAlreadyUpgraded(err) { + fmt.Println(err.Error()) + } else { + return err + } + } + + return nil +} diff --git a/vendor/github.com/vmware/govmomi/object/cluster_compute_resource.go b/vendor/github.com/vmware/govmomi/object/cluster_compute_resource.go index 225f41b6d1..c9fe3aa035 100644 --- a/vendor/github.com/vmware/govmomi/object/cluster_compute_resource.go +++ b/vendor/github.com/vmware/govmomi/object/cluster_compute_resource.go @@ -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 -} diff --git a/vendor/github.com/vmware/govmomi/object/compute_resource.go b/vendor/github.com/vmware/govmomi/object/compute_resource.go index ac1c73019f..7645fddaf3 100644 --- a/vendor/github.com/vmware/govmomi/object/compute_resource.go +++ b/vendor/github.com/vmware/govmomi/object/compute_resource.go @@ -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 -} diff --git a/vendor/github.com/vmware/govmomi/object/datastore.go b/vendor/github.com/vmware/govmomi/object/datastore.go index fc696cdf21..6e0e0dbae3 100644 --- a/vendor/github.com/vmware/govmomi/object/datastore.go +++ b/vendor/github.com/vmware/govmomi/object/datastore.go @@ -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 diff --git a/vendor/github.com/vmware/govmomi/object/host_storage_system.go b/vendor/github.com/vmware/govmomi/object/host_storage_system.go index 6785eecdcd..f284d3fbcb 100644 --- a/vendor/github.com/vmware/govmomi/object/host_storage_system.go +++ b/vendor/github.com/vmware/govmomi/object/host_storage_system.go @@ -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(), diff --git a/vendor/github.com/vmware/govmomi/object/virtual_disk_manager.go b/vendor/github.com/vmware/govmomi/object/virtual_disk_manager.go index b26e2f71c2..7bea49d51e 100644 --- a/vendor/github.com/vmware/govmomi/object/virtual_disk_manager.go +++ b/vendor/github.com/vmware/govmomi/object/virtual_disk_manager.go @@ -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{ diff --git a/vendor/github.com/vmware/govmomi/object/virtual_disk_manager_internal.go b/vendor/github.com/vmware/govmomi/object/virtual_disk_manager_internal.go index 642cd62f6e..dc747c121b 100644 --- a/vendor/github.com/vmware/govmomi/object/virtual_disk_manager_internal.go +++ b/vendor/github.com/vmware/govmomi/object/virtual_disk_manager_internal.go @@ -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 +} diff --git a/vendor/github.com/vmware/govmomi/object/virtual_machine.go b/vendor/github.com/vmware/govmomi/object/virtual_machine.go index 4c36ee10e0..511f557235 100644 --- a/vendor/github.com/vmware/govmomi/object/virtual_machine.go +++ b/vendor/github.com/vmware/govmomi/object/virtual_machine.go @@ -785,3 +785,17 @@ func (v VirtualMachine) Export(ctx context.Context) (*nfc.Lease, error) { return nfc.NewLease(v.c, res.Returnval), nil } + +func (v VirtualMachine) UpgradeVM(ctx context.Context, version string) (*Task, error) { + req := types.UpgradeVM_Task{ + This: v.Reference(), + Version: version, + } + + res, err := methods.UpgradeVM_Task(ctx, v.Client(), &req) + if err != nil { + return nil, err + } + + return NewTask(v.c, res.Returnval), nil +} diff --git a/vendor/github.com/vmware/govmomi/property/collector.go b/vendor/github.com/vmware/govmomi/property/collector.go index 04a9e77373..ccf712cf9d 100644 --- a/vendor/github.com/vmware/govmomi/property/collector.go +++ b/vendor/github.com/vmware/govmomi/property/collector.go @@ -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 diff --git a/vendor/github.com/vmware/govmomi/simulator/authorization_manager.go b/vendor/github.com/vmware/govmomi/simulator/authorization_manager.go index b65db933e8..969ca36704 100644 --- a/vendor/github.com/vmware/govmomi/simulator/authorization_manager.go +++ b/vendor/github.com/vmware/govmomi/simulator/authorization_manager.go @@ -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) diff --git a/vendor/github.com/vmware/govmomi/simulator/cluster_compute_resource.go b/vendor/github.com/vmware/govmomi/simulator/cluster_compute_resource.go index fe51ae3e7c..a4eca42eb6 100644 --- a/vendor/github.com/vmware/govmomi/simulator/cluster_compute_resource.go +++ b/vendor/github.com/vmware/govmomi/simulator/cluster_compute_resource.go @@ -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 { @@ -68,6 +73,125 @@ 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) 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, + } + + 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 +209,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() diff --git a/vendor/github.com/vmware/govmomi/simulator/esx/service_content.go b/vendor/github.com/vmware/govmomi/simulator/esx/service_content.go index 9c13cc0cc8..cc8938f878 100644 --- a/vendor/github.com/vmware/govmomi/simulator/esx/service_content.go +++ b/vendor/github.com/vmware/govmomi/simulator/esx/service_content.go @@ -22,61 +22,65 @@ import "github.com/vmware/govmomi/vim25/types" // Capture method: // govc object.collect -s -dump - content var ServiceContent = types.ServiceContent{ - DynamicData: types.DynamicData{}, RootFolder: types.ManagedObjectReference{Type: "Folder", Value: "ha-folder-root"}, PropertyCollector: types.ManagedObjectReference{Type: "PropertyCollector", Value: "ha-property-collector"}, ViewManager: &types.ManagedObjectReference{Type: "ViewManager", Value: "ViewManager"}, About: types.AboutInfo{ - DynamicData: types.DynamicData{}, Name: "VMware ESXi", - FullName: "VMware ESXi 6.0.0 build-3620759", + FullName: "VMware ESXi 6.5.0 build-5969303", Vendor: "VMware, Inc.", - Version: "6.0.0", - Build: "3620759", + Version: "6.5.0", + Build: "5969303", LocaleVersion: "INTL", LocaleBuild: "000", OsType: "vmnix-x86", ProductLineId: "embeddedEsx", ApiType: "HostAgent", - ApiVersion: "6.0", + ApiVersion: "6.5", InstanceUuid: "", LicenseProductName: "VMware ESX Server", LicenseProductVersion: "6.0", }, - Setting: &types.ManagedObjectReference{Type: "OptionManager", Value: "HostAgentSettings"}, - UserDirectory: &types.ManagedObjectReference{Type: "UserDirectory", Value: "ha-user-directory"}, - SessionManager: &types.ManagedObjectReference{Type: "SessionManager", Value: "ha-sessionmgr"}, - AuthorizationManager: &types.ManagedObjectReference{Type: "AuthorizationManager", Value: "ha-authmgr"}, - ServiceManager: &types.ManagedObjectReference{Type: "ServiceManager", Value: "ha-servicemanager"}, - PerfManager: &types.ManagedObjectReference{Type: "PerformanceManager", Value: "ha-perfmgr"}, - ScheduledTaskManager: (*types.ManagedObjectReference)(nil), - AlarmManager: (*types.ManagedObjectReference)(nil), - EventManager: &types.ManagedObjectReference{Type: "EventManager", Value: "ha-eventmgr"}, - TaskManager: &types.ManagedObjectReference{Type: "TaskManager", Value: "ha-taskmgr"}, - ExtensionManager: (*types.ManagedObjectReference)(nil), - CustomizationSpecManager: (*types.ManagedObjectReference)(nil), - CustomFieldsManager: (*types.ManagedObjectReference)(nil), - AccountManager: &types.ManagedObjectReference{Type: "HostLocalAccountManager", Value: "ha-localacctmgr"}, - DiagnosticManager: &types.ManagedObjectReference{Type: "DiagnosticManager", Value: "ha-diagnosticmgr"}, - LicenseManager: &types.ManagedObjectReference{Type: "LicenseManager", Value: "ha-license-manager"}, - SearchIndex: &types.ManagedObjectReference{Type: "SearchIndex", Value: "ha-searchindex"}, - FileManager: &types.ManagedObjectReference{Type: "FileManager", Value: "ha-nfc-file-manager"}, - DatastoreNamespaceManager: &types.ManagedObjectReference{Type: "DatastoreNamespaceManager", Value: "ha-datastore-namespace-manager"}, - VirtualDiskManager: &types.ManagedObjectReference{Type: "VirtualDiskManager", Value: "ha-vdiskmanager"}, - VirtualizationManager: (*types.ManagedObjectReference)(nil), - SnmpSystem: (*types.ManagedObjectReference)(nil), - VmProvisioningChecker: (*types.ManagedObjectReference)(nil), - VmCompatibilityChecker: (*types.ManagedObjectReference)(nil), - OvfManager: &types.ManagedObjectReference{Type: "OvfManager", Value: "ha-ovf-manager"}, - IpPoolManager: (*types.ManagedObjectReference)(nil), - DvSwitchManager: &types.ManagedObjectReference{Type: "DistributedVirtualSwitchManager", Value: "ha-dvsmanager"}, - HostProfileManager: (*types.ManagedObjectReference)(nil), - ClusterProfileManager: (*types.ManagedObjectReference)(nil), - ComplianceManager: (*types.ManagedObjectReference)(nil), - LocalizationManager: &types.ManagedObjectReference{Type: "LocalizationManager", Value: "ha-l10n-manager"}, - StorageResourceManager: &types.ManagedObjectReference{Type: "StorageResourceManager", Value: "ha-storage-resource-manager"}, - GuestOperationsManager: &types.ManagedObjectReference{Type: "GuestOperationsManager", Value: "ha-guest-operations-manager"}, - OverheadMemoryManager: (*types.ManagedObjectReference)(nil), - CertificateManager: (*types.ManagedObjectReference)(nil), - IoFilterManager: (*types.ManagedObjectReference)(nil), + Setting: &types.ManagedObjectReference{Type: "OptionManager", Value: "HostAgentSettings"}, + UserDirectory: &types.ManagedObjectReference{Type: "UserDirectory", Value: "ha-user-directory"}, + SessionManager: &types.ManagedObjectReference{Type: "SessionManager", Value: "ha-sessionmgr"}, + AuthorizationManager: &types.ManagedObjectReference{Type: "AuthorizationManager", Value: "ha-authmgr"}, + ServiceManager: &types.ManagedObjectReference{Type: "ServiceManager", Value: "ha-servicemanager"}, + PerfManager: &types.ManagedObjectReference{Type: "PerformanceManager", Value: "ha-perfmgr"}, + ScheduledTaskManager: (*types.ManagedObjectReference)(nil), + AlarmManager: (*types.ManagedObjectReference)(nil), + EventManager: &types.ManagedObjectReference{Type: "EventManager", Value: "ha-eventmgr"}, + TaskManager: &types.ManagedObjectReference{Type: "TaskManager", Value: "ha-taskmgr"}, + ExtensionManager: (*types.ManagedObjectReference)(nil), + CustomizationSpecManager: (*types.ManagedObjectReference)(nil), + CustomFieldsManager: (*types.ManagedObjectReference)(nil), + AccountManager: &types.ManagedObjectReference{Type: "HostLocalAccountManager", Value: "ha-localacctmgr"}, + DiagnosticManager: &types.ManagedObjectReference{Type: "DiagnosticManager", Value: "ha-diagnosticmgr"}, + LicenseManager: &types.ManagedObjectReference{Type: "LicenseManager", Value: "ha-license-manager"}, + SearchIndex: &types.ManagedObjectReference{Type: "SearchIndex", Value: "ha-searchindex"}, + FileManager: &types.ManagedObjectReference{Type: "FileManager", Value: "ha-nfc-file-manager"}, + DatastoreNamespaceManager: &types.ManagedObjectReference{Type: "DatastoreNamespaceManager", Value: "ha-datastore-namespace-manager"}, + VirtualDiskManager: &types.ManagedObjectReference{Type: "VirtualDiskManager", Value: "ha-vdiskmanager"}, + VirtualizationManager: (*types.ManagedObjectReference)(nil), + SnmpSystem: (*types.ManagedObjectReference)(nil), + VmProvisioningChecker: (*types.ManagedObjectReference)(nil), + VmCompatibilityChecker: (*types.ManagedObjectReference)(nil), + OvfManager: &types.ManagedObjectReference{Type: "OvfManager", Value: "ha-ovf-manager"}, + IpPoolManager: (*types.ManagedObjectReference)(nil), + DvSwitchManager: &types.ManagedObjectReference{Type: "DistributedVirtualSwitchManager", Value: "ha-dvsmanager"}, + HostProfileManager: (*types.ManagedObjectReference)(nil), + ClusterProfileManager: (*types.ManagedObjectReference)(nil), + ComplianceManager: (*types.ManagedObjectReference)(nil), + LocalizationManager: &types.ManagedObjectReference{Type: "LocalizationManager", Value: "ha-l10n-manager"}, + StorageResourceManager: &types.ManagedObjectReference{Type: "StorageResourceManager", Value: "ha-storage-resource-manager"}, + GuestOperationsManager: &types.ManagedObjectReference{Type: "GuestOperationsManager", Value: "ha-guest-operations-manager"}, + OverheadMemoryManager: (*types.ManagedObjectReference)(nil), + CertificateManager: (*types.ManagedObjectReference)(nil), + IoFilterManager: (*types.ManagedObjectReference)(nil), + VStorageObjectManager: &types.ManagedObjectReference{Type: "HostVStorageObjectManager", Value: "ha-vstorage-object-manager"}, + HostSpecManager: (*types.ManagedObjectReference)(nil), + CryptoManager: &types.ManagedObjectReference{Type: "CryptoManager", Value: "ha-crypto-manager"}, + HealthUpdateManager: (*types.ManagedObjectReference)(nil), + FailoverClusterConfigurator: (*types.ManagedObjectReference)(nil), + FailoverClusterManager: (*types.ManagedObjectReference)(nil), } diff --git a/vendor/github.com/vmware/govmomi/simulator/file_manager.go b/vendor/github.com/vmware/govmomi/simulator/file_manager.go index 6e76b5fd02..a0bb034867 100644 --- a/vendor/github.com/vmware/govmomi/simulator/file_manager.go +++ b/vendor/github.com/vmware/govmomi/simulator/file_manager.go @@ -160,6 +160,7 @@ func (f *FileManager) MakeDirectory(req *types.MakeDirectory) soap.HasFault { return body } + body.Res = new(types.MakeDirectoryResponse) return body } diff --git a/vendor/github.com/vmware/govmomi/simulator/folder.go b/vendor/github.com/vmware/govmomi/simulator/folder.go index f5dea3291e..e485344d56 100644 --- a/vendor/github.com/vmware/govmomi/simulator/folder.go +++ b/vendor/github.com/vmware/govmomi/simulator/folder.go @@ -445,6 +445,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{ diff --git a/vendor/github.com/vmware/govmomi/simulator/guest_id.go b/vendor/github.com/vmware/govmomi/simulator/guest_id.go new file mode 100644 index 0000000000..87cf4aaf83 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/simulator/guest_id.go @@ -0,0 +1,171 @@ +/* +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/vim25/types" + +// GuestID is the list of valid types.VirtualMachineGuestOsIdentifier +var GuestID = []types.VirtualMachineGuestOsIdentifier{ + types.VirtualMachineGuestOsIdentifierDosGuest, + types.VirtualMachineGuestOsIdentifierWin31Guest, + types.VirtualMachineGuestOsIdentifierWin95Guest, + types.VirtualMachineGuestOsIdentifierWin98Guest, + types.VirtualMachineGuestOsIdentifierWinMeGuest, + types.VirtualMachineGuestOsIdentifierWinNTGuest, + types.VirtualMachineGuestOsIdentifierWin2000ProGuest, + types.VirtualMachineGuestOsIdentifierWin2000ServGuest, + types.VirtualMachineGuestOsIdentifierWin2000AdvServGuest, + types.VirtualMachineGuestOsIdentifierWinXPHomeGuest, + types.VirtualMachineGuestOsIdentifierWinXPProGuest, + types.VirtualMachineGuestOsIdentifierWinXPPro64Guest, + types.VirtualMachineGuestOsIdentifierWinNetWebGuest, + types.VirtualMachineGuestOsIdentifierWinNetStandardGuest, + types.VirtualMachineGuestOsIdentifierWinNetEnterpriseGuest, + types.VirtualMachineGuestOsIdentifierWinNetDatacenterGuest, + types.VirtualMachineGuestOsIdentifierWinNetBusinessGuest, + types.VirtualMachineGuestOsIdentifierWinNetStandard64Guest, + types.VirtualMachineGuestOsIdentifierWinNetEnterprise64Guest, + types.VirtualMachineGuestOsIdentifierWinLonghornGuest, + types.VirtualMachineGuestOsIdentifierWinLonghorn64Guest, + types.VirtualMachineGuestOsIdentifierWinNetDatacenter64Guest, + types.VirtualMachineGuestOsIdentifierWinVistaGuest, + types.VirtualMachineGuestOsIdentifierWinVista64Guest, + types.VirtualMachineGuestOsIdentifierWindows7Guest, + types.VirtualMachineGuestOsIdentifierWindows7_64Guest, + types.VirtualMachineGuestOsIdentifierWindows7Server64Guest, + types.VirtualMachineGuestOsIdentifierWindows8Guest, + types.VirtualMachineGuestOsIdentifierWindows8_64Guest, + types.VirtualMachineGuestOsIdentifierWindows8Server64Guest, + types.VirtualMachineGuestOsIdentifierWindows9Guest, + types.VirtualMachineGuestOsIdentifierWindows9_64Guest, + types.VirtualMachineGuestOsIdentifierWindows9Server64Guest, + types.VirtualMachineGuestOsIdentifierWindowsHyperVGuest, + types.VirtualMachineGuestOsIdentifierFreebsdGuest, + types.VirtualMachineGuestOsIdentifierFreebsd64Guest, + types.VirtualMachineGuestOsIdentifierRedhatGuest, + types.VirtualMachineGuestOsIdentifierRhel2Guest, + types.VirtualMachineGuestOsIdentifierRhel3Guest, + types.VirtualMachineGuestOsIdentifierRhel3_64Guest, + types.VirtualMachineGuestOsIdentifierRhel4Guest, + types.VirtualMachineGuestOsIdentifierRhel4_64Guest, + types.VirtualMachineGuestOsIdentifierRhel5Guest, + types.VirtualMachineGuestOsIdentifierRhel5_64Guest, + types.VirtualMachineGuestOsIdentifierRhel6Guest, + types.VirtualMachineGuestOsIdentifierRhel6_64Guest, + types.VirtualMachineGuestOsIdentifierRhel7Guest, + types.VirtualMachineGuestOsIdentifierRhel7_64Guest, + types.VirtualMachineGuestOsIdentifierCentosGuest, + types.VirtualMachineGuestOsIdentifierCentos64Guest, + types.VirtualMachineGuestOsIdentifierCentos6Guest, + types.VirtualMachineGuestOsIdentifierCentos6_64Guest, + types.VirtualMachineGuestOsIdentifierCentos7Guest, + types.VirtualMachineGuestOsIdentifierCentos7_64Guest, + types.VirtualMachineGuestOsIdentifierOracleLinuxGuest, + types.VirtualMachineGuestOsIdentifierOracleLinux64Guest, + types.VirtualMachineGuestOsIdentifierOracleLinux6Guest, + types.VirtualMachineGuestOsIdentifierOracleLinux6_64Guest, + types.VirtualMachineGuestOsIdentifierOracleLinux7Guest, + types.VirtualMachineGuestOsIdentifierOracleLinux7_64Guest, + types.VirtualMachineGuestOsIdentifierSuseGuest, + types.VirtualMachineGuestOsIdentifierSuse64Guest, + types.VirtualMachineGuestOsIdentifierSlesGuest, + types.VirtualMachineGuestOsIdentifierSles64Guest, + types.VirtualMachineGuestOsIdentifierSles10Guest, + types.VirtualMachineGuestOsIdentifierSles10_64Guest, + types.VirtualMachineGuestOsIdentifierSles11Guest, + types.VirtualMachineGuestOsIdentifierSles11_64Guest, + types.VirtualMachineGuestOsIdentifierSles12Guest, + types.VirtualMachineGuestOsIdentifierSles12_64Guest, + types.VirtualMachineGuestOsIdentifierNld9Guest, + types.VirtualMachineGuestOsIdentifierOesGuest, + types.VirtualMachineGuestOsIdentifierSjdsGuest, + types.VirtualMachineGuestOsIdentifierMandrakeGuest, + types.VirtualMachineGuestOsIdentifierMandrivaGuest, + types.VirtualMachineGuestOsIdentifierMandriva64Guest, + types.VirtualMachineGuestOsIdentifierTurboLinuxGuest, + types.VirtualMachineGuestOsIdentifierTurboLinux64Guest, + types.VirtualMachineGuestOsIdentifierUbuntuGuest, + types.VirtualMachineGuestOsIdentifierUbuntu64Guest, + types.VirtualMachineGuestOsIdentifierDebian4Guest, + types.VirtualMachineGuestOsIdentifierDebian4_64Guest, + types.VirtualMachineGuestOsIdentifierDebian5Guest, + types.VirtualMachineGuestOsIdentifierDebian5_64Guest, + types.VirtualMachineGuestOsIdentifierDebian6Guest, + types.VirtualMachineGuestOsIdentifierDebian6_64Guest, + types.VirtualMachineGuestOsIdentifierDebian7Guest, + types.VirtualMachineGuestOsIdentifierDebian7_64Guest, + types.VirtualMachineGuestOsIdentifierDebian8Guest, + types.VirtualMachineGuestOsIdentifierDebian8_64Guest, + types.VirtualMachineGuestOsIdentifierDebian9Guest, + types.VirtualMachineGuestOsIdentifierDebian9_64Guest, + types.VirtualMachineGuestOsIdentifierDebian10Guest, + types.VirtualMachineGuestOsIdentifierDebian10_64Guest, + types.VirtualMachineGuestOsIdentifierAsianux3Guest, + types.VirtualMachineGuestOsIdentifierAsianux3_64Guest, + types.VirtualMachineGuestOsIdentifierAsianux4Guest, + types.VirtualMachineGuestOsIdentifierAsianux4_64Guest, + types.VirtualMachineGuestOsIdentifierAsianux5_64Guest, + types.VirtualMachineGuestOsIdentifierAsianux7_64Guest, + types.VirtualMachineGuestOsIdentifierOpensuseGuest, + types.VirtualMachineGuestOsIdentifierOpensuse64Guest, + types.VirtualMachineGuestOsIdentifierFedoraGuest, + types.VirtualMachineGuestOsIdentifierFedora64Guest, + types.VirtualMachineGuestOsIdentifierCoreos64Guest, + types.VirtualMachineGuestOsIdentifierVmwarePhoton64Guest, + types.VirtualMachineGuestOsIdentifierOther24xLinuxGuest, + types.VirtualMachineGuestOsIdentifierOther26xLinuxGuest, + types.VirtualMachineGuestOsIdentifierOtherLinuxGuest, + types.VirtualMachineGuestOsIdentifierOther3xLinuxGuest, + types.VirtualMachineGuestOsIdentifierGenericLinuxGuest, + types.VirtualMachineGuestOsIdentifierOther24xLinux64Guest, + types.VirtualMachineGuestOsIdentifierOther26xLinux64Guest, + types.VirtualMachineGuestOsIdentifierOther3xLinux64Guest, + types.VirtualMachineGuestOsIdentifierOtherLinux64Guest, + types.VirtualMachineGuestOsIdentifierSolaris6Guest, + types.VirtualMachineGuestOsIdentifierSolaris7Guest, + types.VirtualMachineGuestOsIdentifierSolaris8Guest, + types.VirtualMachineGuestOsIdentifierSolaris9Guest, + types.VirtualMachineGuestOsIdentifierSolaris10Guest, + types.VirtualMachineGuestOsIdentifierSolaris10_64Guest, + types.VirtualMachineGuestOsIdentifierSolaris11_64Guest, + types.VirtualMachineGuestOsIdentifierOs2Guest, + types.VirtualMachineGuestOsIdentifierEComStationGuest, + types.VirtualMachineGuestOsIdentifierEComStation2Guest, + types.VirtualMachineGuestOsIdentifierNetware4Guest, + types.VirtualMachineGuestOsIdentifierNetware5Guest, + types.VirtualMachineGuestOsIdentifierNetware6Guest, + types.VirtualMachineGuestOsIdentifierOpenServer5Guest, + types.VirtualMachineGuestOsIdentifierOpenServer6Guest, + types.VirtualMachineGuestOsIdentifierUnixWare7Guest, + types.VirtualMachineGuestOsIdentifierDarwinGuest, + types.VirtualMachineGuestOsIdentifierDarwin64Guest, + types.VirtualMachineGuestOsIdentifierDarwin10Guest, + types.VirtualMachineGuestOsIdentifierDarwin10_64Guest, + types.VirtualMachineGuestOsIdentifierDarwin11Guest, + types.VirtualMachineGuestOsIdentifierDarwin11_64Guest, + types.VirtualMachineGuestOsIdentifierDarwin12_64Guest, + types.VirtualMachineGuestOsIdentifierDarwin13_64Guest, + types.VirtualMachineGuestOsIdentifierDarwin14_64Guest, + types.VirtualMachineGuestOsIdentifierDarwin15_64Guest, + types.VirtualMachineGuestOsIdentifierDarwin16_64Guest, + types.VirtualMachineGuestOsIdentifierVmkernelGuest, + types.VirtualMachineGuestOsIdentifierVmkernel5Guest, + types.VirtualMachineGuestOsIdentifierVmkernel6Guest, + types.VirtualMachineGuestOsIdentifierVmkernel65Guest, + types.VirtualMachineGuestOsIdentifierOtherGuest, + types.VirtualMachineGuestOsIdentifierOtherGuest64, +} diff --git a/vendor/github.com/vmware/govmomi/simulator/host_local_account_manager.go b/vendor/github.com/vmware/govmomi/simulator/host_local_account_manager.go new file mode 100644 index 0000000000..0d46331056 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/simulator/host_local_account_manager.go @@ -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{}, + } +} diff --git a/vendor/github.com/vmware/govmomi/simulator/host_system.go b/vendor/github.com/vmware/govmomi/simulator/host_system.go index 600dbcf388..2dd37f1eda 100644 --- a/vendor/github.com/vmware/govmomi/simulator/host_system.go +++ b/vendor/github.com/vmware/govmomi/simulator/host_system.go @@ -137,7 +137,12 @@ 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)) diff --git a/vendor/github.com/vmware/govmomi/simulator/registry.go b/vendor/github.com/vmware/govmomi/simulator/registry.go index 2fdc55f10e..c2e0913505 100644 --- a/vendor/github.com/vmware/govmomi/simulator/registry.go +++ b/vendor/github.com/vmware/govmomi/simulator/registry.go @@ -336,3 +336,8 @@ 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) +} diff --git a/vendor/github.com/vmware/govmomi/simulator/resource_pool.go b/vendor/github.com/vmware/govmomi/simulator/resource_pool.go index 1b42580f36..604f7b44db 100644 --- a/vendor/github.com/vmware/govmomi/simulator/resource_pool.go +++ b/vendor/github.com/vmware/govmomi/simulator/resource_pool.go @@ -43,14 +43,14 @@ func NewResourcePool() *ResourcePool { return pool } -func (p *ResourcePool) allFieldsSet(info types.ResourceAllocationInfo) bool { +func allResourceFieldsSet(info *types.ResourceAllocationInfo) bool { return info.Reservation != nil && info.Limit != nil && info.ExpandableReservation != nil && info.Shares != nil } -func (p *ResourcePool) allFieldsValid(info types.ResourceAllocationInfo) bool { +func allResourceFieldsValid(info *types.ResourceAllocationInfo) bool { if info.Reservation != nil { if *info.Reservation < 0 { return false @@ -86,13 +86,13 @@ func (p *ResourcePool) createChild(name string, spec types.ResourceConfigSpec) ( }) } - if !(p.allFieldsSet(spec.CpuAllocation) && p.allFieldsValid(spec.CpuAllocation)) { + if !(allResourceFieldsSet(&spec.CpuAllocation) && allResourceFieldsValid(&spec.CpuAllocation)) { return nil, Fault("", &types.InvalidArgument{ InvalidProperty: "spec.cpuAllocation", }) } - if !(p.allFieldsSet(spec.MemoryAllocation) && p.allFieldsValid(spec.MemoryAllocation)) { + if !(allResourceFieldsSet(&spec.MemoryAllocation) && allResourceFieldsValid(&spec.MemoryAllocation)) { return nil, Fault("", &types.InvalidArgument{ InvalidProperty: "spec.memoryAllocation", }) @@ -130,11 +130,11 @@ func (p *ResourcePool) CreateResourcePool(c *types.CreateResourcePool) soap.HasF return body } -func (p *ResourcePool) updateAllocation(kind string, src types.ResourceAllocationInfo, dst *types.ResourceAllocationInfo) *soap.Fault { - if !p.allFieldsValid(src) { - return Fault("", &types.InvalidArgument{ +func updateResourceAllocation(kind string, src, dst *types.ResourceAllocationInfo) types.BaseMethodFault { + if !allResourceFieldsValid(src) { + return &types.InvalidArgument{ InvalidProperty: fmt.Sprintf("spec.%sAllocation", kind), - }) + } } if src.Reservation != nil { @@ -170,13 +170,13 @@ func (p *ResourcePool) UpdateConfig(c *types.UpdateConfig) soap.HasFault { spec := c.Config if spec != nil { - if err := p.updateAllocation("memory", spec.MemoryAllocation, &p.Config.MemoryAllocation); err != nil { - body.Fault_ = err + if err := updateResourceAllocation("memory", &spec.MemoryAllocation, &p.Config.MemoryAllocation); err != nil { + body.Fault_ = Fault("", err) return body } - if err := p.updateAllocation("cpu", spec.CpuAllocation, &p.Config.CpuAllocation); err != nil { - body.Fault_ = err + if err := updateResourceAllocation("cpu", &spec.CpuAllocation, &p.Config.CpuAllocation); err != nil { + body.Fault_ = Fault("", err) return body } } diff --git a/vendor/github.com/vmware/govmomi/simulator/service_instance.go b/vendor/github.com/vmware/govmomi/simulator/service_instance.go index 4f6a3bbe7d..d5d908b1b9 100644 --- a/vendor/github.com/vmware/govmomi/simulator/service_instance.go +++ b/vendor/github.com/vmware/govmomi/simulator/service_instance.go @@ -75,6 +75,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) } diff --git a/vendor/github.com/vmware/govmomi/simulator/simulator.go b/vendor/github.com/vmware/govmomi/simulator/simulator.go index 9a9cf0194b..18ad929f79 100644 --- a/vendor/github.com/vmware/govmomi/simulator/simulator.go +++ b/vendor/github.com/vmware/govmomi/simulator/simulator.go @@ -491,7 +491,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) { diff --git a/vendor/github.com/vmware/govmomi/simulator/user_directory.go b/vendor/github.com/vmware/govmomi/simulator/user_directory.go index 2a2f0a3aab..6c474f9016 100644 --- a/vendor/github.com/vmware/govmomi/simulator/user_directory.go +++ b/vendor/github.com/vmware/govmomi/simulator/user_directory.go @@ -50,22 +50,54 @@ 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 + res := u.search(req.FindUsers, req.FindGroups, compare) + + body := &methods.RetrieveUserGroupsBody{ + Res: &types.RetrieveUserGroupsResponse{ + Returnval: res, + }, + } + + return body +} + +func (u *UserDirectory) search(findUsers, findGroups bool, compare func(string) bool) (res []types.BaseUserSearchResult) { for _, ug := range u.userGroup { - if req.FindUsers && !ug.Group || req.FindGroups && ug.Group { + if findUsers && !ug.Group || findGroups && ug.Group { if compare(ug.Principal) { res = append(res, ug) } } } - body := &methods.RetrieveUserGroupsBody{ - Res: &types.RetrieveUserGroupsResponse{ - Returnval: res, - }, + 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, } - return body + 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 { diff --git a/vendor/github.com/vmware/govmomi/simulator/virtual_disk_manager.go b/vendor/github.com/vmware/govmomi/simulator/virtual_disk_manager.go index 500e515182..ba37e42ed6 100644 --- a/vendor/github.com/vmware/govmomi/simulator/virtual_disk_manager.go +++ b/vendor/github.com/vmware/govmomi/simulator/virtual_disk_manager.go @@ -20,6 +20,7 @@ import ( "os" "strings" + "github.com/google/uuid" "github.com/vmware/govmomi/object" "github.com/vmware/govmomi/vim25/methods" "github.com/vmware/govmomi/vim25/mo" @@ -165,3 +166,28 @@ func (m *VirtualDiskManager) CopyVirtualDiskTask(req *types.CopyVirtualDisk_Task }, } } + +func (m *VirtualDiskManager) QueryVirtualDiskUuid(req *types.QueryVirtualDiskUuid) soap.HasFault { + body := new(methods.QueryVirtualDiskUuidBody) + + fm := Map.FileManager() + + file, fault := fm.resolve(req.Datacenter, req.Name) + if fault != nil { + body.Fault_ = Fault("", fault) + return body + } + + _, err := os.Stat(file) + if err != nil { + fault = fm.fault(file, err, new(types.CannotAccessFile)) + body.Fault_ = Fault("", fault) + return body + } + + body.Res = &types.QueryVirtualDiskUuidResponse{ + Returnval: uuid.NewSHA1(uuid.NameSpaceOID, []byte(file)).String(), + } + + return body +} diff --git a/vendor/github.com/vmware/govmomi/simulator/virtual_machine.go b/vendor/github.com/vmware/govmomi/simulator/virtual_machine.go index 1414ea4719..b2bcb66f8b 100644 --- a/vendor/github.com/vmware/govmomi/simulator/virtual_machine.go +++ b/vendor/github.com/vmware/govmomi/simulator/virtual_machine.go @@ -57,13 +57,23 @@ func NewVirtualMachine(parent types.ManagedObjectReference, spec *types.VirtualM return nil, &types.InvalidVmConfig{Property: "configSpec.files.vmPathName"} } + rspec := types.DefaultResourceConfigSpec() + vm.Guest = &types.GuestInfo{} vm.Config = &types.VirtualMachineConfigInfo{ - ExtraConfig: []types.BaseOptionValue{&types.OptionValue{Key: "govcsim", Value: "TRUE"}}, - Tools: &types.ToolsConfigInfo{}, + 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]" @@ -117,6 +127,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}, @@ -139,6 +155,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 @@ -149,6 +235,10 @@ 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() @@ -156,9 +246,37 @@ func (vm *VirtualMachine) apply(spec *types.VirtualMachineConfigSpec) { vm.Summary.Config.Uuid = vm.Config.Uuid } +func validateGuestID(id string) types.BaseMethodFault { + for _, x := range GuestID { + if id == string(x) { + return nil + } + } + + return &types.InvalidArgument{InvalidProperty: "configSpec.guestId"} +} + func (vm *VirtualMachine) configure(spec *types.VirtualMachineConfigSpec) types.BaseMethodFault { vm.apply(spec) + if spec.MemoryAllocation != nil { + if err := updateResourceAllocation("memory", spec.MemoryAllocation, vm.Config.MemoryAllocation); err != nil { + return err + } + } + + if spec.CpuAllocation != nil { + if err := updateResourceAllocation("cpu", spec.CpuAllocation, vm.Config.CpuAllocation); err != nil { + return err + } + } + + if spec.GuestId != "" { + if err := validateGuestID(spec.GuestId); err != nil { + return err + } + } + return vm.configureDevices(spec) } diff --git a/vendor/github.com/vmware/govmomi/simulator/vpx/service_content.go b/vendor/github.com/vmware/govmomi/simulator/vpx/service_content.go index 1c570f8025..90b93cc147 100644 --- a/vendor/github.com/vmware/govmomi/simulator/vpx/service_content.go +++ b/vendor/github.com/vmware/govmomi/simulator/vpx/service_content.go @@ -18,62 +18,69 @@ package vpx import "github.com/vmware/govmomi/vim25/types" +// ServiceContent is the default template for the ServiceInstance content property. +// Capture method: +// govc object.collect -s -dump - content var ServiceContent = types.ServiceContent{ - DynamicData: types.DynamicData{}, RootFolder: types.ManagedObjectReference{Type: "Folder", Value: "group-d1"}, PropertyCollector: types.ManagedObjectReference{Type: "PropertyCollector", Value: "propertyCollector"}, ViewManager: &types.ManagedObjectReference{Type: "ViewManager", Value: "ViewManager"}, About: types.AboutInfo{ - DynamicData: types.DynamicData{}, Name: "VMware vCenter Server", - FullName: "VMware vCenter Server 6.0.0 build-3634794", + FullName: "VMware vCenter Server 6.5.0 build-5973321", Vendor: "VMware, Inc.", - Version: "6.0.0", - Build: "3634794", + Version: "6.5.0", + Build: "5973321", LocaleVersion: "INTL", LocaleBuild: "000", OsType: "linux-x64", ProductLineId: "vpx", ApiType: "VirtualCenter", - ApiVersion: "6.0", - InstanceUuid: "8e7597d6-f720-4b5c-b9fc-3412faf07d99", + ApiVersion: "6.5", + InstanceUuid: "dbed6e0c-bd88-4ef6-b594-21283e1c677f", LicenseProductName: "VMware VirtualCenter Server", LicenseProductVersion: "6.0", }, - Setting: &types.ManagedObjectReference{Type: "OptionManager", Value: "VpxSettings"}, - UserDirectory: &types.ManagedObjectReference{Type: "UserDirectory", Value: "UserDirectory"}, - SessionManager: &types.ManagedObjectReference{Type: "SessionManager", Value: "SessionManager"}, - AuthorizationManager: &types.ManagedObjectReference{Type: "AuthorizationManager", Value: "AuthorizationManager"}, - ServiceManager: &types.ManagedObjectReference{Type: "ServiceManager", Value: "ServiceMgr"}, - PerfManager: &types.ManagedObjectReference{Type: "PerformanceManager", Value: "PerfMgr"}, - ScheduledTaskManager: &types.ManagedObjectReference{Type: "ScheduledTaskManager", Value: "ScheduledTaskManager"}, - AlarmManager: &types.ManagedObjectReference{Type: "AlarmManager", Value: "AlarmManager"}, - EventManager: &types.ManagedObjectReference{Type: "EventManager", Value: "EventManager"}, - TaskManager: &types.ManagedObjectReference{Type: "TaskManager", Value: "TaskManager"}, - ExtensionManager: &types.ManagedObjectReference{Type: "ExtensionManager", Value: "ExtensionManager"}, - CustomizationSpecManager: &types.ManagedObjectReference{Type: "CustomizationSpecManager", Value: "CustomizationSpecManager"}, - CustomFieldsManager: &types.ManagedObjectReference{Type: "CustomFieldsManager", Value: "CustomFieldsManager"}, - AccountManager: (*types.ManagedObjectReference)(nil), - DiagnosticManager: &types.ManagedObjectReference{Type: "DiagnosticManager", Value: "DiagMgr"}, - LicenseManager: &types.ManagedObjectReference{Type: "LicenseManager", Value: "LicenseManager"}, - SearchIndex: &types.ManagedObjectReference{Type: "SearchIndex", Value: "SearchIndex"}, - FileManager: &types.ManagedObjectReference{Type: "FileManager", Value: "FileManager"}, - DatastoreNamespaceManager: &types.ManagedObjectReference{Type: "DatastoreNamespaceManager", Value: "DatastoreNamespaceManager"}, - VirtualDiskManager: &types.ManagedObjectReference{Type: "VirtualDiskManager", Value: "virtualDiskManager"}, - VirtualizationManager: (*types.ManagedObjectReference)(nil), - SnmpSystem: &types.ManagedObjectReference{Type: "HostSnmpSystem", Value: "SnmpSystem"}, - VmProvisioningChecker: &types.ManagedObjectReference{Type: "VirtualMachineProvisioningChecker", Value: "ProvChecker"}, - VmCompatibilityChecker: &types.ManagedObjectReference{Type: "VirtualMachineCompatibilityChecker", Value: "CompatChecker"}, - OvfManager: &types.ManagedObjectReference{Type: "OvfManager", Value: "OvfManager"}, - IpPoolManager: &types.ManagedObjectReference{Type: "IpPoolManager", Value: "IpPoolManager"}, - DvSwitchManager: &types.ManagedObjectReference{Type: "DistributedVirtualSwitchManager", Value: "DVSManager"}, - HostProfileManager: &types.ManagedObjectReference{Type: "HostProfileManager", Value: "HostProfileManager"}, - ClusterProfileManager: &types.ManagedObjectReference{Type: "ClusterProfileManager", Value: "ClusterProfileManager"}, - ComplianceManager: &types.ManagedObjectReference{Type: "ProfileComplianceManager", Value: "MoComplianceManager"}, - LocalizationManager: &types.ManagedObjectReference{Type: "LocalizationManager", Value: "LocalizationManager"}, - StorageResourceManager: &types.ManagedObjectReference{Type: "StorageResourceManager", Value: "StorageResourceManager"}, - GuestOperationsManager: &types.ManagedObjectReference{Type: "GuestOperationsManager", Value: "guestOperationsManager"}, - OverheadMemoryManager: &types.ManagedObjectReference{Type: "OverheadMemoryManager", Value: "OverheadMemoryManger"}, - CertificateManager: &types.ManagedObjectReference{Type: "CertificateManager", Value: "certificateManager"}, - IoFilterManager: &types.ManagedObjectReference{Type: "IoFilterManager", Value: "IoFilterManager"}, + Setting: &types.ManagedObjectReference{Type: "OptionManager", Value: "VpxSettings"}, + UserDirectory: &types.ManagedObjectReference{Type: "UserDirectory", Value: "UserDirectory"}, + SessionManager: &types.ManagedObjectReference{Type: "SessionManager", Value: "SessionManager"}, + AuthorizationManager: &types.ManagedObjectReference{Type: "AuthorizationManager", Value: "AuthorizationManager"}, + ServiceManager: &types.ManagedObjectReference{Type: "ServiceManager", Value: "ServiceMgr"}, + PerfManager: &types.ManagedObjectReference{Type: "PerformanceManager", Value: "PerfMgr"}, + ScheduledTaskManager: &types.ManagedObjectReference{Type: "ScheduledTaskManager", Value: "ScheduledTaskManager"}, + AlarmManager: &types.ManagedObjectReference{Type: "AlarmManager", Value: "AlarmManager"}, + EventManager: &types.ManagedObjectReference{Type: "EventManager", Value: "EventManager"}, + TaskManager: &types.ManagedObjectReference{Type: "TaskManager", Value: "TaskManager"}, + ExtensionManager: &types.ManagedObjectReference{Type: "ExtensionManager", Value: "ExtensionManager"}, + CustomizationSpecManager: &types.ManagedObjectReference{Type: "CustomizationSpecManager", Value: "CustomizationSpecManager"}, + CustomFieldsManager: &types.ManagedObjectReference{Type: "CustomFieldsManager", Value: "CustomFieldsManager"}, + AccountManager: (*types.ManagedObjectReference)(nil), + DiagnosticManager: &types.ManagedObjectReference{Type: "DiagnosticManager", Value: "DiagMgr"}, + LicenseManager: &types.ManagedObjectReference{Type: "LicenseManager", Value: "LicenseManager"}, + SearchIndex: &types.ManagedObjectReference{Type: "SearchIndex", Value: "SearchIndex"}, + FileManager: &types.ManagedObjectReference{Type: "FileManager", Value: "FileManager"}, + DatastoreNamespaceManager: &types.ManagedObjectReference{Type: "DatastoreNamespaceManager", Value: "DatastoreNamespaceManager"}, + VirtualDiskManager: &types.ManagedObjectReference{Type: "VirtualDiskManager", Value: "virtualDiskManager"}, + VirtualizationManager: (*types.ManagedObjectReference)(nil), + SnmpSystem: &types.ManagedObjectReference{Type: "HostSnmpSystem", Value: "SnmpSystem"}, + VmProvisioningChecker: &types.ManagedObjectReference{Type: "VirtualMachineProvisioningChecker", Value: "ProvChecker"}, + VmCompatibilityChecker: &types.ManagedObjectReference{Type: "VirtualMachineCompatibilityChecker", Value: "CompatChecker"}, + OvfManager: &types.ManagedObjectReference{Type: "OvfManager", Value: "OvfManager"}, + IpPoolManager: &types.ManagedObjectReference{Type: "IpPoolManager", Value: "IpPoolManager"}, + DvSwitchManager: &types.ManagedObjectReference{Type: "DistributedVirtualSwitchManager", Value: "DVSManager"}, + HostProfileManager: &types.ManagedObjectReference{Type: "HostProfileManager", Value: "HostProfileManager"}, + ClusterProfileManager: &types.ManagedObjectReference{Type: "ClusterProfileManager", Value: "ClusterProfileManager"}, + ComplianceManager: &types.ManagedObjectReference{Type: "ProfileComplianceManager", Value: "MoComplianceManager"}, + LocalizationManager: &types.ManagedObjectReference{Type: "LocalizationManager", Value: "LocalizationManager"}, + StorageResourceManager: &types.ManagedObjectReference{Type: "StorageResourceManager", Value: "StorageResourceManager"}, + GuestOperationsManager: &types.ManagedObjectReference{Type: "GuestOperationsManager", Value: "guestOperationsManager"}, + OverheadMemoryManager: &types.ManagedObjectReference{Type: "OverheadMemoryManager", Value: "OverheadMemoryManager"}, + CertificateManager: &types.ManagedObjectReference{Type: "CertificateManager", Value: "certificateManager"}, + IoFilterManager: &types.ManagedObjectReference{Type: "IoFilterManager", Value: "IoFilterManager"}, + VStorageObjectManager: &types.ManagedObjectReference{Type: "VcenterVStorageObjectManager", Value: "VStorageObjectManager"}, + HostSpecManager: &types.ManagedObjectReference{Type: "HostSpecificationManager", Value: "HostSpecificationManager"}, + CryptoManager: &types.ManagedObjectReference{Type: "CryptoManagerKmip", Value: "CryptoManager"}, + HealthUpdateManager: &types.ManagedObjectReference{Type: "HealthUpdateManager", Value: "HealthUpdateManager"}, + FailoverClusterConfigurator: &types.ManagedObjectReference{Type: "FailoverClusterConfigurator", Value: "FailoverClusterConfigurator"}, + FailoverClusterManager: &types.ManagedObjectReference{Type: "FailoverClusterManager", Value: "FailoverClusterManager"}, } diff --git a/vendor/github.com/vmware/govmomi/toolbox/command.go b/vendor/github.com/vmware/govmomi/toolbox/command.go index 84d4b808a5..83fd0173a0 100644 --- a/vendor/github.com/vmware/govmomi/toolbox/command.go +++ b/vendor/github.com/vmware/govmomi/toolbox/command.go @@ -511,8 +511,11 @@ func (c *CommandServer) ListFiles(header vix.CommandRequestHeader, data []byte) offset := r.Body.Offset + uint64(r.Body.Index) total := uint64(len(files)) - offset - - files = files[offset:] + if int(offset) < len(files) { + files = files[offset:] + } else { + total = 0 // offset is not valid (open-vm-tools behaves the same in this case) + } var remaining uint64 diff --git a/vendor/manifest b/vendor/manifest index 3faf3eaa13..db725fd6f1 100644 --- a/vendor/manifest +++ b/vendor/manifest @@ -1143,7 +1143,7 @@ "importpath": "github.com/vmware/govmomi", "repository": "https://github.com/vmware/govmomi", "vcs": "git", - "revision": "7d879bac14d09f2f2a45a0477c1e45fbf52240f5", + "revision": "91fbd1f705a64043039044b469b7fcf33d2e61d2", "branch": "master", "notests": true }, From 255c970f0d1ffe5e812df9c714848da57568aee0 Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Thu, 21 Dec 2017 14:40:05 -0800 Subject: [PATCH 2/3] Use event types to filter events An alternative to increasing the collector page size. It will reduce the throughput to the event collector and hence reduce event misses. See issues #6937 and #6998 --- .../event/collector/vsphere/collector.go | 47 ++++++++++--------- .../event/collector/vsphere/collector_test.go | 28 ++++++----- 2 files changed, 39 insertions(+), 36 deletions(-) diff --git a/lib/portlayer/event/collector/vsphere/collector.go b/lib/portlayer/event/collector/vsphere/collector.go index 6f9bf8855a..67519ae221 100644 --- a/lib/portlayer/event/collector/vsphere/collector.go +++ b/lib/portlayer/event/collector/vsphere/collector.go @@ -17,6 +17,7 @@ package vsphere import ( "context" "fmt" + "reflect" "sync" "github.com/vmware/vic/lib/portlayer/event/events" @@ -107,6 +108,27 @@ func (ec *EventCollector) Stop() { } } +// eventTypes is used to filter the event collector so we only receive these event types. +var eventTypes []string + +func init() { + events := []types.BaseEvent{ + (*types.VmGuestShutdownEvent)(nil), + (*types.VmPoweredOnEvent)(nil), + (*types.DrsVmPoweredOnEvent)(nil), + (*types.VmPoweredOffEvent)(nil), + (*types.VmRemovedEvent)(nil), + (*types.VmSuspendedEvent)(nil), + (*types.VmMigratedEvent)(nil), + (*types.DrsVmMigratedEvent)(nil), + (*types.VmRelocatedEvent)(nil), + } + + for _, event := range events { + eventTypes = append(eventTypes, reflect.TypeOf(event).Elem().Name()) + } +} + // Start the event collector func (ec *EventCollector) Start() error { // array of managed objects @@ -143,7 +165,7 @@ func (ec *EventCollector) Start() error { err := ec.vmwManager.Events(ctx, refs, pageSize, followStream, force, func(_ types.ManagedObjectReference, page []types.BaseEvent) error { evented(ec, page) return nil - }) + }, eventTypes...) // TODO: this will disappear in the ether if err != nil { log.Debugf("Error configuring %s: %s", name, err.Error()) @@ -179,28 +201,7 @@ func evented(ec *EventCollector, page []types.BaseEvent) { // events appear in page with most recent first - need to reverse for sane ordering // we start from the first new event after the last one processed for i := oldIndex - 1; i >= 0; i-- { - // what type of event do we have - switch page[i].(type) { - case *types.VmGuestShutdownEvent, - *types.VmPoweredOnEvent, - *types.DrsVmPoweredOnEvent, - *types.VmPoweredOffEvent, - *types.VmRemovedEvent, - *types.VmSuspendedEvent, - *types.VmMigratedEvent, - *types.DrsVmMigratedEvent, - *types.VmRelocatedEvent: - - // we have an event we need to process - ec.callback(NewVMEvent(page[i])) - case *types.VmReconfiguredEvent: - // reconfigures happen often, so completely ignore for now - continue - default: - // log the skipped event - e := page[i].GetEvent() - log.Debugf("vSphere Event %s for eventID(%d) ignored by the event collector", e.FullFormattedMessage, int(e.Key)) - } + ec.callback(NewVMEvent(page[i])) ec.lastProcessedID = page[i].GetEvent().Key } diff --git a/lib/portlayer/event/collector/vsphere/collector_test.go b/lib/portlayer/event/collector/vsphere/collector_test.go index 1739950100..bce8afa63c 100644 --- a/lib/portlayer/event/collector/vsphere/collector_test.go +++ b/lib/portlayer/event/collector/vsphere/collector_test.go @@ -70,19 +70,6 @@ func TestEvented(t *testing.T) { page := eventPage(3, LifeCycle) evented(mgr, page) assert.Equal(t, 3, callcount) - - // non-lifecycle events, should be ignored - callcount = 0 - page = eventPage(2, Reconfigure) - evented(mgr, page) - assert.Equal(t, 0, callcount) - - // mixed events, ignore half - callcount = 0 - page = eventPage(6, Mixed) - evented(mgr, page) - assert.Equal(t, 3, callcount) - } func TestName(t *testing.T) { @@ -97,6 +84,21 @@ func TestStart(t *testing.T) { assert.Error(t, mgr.Start()) } +func TestEventTypes(t *testing.T) { + if len(eventTypes) != 9 { + t.Fatalf("eventTypes=%d", len(eventTypes)) + } + + f := types.TypeFunc() + + for _, name := range eventTypes { + _, ok := f(name) + if !ok { + t.Errorf("unknown event type: %q", name) + } + } +} + func newCollector() *EventCollector { return &EventCollector{mos: monitoredCache{mos: make(map[string]types.ManagedObjectReference)}, lastProcessedID: -1} } From 22da1b696f3ea4c96c38d81329a51e41f7645066 Mon Sep 17 00:00:00 2001 From: George Hicken Date: Thu, 21 Dec 2017 17:09:04 -0800 Subject: [PATCH 3/3] Set eventPageSize to 200 with type filter Hypothesis is that it was primarily the reconfigure events that were overwhelming the heap due to associated config spec. This has not been confirmed by code inspection or similar, but this commit aims to experientially determine the impact on hostd memory. Experiments have shown that a filtered collector with pagesize of 200 has the same memory profile across full CI as the 1.2.1 release code with an unfiltered pagesize of 25 (maxes out at approx 125000). Without the filtering, significant deviation was observed. --- lib/portlayer/event/collector/vsphere/collector.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/portlayer/event/collector/vsphere/collector.go b/lib/portlayer/event/collector/vsphere/collector.go index 67519ae221..0e0889a1c9 100644 --- a/lib/portlayer/event/collector/vsphere/collector.go +++ b/lib/portlayer/event/collector/vsphere/collector.go @@ -147,8 +147,17 @@ func (ec *EventCollector) Start() error { // pageSize is the number of events on the last page of the eventCollector // as new events are added the oldest are removed. Originally this value // was 1 and we encountered missed events due to them being evicted - // before being processed. A setting of 25 should provide ample buffer. - pageSize := int32(25) + // before being processed. We bumped to 25 but we still miss events during + // storms such as a host HA event. + // Setting pageSize to 1000 overwhelmed hostd via the task history and caused + // memory exhaustion. Setting pagesize to 200 while filtering for the specific + // types we require showed directly comparable memory overhead vs the 25 page + // size setting when running full ci. We may still have significantly higher + // memory usage in the scenario where we legitimately have events of interest + // at a rate of greater than 25 per page. + // This should eventually be replaced with a smaller maximum page size, a page + // cursor, and maybe a sliding window for the actual page size. + pageSize := int32(200) // bool to follow the stream followStream := true // don't exceed the govmomi object limit