diff --git a/lib/portlayer/event/collector/vsphere/collector.go b/lib/portlayer/event/collector/vsphere/collector.go index 6f9bf8855a..0e0889a1c9 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 @@ -125,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 @@ -143,7 +174,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 +210,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} } 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 },