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