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  }