github.com/vmware/govmomi@v0.43.0/simulator/custom_fields_manager.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 "github.com/vmware/govmomi/vim25/methods" 21 "github.com/vmware/govmomi/vim25/mo" 22 "github.com/vmware/govmomi/vim25/soap" 23 "github.com/vmware/govmomi/vim25/types" 24 ) 25 26 type CustomFieldsManager struct { 27 mo.CustomFieldsManager 28 29 nextKey int32 30 } 31 32 // Iterates through all entities of passed field type; 33 // Removes found field from their custom field properties. 34 func entitiesFieldRemove(ctx *Context, field types.CustomFieldDef) { 35 entities := ctx.Map.All(field.ManagedObjectType) 36 for _, e := range entities { 37 entity := e.Entity() 38 ctx.WithLock(entity, func() { 39 aFields := entity.AvailableField 40 for i, aField := range aFields { 41 if aField.Key == field.Key { 42 entity.AvailableField = append(aFields[:i], aFields[i+1:]...) 43 break 44 } 45 } 46 47 values := e.Entity().Value 48 for i, value := range values { 49 if value.(*types.CustomFieldStringValue).Key == field.Key { 50 entity.Value = append(values[:i], values[i+1:]...) 51 break 52 } 53 } 54 55 cValues := e.Entity().CustomValue 56 for i, cValue := range cValues { 57 if cValue.(*types.CustomFieldStringValue).Key == field.Key { 58 entity.CustomValue = append(cValues[:i], cValues[i+1:]...) 59 break 60 } 61 } 62 }) 63 } 64 } 65 66 // Iterates through all entities of passed field type; 67 // Renames found field in entity's AvailableField property. 68 func entitiesFieldRename(ctx *Context, field types.CustomFieldDef) { 69 entities := ctx.Map.All(field.ManagedObjectType) 70 for _, e := range entities { 71 entity := e.Entity() 72 ctx.WithLock(entity, func() { 73 aFields := entity.AvailableField 74 for i, aField := range aFields { 75 if aField.Key == field.Key { 76 aFields[i].Name = field.Name 77 break 78 } 79 } 80 }) 81 } 82 } 83 84 func (c *CustomFieldsManager) findByNameType(name, moType string) (int, *types.CustomFieldDef) { 85 for i, field := range c.Field { 86 if (field.ManagedObjectType == "" || field.ManagedObjectType == moType || moType == "") && 87 field.Name == name { 88 return i, &c.Field[i] 89 } 90 } 91 92 return -1, nil 93 } 94 95 func (c *CustomFieldsManager) findByKey(key int32) (int, *types.CustomFieldDef) { 96 for i, field := range c.Field { 97 if field.Key == key { 98 return i, &c.Field[i] 99 } 100 } 101 102 return -1, nil 103 } 104 105 func (c *CustomFieldsManager) AddCustomFieldDef(ctx *Context, req *types.AddCustomFieldDef) soap.HasFault { 106 body := &methods.AddCustomFieldDefBody{} 107 108 _, field := c.findByNameType(req.Name, req.MoType) 109 if field != nil { 110 body.Fault_ = Fault("", &types.DuplicateName{ 111 Name: req.Name, 112 Object: c.Reference(), 113 }) 114 return body 115 } 116 117 def := types.CustomFieldDef{ 118 Key: c.nextKey, 119 Name: req.Name, 120 ManagedObjectType: req.MoType, 121 Type: req.MoType, 122 FieldDefPrivileges: req.FieldDefPolicy, 123 FieldInstancePrivileges: req.FieldPolicy, 124 } 125 126 entities := ctx.Map.All(req.MoType) 127 for _, e := range entities { 128 entity := e.Entity() 129 ctx.WithLock(entity, func() { 130 entity.AvailableField = append(entity.AvailableField, def) 131 }) 132 } 133 134 c.Field = append(c.Field, def) 135 c.nextKey++ 136 137 body.Res = &types.AddCustomFieldDefResponse{ 138 Returnval: def, 139 } 140 return body 141 } 142 143 func (c *CustomFieldsManager) RemoveCustomFieldDef(ctx *Context, req *types.RemoveCustomFieldDef) soap.HasFault { 144 body := &methods.RemoveCustomFieldDefBody{} 145 146 i, field := c.findByKey(req.Key) 147 if field == nil { 148 body.Fault_ = Fault("", &types.NotFound{}) 149 return body 150 } 151 152 entitiesFieldRemove(ctx, *field) 153 154 c.Field = append(c.Field[:i], c.Field[i+1:]...) 155 156 body.Res = &types.RemoveCustomFieldDefResponse{} 157 return body 158 } 159 160 func (c *CustomFieldsManager) RenameCustomFieldDef(ctx *Context, req *types.RenameCustomFieldDef) soap.HasFault { 161 body := &methods.RenameCustomFieldDefBody{} 162 163 _, field := c.findByKey(req.Key) 164 if field == nil { 165 body.Fault_ = Fault("", &types.NotFound{}) 166 return body 167 } 168 169 field.Name = req.Name 170 171 entitiesFieldRename(ctx, *field) 172 173 body.Res = &types.RenameCustomFieldDefResponse{} 174 return body 175 } 176 177 func (c *CustomFieldsManager) SetField(ctx *Context, req *types.SetField) soap.HasFault { 178 body := &methods.SetFieldBody{} 179 180 _, field := c.findByKey(req.Key) 181 if field == nil { 182 body.Fault_ = Fault("", &types.InvalidArgument{InvalidProperty: "key"}) 183 return body 184 } 185 186 newValue := &types.CustomFieldStringValue{ 187 CustomFieldValue: types.CustomFieldValue{Key: req.Key}, 188 Value: req.Value, 189 } 190 191 removeIndex := func(s []types.BaseCustomFieldValue, i int) []types.BaseCustomFieldValue { 192 new := make([]types.BaseCustomFieldValue, 0) 193 new = append(new, s[:i]...) 194 return append(new, s[i+1:]...) 195 } 196 197 removeExistingValues := func(s []types.BaseCustomFieldValue) []types.BaseCustomFieldValue { 198 for i := 0; i < len(s); { 199 if s[i].GetCustomFieldValue().Key == newValue.GetCustomFieldValue().Key { 200 s = removeIndex(s, i) 201 } 202 i++ 203 } 204 return s 205 } 206 207 entity := ctx.Map.Get(req.Entity).(mo.Entity).Entity() 208 209 ctx.WithLock(entity, func() { 210 // Check if custom value and value are already set. If so, remove them. 211 entity.CustomValue = removeExistingValues(entity.CustomValue) 212 entity.Value = removeExistingValues(entity.Value) 213 214 // Add the new value 215 entity.CustomValue = append(entity.CustomValue, newValue) 216 entity.Value = append(entity.Value, newValue) 217 }) 218 219 body.Res = &types.SetFieldResponse{} 220 return body 221 }