1/*
2Copyright (c) 2014-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 flags
18
19import (
20	"context"
21	"flag"
22	"fmt"
23	"os"
24
25	"github.com/vmware/govmomi/object"
26)
27
28type VirtualMachineFlag struct {
29	common
30
31	*ClientFlag
32	*DatacenterFlag
33	*SearchFlag
34
35	name string
36	vm   *object.VirtualMachine
37}
38
39var virtualMachineFlagKey = flagKey("virtualMachine")
40
41func NewVirtualMachineFlag(ctx context.Context) (*VirtualMachineFlag, context.Context) {
42	if v := ctx.Value(virtualMachineFlagKey); v != nil {
43		return v.(*VirtualMachineFlag), ctx
44	}
45
46	v := &VirtualMachineFlag{}
47	v.ClientFlag, ctx = NewClientFlag(ctx)
48	v.DatacenterFlag, ctx = NewDatacenterFlag(ctx)
49	v.SearchFlag, ctx = NewSearchFlag(ctx, SearchVirtualMachines)
50	ctx = context.WithValue(ctx, virtualMachineFlagKey, v)
51	return v, ctx
52}
53
54func (flag *VirtualMachineFlag) Register(ctx context.Context, f *flag.FlagSet) {
55	flag.RegisterOnce(func() {
56		flag.ClientFlag.Register(ctx, f)
57		flag.DatacenterFlag.Register(ctx, f)
58		flag.SearchFlag.Register(ctx, f)
59
60		env := "GOVC_VM"
61		value := os.Getenv(env)
62		usage := fmt.Sprintf("Virtual machine [%s]", env)
63		f.StringVar(&flag.name, "vm", value, usage)
64	})
65}
66
67func (flag *VirtualMachineFlag) Process(ctx context.Context) error {
68	return flag.ProcessOnce(func() error {
69		if err := flag.ClientFlag.Process(ctx); err != nil {
70			return err
71		}
72		if err := flag.DatacenterFlag.Process(ctx); err != nil {
73			return err
74		}
75		if err := flag.SearchFlag.Process(ctx); err != nil {
76			return err
77		}
78		return nil
79	})
80}
81
82func (flag *VirtualMachineFlag) VirtualMachine() (*object.VirtualMachine, error) {
83	ctx := context.TODO()
84
85	if flag.vm != nil {
86		return flag.vm, nil
87	}
88
89	// Use search flags if specified.
90	if flag.SearchFlag.IsSet() {
91		vm, err := flag.SearchFlag.VirtualMachine()
92		if err != nil {
93			return nil, err
94		}
95
96		flag.vm = vm
97		return flag.vm, nil
98	}
99
100	// Never look for a default virtual machine.
101	if flag.name == "" {
102		return nil, nil
103	}
104
105	finder, err := flag.Finder()
106	if err != nil {
107		return nil, err
108	}
109
110	flag.vm, err = finder.VirtualMachine(ctx, flag.name)
111	return flag.vm, err
112}
113