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