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 }