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  }