github.com/vmware/govmomi@v0.37.1/simulator/property_filter.go (about) 1 /* 2 Copyright (c) 2017 VMware, Inc. All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package simulator 18 19 import ( 20 "reflect" 21 "strings" 22 23 "github.com/vmware/govmomi/vim25/methods" 24 "github.com/vmware/govmomi/vim25/mo" 25 "github.com/vmware/govmomi/vim25/soap" 26 "github.com/vmware/govmomi/vim25/types" 27 ) 28 29 type PropertyFilter struct { 30 mo.PropertyFilter 31 32 pc *PropertyCollector 33 refs map[types.ManagedObjectReference]struct{} 34 } 35 36 func (f *PropertyFilter) DestroyPropertyFilter(ctx *Context, c *types.DestroyPropertyFilter) soap.HasFault { 37 body := &methods.DestroyPropertyFilterBody{} 38 39 RemoveReference(&f.pc.Filter, c.This) 40 41 ctx.Session.Remove(ctx, c.This) 42 43 body.Res = &types.DestroyPropertyFilterResponse{} 44 45 return body 46 } 47 48 // matches returns true if the change matches one of the filter Spec.PropSet 49 func (f *PropertyFilter) matches(ctx *Context, ref types.ManagedObjectReference, change *types.PropertyChange) bool { 50 var kind reflect.Type 51 52 for _, p := range f.Spec.PropSet { 53 if p.Type != ref.Type { 54 if kind == nil { 55 kind = getManagedObject(ctx.Map.Get(ref)).Type() 56 } 57 // e.g. ManagedEntity, ComputeResource 58 field, ok := kind.FieldByName(p.Type) 59 if !(ok && field.Anonymous) { 60 continue 61 } 62 } 63 64 if isTrue(p.All) { 65 return true 66 } 67 68 for _, name := range p.PathSet { 69 if name == change.Name { 70 return true 71 } 72 73 // strings.HasPrefix("runtime.powerState", "runtime") == parent field matches 74 if strings.HasPrefix(change.Name, name) { 75 if obj := ctx.Map.Get(ref); obj != nil { // object may have since been deleted 76 change.Name = name 77 change.Val, _ = fieldValue(reflect.ValueOf(obj), name) 78 } 79 80 return true 81 } 82 } 83 } 84 85 return false 86 } 87 88 // apply the PropertyFilter.Spec to the given ObjectUpdate 89 func (f *PropertyFilter) apply(ctx *Context, change types.ObjectUpdate) types.ObjectUpdate { 90 parents := make(map[string]bool) 91 set := change.ChangeSet 92 change.ChangeSet = nil 93 94 for i, p := range set { 95 if f.matches(ctx, change.Obj, &p) { 96 if p.Name != set[i].Name { 97 // update matches a parent field from the spec. 98 if parents[p.Name] { 99 continue // only return 1 instance of the parent 100 } 101 parents[p.Name] = true 102 } 103 change.ChangeSet = append(change.ChangeSet, p) 104 } 105 } 106 107 return change 108 }