github.com/vmware/govmomi@v0.51.0/simulator/license_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 "slices" 9 10 "github.com/vmware/govmomi/vim25/methods" 11 "github.com/vmware/govmomi/vim25/mo" 12 "github.com/vmware/govmomi/vim25/soap" 13 "github.com/vmware/govmomi/vim25/types" 14 ) 15 16 // EvalLicense is the default license 17 var EvalLicense = types.LicenseManagerLicenseInfo{ 18 LicenseKey: "00000-00000-00000-00000-00000", 19 EditionKey: "eval", 20 Name: "Evaluation Mode", 21 Properties: []types.KeyAnyValue{ 22 { 23 Key: "feature", 24 Value: types.KeyValue{ 25 Key: "serialuri:2", 26 Value: "Remote virtual Serial Port Concentrator", 27 }, 28 }, 29 { 30 Key: "feature", 31 Value: types.KeyValue{ 32 Key: "dvs", 33 Value: "vSphere Distributed Switch", 34 }, 35 }, 36 }, 37 } 38 39 type LicenseManager struct { 40 mo.LicenseManager 41 } 42 43 func (m *LicenseManager) init(r *Registry) { 44 if len(m.Licenses) == 0 { 45 about := r.content().About 46 product := []types.KeyAnyValue{ 47 { 48 Key: "ProductName", 49 Value: about.LicenseProductName, 50 }, 51 { 52 Key: "ProductVersion", 53 Value: about.LicenseProductVersion, 54 }, 55 } 56 57 EvalLicense.Properties = append(EvalLicense.Properties, product...) 58 59 m.Licenses = []types.LicenseManagerLicenseInfo{EvalLicense} 60 } 61 62 if r.IsVPX() { 63 if m.LicenseAssignmentManager == nil { 64 m.LicenseAssignmentManager = &types.ManagedObjectReference{ 65 Type: "LicenseAssignmentManager", 66 Value: "LicenseAssignmentManager", 67 } 68 } 69 70 lam := new(LicenseAssignmentManager) 71 lam.Self = *m.LicenseAssignmentManager 72 lam.QueryAssignedLicensesResponse.Returnval = []types.LicenseAssignmentManagerLicenseAssignment{{ 73 EntityId: r.content().About.InstanceUuid, 74 EntityDisplayName: "vcsim", 75 AssignedLicense: EvalLicense, 76 }} 77 r.Put(lam) 78 r.AddHandler(lam) 79 } 80 } 81 82 func (m *LicenseManager) AddLicense(ctx *Context, req *types.AddLicense) soap.HasFault { 83 body := &methods.AddLicenseBody{ 84 Res: &types.AddLicenseResponse{}, 85 } 86 87 for _, license := range m.Licenses { 88 if license.LicenseKey == req.LicenseKey { 89 body.Res.Returnval = licenseInfo(license.LicenseKey, license.Labels) 90 return body 91 } 92 } 93 94 m.Licenses = append(m.Licenses, types.LicenseManagerLicenseInfo{ 95 LicenseKey: req.LicenseKey, 96 Labels: req.Labels, 97 }) 98 99 body.Res.Returnval = licenseInfo(req.LicenseKey, req.Labels) 100 101 return body 102 } 103 104 func (m *LicenseManager) RemoveLicense(ctx *Context, req *types.RemoveLicense) soap.HasFault { 105 body := &methods.RemoveLicenseBody{ 106 Res: &types.RemoveLicenseResponse{}, 107 } 108 109 for i, license := range m.Licenses { 110 if req.LicenseKey == license.LicenseKey { 111 m.Licenses = append(m.Licenses[:i], m.Licenses[i+1:]...) 112 return body 113 } 114 } 115 return body 116 } 117 118 func (m *LicenseManager) DecodeLicense(ctx *Context, req *types.DecodeLicense) soap.HasFault { 119 body := &methods.DecodeLicenseBody{ 120 Res: &types.DecodeLicenseResponse{}, 121 } 122 123 for _, license := range m.Licenses { 124 if req.LicenseKey == license.LicenseKey { 125 body.Res.Returnval = license 126 break 127 } 128 } 129 130 return body 131 } 132 133 func (m *LicenseManager) UpdateLicenseLabel(ctx *Context, req *types.UpdateLicenseLabel) soap.HasFault { 134 body := &methods.UpdateLicenseLabelBody{} 135 136 for i := range m.Licenses { 137 license := &m.Licenses[i] 138 139 if req.LicenseKey != license.LicenseKey { 140 continue 141 } 142 143 body.Res = new(types.UpdateLicenseLabelResponse) 144 145 for j := range license.Labels { 146 label := &license.Labels[j] 147 148 if label.Key == req.LabelKey { 149 if req.LabelValue == "" { 150 license.Labels = append(license.Labels[:i], license.Labels[i+1:]...) 151 } else { 152 label.Value = req.LabelValue 153 } 154 return body 155 } 156 } 157 158 license.Labels = append(license.Labels, types.KeyValue{ 159 Key: req.LabelKey, 160 Value: req.LabelValue, 161 }) 162 163 return body 164 } 165 166 body.Fault_ = Fault("", &types.InvalidArgument{InvalidProperty: "licenseKey"}) 167 return body 168 } 169 170 type LicenseAssignmentManager struct { 171 mo.LicenseAssignmentManager 172 173 types.QueryAssignedLicensesResponse 174 } 175 176 var licensedTypes = []string{"HostSystem", "ClusterComputeResource"} 177 178 // PutObject assigns a license when a host or cluster is created. 179 func (m *LicenseAssignmentManager) PutObject(ctx *Context, obj mo.Reference) { 180 ref := obj.Reference() 181 182 if !slices.Contains(licensedTypes, ref.Type) { 183 return 184 } 185 186 if slices.ContainsFunc(m.QueryAssignedLicensesResponse.Returnval, 187 func(am types.LicenseAssignmentManagerLicenseAssignment) bool { 188 return am.EntityId == ref.Value 189 }) { 190 return // via vcsim -load 191 } 192 193 la := types.LicenseAssignmentManagerLicenseAssignment{ 194 EntityId: ref.Value, 195 Scope: ctx.Map.content().About.InstanceUuid, 196 EntityDisplayName: obj.(mo.Entity).Entity().Name, 197 AssignedLicense: EvalLicense, 198 } 199 200 m.QueryAssignedLicensesResponse.Returnval = 201 append(m.QueryAssignedLicensesResponse.Returnval, la) 202 } 203 204 // RemoveObject removes the license assignment when a host or cluster is removed. 205 func (m *LicenseAssignmentManager) RemoveObject(ctx *Context, ref types.ManagedObjectReference) { 206 if !slices.Contains(licensedTypes, ref.Type) { 207 return 208 } 209 210 m.QueryAssignedLicensesResponse.Returnval = 211 slices.DeleteFunc(m.QueryAssignedLicensesResponse.Returnval, 212 func(am types.LicenseAssignmentManagerLicenseAssignment) bool { 213 return am.EntityId == ref.Value 214 }) 215 } 216 217 func (*LicenseAssignmentManager) UpdateObject(*Context, mo.Reference, []types.PropertyChange) {} 218 219 func (m *LicenseAssignmentManager) init(r *Registry) { 220 r.AddHandler(m) 221 } 222 223 func (m *LicenseAssignmentManager) QueryAssignedLicenses(ctx *Context, req *types.QueryAssignedLicenses) soap.HasFault { 224 body := &methods.QueryAssignedLicensesBody{ 225 Res: &types.QueryAssignedLicensesResponse{}, 226 } 227 228 if req.EntityId == "" { 229 body.Res = &m.QueryAssignedLicensesResponse 230 } else { 231 for _, r := range m.QueryAssignedLicensesResponse.Returnval { 232 if r.EntityId == req.EntityId { 233 body.Res.Returnval = append(body.Res.Returnval, r) 234 } 235 } 236 } 237 238 return body 239 } 240 241 func (m *LicenseAssignmentManager) UpdateAssignedLicense(ctx *Context, req *types.UpdateAssignedLicense) soap.HasFault { 242 body := new(methods.UpdateAssignedLicenseBody) 243 244 var license *types.LicenseManagerLicenseInfo 245 lm := ctx.Map.Get(*ctx.Map.content().LicenseManager).(*LicenseManager) 246 247 for i, l := range lm.Licenses { 248 if l.LicenseKey == req.LicenseKey { 249 license = &lm.Licenses[i] 250 } 251 } 252 253 if license == nil { 254 body.Fault_ = Fault("", &types.InvalidArgument{InvalidProperty: "entityId"}) 255 return body 256 } 257 258 for i, r := range m.QueryAssignedLicensesResponse.Returnval { 259 if r.EntityId == req.Entity { 260 r.AssignedLicense = *license 261 262 if req.EntityDisplayName != "" { 263 r.EntityDisplayName = req.EntityDisplayName 264 } 265 266 m.QueryAssignedLicensesResponse.Returnval[i] = r 267 268 body.Res = &types.UpdateAssignedLicenseResponse{ 269 Returnval: r.AssignedLicense, 270 } 271 272 break 273 } 274 } 275 276 return body 277 } 278 279 func licenseInfo(key string, labels []types.KeyValue) types.LicenseManagerLicenseInfo { 280 info := EvalLicense 281 282 info.LicenseKey = key 283 info.Labels = labels 284 285 return info 286 }