1/*
2Copyright (c) 2015 VMware, Inc. All Rights Reserved.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8    http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17package object
18
19import (
20	"context"
21	"errors"
22	"fmt"
23	"path"
24
25	"github.com/vmware/govmomi/property"
26	"github.com/vmware/govmomi/vim25"
27	"github.com/vmware/govmomi/vim25/methods"
28	"github.com/vmware/govmomi/vim25/mo"
29	"github.com/vmware/govmomi/vim25/types"
30)
31
32var (
33	ErrNotSupported = errors.New("product/version specific feature not supported by target")
34)
35
36// Common contains the fields and functions common to all objects.
37type Common struct {
38	InventoryPath string
39
40	c *vim25.Client
41	r types.ManagedObjectReference
42}
43
44func (c Common) String() string {
45	ref := fmt.Sprintf("%v", c.Reference())
46
47	if c.InventoryPath == "" {
48		return ref
49	}
50
51	return fmt.Sprintf("%s @ %s", ref, c.InventoryPath)
52}
53
54func NewCommon(c *vim25.Client, r types.ManagedObjectReference) Common {
55	return Common{c: c, r: r}
56}
57
58func (c Common) Reference() types.ManagedObjectReference {
59	return c.r
60}
61
62func (c Common) Client() *vim25.Client {
63	return c.c
64}
65
66// Name returns the base name of the InventoryPath field
67func (c Common) Name() string {
68	if c.InventoryPath == "" {
69		return ""
70	}
71	return path.Base(c.InventoryPath)
72}
73
74func (c *Common) SetInventoryPath(p string) {
75	c.InventoryPath = p
76}
77
78// ObjectName returns the base name of the InventoryPath field if set,
79// otherwise fetches the mo.ManagedEntity.Name field via the property collector.
80func (c Common) ObjectName(ctx context.Context) (string, error) {
81	var o mo.ManagedEntity
82
83	err := c.Properties(ctx, c.Reference(), []string{"name"}, &o)
84	if err != nil {
85		return "", err
86	}
87
88	if o.Name != "" {
89		return o.Name, nil
90	}
91
92	// Network has its own "name" field...
93	var n mo.Network
94
95	err = c.Properties(ctx, c.Reference(), []string{"name"}, &n)
96	if err != nil {
97		return "", err
98	}
99
100	return n.Name, nil
101}
102
103func (c Common) Properties(ctx context.Context, r types.ManagedObjectReference, ps []string, dst interface{}) error {
104	return property.DefaultCollector(c.c).RetrieveOne(ctx, r, ps, dst)
105}
106
107func (c Common) Destroy(ctx context.Context) (*Task, error) {
108	req := types.Destroy_Task{
109		This: c.Reference(),
110	}
111
112	res, err := methods.Destroy_Task(ctx, c.c, &req)
113	if err != nil {
114		return nil, err
115	}
116
117	return NewTask(c.c, res.Returnval), nil
118}
119
120func (c Common) Rename(ctx context.Context, name string) (*Task, error) {
121	req := types.Rename_Task{
122		This:    c.Reference(),
123		NewName: name,
124	}
125
126	res, err := methods.Rename_Task(ctx, c.c, &req)
127	if err != nil {
128		return nil, err
129	}
130
131	return NewTask(c.c, res.Returnval), nil
132}
133