| /* |
| Copyright (c) 2015 VMware, Inc. All Rights Reserved. |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| package property |
| |
| import ( |
| "context" |
| "errors" |
| |
| "github.com/vmware/govmomi/vim25" |
| "github.com/vmware/govmomi/vim25/methods" |
| "github.com/vmware/govmomi/vim25/mo" |
| "github.com/vmware/govmomi/vim25/soap" |
| "github.com/vmware/govmomi/vim25/types" |
| ) |
| |
| // Collector models the PropertyCollector managed object. |
| // |
| // For more information, see: |
| // http://pubs.vmware.com/vsphere-60/index.jsp?topic=%2Fcom.vmware.wssdk.apiref.doc%2Fvmodl.query.PropertyCollector.html |
| // |
| type Collector struct { |
| roundTripper soap.RoundTripper |
| reference types.ManagedObjectReference |
| } |
| |
| // DefaultCollector returns the session's default property collector. |
| func DefaultCollector(c *vim25.Client) *Collector { |
| p := Collector{ |
| roundTripper: c, |
| reference: c.ServiceContent.PropertyCollector, |
| } |
| |
| return &p |
| } |
| |
| func (p Collector) Reference() types.ManagedObjectReference { |
| return p.reference |
| } |
| |
| // Create creates a new session-specific Collector that can be used to |
| // retrieve property updates independent of any other Collector. |
| func (p *Collector) Create(ctx context.Context) (*Collector, error) { |
| req := types.CreatePropertyCollector{ |
| This: p.Reference(), |
| } |
| |
| res, err := methods.CreatePropertyCollector(ctx, p.roundTripper, &req) |
| if err != nil { |
| return nil, err |
| } |
| |
| newp := Collector{ |
| roundTripper: p.roundTripper, |
| reference: res.Returnval, |
| } |
| |
| return &newp, nil |
| } |
| |
| // Destroy destroys this Collector. |
| func (p *Collector) Destroy(ctx context.Context) error { |
| req := types.DestroyPropertyCollector{ |
| This: p.Reference(), |
| } |
| |
| _, err := methods.DestroyPropertyCollector(ctx, p.roundTripper, &req) |
| if err != nil { |
| return err |
| } |
| |
| p.reference = types.ManagedObjectReference{} |
| return nil |
| } |
| |
| func (p *Collector) CreateFilter(ctx context.Context, req types.CreateFilter) error { |
| req.This = p.Reference() |
| |
| _, err := methods.CreateFilter(ctx, p.roundTripper, &req) |
| if err != nil { |
| return err |
| } |
| |
| return nil |
| } |
| |
| func (p *Collector) WaitForUpdates(ctx context.Context, v string) (*types.UpdateSet, error) { |
| req := types.WaitForUpdatesEx{ |
| This: p.Reference(), |
| Version: v, |
| } |
| |
| res, err := methods.WaitForUpdatesEx(ctx, p.roundTripper, &req) |
| if err != nil { |
| return nil, err |
| } |
| |
| return res.Returnval, nil |
| } |
| |
| func (p *Collector) CancelWaitForUpdates(ctx context.Context) error { |
| req := &types.CancelWaitForUpdates{This: p.Reference()} |
| _, err := methods.CancelWaitForUpdates(ctx, p.roundTripper, req) |
| return err |
| } |
| |
| func (p *Collector) RetrieveProperties(ctx context.Context, req types.RetrieveProperties) (*types.RetrievePropertiesResponse, error) { |
| req.This = p.Reference() |
| return methods.RetrieveProperties(ctx, p.roundTripper, &req) |
| } |
| |
| // Retrieve loads properties for a slice of managed objects. The dst argument |
| // must be a pointer to a []interface{}, which is populated with the instances |
| // of the specified managed objects, with the relevant properties filled in. If |
| // the properties slice is nil, all properties are loaded. |
| // Note that pointer types are optional fields that may be left as a nil value. |
| // The caller should check such fields for a nil value before dereferencing. |
| 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") |
| } |
| |
| kinds := make(map[string]bool) |
| |
| var propSet []types.PropertySpec |
| var objectSet []types.ObjectSpec |
| |
| for _, obj := range objs { |
| if _, ok := kinds[obj.Type]; !ok { |
| spec := types.PropertySpec{ |
| Type: obj.Type, |
| } |
| if ps == nil { |
| spec.All = types.NewBool(true) |
| } else { |
| spec.PathSet = ps |
| } |
| propSet = append(propSet, spec) |
| kinds[obj.Type] = true |
| } |
| |
| objectSpec := types.ObjectSpec{ |
| Obj: obj, |
| Skip: types.NewBool(false), |
| } |
| |
| objectSet = append(objectSet, objectSpec) |
| } |
| |
| req := types.RetrieveProperties{ |
| SpecSet: []types.PropertyFilterSpec{ |
| { |
| ObjectSet: objectSet, |
| PropSet: propSet, |
| }, |
| }, |
| } |
| |
| res, err := p.RetrieveProperties(ctx, req) |
| if err != nil { |
| return err |
| } |
| |
| if d, ok := dst.(*[]types.ObjectContent); ok { |
| *d = res.Returnval |
| return nil |
| } |
| |
| return mo.LoadRetrievePropertiesResponse(res, dst) |
| } |
| |
| // RetrieveWithFilter populates dst as Retrieve does, but only for entities matching the given filter. |
| func (p *Collector) RetrieveWithFilter(ctx context.Context, objs []types.ManagedObjectReference, ps []string, dst interface{}, filter Filter) error { |
| if len(filter) == 0 { |
| return p.Retrieve(ctx, objs, ps, dst) |
| } |
| |
| var content []types.ObjectContent |
| |
| err := p.Retrieve(ctx, objs, filter.Keys(), &content) |
| if err != nil { |
| return err |
| } |
| |
| objs = filter.MatchObjectContent(content) |
| |
| if len(objs) == 0 { |
| return nil |
| } |
| |
| return p.Retrieve(ctx, objs, ps, dst) |
| } |
| |
| // RetrieveOne calls Retrieve with a single managed object reference via Collector.Retrieve(). |
| func (p *Collector) RetrieveOne(ctx context.Context, obj types.ManagedObjectReference, ps []string, dst interface{}) error { |
| var objs = []types.ManagedObjectReference{obj} |
| return p.Retrieve(ctx, objs, ps, dst) |
| } |