github.com/vmware/govmomi@v0.51.0/simulator/option_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 "strings" 9 10 "github.com/vmware/govmomi/object" 11 "github.com/vmware/govmomi/simulator/esx" 12 "github.com/vmware/govmomi/simulator/vpx" 13 "github.com/vmware/govmomi/vim25/methods" 14 "github.com/vmware/govmomi/vim25/mo" 15 "github.com/vmware/govmomi/vim25/soap" 16 "github.com/vmware/govmomi/vim25/types" 17 ) 18 19 // OptionManager is used in at least two locations for ESX: 20 // 1. ServiceContent.setting - this is empty on ESX and //TODO on VC 21 // 2. ConfigManager.advancedOption - this is where the bulk of the ESX settings are found 22 type OptionManager struct { 23 mo.OptionManager 24 25 // mirror is an array to keep in sync with OptionManager.Settings. Necessary because we use append. 26 // uni-directional - changes made to the mirrored array are not reflected back to Settings 27 mirror *[]types.BaseOptionValue 28 } 29 30 // NewOptionManager constructs the type. If mirror is non-nil it takes precedence over settings, and settings is ignored. 31 // Args: 32 // - ref - used to set OptionManager.Self if non-nil 33 // - setting - initial options, may be nil. 34 // - mirror - options array to keep updated with the OptionManager.Settings, may be nil. 35 func NewOptionManager(ref *types.ManagedObjectReference, setting []types.BaseOptionValue, mirror *[]types.BaseOptionValue) object.Reference { 36 s := &OptionManager{} 37 38 s.Setting = setting 39 if mirror != nil { 40 s.mirror = mirror 41 s.Setting = *mirror 42 } 43 44 if ref != nil { 45 s.Self = *ref 46 } 47 48 return s 49 } 50 51 // init constructs the OptionManager for ServiceContent.setting from the template directories. 52 // This does _not_ construct the OptionManager for ConfigManager.advancedOption. 53 func (m *OptionManager) init(r *Registry) { 54 if len(m.Setting) == 0 { 55 if r.IsVPX() { 56 m.Setting = vpx.Setting 57 } else { 58 m.Setting = esx.Setting 59 } 60 } 61 } 62 63 func (m *OptionManager) model(model *Model) error { 64 return model.createRootTempDir(m) 65 } 66 67 func (m *OptionManager) QueryOptions(req *types.QueryOptions) soap.HasFault { 68 body := &methods.QueryOptionsBody{} 69 res := &types.QueryOptionsResponse{} 70 71 for _, opt := range m.Setting { 72 if strings.HasPrefix(opt.GetOptionValue().Key, req.Name) { 73 res.Returnval = append(res.Returnval, opt) 74 } 75 } 76 77 if len(res.Returnval) == 0 { 78 body.Fault_ = Fault("", &types.InvalidName{Name: req.Name}) 79 } else { 80 body.Res = res 81 } 82 83 return body 84 } 85 86 func (m *OptionManager) find(key string) *types.OptionValue { 87 for _, opt := range m.Setting { 88 setting := opt.GetOptionValue() 89 if setting.Key == key { 90 return setting 91 } 92 } 93 return nil 94 } 95 96 func (m *OptionManager) UpdateOptions(req *types.UpdateOptions) soap.HasFault { 97 body := new(methods.UpdateOptionsBody) 98 99 for _, change := range req.ChangedValue { 100 setting := change.GetOptionValue() 101 102 // We don't currently include the entire list of default settings for ESX and vCenter, 103 // this prefix is currently used to test the failure path. 104 // Real vCenter seems to only allow new options if Key has a "config." prefix. 105 // TODO: consider behaving the same, which would require including 2 long lists of options in vpx.Setting and esx.Setting 106 if strings.HasPrefix(setting.Key, "ENOENT.") { 107 body.Fault_ = Fault("", &types.InvalidName{Name: setting.Key}) 108 return body 109 } 110 111 opt := m.find(setting.Key) 112 if opt != nil { 113 // This is an existing option. 114 opt.Value = setting.Value 115 continue 116 } 117 118 m.Setting = append(m.Setting, change) 119 if m.mirror != nil { 120 *m.mirror = m.Setting 121 } 122 } 123 124 body.Res = new(types.UpdateOptionsResponse) 125 return body 126 }