github.com/vmware/govmomi@v0.51.0/object/common.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 object
     6  
     7  import (
     8  	"context"
     9  	"errors"
    10  	"fmt"
    11  	"path"
    12  	"strings"
    13  
    14  	"github.com/vmware/govmomi/property"
    15  	"github.com/vmware/govmomi/vim25"
    16  	"github.com/vmware/govmomi/vim25/methods"
    17  	"github.com/vmware/govmomi/vim25/mo"
    18  	"github.com/vmware/govmomi/vim25/types"
    19  )
    20  
    21  var (
    22  	ErrNotSupported = errors.New("product/version specific feature not supported by target")
    23  )
    24  
    25  // Common contains the fields and functions common to all objects.
    26  type Common struct {
    27  	InventoryPath string
    28  
    29  	c *vim25.Client
    30  	r types.ManagedObjectReference
    31  }
    32  
    33  func (c Common) String() string {
    34  	ref := fmt.Sprintf("%v", c.Reference())
    35  
    36  	if c.InventoryPath == "" {
    37  		return ref
    38  	}
    39  
    40  	return fmt.Sprintf("%s @ %s", ref, c.InventoryPath)
    41  }
    42  
    43  func NewCommon(c *vim25.Client, r types.ManagedObjectReference) Common {
    44  	return Common{c: c, r: r}
    45  }
    46  
    47  func (c Common) Reference() types.ManagedObjectReference {
    48  	return c.r
    49  }
    50  
    51  func (c Common) Client() *vim25.Client {
    52  	return c.c
    53  }
    54  
    55  // Name returns the base name of the InventoryPath field
    56  func (c Common) Name() string {
    57  	if c.InventoryPath == "" {
    58  		return ""
    59  	}
    60  	return path.Base(c.InventoryPath)
    61  }
    62  
    63  func (c *Common) SetInventoryPath(p string) {
    64  	c.InventoryPath = p
    65  }
    66  
    67  // ObjectName fetches the mo.ManagedEntity.Name field via the property collector.
    68  func (c Common) ObjectName(ctx context.Context) (string, error) {
    69  	var content []types.ObjectContent
    70  
    71  	err := c.Properties(ctx, c.Reference(), []string{"name"}, &content)
    72  	if err != nil {
    73  		return "", err
    74  	}
    75  
    76  	for i := range content {
    77  		for _, prop := range content[i].PropSet {
    78  			return prop.Val.(string), nil
    79  		}
    80  	}
    81  
    82  	return "", nil
    83  }
    84  
    85  // Properties is a wrapper for property.DefaultCollector().RetrieveOne()
    86  func (c Common) Properties(ctx context.Context, r types.ManagedObjectReference, ps []string, dst any) error {
    87  	return property.DefaultCollector(c.c).RetrieveOne(ctx, r, ps, dst)
    88  }
    89  
    90  func (c Common) Destroy(ctx context.Context) (*Task, error) {
    91  	req := types.Destroy_Task{
    92  		This: c.Reference(),
    93  	}
    94  
    95  	res, err := methods.Destroy_Task(ctx, c.c, &req)
    96  	if err != nil {
    97  		return nil, err
    98  	}
    99  
   100  	return NewTask(c.c, res.Returnval), nil
   101  }
   102  
   103  func (c Common) Rename(ctx context.Context, name string) (*Task, error) {
   104  	req := types.Rename_Task{
   105  		This:    c.Reference(),
   106  		NewName: name,
   107  	}
   108  
   109  	res, err := methods.Rename_Task(ctx, c.c, &req)
   110  	if err != nil {
   111  		return nil, err
   112  	}
   113  
   114  	return NewTask(c.c, res.Returnval), nil
   115  }
   116  
   117  func (c Common) SetCustomValue(ctx context.Context, key string, value string) error {
   118  	req := types.SetCustomValue{
   119  		This:  c.Reference(),
   120  		Key:   key,
   121  		Value: value,
   122  	}
   123  
   124  	_, err := methods.SetCustomValue(ctx, c.c, &req)
   125  	return err
   126  }
   127  
   128  var refTypeMap = map[string]string{
   129  	"datacenter":  "Datacenter",
   130  	"datastore":   "Datastore",
   131  	"domain":      "ComputeResource",
   132  	"dvportgroup": "DistributedVirtualPortgroup",
   133  	"dvs":         "DistributedVirtualSwitch",
   134  	"group":       "Folder",
   135  	"host":        "HostSystem",
   136  	"network":     "Network",
   137  	"resgroup":    "ResourcePool",
   138  	"vm":          "VirtualMachine",
   139  }
   140  
   141  // sub types
   142  var prefixTypeMap = map[string]struct{ prefix, kind string }{
   143  	"domain":   {"c", "ClusterComputeResource"}, // extends ComputeResource
   144  	"group":    {"p", "StoragePod"},             // extends Folder
   145  	"resgroup": {"v", "VirtualApp"},             // extends ResourcePool
   146  }
   147  
   148  // ReferenceFromString converts a string to ManagedObjectReference.
   149  // First checks for ManagedObjectReference (MOR), in the format of:
   150  // "$Type:$ID", e.g. "Datacenter:datacenter-3"
   151  // Next checks for Managed Object ID (MOID), where type is derived from the ID.
   152  // For example, "datacenter-3" is converted to a MOR "Datacenter:datacenter-3"
   153  // Returns nil if string is not in either format.
   154  func ReferenceFromString(s string) *types.ManagedObjectReference {
   155  	var ref types.ManagedObjectReference
   156  	if ref.FromString(s) && mo.IsManagedObjectType(ref.Type) {
   157  		return &ref
   158  	}
   159  
   160  	id := strings.SplitN(s, "-", 2)
   161  	if len(id) != 2 {
   162  		return nil
   163  	}
   164  
   165  	if kind, ok := refTypeMap[id[0]]; ok {
   166  		if p, ok := prefixTypeMap[id[0]]; ok {
   167  			if strings.HasPrefix(id[1], p.prefix) {
   168  				return &types.ManagedObjectReference{
   169  					Type:  p.kind,
   170  					Value: s,
   171  				}
   172  			}
   173  		}
   174  
   175  		return &types.ManagedObjectReference{
   176  			Type:  kind,
   177  			Value: s,
   178  		}
   179  	}
   180  
   181  	return nil
   182  }