[vmwarevsphere] Start using govmomi provided helpers

Also update govmomi to latest revision and call Logout method when needed

Signed-off-by: S.Çağlar Onur <conur@vmware.com>
This commit is contained in:
S.Çağlar Onur 2016-01-26 10:22:20 -08:00
parent 7f708edcec
commit 0aedfd201d
268 changed files with 9881 additions and 1639 deletions

4
Godeps/Godeps.json generated
View File

@ -234,8 +234,8 @@
},
{
"ImportPath": "github.com/vmware/govmomi",
"Comment": "prerelease-v0.1.0-73-gfc131d4-65-g482cd82",
"Rev": "482cd823716e0fa9bc4e186d262a6ea23d940fbf"
"Comment": "v0.3.0-11-g20c009c",
"Rev": "20c009ce9c493f0c714a9fffa5bda5fb84df2b6c"
},
{
"ImportPath": "github.com/docker/go-units",

View File

@ -225,6 +225,7 @@ func (d *Driver) GetIP() (string, error) {
if err != nil {
return "", err
}
defer c.Logout(ctx)
vm, err := d.fetchVM(c, ctx, d.MachineName)
if err != nil {
@ -250,6 +251,7 @@ func (d *Driver) GetState() (state.State, error) {
if err != nil {
return state.None, err
}
defer c.Logout(ctx)
vm, err := d.fetchVM(c, ctx, d.MachineName)
if err != nil {
@ -284,26 +286,27 @@ func (d *Driver) PreCreateCheck() error {
if err != nil {
return err
}
defer c.Logout(ctx)
// Create a new finder
f := find.NewFinder(c.Client, true)
dc, err := d.getDatacenter(f, ctx)
dc, err := f.DatacenterOrDefault(ctx, d.Datacenter)
if err != nil {
return err
}
f.SetDatacenter(dc)
if _, err := d.getDatastore(f, ctx); err != nil {
if _, err := f.DatastoreOrDefault(ctx, d.Datastore); err != nil {
return err
}
if _, err := d.getNetwork(f, ctx); err != nil {
if _, err := f.NetworkOrDefault(ctx, d.Network); err != nil {
return err
}
hs, err := d.getHostSystem(f, ctx)
hs, err := f.HostSystemOrDefault(ctx, d.HostSystem)
if err != nil {
return err
}
@ -348,27 +351,29 @@ func (d *Driver) Create() error {
if err != nil {
return err
}
defer c.Logout(ctx)
// Create a new finder
f := find.NewFinder(c.Client, true)
dc, err := d.getDatacenter(f, ctx)
dc, err := f.DatacenterOrDefault(ctx, d.Datacenter)
if err != nil {
return err
}
f.SetDatacenter(dc)
dss, err := d.getDatastore(f, ctx)
dss, err := f.DatastoreOrDefault(ctx, d.Datastore)
if err != nil {
return err
}
net, err := d.getNetwork(f, ctx)
net, err := f.NetworkOrDefault(ctx, d.Network)
if err != nil {
return err
}
hs, err := d.getHostSystem(f, ctx)
hs, err := f.HostSystemOrDefault(ctx, d.HostSystem)
if err != nil {
return err
}
@ -558,6 +563,7 @@ func (d *Driver) Start() error {
if err != nil {
return err
}
defer c.Logout(ctx)
vm, err := d.fetchVM(c, ctx, d.MachineName)
if err != nil {
@ -590,6 +596,7 @@ func (d *Driver) Stop() error {
if err != nil {
return err
}
defer c.Logout(ctx)
vm, err := d.fetchVM(c, ctx, d.MachineName)
if err != nil {
@ -645,6 +652,7 @@ func (d *Driver) Kill() error {
if err != nil {
return err
}
defer c.Logout(ctx)
vm, err := d.fetchVM(c, ctx, d.MachineName)
if err != nil {
@ -683,18 +691,19 @@ func (d *Driver) Remove() error {
if err != nil {
return err
}
defer c.Logout(ctx)
// Create a new finder
f := find.NewFinder(c.Client, true)
dc, err := d.getDatacenter(f, ctx)
dc, err := f.DatacenterOrDefault(ctx, d.Datacenter)
if err != nil {
return err
}
f.SetDatacenter(dc)
dss, err := d.getDatastore(f, ctx)
dss, err := f.DatastoreOrDefault(ctx, d.Datastore)
if err != nil {
return err
}
@ -821,7 +830,7 @@ func (d *Driver) fetchVM(c *govmomi.Client, ctx context.Context, vmname string)
var vm *object.VirtualMachine
var err error
dc, err := d.getDatacenter(f, ctx)
dc, err := f.DatacenterOrDefault(ctx, d.Datacenter)
if err != nil {
return vm, err
}
@ -856,83 +865,3 @@ func (f *FileAttrFlag) SetPerms(owner, group, perms int) {
func (f *FileAttrFlag) Attr() types.BaseGuestFileAttributes {
return &f.GuestPosixFileAttributes
}
func (d *Driver) getDatacenter(f *find.Finder, ctx context.Context) (dc *object.Datacenter, err error) {
// Datacenter
if d.Datacenter != "" {
// Find specified Datacenter
dc, err = f.Datacenter(ctx, d.Datacenter)
if err != nil {
return dc, err
}
} else {
// Use default Datacenter
dc, err = f.DefaultDatacenter(ctx)
if err != nil {
return dc, err
}
}
log.Debug("Datacenter found: ", dc)
return dc, nil
}
func (d *Driver) getDatastore(f *find.Finder, ctx context.Context) (dss *object.Datastore, err error) {
// Datastore
if d.Datastore != "" {
// Find specified Datastore
dss, err = f.Datastore(ctx, d.Datastore)
if err != nil {
return dss, err
}
} else {
// Find default Datastore
dss, err = f.DefaultDatastore(ctx)
if err != nil {
return dss, err
}
}
log.Debug("Datastore found: ", dss)
return dss, err
}
func (d *Driver) getNetwork(f *find.Finder, ctx context.Context) (net object.NetworkReference, err error) {
// Network
if d.Network != "" {
// Find specified Network
net, err = f.Network(ctx, d.Network)
if err != nil {
return net, err
}
} else {
// Find default Network
net, err = f.DefaultNetwork(ctx)
if err != nil {
return net, err
}
}
log.Debug("Network found: ", net)
return net, nil
}
func (d *Driver) getHostSystem(f *find.Finder, ctx context.Context) (hs *object.HostSystem, err error) {
// HostSystem
if d.HostSystem != "" {
// Find specified HostSystem
hs, err = f.HostSystem(ctx, d.HostSystem)
if err != nil {
return hs, err
}
} else {
// Find default HostSystem
hs, err = f.DefaultHostSystem(ctx)
if err != nil {
return hs, err
}
}
log.Debug("HostSystem found: ", hs)
return hs, nil
}

View File

@ -1,9 +1,35 @@
# changelog
### (unreleased)
### 0.3.0 (2016-01-16)
* Add object.VirtualNicManager wrapper
* Add object.HostVsanSystem wrapper
* Add object.HostSystem methods: EnterMaintenanceMode, ExitMaintenanceMode, Disconnect, Reconnect
* Add finder.Folder method
* Add object.Common.Destroy method
* Add object.ComputeResource.Reconfigure method
* Add license.AssignmentManager wrapper
* Add object.HostFirewallSystem wrapper
* Add object.DiagnosticManager wrapper
* Add LoginExtensionByCertificate support
* Add object.ExtensionManager
...
### 0.2.0 (2015-09-15)
* Update to vim25/6.0 API
* Stop returning children from `ManagedObjectList`
Change the `ManagedObjectList` function in the `find` package to only

View File

@ -4,19 +4,23 @@
#
Alvaro Miranda <kikitux@gmail.com>
Amit Bathla <abathla@vmware.com>
Bob Killen <killen.bob@gmail.com>
Bruce Downs <bdowns@vmware.com>
Clint Greenwood <cgreenwood@vmware.com> <clint.greenwood@gmail.com>
Danny Lockard <danny.lockard@banno.com>
Doug MacEachern <dougm@vmware.com>
Eloy Coto <eloy.coto@gmail.com>
Eric Yutao <eric.yutao@gmail.com>
Faiyaz Ahmed <ahmedf@vmware.com>
Gavin Gray <gavin@infinio.com>
Gavrie Philipson <gavrie@philipson.co.il> <gavrie.philipson@elastifile.com>
Louie Jiang <jiangl@vmware.com>
Mevan Samaratunga <mevansam@gmail.com>
Pieter Noordhuis <pnoordhuis@vmware.com> <pcnoordhuis@gmail.com>
runner.mei <runner.mei@gmail.com>
S.Çağlar Onur <conur@vmware.com>
Takaaki Furukawa <takaaki.frkw@gmail.com>
Takaaki Furukawa <takaaki.frkw@gmail.com> <takaaki.furukawa@mail.rakuten.com>
Yang Yang <yangy@vmware.com>
Yuya Kusakabe <yuya.kusakabe@gmail.com>
Zee Yang <zeey@vmware.com> <zee.yang@gmail.com>

View File

@ -8,7 +8,7 @@ For `govc`, a CLI built on top of govmomi, check out the [govc](./govc) director
## Compatibility
This library is built for and tested against ESXi and vCenter 5.5.
This library is built for and tested against ESXi and vCenter 5.5 and 6.0.
If you're able to use it against older versions of ESXi and/or vCenter, please
leave a note and we'll include it in this compatibility list.
@ -22,7 +22,7 @@ The code in the `govmomi` package is a wrapper for the code that is generated fr
It primarily provides convenience functions for working with the vSphere API.
See [godoc.org][godoc] for documentation.
[apiref]:http://pubs.vmware.com/vsphere-55/index.jsp#com.vmware.wssdk.apiref.doc/right-pane.html
[apiref]:http://pubs.vmware.com/vsphere-60/index.jsp#com.vmware.wssdk.apiref.doc/right-pane.html
[godoc]:http://godoc.org/github.com/vmware/govmomi
## Status

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -57,6 +57,7 @@ are kept outside the object package.
package govmomi
import (
"crypto/tls"
"net/url"
"github.com/vmware/govmomi/property"
@ -74,7 +75,7 @@ type Client struct {
}
// NewClient creates a new client from a URL. The client authenticates with the
// server before returning if the URL contains user information.
// server with username/password before returning if the URL contains user information.
func NewClient(ctx context.Context, u *url.URL, insecure bool) (*Client, error) {
soapClient := soap.NewClient(u, insecure)
vimClient, err := vim25.NewClient(ctx, soapClient)
@ -98,11 +99,41 @@ func NewClient(ctx context.Context, u *url.URL, insecure bool) (*Client, error)
return c, nil
}
// NewClientWithCertificate creates a new client from a URL. The client authenticates with the
// server with the certificate before returning if the URL contains user information.
func NewClientWithCertificate(ctx context.Context, u *url.URL, insecure bool, cert tls.Certificate) (*Client, error) {
soapClient := soap.NewClient(u, insecure)
soapClient.SetCertificate(cert)
vimClient, err := vim25.NewClient(ctx, soapClient)
if err != nil {
return nil, err
}
c := &Client{
Client: vimClient,
SessionManager: session.NewManager(vimClient),
}
if u.User != nil {
err = c.LoginExtensionByCertificate(ctx, u.User.Username(), "")
if err != nil {
return nil, err
}
}
return c, nil
}
// Login dispatches to the SessionManager.
func (c *Client) Login(ctx context.Context, u *url.Userinfo) error {
return c.SessionManager.Login(ctx, u)
}
// Login dispatches to the SessionManager.
func (c *Client) LoginExtensionByCertificate(ctx context.Context, key string, locale string) error {
return c.SessionManager.LoginExtensionByCertificate(ctx, key, locale)
}
// Logout dispatches to the SessionManager.
func (c *Client) Logout(ctx context.Context) error {
// Close any idle connections after logging out.

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -43,6 +43,7 @@ func NewManager(c *vim25.Client) *Manager {
c: c,
eventCategory: make(map[string]string),
eventCategoryMu: new(sync.Mutex),
}
@ -125,7 +126,7 @@ func (m Manager) eventCategoryMap(ctx context.Context) (map[string]string, error
m.eventCategoryMu.Lock()
defer m.eventCategoryMu.Unlock()
if m.eventCategory != nil {
if len(m.eventCategory) != 0 {
return m.eventCategory, nil
}
@ -137,8 +138,6 @@ func (m Manager) eventCategoryMap(ctx context.Context) (map[string]string, error
return nil, err
}
m.eventCategory = make(map[string]string, len(o.Description.EventInfo))
for _, info := range o.Description.EventInfo {
m.eventCategory[info.Key] = info.Category
}

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -243,6 +243,18 @@ func (f *Finder) DefaultDatacenter(ctx context.Context) (*object.Datacenter, err
return dc, nil
}
func (f *Finder) DatacenterOrDefault(ctx context.Context, path string) (*object.Datacenter, error) {
if path != "" {
dc, err := f.Datacenter(ctx, path)
if err != nil {
return nil, err
}
return dc, nil
}
return f.DefaultDatacenter(ctx)
}
func (f *Finder) DatastoreList(ctx context.Context, path string) ([]*object.Datastore, error) {
es, err := f.find(ctx, f.datastoreFolder, false, path)
if err != nil {
@ -289,6 +301,18 @@ func (f *Finder) DefaultDatastore(ctx context.Context) (*object.Datastore, error
return ds, nil
}
func (f *Finder) DatastoreOrDefault(ctx context.Context, path string) (*object.Datastore, error) {
if path != "" {
ds, err := f.Datastore(ctx, path)
if err != nil {
return nil, err
}
return ds, nil
}
return f.DefaultDatastore(ctx)
}
func (f *Finder) ComputeResourceList(ctx context.Context, path string) ([]*object.ComputeResource, error) {
es, err := f.find(ctx, f.hostFolder, false, path)
if err != nil {
@ -339,6 +363,18 @@ func (f *Finder) DefaultComputeResource(ctx context.Context) (*object.ComputeRes
return cr, nil
}
func (f *Finder) ComputeResourceOrDefault(ctx context.Context, path string) (*object.ComputeResource, error) {
if path != "" {
cr, err := f.ComputeResource(ctx, path)
if err != nil {
return nil, err
}
return cr, nil
}
return f.DefaultComputeResource(ctx)
}
func (f *Finder) ClusterComputeResourceList(ctx context.Context, path string) ([]*object.ClusterComputeResource, error) {
es, err := f.find(ctx, f.hostFolder, false, path)
if err != nil {
@ -393,19 +429,21 @@ func (f *Finder) HostSystemList(ctx context.Context, path string) ([]*object.Hos
switch o := e.Object.(type) {
case mo.HostSystem:
hs = object.NewHostSystem(f.client, o.Reference())
case mo.ComputeResource:
hs.InventoryPath = e.Path
hss = append(hss, hs)
case mo.ComputeResource, mo.ClusterComputeResource:
cr := object.NewComputeResource(f.client, o.Reference())
cr.InventoryPath = e.Path
hosts, err := cr.Hosts(ctx)
if err != nil {
return nil, err
}
hs = object.NewHostSystem(f.client, hosts[0])
default:
continue
}
hs.InventoryPath = e.Path
hss = append(hss, hs)
hss = append(hss, hosts...)
}
}
if len(hss) == 0 {
@ -437,6 +475,18 @@ func (f *Finder) DefaultHostSystem(ctx context.Context) (*object.HostSystem, err
return hs, nil
}
func (f *Finder) HostSystemOrDefault(ctx context.Context, path string) (*object.HostSystem, error) {
if path != "" {
hs, err := f.HostSystem(ctx, path)
if err != nil {
return nil, err
}
return hs, nil
}
return f.DefaultHostSystem(ctx)
}
func (f *Finder) NetworkList(ctx context.Context, path string) ([]object.NetworkReference, error) {
es, err := f.find(ctx, f.networkFolder, false, path)
if err != nil {
@ -455,6 +505,10 @@ func (f *Finder) NetworkList(ctx context.Context, path string) ([]object.Network
r := object.NewDistributedVirtualPortgroup(f.client, ref)
r.InventoryPath = e.Path
ns = append(ns, r)
case "DistributedVirtualSwitch", "VmwareDistributedVirtualSwitch":
r := object.NewDistributedVirtualSwitch(f.client, ref)
r.InventoryPath = e.Path
ns = append(ns, r)
}
}
@ -487,6 +541,18 @@ func (f *Finder) DefaultNetwork(ctx context.Context) (object.NetworkReference, e
return network, nil
}
func (f *Finder) NetworkOrDefault(ctx context.Context, path string) (object.NetworkReference, error) {
if path != "" {
network, err := f.Network(ctx, path)
if err != nil {
return nil, err
}
return network, nil
}
return f.DefaultNetwork(ctx)
}
func (f *Finder) ResourcePoolList(ctx context.Context, path string) ([]*object.ResourcePool, error) {
es, err := f.find(ctx, f.hostFolder, true, path)
if err != nil {
@ -534,6 +600,18 @@ func (f *Finder) DefaultResourcePool(ctx context.Context) (*object.ResourcePool,
return rp, nil
}
func (f *Finder) ResourcePoolOrDefault(ctx context.Context, path string) (*object.ResourcePool, error) {
if path != "" {
rp, err := f.ResourcePool(ctx, path)
if err != nil {
return nil, err
}
return rp, nil
}
return f.DefaultResourcePool(ctx)
}
func (f *Finder) VirtualMachineList(ctx context.Context, path string) ([]*object.VirtualMachine, error) {
es, err := f.find(ctx, f.vmFolder, false, path)
if err != nil {
@ -605,3 +683,29 @@ func (f *Finder) VirtualApp(ctx context.Context, path string) (*object.VirtualAp
return apps[0], nil
}
func (f *Finder) Folder(ctx context.Context, path string) (*object.Folder, error) {
mo, err := f.ManagedObjectList(ctx, path)
if err != nil {
return nil, err
}
if len(mo) == 0 {
return nil, &NotFoundError{"folder", path}
}
if len(mo) > 1 {
return nil, &MultipleFoundError{"folder", path}
}
ref := mo[0].Object.Reference()
if ref.Type != "Folder" {
return nil, &NotFoundError{"folder", path}
}
folder := object.NewFolder(f.client, ref)
folder.InventoryPath = mo[0].Path
return folder, nil
}

12
vendor/github.com/vmware/govmomi/gen/Gemfile.lock generated vendored Normal file
View File

@ -0,0 +1,12 @@
GEM
remote: https://rubygems.org/
specs:
mini_portile (0.6.0)
nokogiri (1.6.3.1)
mini_portile (= 0.6.0)
PLATFORMS
ruby
DEPENDENCIES
nokogiri

View File

@ -1,4 +1,4 @@
# Copyright (c) 2014 VMware, Inc. All Rights Reserved.
# Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -738,22 +738,6 @@ class WSDL
def self.header(name)
return <<EOF
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package #{name}
EOF

View File

@ -2,6 +2,39 @@
### (unreleased)
* Add `-p` and `-a` options to govc datastore.ls command
### 0.3.0 (2016-01-16)
* Add permissions.{ls,set,remove} commands
* Add datastore.{create,remove} commands.
The new create command supports both creating NAS and VMFS datastores.
* Add dvs.{create,add} and dvs.portgroup.add commands
* Add host.vnic.{service,info} commands
* Add cluster.{create,change,add} commands
* Add host.{disconnect,reconnect,remove,maintenance.enter,maintenance.exit} commands
* Add license.decode, license.assigned.list and license.assign commands
* Add firewall.ruleset.find command
* Add logs, logs.ls and logs.download commands
* Add support for LoginExtensionByCertificate with new `-cert` and `-key` flags
* Add govc extension.{info,register,unregister,setcert} commands
* Add govc vapp.{info,destroy,power} commands
### 0.2.0 (2015-09-15)
* The `vm.power` guest `-s` and `-r` options will fallback to hard `-off` / `-reset` if tools is unavailable and `-force` flag is given
* Add `PowerOn, InjectOvfEnv, WaitForIP` options to `import.ovf` and `import.ova` option spec file
* Add `import.spec` to produce an example json document
@ -10,12 +43,22 @@
* Add `-folder` to `import.ovf` and `import.ova`
* Add `fields` command to manage custom fields
* Add `datastore.info` command
* Add `events` command
* Add `-net.address` (Hardware Address) option to `vm.change` and `vm.create`
* Add `host.add` command to add host to datacenter.
* Add `GOVC_USERNAME` and `GOVC_PASSWORD` to allow overriding username and/or
password (used when they contain special characters that prevent them from
being embedded in the URL).
* Add `-e' (ExtraConfig) option to `vm.change` and `vm.info`
* Retry twice on temporary network errors.
* Add `host.autostart` commands to manage VM autostart.

View File

@ -22,6 +22,8 @@ import (
"os"
"text/tabwriter"
"golang.org/x/net/context"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
)
@ -34,11 +36,19 @@ func init() {
cli.Register("about", &about{})
}
func (cmd *about) Register(f *flag.FlagSet) {}
func (cmd *about) Register(ctx context.Context, f *flag.FlagSet) {
cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
cmd.ClientFlag.Register(ctx, f)
}
func (cmd *about) Process() error { return nil }
func (cmd *about) Process(ctx context.Context) error {
if err := cmd.ClientFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *about) Run(f *flag.FlagSet) error {
func (cmd *about) Run(ctx context.Context, f *flag.FlagSet) error {
c, err := cmd.Client()
if err != nil {
return err

View File

@ -1,22 +1,32 @@
#!/bin/bash -e
if ! which gox > /dev/null; then
echo "gox is not installed..."
exit 1
fi
git_version=$(git describe)
if git_status=$(git status --porcelain 2>/dev/null) && [ -n "${git_status}" ]; then
git_version="${git_version}-dirty"
fi
ldflags="-X github.com/vmware/govmomi/govc/version.gitVersion ${git_version}"
ldflags="-X github.com/vmware/govmomi/govc/version.gitVersion=${git_version}"
BUILD_OS=${BUILD_OS:-darwin linux windows freebsd}
BUILD_ARCH=${BUILD_ARCH:-386 amd64}
gox \
-parallel=1 \
-ldflags="${ldflags}" \
-os="${BUILD_OS}" \
-arch="${BUILD_ARCH}" \
github.com/vmware/govmomi/govc
for os in ${BUILD_OS}; do
export GOOS="${os}"
for arch in ${BUILD_ARCH}; do
export GOARCH="${arch}"
out="govc_${os}_${arch}"
if [ "${os}" == "windows" ]; then
out="${out}.exe"
fi
set -x
go build \
-o="${out}" \
-pkgdir="./_pkg" \
-compiler='gc' \
-ldflags="${ldflags}" \
github.com/vmware/govmomi/govc
set +x
done
done

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -21,50 +21,24 @@ import (
"fmt"
"io/ioutil"
"os"
"reflect"
"sort"
"text/tabwriter"
"golang.org/x/net/context"
)
type HasFlags interface {
// Register may be called more than once and should be idempotent.
Register(f *flag.FlagSet)
Register(ctx context.Context, f *flag.FlagSet)
// Process may be called more than once and should be idempotent.
Process() error
Process(ctx context.Context) error
}
type Command interface {
HasFlags
Run(f *flag.FlagSet) error
}
var hasFlagsType = reflect.TypeOf((*HasFlags)(nil)).Elem()
func RegisterCommand(h HasFlags, f *flag.FlagSet) {
visited := make(map[interface{}]struct{})
Walk(h, hasFlagsType, func(v interface{}) error {
if _, ok := visited[v]; ok {
return nil
}
visited[v] = struct{}{}
v.(HasFlags).Register(f)
return nil
})
}
func ProcessCommand(h HasFlags) error {
visited := make(map[interface{}]struct{})
err := Walk(h, hasFlagsType, func(v interface{}) error {
if _, ok := visited[v]; ok {
return nil
}
visited[v] = struct{}{}
err := v.(HasFlags).Process()
return err
})
return err
Run(ctx context.Context, f *flag.FlagSet) error
}
func generalHelp() {
@ -117,6 +91,8 @@ func commandHelp(name string, cmd Command, f *flag.FlagSet) {
}
func Run(args []string) int {
var err error
if len(args) == 0 {
generalHelp()
return 1
@ -134,37 +110,33 @@ func Run(args []string) int {
return 1
}
f := flag.NewFlagSet("", flag.ContinueOnError)
f.SetOutput(ioutil.Discard)
fs := flag.NewFlagSet("", flag.ContinueOnError)
fs.SetOutput(ioutil.Discard)
RegisterCommand(cmd, f)
ctx := context.Background()
cmd.Register(ctx, fs)
if err := f.Parse(args[1:]); err != nil {
if err == flag.ErrHelp {
commandHelp(args[0], cmd, f)
} else {
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
}
return 1
if err = fs.Parse(args[1:]); err != nil {
goto error
}
if err := ProcessCommand(cmd); err != nil {
if err == flag.ErrHelp {
commandHelp(args[0], cmd, f)
} else {
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
}
return 1
if err = cmd.Process(ctx); err != nil {
goto error
}
if err := cmd.Run(f); err != nil {
if err == flag.ErrHelp {
commandHelp(args[0], cmd, f)
} else {
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
}
return 1
if err = cmd.Run(ctx, fs); err != nil {
goto error
}
return 0
error:
if err == flag.ErrHelp {
commandHelp(args[0], cmd, fs)
} else {
fmt.Fprintf(os.Stderr, "%s: %s\n", os.Args[0], err)
}
return 1
}

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@ -1,108 +0,0 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cli
import (
"fmt"
"reflect"
)
type WalkFn func(c interface{}) error
// Walk recursively walks struct types that implement the specified interface.
// Fields that implement the specified interface are expected to be pointer
// values. This allows the function to cache pointer values on a per-type
// basis. If, during a recursive walk, the same type is encountered twice, the
// function creates a new value of that type the first time, and reuses that
// same value the second time.
//
// This function is used to make sure that a hierarchy of flags where multiple
// structs refer to the `Client` flag will not end up with more than one
// instance of the actual client. Rather, every struct referring to the
// `Client` flag will have a pointer to the same underlying `Client` struct.
//
func Walk(c interface{}, ifaceType reflect.Type, fn WalkFn) error {
var walker WalkFn
visited := make(map[reflect.Type]reflect.Value)
walker = func(c interface{}) error {
v := reflect.ValueOf(c)
if v.Kind() == reflect.Interface {
v = v.Elem()
}
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
t := v.Type()
// Call user specified function.
err := fn(c)
if err != nil {
return err
}
for i := 0; i < t.NumField(); i++ {
ff := t.Field(i)
ft := ff.Type
fv := v.Field(i)
// Check that a pointer to this field's type doesn't implement the
// specified interface. If it does, this field references the type as
// value. This is not allowed because it prohibits a value from being
// shared among multiple structs that reference it.
//
// For example: if a struct has two fields of the same type, they must
// both point to the same value after this routine has executed. If these
// fields are not a pointer type, the value cannot be shared.
//
if reflect.PtrTo(ft).Implements(ifaceType) {
panic(fmt.Sprintf(`field "%s" in struct "%s" must be a pointer`, ff.Name, v.Type()))
}
// Type must implement specified interface.
if !ft.Implements(ifaceType) {
continue
}
// Type must be a pointer.
if ft.Kind() != reflect.Ptr {
panic(fmt.Sprintf(`field "%s" in struct "%s" must be a pointer`, ff.Name, v.Type()))
}
// Have not seen this type before, create a value.
if _, ok := visited[ft]; !ok {
visited[ft] = reflect.New(ft.Elem())
}
// Make sure current field is set.
if fv.IsNil() {
fv.Set(visited[ft])
}
// Recurse.
err := walker(fv.Interface())
if err != nil {
return err
}
}
return nil
}
return walker(c)
}

129
vendor/github.com/vmware/govmomi/govc/cluster/add.go generated vendored Normal file
View File

@ -0,0 +1,129 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cluster
import (
"flag"
"fmt"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/object"
"golang.org/x/net/context"
)
type add struct {
*flags.DatacenterFlag
*flags.HostConnectFlag
cluster string
connect bool
license string
}
func init() {
cli.Register("cluster.add", &add{})
}
func (cmd *add) Register(ctx context.Context, f *flag.FlagSet) {
cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx)
cmd.DatacenterFlag.Register(ctx, f)
cmd.HostConnectFlag, ctx = flags.NewHostConnectFlag(ctx)
cmd.HostConnectFlag.Register(ctx, f)
f.StringVar(&cmd.cluster, "cluster", "*", "Path to cluster")
f.StringVar(&cmd.license, "license", "", "Assign license key")
f.BoolVar(&cmd.connect, "connect", true, "Immediately connect to host")
}
func (cmd *add) Process(ctx context.Context) error {
if err := cmd.DatacenterFlag.Process(ctx); err != nil {
return err
}
if err := cmd.HostConnectFlag.Process(ctx); err != nil {
return err
}
if cmd.HostName == "" {
return flag.ErrHelp
}
if cmd.UserName == "" {
return flag.ErrHelp
}
if cmd.Password == "" {
return flag.ErrHelp
}
return nil
}
func (cmd *add) Description() string {
return `Add host to cluster.
The host is added to the cluster specified by the 'cluster' flag.`
}
func (cmd *add) Add(ctx context.Context, cluster *object.ClusterComputeResource) error {
spec := cmd.HostConnectSpec
var license *string
if cmd.license != "" {
license = &cmd.license
}
task, err := cluster.AddHost(ctx, spec, cmd.connect, license, nil)
if err != nil {
return err
}
logger := cmd.ProgressLogger(fmt.Sprintf("adding %s to cluster %s... ", spec.HostName, cluster.InventoryPath))
defer logger.Wait()
_, err = task.WaitForResult(ctx, logger)
return err
}
func (cmd *add) Run(ctx context.Context, f *flag.FlagSet) error {
if f.NArg() != 0 {
return flag.ErrHelp
}
finder, err := cmd.Finder()
if err != nil {
return err
}
cluster, err := finder.ClusterComputeResource(ctx, cmd.cluster)
if err != nil {
return nil
}
err = cmd.Add(ctx, cluster)
if err == nil {
return nil
}
// Check if we failed due to SSLVerifyFault and -noverify is set
if err := cmd.AcceptThumbprint(err); err != nil {
return err
}
// Accepted unverified thumbprint, try again
return cmd.Add(ctx, cluster)
}

109
vendor/github.com/vmware/govmomi/govc/cluster/change.go generated vendored Normal file
View File

@ -0,0 +1,109 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cluster
import (
"flag"
"strings"
"golang.org/x/net/context"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/vim25/types"
)
type change struct {
*flags.DatacenterFlag
types.ClusterConfigSpecEx
}
func init() {
cli.Register("cluster.change", &change{})
}
func (cmd *change) Register(ctx context.Context, f *flag.FlagSet) {
cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx)
cmd.DatacenterFlag.Register(ctx, f)
cmd.DrsConfig = new(types.ClusterDrsConfigInfo)
cmd.DasConfig = new(types.ClusterDasConfigInfo)
cmd.VsanConfig = new(types.VsanClusterConfigInfo)
cmd.VsanConfig.DefaultConfig = new(types.VsanClusterConfigInfoHostDefaultInfo)
// DRS
f.Var(flags.NewOptionalBool(&cmd.DrsConfig.Enabled), "drs-enabled", "Enable DRS")
drsModes := []string{
string(types.DrsBehaviorManual),
string(types.DrsBehaviorPartiallyAutomated),
string(types.DrsBehaviorFullyAutomated),
}
f.StringVar((*string)(&cmd.DrsConfig.DefaultVmBehavior), "drs-mode", "",
"DRS behavior for virtual machines: "+strings.Join(drsModes, ", "))
// HA
f.Var(flags.NewOptionalBool(&cmd.DasConfig.Enabled), "ha-enabled", "Enable HA")
// vSAN
f.Var(flags.NewOptionalBool(&cmd.VsanConfig.Enabled), "vsan-enabled", "Enable vSAN")
f.Var(flags.NewOptionalBool(&cmd.VsanConfig.DefaultConfig.AutoClaimStorage), "vsan-autoclaim", "")
}
func (cmd *change) Process(ctx context.Context) error {
if err := cmd.DatacenterFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *change) Usage() string {
return "CLUSTER..."
}
func (cmd *change) Description() string {
return `Change configuration of the given clusters.`
}
func (cmd *change) Run(ctx context.Context, f *flag.FlagSet) error {
finder, err := cmd.Finder()
if err != nil {
return err
}
for _, path := range f.Args() {
clusters, err := finder.ClusterComputeResourceList(ctx, path)
if err != nil {
return err
}
for _, cluster := range clusters {
task, err := cluster.Reconfigure(ctx, &cmd.ClusterConfigSpecEx, true)
if err != nil {
return err
}
_, err = task.WaitForResult(ctx, nil)
if err != nil {
return err
}
}
}
return nil
}

104
vendor/github.com/vmware/govmomi/govc/cluster/create.go generated vendored Normal file
View File

@ -0,0 +1,104 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cluster
import (
"flag"
"golang.org/x/net/context"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/types"
)
type create struct {
*flags.DatacenterFlag
parent string
types.ClusterConfigSpecEx
}
func init() {
cli.Register("cluster.create", &create{})
}
func (cmd *create) Register(ctx context.Context, f *flag.FlagSet) {
cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx)
cmd.DatacenterFlag.Register(ctx, f)
f.StringVar(&cmd.parent, "parent", "", "Path to parent folder for the new cluster")
}
func (cmd *create) Usage() string {
return "CLUSTER"
}
func (cmd *create) Description() string {
return `Create CLUSTER in datacenter.
The cluster is added to the folder specified by the 'parent' flag. If not given,
this defaults to the hosts folder in the specified or default datacenter.`
}
func (cmd *create) Process(ctx context.Context) error {
if err := cmd.DatacenterFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *create) Run(ctx context.Context, f *flag.FlagSet) error {
var parent *object.Folder
if f.NArg() != 1 {
return flag.ErrHelp
}
if cmd.parent == "" {
dc, err := cmd.Datacenter()
if err != nil {
return err
}
folders, err := dc.Folders(ctx)
if err != nil {
return err
}
parent = folders.HostFolder
} else {
finder, err := cmd.Finder()
if err != nil {
return err
}
parent, err = finder.Folder(ctx, cmd.parent)
if err != nil {
return err
}
}
_, err := parent.CreateCluster(ctx, f.Arg(0), cmd.ClusterConfigSpecEx)
if err != nil {
return err
}
return nil
}

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -34,15 +34,23 @@ func init() {
cli.Register("datacenter.create", &create{})
}
func (cmd *create) Register(f *flag.FlagSet) {}
func (cmd *create) Register(ctx context.Context, f *flag.FlagSet) {
cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
cmd.ClientFlag.Register(ctx, f)
}
func (cmd *create) Usage() string {
return "[DATACENTER NAME]..."
}
func (cmd *create) Process() error { return nil }
func (cmd *create) Process(ctx context.Context) error {
if err := cmd.ClientFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *create) Run(f *flag.FlagSet) error {
func (cmd *create) Run(ctx context.Context, f *flag.FlagSet) error {
datacenters := f.Args()
if len(datacenters) < 1 {
return flag.ErrHelp

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -33,15 +33,23 @@ func init() {
cli.Register("datacenter.destroy", &destroy{})
}
func (cmd *destroy) Register(f *flag.FlagSet) {}
func (cmd *destroy) Register(ctx context.Context, f *flag.FlagSet) {
cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
cmd.ClientFlag.Register(ctx, f)
}
func (cmd *destroy) Usage() string {
return "[DATACENTER NAME]..."
}
func (cmd *destroy) Process() error { return nil }
func (cmd *destroy) Process(ctx context.Context) error {
if err := cmd.ClientFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *destroy) Run(f *flag.FlagSet) error {
func (cmd *destroy) Run(ctx context.Context, f *flag.FlagSet) error {
if len(f.Args()) < 1 {
return flag.ErrHelp
}

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -37,17 +37,31 @@ func init() {
cli.Register("datastore.cp", &cp{})
}
func (cmd *cp) Register(f *flag.FlagSet) {
func (cmd *cp) Register(ctx context.Context, f *flag.FlagSet) {
cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
cmd.OutputFlag.Register(ctx, f)
cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
cmd.DatastoreFlag.Register(ctx, f)
f.BoolVar(&cmd.force, "f", false, "If true, overwrite any identically named file at the destination")
}
func (cmd *cp) Process() error { return nil }
func (cmd *cp) Process(ctx context.Context) error {
if err := cmd.OutputFlag.Process(ctx); err != nil {
return err
}
if err := cmd.DatastoreFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *cp) Usage() string {
return "SRC DST"
}
func (cmd *cp) Run(f *flag.FlagSet) error {
func (cmd *cp) Run(ctx context.Context, f *flag.FlagSet) error {
args := f.Args()
if len(args) != 2 {
return errors.New("SRC and DST arguments are required")

View File

@ -0,0 +1,273 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package datastore
import (
"errors"
"flag"
"fmt"
"os"
"strings"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type create struct {
*flags.HostSystemFlag
// Generic options
Type typeFlag
Name string
Force bool
// Options for NAS
RemoteHost string
RemotePath string
AccessMode string
UserName string
Password string
// Options for VMFS
DiskCanonicalName string
}
func init() {
cli.Register("datastore.create", &create{})
}
var nasTypes = []string{
string(types.HostFileSystemVolumeFileSystemTypeNFS),
string(types.HostFileSystemVolumeFileSystemTypeNFS41),
string(types.HostFileSystemVolumeFileSystemTypeCIFS),
}
var vmfsTypes = []string{
"VMFS",
}
var allTypes = []string{}
func init() {
allTypes = append(allTypes, nasTypes...)
allTypes = append(allTypes, vmfsTypes...)
}
type typeFlag string
func (t *typeFlag) Set(s string) error {
s = strings.ToLower(s)
for _, e := range allTypes {
if s == strings.ToLower(e) {
*t = typeFlag(e)
return nil
}
}
return fmt.Errorf("unknown type")
}
func (t *typeFlag) String() string {
return string(*t)
}
func (t *typeFlag) partOf(m []string) bool {
for _, e := range m {
if t.String() == e {
return true
}
}
return false
}
func (t *typeFlag) IsNasType() bool {
return t.partOf(nasTypes)
}
func (t *typeFlag) IsVmfsType() bool {
return t.partOf(vmfsTypes)
}
func (cmd *create) Register(ctx context.Context, f *flag.FlagSet) {
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
cmd.HostSystemFlag.Register(ctx, f)
modes := []string{
string(types.HostMountModeReadOnly),
string(types.HostMountModeReadWrite),
}
f.StringVar(&cmd.Name, "name", "", "Datastore name")
f.Var(&cmd.Type, "type", fmt.Sprintf("Datastore type (%s)", strings.Join(allTypes, "|")))
f.BoolVar(&cmd.Force, "force", false, "Ignore DuplicateName error if datastore is already mounted on a host")
// Options for NAS
f.StringVar(&cmd.RemoteHost, "remote-host", "", "Remote hostname of the NAS datastore")
f.StringVar(&cmd.RemotePath, "remote-path", "", "Remote path of the NFS mount point")
f.StringVar(&cmd.AccessMode, "mode", modes[0],
fmt.Sprintf("Access mode for the mount point (%s)", strings.Join(modes, "|")))
f.StringVar(&cmd.UserName, "username", "", "Username to use when connecting (CIFS only)")
f.StringVar(&cmd.Password, "password", "", "Password to use when connecting (CIFS only)")
// Options for VMFS
f.StringVar(&cmd.DiskCanonicalName, "disk", "", "Canonical name of disk (VMFS only)")
}
func (cmd *create) Process(ctx context.Context) error {
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *create) Usage() string {
return "HOST..."
}
func (cmd *create) Description() string {
return `Create datastore on HOST.
Examples:
govc datastore.create -type nfs -name nfsDatastore -remote-host 10.143.2.232 -remote-path /share cluster1
govc datastore.create -type vmfs -name localDatastore -disk=mpx.vmhba0:C0:T0:L0 cluster1`
}
func (cmd *create) Run(ctx context.Context, f *flag.FlagSet) error {
hosts, err := cmd.HostSystems(f.Args())
if err != nil {
return err
}
switch {
case cmd.Type.IsNasType():
return cmd.CreateNasDatastore(ctx, hosts)
case cmd.Type.IsVmfsType():
return cmd.CreateVmfsDatastore(ctx, hosts)
default:
return fmt.Errorf("unhandled type %#v", cmd.Type)
}
}
func (cmd *create) GetHostNasVolumeSpec() types.HostNasVolumeSpec {
s := types.HostNasVolumeSpec{
LocalPath: cmd.Name,
Type: cmd.Type.String(),
RemoteHost: cmd.RemoteHost,
RemotePath: cmd.RemotePath,
AccessMode: cmd.AccessMode,
UserName: cmd.UserName,
Password: cmd.Password,
}
return s
}
func (cmd *create) CreateNasDatastore(ctx context.Context, hosts []*object.HostSystem) error {
object := types.ManagedObjectReference{
Type: "Datastore",
Value: fmt.Sprintf("%s:%s", cmd.RemoteHost, cmd.RemotePath),
}
spec := cmd.GetHostNasVolumeSpec()
for _, host := range hosts {
ds, err := host.ConfigManager().DatastoreSystem(ctx)
if err != nil {
return err
}
_, err = ds.CreateNasDatastore(ctx, spec)
if err != nil {
if soap.IsSoapFault(err) {
switch fault := soap.ToSoapFault(err).VimFault().(type) {
case types.PlatformConfigFault:
if len(fault.FaultMessage) != 0 {
return errors.New(fault.FaultMessage[0].Message)
}
case types.DuplicateName:
if cmd.Force && fault.Object == object {
fmt.Fprintf(os.Stderr, "%s: '%s' already mounted\n",
host.InventoryPath, cmd.Name)
continue
}
}
}
return fmt.Errorf("%s: %s", host.InventoryPath, err)
}
}
return nil
}
func (cmd *create) CreateVmfsDatastore(ctx context.Context, hosts []*object.HostSystem) error {
for _, host := range hosts {
ds, err := host.ConfigManager().DatastoreSystem(ctx)
if err != nil {
return err
}
// Find the specified disk
disks, err := ds.QueryAvailableDisksForVmfs(ctx)
if err != nil {
return err
}
var disk *types.HostScsiDisk
for _, e := range disks {
if e.CanonicalName == cmd.DiskCanonicalName {
disk = &e
break
}
}
if disk == nil {
return fmt.Errorf("no eligible disk found for name %#v", cmd.DiskCanonicalName)
}
// Query for creation options and pick the right one
options, err := ds.QueryVmfsDatastoreCreateOptions(ctx, disk.DevicePath)
if err != nil {
return err
}
var option *types.VmfsDatastoreOption
for _, e := range options {
if _, ok := e.Info.(*types.VmfsDatastoreAllExtentOption); ok {
option = &e
break
}
}
if option == nil {
return fmt.Errorf("cannot use entire disk for datastore for name %#v", cmd.DiskCanonicalName)
}
spec := *option.Spec.(*types.VmfsDatastoreCreateSpec)
spec.Vmfs.VolumeName = cmd.Name
_, err = ds.CreateVmfsDatastore(ctx, spec)
if err != nil {
return err
}
}
return nil
}

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -20,6 +20,8 @@ import (
"errors"
"flag"
"golang.org/x/net/context"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/vim25/soap"
@ -33,26 +35,29 @@ func init() {
cli.Register("datastore.download", &download{})
}
func (cmd *download) Register(f *flag.FlagSet) {}
func (cmd *download) Register(ctx context.Context, f *flag.FlagSet) {
cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
cmd.DatastoreFlag.Register(ctx, f)
}
func (cmd *download) Process() error { return nil }
func (cmd *download) Process(ctx context.Context) error {
if err := cmd.DatastoreFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *download) Usage() string {
return "REMOTE LOCAL"
}
func (cmd *download) Run(f *flag.FlagSet) error {
func (cmd *download) Run(ctx context.Context, f *flag.FlagSet) error {
args := f.Args()
if len(args) != 2 {
return errors.New("invalid arguments")
}
c, err := cmd.Client()
if err != nil {
return err
}
u, err := cmd.DatastoreURL(args[0])
ds, err := cmd.Datastore()
if err != nil {
return err
}
@ -64,5 +69,5 @@ func (cmd *download) Run(f *flag.FlagSet) error {
defer logger.Wait()
}
return c.Client.DownloadFile(args[1], u, &p)
return ds.DownloadFile(context.TODO(), args[0], args[1], &p)
}

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -25,6 +25,7 @@ import (
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
@ -41,22 +42,40 @@ func init() {
cli.Register("datastore.info", &info{})
}
func (cmd *info) Register(f *flag.FlagSet) {}
func (cmd *info) Register(ctx context.Context, f *flag.FlagSet) {
cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
cmd.ClientFlag.Register(ctx, f)
func (cmd *info) Process() error { return nil }
cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
cmd.OutputFlag.Register(ctx, f)
cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx)
cmd.DatacenterFlag.Register(ctx, f)
}
func (cmd *info) Process(ctx context.Context) error {
if err := cmd.ClientFlag.Process(ctx); err != nil {
return err
}
if err := cmd.OutputFlag.Process(ctx); err != nil {
return err
}
if err := cmd.DatacenterFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *info) Usage() string {
return "[PATH]..."
}
func (cmd *info) Run(f *flag.FlagSet) error {
func (cmd *info) Run(ctx context.Context, f *flag.FlagSet) error {
c, err := cmd.Client()
if err != nil {
return err
}
ctx := context.TODO()
finder, err := cmd.Finder()
if err != nil {
return err
@ -67,16 +86,6 @@ func (cmd *info) Run(f *flag.FlagSet) error {
args = []string{"*"}
}
datastores, err := finder.DatastoreList(ctx, args[0])
if err != nil {
return err
}
refs := make([]types.ManagedObjectReference, 0, len(datastores))
for _, ds := range datastores {
refs = append(refs, ds.Reference())
}
var res infoResult
var props []string
@ -86,10 +95,25 @@ func (cmd *info) Run(f *flag.FlagSet) error {
props = []string{"info", "summary"} // Load summary
}
pc := property.DefaultCollector(c)
err = pc.Retrieve(ctx, refs, props, &res.Datastores)
if err != nil {
return err
for _, arg := range args {
objects, err := finder.DatastoreList(ctx, arg)
if err != nil {
return err
}
res.objects = append(res.objects, objects...)
}
if len(res.objects) != 0 {
refs := make([]types.ManagedObjectReference, 0, len(res.objects))
for _, o := range res.objects {
refs = append(refs, o.Reference())
}
pc := property.DefaultCollector(c)
err = pc.Retrieve(ctx, refs, props, &res.Datastores)
if err != nil {
return err
}
}
return cmd.WriteResult(&res)
@ -97,14 +121,23 @@ func (cmd *info) Run(f *flag.FlagSet) error {
type infoResult struct {
Datastores []mo.Datastore
objects []*object.Datastore
}
func (r *infoResult) Write(w io.Writer) error {
// Maintain order via r.objects as Property collector does not always return results in order.
objects := make(map[types.ManagedObjectReference]mo.Datastore, len(r.Datastores))
for _, o := range r.Datastores {
objects[o.Reference()] = o
}
tw := tabwriter.NewWriter(os.Stdout, 2, 0, 2, ' ', 0)
for _, ds := range r.Datastores {
for _, o := range r.objects {
ds := objects[o.Reference()]
s := ds.Summary
fmt.Fprintf(tw, "Name:\t%s\n", s.Name)
fmt.Fprintf(tw, " Path:\t%s\n", o.InventoryPath)
fmt.Fprintf(tw, " Type:\t%s\n", s.Type)
fmt.Fprintf(tw, " URL:\t%s\n", s.Url)
fmt.Fprintf(tw, " Capacity:\t%.1f GB\n", float64(s.Capacity)/(1<<30))

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -36,24 +36,42 @@ type ls struct {
*flags.DatastoreFlag
*flags.OutputFlag
long bool
long bool
slash bool
all bool
}
func init() {
cli.Register("datastore.ls", &ls{})
}
func (cmd *ls) Register(f *flag.FlagSet) {
func (cmd *ls) Register(ctx context.Context, f *flag.FlagSet) {
cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
cmd.DatastoreFlag.Register(ctx, f)
cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
cmd.OutputFlag.Register(ctx, f)
f.BoolVar(&cmd.long, "l", false, "Long listing format")
f.BoolVar(&cmd.slash, "p", false, "Write a slash (`/') after each filename if that file is a directory")
f.BoolVar(&cmd.all, "a", false, "Include entries whose names begin with a dot (.)")
}
func (cmd *ls) Process() error { return nil }
func (cmd *ls) Process(ctx context.Context) error {
if err := cmd.DatastoreFlag.Process(ctx); err != nil {
return err
}
if err := cmd.OutputFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *ls) Usage() string {
return "[FILE]..."
}
func (cmd *ls) Run(f *flag.FlagSet) error {
func (cmd *ls) Run(ctx context.Context, f *flag.FlagSet) error {
ds, err := cmd.Datastore()
if err != nil {
return err
@ -70,8 +88,8 @@ func (cmd *ls) Run(f *flag.FlagSet) error {
}
result := &listOutput{
rs: make([]types.HostDatastoreBrowserSearchResults, 0),
long: cmd.long,
rs: make([]types.HostDatastoreBrowserSearchResults, 0),
cmd: cmd,
}
for _, arg := range args {
@ -137,12 +155,29 @@ func (cmd *ls) ListPath(b *object.HostDatastoreBrowser, path string, spec types.
}
type listOutput struct {
rs []types.HostDatastoreBrowserSearchResults
long bool
rs []types.HostDatastoreBrowserSearchResults
cmd *ls
}
func (o *listOutput) add(r types.HostDatastoreBrowserSearchResults) {
o.rs = append(o.rs, r)
res := r
res.File = nil
for _, f := range r.File {
if f.GetFileInfo().Path[0] == '.' && !o.cmd.all {
continue
}
if o.cmd.slash {
if d, ok := f.(*types.FolderFileInfo); ok {
d.Path += "/"
}
}
res.File = append(res.File, f)
}
o.rs = append(o.rs, res)
}
// hasMultiplePaths returns whether or not the slice of search results contains
@ -185,7 +220,7 @@ func (o *listOutput) Write(w io.Writer) error {
}
for _, file := range r.File {
info := file.GetFileInfo()
if o.long {
if o.cmd.long {
fmt.Fprintf(tw, "%s\t%s\t%s\n", units.ByteSize(info.FileSize), info.Modification.Format("Mon Jan 2 15:04:05 2006"), info.Path)
} else {
fmt.Fprintf(tw, "%s\n", info.Path)

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -38,17 +38,25 @@ func init() {
cli.Register("datastore.mkdir", &mkdir{})
}
func (cmd *mkdir) Register(f *flag.FlagSet) {
func (cmd *mkdir) Register(ctx context.Context, f *flag.FlagSet) {
cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
cmd.DatastoreFlag.Register(ctx, f)
f.BoolVar(&cmd.createParents, "p", false, "Create intermediate directories as needed")
}
func (cmd *mkdir) Process() error { return nil }
func (cmd *mkdir) Process(ctx context.Context) error {
if err := cmd.DatastoreFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *mkdir) Usage() string {
return "DIRECTORY"
}
func (cmd *mkdir) Run(f *flag.FlagSet) error {
func (cmd *mkdir) Run(ctx context.Context, f *flag.FlagSet) error {
args := f.Args()
if len(args) == 0 {
return errors.New("missing operand")

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -36,17 +36,25 @@ func init() {
cli.Register("datastore.mv", &mv{})
}
func (cmd *mv) Register(f *flag.FlagSet) {
func (cmd *mv) Register(ctx context.Context, f *flag.FlagSet) {
cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
cmd.DatastoreFlag.Register(ctx, f)
f.BoolVar(&cmd.force, "f", false, "If true, overwrite any identically named file at the destination")
}
func (cmd *mv) Process() error { return nil }
func (cmd *mv) Process(ctx context.Context) error {
if err := cmd.DatastoreFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *mv) Usage() string {
return "SRC DST"
}
func (cmd *mv) Run(f *flag.FlagSet) error {
func (cmd *mv) Run(ctx context.Context, f *flag.FlagSet) error {
args := f.Args()
if len(args) != 2 {
return errors.New("SRC and DST arguments are required")

View File

@ -0,0 +1,90 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package datastore
import (
"flag"
"golang.org/x/net/context"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
)
type remove struct {
*flags.HostSystemFlag
*flags.DatastoreFlag
}
func init() {
cli.Register("datastore.remove", &remove{})
}
func (cmd *remove) Register(ctx context.Context, f *flag.FlagSet) {
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
cmd.HostSystemFlag.Register(ctx, f)
cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
cmd.DatastoreFlag.Register(ctx, f)
}
func (cmd *remove) Process(ctx context.Context) error {
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
return err
}
if err := cmd.DatastoreFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *remove) Usage() string {
return "HOST..."
}
func (cmd *remove) Description() string {
return `Remove datastore from HOST.
Example:
govc datastore.remove -ds nfsDatastore cluster1
`
}
func (cmd *remove) Run(ctx context.Context, f *flag.FlagSet) error {
ds, err := cmd.Datastore()
if err != nil {
return err
}
hosts, err := cmd.HostSystems(f.Args())
if err != nil {
return err
}
for _, host := range hosts {
hds, err := host.ConfigManager().DatastoreSystem(ctx)
if err != nil {
return err
}
err = hds.Remove(ctx, ds)
if err != nil {
return err
}
}
return nil
}

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -38,17 +38,25 @@ func init() {
cli.Alias("datastore.rm", "datastore.delete")
}
func (cmd *rm) Register(f *flag.FlagSet) {
func (cmd *rm) Register(ctx context.Context, f *flag.FlagSet) {
cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
cmd.DatastoreFlag.Register(ctx, f)
f.BoolVar(&cmd.force, "f", false, "Force; ignore nonexistent files and arguments")
}
func (cmd *rm) Process() error { return nil }
func (cmd *rm) Process(ctx context.Context) error {
if err := cmd.DatastoreFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *rm) Usage() string {
return "FILE"
}
func (cmd *rm) Run(f *flag.FlagSet) error {
func (cmd *rm) Run(ctx context.Context, f *flag.FlagSet) error {
args := f.Args()
if len(args) == 0 {
return errors.New("missing operand")

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -20,6 +20,8 @@ import (
"errors"
"flag"
"golang.org/x/net/context"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/vim25/soap"
@ -34,26 +36,35 @@ func init() {
cli.Register("datastore.upload", &upload{})
}
func (cmd *upload) Register(f *flag.FlagSet) {}
func (cmd *upload) Register(ctx context.Context, f *flag.FlagSet) {
cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
cmd.OutputFlag.Register(ctx, f)
func (cmd *upload) Process() error { return nil }
cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
cmd.DatastoreFlag.Register(ctx, f)
}
func (cmd *upload) Process(ctx context.Context) error {
if err := cmd.OutputFlag.Process(ctx); err != nil {
return err
}
if err := cmd.DatastoreFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *upload) Usage() string {
return "LOCAL REMOTE"
}
func (cmd *upload) Run(f *flag.FlagSet) error {
func (cmd *upload) Run(ctx context.Context, f *flag.FlagSet) error {
args := f.Args()
if len(args) != 2 {
return errors.New("invalid arguments")
}
c, err := cmd.Client()
if err != nil {
return err
}
u, err := cmd.DatastoreURL(args[1])
ds, err := cmd.Datastore()
if err != nil {
return err
}
@ -65,5 +76,5 @@ func (cmd *upload) Run(f *flag.FlagSet) error {
defer logger.Wait()
}
return c.Client.UploadFile(args[0], u, &p)
return ds.UploadFile(context.TODO(), args[0], args[1], &p)
}

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -37,7 +37,10 @@ func init() {
cli.Register("device.boot", &boot{})
}
func (cmd *boot) Register(f *flag.FlagSet) {
func (cmd *boot) Register(ctx context.Context, f *flag.FlagSet) {
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
cmd.VirtualMachineFlag.Register(ctx, f)
f.Int64Var(&cmd.BootDelay, "delay", 0, "Delay in ms before starting the boot sequence")
f.StringVar(&cmd.order, "order", "", "Boot device order")
f.Int64Var(&cmd.BootRetryDelay, "retry-delay", 0, "Delay in ms before a boot retry")
@ -49,9 +52,14 @@ func (cmd *boot) Register(f *flag.FlagSet) {
f.BoolVar(cmd.EnterBIOSSetup, "setup", false, "If true, enter BIOS setup on next boot")
}
func (cmd *boot) Process() error { return nil }
func (cmd *boot) Process(ctx context.Context) error {
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *boot) Run(f *flag.FlagSet) error {
func (cmd *boot) Run(ctx context.Context, f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -35,13 +35,21 @@ func init() {
cli.Register("device.cdrom.add", &add{})
}
func (cmd *add) Register(f *flag.FlagSet) {
func (cmd *add) Register(ctx context.Context, f *flag.FlagSet) {
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
cmd.VirtualMachineFlag.Register(ctx, f)
f.StringVar(&cmd.controller, "controller", "", "IDE controller name")
}
func (cmd *add) Process() error { return nil }
func (cmd *add) Process(ctx context.Context) error {
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *add) Run(f *flag.FlagSet) error {
func (cmd *add) Run(ctx context.Context, f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -34,11 +34,19 @@ func init() {
cli.Register("device.cdrom.eject", &eject{})
}
func (cmd *eject) Register(f *flag.FlagSet) {
func (cmd *eject) Register(ctx context.Context, f *flag.FlagSet) {
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
cmd.VirtualMachineFlag.Register(ctx, f)
f.StringVar(&cmd.device, "device", "", "CD-ROM device name")
}
func (cmd *eject) Process() error { return nil }
func (cmd *eject) Process(ctx context.Context) error {
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *eject) Description() string {
return `Eject media from CD-ROM device.
@ -46,7 +54,7 @@ func (cmd *eject) Description() string {
If device is not specified, the first CD-ROM device is used.`
}
func (cmd *eject) Run(f *flag.FlagSet) error {
func (cmd *eject) Run(ctx context.Context, f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -35,11 +35,24 @@ func init() {
cli.Register("device.cdrom.insert", &insert{})
}
func (cmd *insert) Register(f *flag.FlagSet) {
func (cmd *insert) Register(ctx context.Context, f *flag.FlagSet) {
cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
cmd.DatastoreFlag.Register(ctx, f)
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
cmd.VirtualMachineFlag.Register(ctx, f)
f.StringVar(&cmd.device, "device", "", "CD-ROM device name")
}
func (cmd *insert) Process() error { return nil }
func (cmd *insert) Process(ctx context.Context) error {
if err := cmd.DatastoreFlag.Process(ctx); err != nil {
return err
}
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *insert) Usage() string {
return "ISO"
@ -51,7 +64,7 @@ func (cmd *insert) Description() string {
If device is not specified, the first CD-ROM device is used.`
}
func (cmd *insert) Run(f *flag.FlagSet) error {
func (cmd *insert) Run(ctx context.Context, f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -33,15 +33,23 @@ func init() {
cli.Register("device.connect", &connect{})
}
func (cmd *connect) Register(f *flag.FlagSet) {}
func (cmd *connect) Register(ctx context.Context, f *flag.FlagSet) {
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
cmd.VirtualMachineFlag.Register(ctx, f)
}
func (cmd *connect) Process() error { return nil }
func (cmd *connect) Process(ctx context.Context) error {
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *connect) Usage() string {
return "DEVICE..."
}
func (cmd *connect) Run(f *flag.FlagSet) error {
func (cmd *connect) Run(ctx context.Context, f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -33,15 +33,23 @@ func init() {
cli.Register("device.disconnect", &disconnect{})
}
func (cmd *disconnect) Register(f *flag.FlagSet) {}
func (cmd *disconnect) Register(ctx context.Context, f *flag.FlagSet) {
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
cmd.VirtualMachineFlag.Register(ctx, f)
}
func (cmd *disconnect) Process() error { return nil }
func (cmd *disconnect) Process(ctx context.Context) error {
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *disconnect) Usage() string {
return "DEVICE..."
}
func (cmd *disconnect) Run(f *flag.FlagSet) error {
func (cmd *disconnect) Run(ctx context.Context, f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -33,11 +33,19 @@ func init() {
cli.Register("device.floppy.add", &add{})
}
func (cmd *add) Register(f *flag.FlagSet) {}
func (cmd *add) Register(ctx context.Context, f *flag.FlagSet) {
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
cmd.VirtualMachineFlag.Register(ctx, f)
}
func (cmd *add) Process() error { return nil }
func (cmd *add) Process(ctx context.Context) error {
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *add) Run(f *flag.FlagSet) error {
func (cmd *add) Run(ctx context.Context, f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -34,11 +34,19 @@ func init() {
cli.Register("device.floppy.eject", &eject{})
}
func (cmd *eject) Register(f *flag.FlagSet) {
func (cmd *eject) Register(ctx context.Context, f *flag.FlagSet) {
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
cmd.VirtualMachineFlag.Register(ctx, f)
f.StringVar(&cmd.device, "device", "", "Floppy device name")
}
func (cmd *eject) Process() error { return nil }
func (cmd *eject) Process(ctx context.Context) error {
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *eject) Description() string {
return `Eject image from floppy device.
@ -46,7 +54,7 @@ func (cmd *eject) Description() string {
If device is not specified, the first floppy device is used.`
}
func (cmd *eject) Run(f *flag.FlagSet) error {
func (cmd *eject) Run(ctx context.Context, f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -35,11 +35,24 @@ func init() {
cli.Register("device.floppy.insert", &insert{})
}
func (cmd *insert) Register(f *flag.FlagSet) {
func (cmd *insert) Register(ctx context.Context, f *flag.FlagSet) {
cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
cmd.DatastoreFlag.Register(ctx, f)
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
cmd.VirtualMachineFlag.Register(ctx, f)
f.StringVar(&cmd.device, "device", "", "Floppy device name")
}
func (cmd *insert) Process() error { return nil }
func (cmd *insert) Process(ctx context.Context) error {
if err := cmd.DatastoreFlag.Process(ctx); err != nil {
return err
}
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *insert) Usage() string {
return "IMG"
@ -51,7 +64,7 @@ func (cmd *insert) Description() string {
If device is not specified, the first floppy device is used.`
}
func (cmd *insert) Run(f *flag.FlagSet) error {
func (cmd *insert) Run(ctx context.Context, f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -19,33 +19,50 @@ package device
import (
"flag"
"fmt"
"io"
"os"
"strings"
"text/tabwriter"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type info struct {
*flags.VirtualMachineFlag
*flags.OutputFlag
}
func init() {
cli.Register("device.info", &info{})
}
func (cmd *info) Register(f *flag.FlagSet) {}
func (cmd *info) Register(ctx context.Context, f *flag.FlagSet) {
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
cmd.VirtualMachineFlag.Register(ctx, f)
func (cmd *info) Process() error { return nil }
func (cmd *info) Usage() string {
return "DEVICE..."
cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
cmd.OutputFlag.Register(ctx, f)
}
func (cmd *info) Run(f *flag.FlagSet) error {
func (cmd *info) Process(ctx context.Context) error {
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
return err
}
if err := cmd.OutputFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *info) Usage() string {
return "[DEVICE]..."
}
func (cmd *info) Run(ctx context.Context, f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err
@ -60,19 +77,41 @@ func (cmd *info) Run(f *flag.FlagSet) error {
return err
}
res := infoResult{
list: devices,
}
if f.NArg() == 0 {
res.Devices = devices
} else {
for _, name := range f.Args() {
device := devices.Find(name)
if device == nil {
return fmt.Errorf("device '%s' not found", name)
}
res.Devices = append(res.Devices, device)
}
}
return cmd.WriteResult(&res)
}
type infoResult struct {
Devices object.VirtualDeviceList
// need the full list of devices to lookup attached devices and controllers
list object.VirtualDeviceList
}
func (r *infoResult) Write(w io.Writer) error {
tw := tabwriter.NewWriter(os.Stdout, 2, 0, 2, ' ', 0)
for _, name := range f.Args() {
device := devices.Find(name)
if device == nil {
return fmt.Errorf("device '%s' not found", name)
}
for _, device := range r.Devices {
d := device.GetVirtualDevice()
info := d.DeviceInfo.GetDescription()
fmt.Fprintf(tw, "Name:\t%s\n", name)
fmt.Fprintf(tw, " Type:\t%s\n", devices.TypeName(device))
fmt.Fprintf(tw, "Name:\t%s\n", r.Devices.Name(device))
fmt.Fprintf(tw, " Type:\t%s\n", r.Devices.TypeName(device))
fmt.Fprintf(tw, " Label:\t%s\n", info.Label)
fmt.Fprintf(tw, " Summary:\t%s\n", info.Summary)
fmt.Fprintf(tw, " Key:\t%d\n", d.Key)
@ -80,12 +119,12 @@ func (cmd *info) Run(f *flag.FlagSet) error {
if c, ok := device.(types.BaseVirtualController); ok {
var attached []string
for _, key := range c.GetVirtualController().Device {
attached = append(attached, devices.Name(devices.FindByKey(key)))
attached = append(attached, r.Devices.Name(r.list.FindByKey(key)))
}
fmt.Fprintf(tw, " Devices:\t%s\n", strings.Join(attached, ", "))
} else {
if c := devices.FindByKey(d.ControllerKey); c != nil {
fmt.Fprintf(tw, " Controller:\t%s\n", devices.Name(c))
if c := r.list.FindByKey(d.ControllerKey); c != nil {
fmt.Fprintf(tw, " Controller:\t%s\n", r.Devices.Name(c))
fmt.Fprintf(tw, " Unit number:\t%d\n", d.UnitNumber)
}
}
@ -108,6 +147,12 @@ func (cmd *info) Run(f *flag.FlagSet) error {
if b, ok := md.Backing.(*types.VirtualDiskFlatVer2BackingInfo); ok && b.Parent != nil {
fmt.Fprintf(tw, " Parent:\t%s\n", b.Parent.GetVirtualDeviceFileBackingInfo().FileName)
}
case *types.VirtualSerialPort:
if b, ok := md.Backing.(*types.VirtualSerialPortURIBackingInfo); ok {
fmt.Fprintf(tw, " Direction:\t%s\n", b.Direction)
fmt.Fprintf(tw, " Service URI:\t%s\n", b.ServiceURI)
fmt.Fprintf(tw, " Proxy URI:\t%s\n", b.ProxyURI)
}
}
}

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -37,13 +37,21 @@ func init() {
cli.Register("device.ls", &ls{})
}
func (cmd *ls) Register(f *flag.FlagSet) {
func (cmd *ls) Register(ctx context.Context, f *flag.FlagSet) {
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
cmd.VirtualMachineFlag.Register(ctx, f)
f.BoolVar(&cmd.boot, "boot", false, "List devices configured in the VM's boot options")
}
func (cmd *ls) Process() error { return nil }
func (cmd *ls) Process(ctx context.Context) error {
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *ls) Run(f *flag.FlagSet) error {
func (cmd *ls) Run(ctx context.Context, f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -33,15 +33,23 @@ func init() {
cli.Register("device.remove", &remove{})
}
func (cmd *remove) Register(f *flag.FlagSet) {}
func (cmd *remove) Register(ctx context.Context, f *flag.FlagSet) {
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
cmd.VirtualMachineFlag.Register(ctx, f)
}
func (cmd *remove) Process() error { return nil }
func (cmd *remove) Process(ctx context.Context) error {
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *remove) Usage() string {
return "DEVICE..."
}
func (cmd *remove) Run(f *flag.FlagSet) error {
func (cmd *remove) Run(ctx context.Context, f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -40,7 +40,10 @@ func init() {
cli.Register("device.scsi.add", &add{})
}
func (cmd *add) Register(f *flag.FlagSet) {
func (cmd *add) Register(ctx context.Context, f *flag.FlagSet) {
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
cmd.VirtualMachineFlag.Register(ctx, f)
var ctypes []string
ct := object.SCSIControllerTypes()
for _, t := range ct {
@ -52,9 +55,14 @@ func (cmd *add) Register(f *flag.FlagSet) {
f.BoolVar(&cmd.hotAddRemove, "hot", false, "Enable hot-add/remove")
}
func (cmd *add) Process() error { return nil }
func (cmd *add) Process(ctx context.Context) error {
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *add) Run(f *flag.FlagSet) error {
func (cmd *add) Run(ctx context.Context, f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -33,11 +33,19 @@ func init() {
cli.Register("device.serial.add", &add{})
}
func (cmd *add) Register(f *flag.FlagSet) {}
func (cmd *add) Register(ctx context.Context, f *flag.FlagSet) {
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
cmd.VirtualMachineFlag.Register(ctx, f)
}
func (cmd *add) Process() error { return nil }
func (cmd *add) Process(ctx context.Context) error {
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *add) Run(f *flag.FlagSet) error {
func (cmd *add) Run(ctx context.Context, f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -11,6 +11,8 @@ Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
@ -35,14 +37,22 @@ func init() {
cli.Register("device.serial.connect", &connect{})
}
func (cmd *connect) Register(f *flag.FlagSet) {
func (cmd *connect) Register(ctx context.Context, f *flag.FlagSet) {
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
cmd.VirtualMachineFlag.Register(ctx, f)
f.StringVar(&cmd.device, "device", "", "serial port device name")
f.BoolVar(&cmd.client, "client", false, "Use client direction")
}
func (cmd *connect) Process() error { return nil }
func (cmd *connect) Process(ctx context.Context) error {
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *connect) Run(f *flag.FlagSet) error {
func (cmd *connect) Run(ctx context.Context, f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -34,13 +34,21 @@ func init() {
cli.Register("device.serial.disconnect", &disconnect{})
}
func (cmd *disconnect) Register(f *flag.FlagSet) {
func (cmd *disconnect) Register(ctx context.Context, f *flag.FlagSet) {
cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
cmd.VirtualMachineFlag.Register(ctx, f)
f.StringVar(&cmd.device, "device", "", "serial port device name")
}
func (cmd *disconnect) Process() error { return nil }
func (cmd *disconnect) Process(ctx context.Context) error {
if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *disconnect) Run(f *flag.FlagSet) error {
func (cmd *disconnect) Run(ctx context.Context, f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err

145
vendor/github.com/vmware/govmomi/govc/dvs/add.go generated vendored Normal file
View File

@ -0,0 +1,145 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package dvs
import (
"flag"
"fmt"
"os"
"strings"
"golang.org/x/net/context"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
)
type add struct {
*flags.HostSystemFlag
path string
pnic string
}
func init() {
cli.Register("dvs.add", &add{})
}
func (cmd *add) Register(ctx context.Context, f *flag.FlagSet) {
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
cmd.HostSystemFlag.Register(ctx, f)
f.StringVar(&cmd.path, "dvs", "", "DVS path")
f.StringVar(&cmd.pnic, "pnic", "vmnic0", "Name of the host physical NIC")
}
func (cmd *add) Process(ctx context.Context) error {
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *add) Usage() string {
return "HOST..."
}
func (cmd *add) Description() string {
return `Add hosts to DVS.`
}
func (cmd *add) Run(ctx context.Context, f *flag.FlagSet) error {
if f.NArg() == 0 {
return flag.ErrHelp
}
finder, err := cmd.Finder()
if err != nil {
return err
}
net, err := finder.Network(ctx, cmd.path)
if err != nil {
return err
}
dvs, ok := net.(*object.DistributedVirtualSwitch)
if !ok {
return fmt.Errorf("%s (%T) is not of type %T", cmd.path, net, dvs)
}
var s mo.VmwareDistributedVirtualSwitch
err = dvs.Properties(ctx, dvs.Reference(), []string{"config"}, &s)
if err != nil {
return err
}
backing := new(types.DistributedVirtualSwitchHostMemberPnicBacking)
for _, vmnic := range strings.Split(cmd.pnic, ",") {
backing.PnicSpec = append(backing.PnicSpec, types.DistributedVirtualSwitchHostMemberPnicSpec{
PnicDevice: strings.TrimSpace(vmnic),
})
}
config := &types.DVSConfigSpec{
ConfigVersion: s.Config.GetDVSConfigInfo().ConfigVersion,
}
hosts, err := cmd.HostSystems(f.Args())
if err != nil {
return err
}
existing := make(map[string]bool)
// TODO: host.pnic.info command
for _, member := range s.Config.GetDVSConfigInfo().Host {
existing[member.Config.Host.Value] = true
}
for _, host := range hosts {
ref := host.Reference()
if existing[ref.Value] {
fmt.Fprintf(os.Stderr, "%s is already a member of %s\n", host.InventoryPath, dvs.InventoryPath)
continue
}
config.Host = append(config.Host, types.DistributedVirtualSwitchHostMemberConfigSpec{
Operation: "add",
Host: ref,
Backing: backing,
})
}
if len(config.Host) == 0 {
return nil
}
task, err := dvs.Reconfigure(ctx, config)
if err != nil {
return err
}
logger := cmd.ProgressLogger(fmt.Sprintf("adding %d hosts to dvs %s... ", len(config.Host), dvs.InventoryPath))
defer logger.Wait()
_, err = task.WaitForResult(ctx, logger)
return err
}

119
vendor/github.com/vmware/govmomi/govc/dvs/create.go generated vendored Normal file
View File

@ -0,0 +1,119 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package dvs
import (
"flag"
"fmt"
"golang.org/x/net/context"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/types"
)
type create struct {
*flags.DatacenterFlag
types.DVSCreateSpec
configSpec *types.VMwareDVSConfigSpec
parent string
}
func init() {
cli.Register("dvs.create", &create{})
}
func (cmd *create) Register(ctx context.Context, f *flag.FlagSet) {
cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx)
cmd.DatacenterFlag.Register(ctx, f)
cmd.configSpec = new(types.VMwareDVSConfigSpec)
cmd.DVSCreateSpec.ConfigSpec = cmd.configSpec
f.StringVar(&cmd.parent, "parent", "", "Path to parent folder for the new dvs")
}
func (cmd *create) Usage() string {
return "DVS"
}
func (cmd *create) Description() string {
return `Create DVS (DistributedVirtualSwitch) in datacenter.
The dvs is added to the folder specified by the 'parent' flag. If not given,
this defaults to the network folder in the specified or default datacenter.`
}
func (cmd *create) Process(ctx context.Context) error {
if err := cmd.DatacenterFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *create) Run(ctx context.Context, f *flag.FlagSet) error {
var parent *object.Folder
if f.NArg() != 1 {
return flag.ErrHelp
}
name := f.Arg(0)
if cmd.parent == "" {
dc, err := cmd.Datacenter()
if err != nil {
return err
}
folders, err := dc.Folders(ctx)
if err != nil {
return err
}
parent = folders.NetworkFolder
} else {
finder, err := cmd.Finder()
if err != nil {
return err
}
parent, err = finder.Folder(ctx, cmd.parent)
if err != nil {
return err
}
}
cmd.configSpec.Name = name
task, err := parent.CreateDVS(ctx, cmd.DVSCreateSpec)
if err != nil {
return err
}
logger := cmd.ProgressLogger(fmt.Sprintf("adding %s to folder %s... ", name, parent.InventoryPath))
defer logger.Wait()
_, err = task.WaitForResult(ctx, logger)
return err
}

View File

@ -0,0 +1,107 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package portgroup
import (
"flag"
"fmt"
"strings"
"golang.org/x/net/context"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/types"
)
type add struct {
*flags.DatacenterFlag
types.DVPortgroupConfigSpec
path string
}
func init() {
cli.Register("dvs.portgroup.add", &add{})
}
func (cmd *add) Register(ctx context.Context, f *flag.FlagSet) {
cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx)
cmd.DatacenterFlag.Register(ctx, f)
f.StringVar(&cmd.path, "dvs", "", "DVS path")
ptypes := []string{
string(types.DistributedVirtualPortgroupPortgroupTypeEarlyBinding),
string(types.DistributedVirtualPortgroupPortgroupTypeLateBinding),
string(types.DistributedVirtualPortgroupPortgroupTypeEphemeral),
}
f.StringVar(&cmd.DVPortgroupConfigSpec.Type, "type", ptypes[0],
fmt.Sprintf("Portgroup type (%s)", strings.Join(ptypes, "|")))
f.IntVar(&cmd.DVPortgroupConfigSpec.NumPorts, "nports", 128, "Number of ports")
}
func (cmd *add) Process(ctx context.Context) error {
if err := cmd.DatacenterFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *add) Usage() string {
return "NAME"
}
func (cmd *add) Run(ctx context.Context, f *flag.FlagSet) error {
if f.NArg() == 0 {
return flag.ErrHelp
}
name := f.Arg(0)
finder, err := cmd.Finder()
if err != nil {
return err
}
net, err := finder.Network(ctx, cmd.path)
if err != nil {
return err
}
dvs, ok := net.(*object.DistributedVirtualSwitch)
if !ok {
return fmt.Errorf("%s (%T) is not of type %T", cmd.path, net, dvs)
}
cmd.DVPortgroupConfigSpec.Name = name
task, err := dvs.AddPortgroup(ctx, []types.DVPortgroupConfigSpec{cmd.DVPortgroupConfigSpec})
if err != nil {
return err
}
logger := cmd.ProgressLogger(fmt.Sprintf("adding %s portgroup to dvs %s... ", name, dvs.InventoryPath))
defer logger.Wait()
_, err = task.WaitForResult(ctx, logger)
return err
}

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -21,13 +21,11 @@ import (
"fmt"
"os"
"strings"
"text/tabwriter"
"time"
"github.com/vmware/govmomi/event"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/list"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
@ -42,24 +40,25 @@ func init() {
cli.Register("events", &events{})
}
func (cmd *events) Register(f *flag.FlagSet) {
func (cmd *events) Register(ctx context.Context, f *flag.FlagSet) {
cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx)
cmd.DatacenterFlag.Register(ctx, f)
f.IntVar(&cmd.Max, "n", 25, "Output the last N events")
}
func (cmd *events) Process() error { return nil }
func (cmd *events) Process(ctx context.Context) error {
if err := cmd.DatacenterFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *events) Usage() string {
return "[PATH]..."
}
func (cmd *events) Run(f *flag.FlagSet) error {
ctx := context.TODO()
finder, err := cmd.Finder()
if err != nil {
return err
}
func (cmd *events) Run(ctx context.Context, f *flag.FlagSet) error {
c, err := cmd.Client()
if err != nil {
return err
@ -67,20 +66,9 @@ func (cmd *events) Run(f *flag.FlagSet) error {
m := event.NewManager(c)
var objs []list.Element
args := f.Args()
if len(args) == 0 {
args = []string{"."}
}
for _, arg := range args {
es, err := finder.ManagedObjectList(ctx, arg)
if err != nil {
return err
}
objs = append(objs, es...)
objs, err := cmd.ManagedObjects(ctx, f.Args())
if err != nil {
return err
}
var events []types.BaseEvent
@ -88,14 +76,14 @@ func (cmd *events) Run(f *flag.FlagSet) error {
for _, o := range objs {
filter := types.EventFilterSpec{
Entity: &types.EventFilterSpecByEntity{
Entity: o.Object.Reference(),
Entity: o,
Recursion: types.EventFilterSpecRecursionOptionAll,
},
}
collector, err := m.CreateCollectorForEvents(ctx, filter)
if err != nil {
return fmt.Errorf("[%s] %s", o.Path, err)
return fmt.Errorf("[%#v] %s", o, err)
}
defer collector.Destroy(ctx)
@ -114,8 +102,6 @@ func (cmd *events) Run(f *flag.FlagSet) error {
event.Sort(events)
tw := tabwriter.NewWriter(os.Stdout, 3, 0, 2, ' ', 0)
for _, e := range events {
cat, err := m.EventCategory(ctx, e)
if err != nil {
@ -129,10 +115,10 @@ func (cmd *events) Run(f *flag.FlagSet) error {
msg = fmt.Sprintf("%s (target=%s %s)", msg, t.Info.Entity.Type, t.Info.EntityName)
}
fmt.Fprintf(tw, "[%s]\t[%s]\t%s\n",
fmt.Fprintf(os.Stdout, "[%s] [%s] %s\n",
event.CreatedTime.Local().Format(time.ANSIC),
cat, msg)
}
return tw.Flush()
return nil
}

121
vendor/github.com/vmware/govmomi/govc/extension/info.go generated vendored Normal file
View File

@ -0,0 +1,121 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package extension
import (
"flag"
"fmt"
"io"
"os"
"text/tabwriter"
"golang.org/x/net/context"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/types"
)
type info struct {
*flags.ClientFlag
*flags.OutputFlag
}
func init() {
cli.Register("extension.info", &info{})
}
func (cmd *info) Register(ctx context.Context, f *flag.FlagSet) {
cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
cmd.ClientFlag.Register(ctx, f)
cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
cmd.OutputFlag.Register(ctx, f)
}
func (cmd *info) Process(ctx context.Context) error {
if err := cmd.ClientFlag.Process(ctx); err != nil {
return err
}
if err := cmd.OutputFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *info) Usage() string {
return "[KEY]..."
}
func (cmd *info) Run(ctx context.Context, f *flag.FlagSet) error {
c, err := cmd.Client()
if err != nil {
return err
}
m, err := object.GetExtensionManager(c)
if err != nil {
return err
}
list, err := m.List(ctx)
if err != nil {
return err
}
var res infoResult
if f.NArg() == 0 {
res.Extensions = list
} else {
exts := make(map[string]types.Extension)
for _, e := range list {
exts[e.Key] = e
}
for _, key := range f.Args() {
if e, ok := exts[key]; ok {
res.Extensions = append(res.Extensions, e)
} else {
return fmt.Errorf("extension %s not found", key)
}
}
}
return cmd.WriteResult(&res)
}
type infoResult struct {
Extensions []types.Extension
}
func (r *infoResult) Write(w io.Writer) error {
tw := tabwriter.NewWriter(os.Stdout, 2, 0, 2, ' ', 0)
for _, e := range r.Extensions {
fmt.Fprintf(tw, "Name:\t%s\n", e.Key)
fmt.Fprintf(tw, " Version:\t%s\n", e.Version)
fmt.Fprintf(tw, " Description:\t%s\n", e.Description.GetDescription().Summary)
fmt.Fprintf(tw, " Company:\t%s\n", e.Company)
fmt.Fprintf(tw, " Last heartbeat time:\t%s\n", e.LastHeartbeatTime)
fmt.Fprintf(tw, " Subject name:\t%s\n", e.SubjectName)
fmt.Fprintf(tw, " Type:\t%s\n", e.Type)
}
return tw.Flush()
}

View File

@ -0,0 +1,81 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package extension
import (
"encoding/json"
"flag"
"os"
"time"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type register struct {
*flags.ClientFlag
update bool
}
func init() {
cli.Register("extension.register", &register{})
}
func (cmd *register) Register(ctx context.Context, f *flag.FlagSet) {
cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
cmd.ClientFlag.Register(ctx, f)
f.BoolVar(&cmd.update, "update", false, "Update extension")
}
func (cmd *register) Process(ctx context.Context) error {
if err := cmd.ClientFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *register) Run(ctx context.Context, f *flag.FlagSet) error {
c, err := cmd.Client()
if err != nil {
return err
}
m, err := object.GetExtensionManager(c)
if err != nil {
return err
}
var e types.Extension
e.Description = new(types.Description)
if err = json.NewDecoder(os.Stdin).Decode(&e); err != nil {
return err
}
e.LastHeartbeatTime = time.Now().UTC()
if cmd.update {
return m.Update(ctx, e)
}
return m.Register(ctx, e)
}

View File

@ -0,0 +1,171 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package extension
import (
"bytes"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"flag"
"fmt"
"io/ioutil"
"math/big"
"os"
"time"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/object"
"golang.org/x/net/context"
)
type setcert struct {
*flags.ClientFlag
cert string
org string
encodedCert bytes.Buffer
}
func init() {
cli.Register("extension.setcert", &setcert{})
}
func (cmd *setcert) Register(ctx context.Context, f *flag.FlagSet) {
cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
cmd.ClientFlag.Register(ctx, f)
f.StringVar(&cmd.cert, "cert-pem", "-", "PEM encoded certificate")
f.StringVar(&cmd.org, "org", "VMware", "Organization for generated certificate")
}
func (cmd *setcert) Process(ctx context.Context) error {
if err := cmd.ClientFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *setcert) Usage() string {
return "ID"
}
func (cmd *setcert) Description() string {
return `The '-cert-pem' option can be one of the following:
'-' : Read the certificate from stdin
'+' : Generate a new key pair and save locally to ID.crt and ID.key
... : Any other value is passed as-is to ExtensionManager.SetCertificate
`
}
func (cmd *setcert) create(id string) error {
certFile, err := os.Create(id + ".crt")
if err != nil {
return err
}
defer certFile.Close()
keyFile, err := os.Create(id + ".key")
if err != nil {
return err
}
defer keyFile.Close()
priv, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return err
}
notBefore := time.Now()
notAfter := notBefore.Add(5 * 365 * 24 * time.Hour) // 5 years
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
return err
}
template := x509.Certificate{
SerialNumber: serialNumber,
Subject: pkix.Name{
Organization: []string{cmd.org},
},
NotBefore: notBefore,
NotAfter: notAfter,
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
BasicConstraintsValid: true,
}
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
if err != nil {
return err
}
err = pem.Encode(&cmd.encodedCert, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
if err != nil {
return err
}
_, err = certFile.Write(cmd.encodedCert.Bytes())
if err != nil {
return err
}
err = pem.Encode(keyFile, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)})
if err != nil {
return err
}
return nil
}
func (cmd *setcert) Run(ctx context.Context, f *flag.FlagSet) error {
c, err := cmd.Client()
if err != nil {
return err
}
m, err := object.GetExtensionManager(c)
if err != nil {
return err
}
if f.NArg() != 1 {
return flag.ErrHelp
}
key := f.Arg(0)
if cmd.cert == "-" {
b, err := ioutil.ReadAll(os.Stdin)
if err != nil {
return err
}
cmd.cert = string(b)
} else if cmd.cert == "+" {
if err := cmd.create(key); err != nil {
return fmt.Errorf("creating certificate: %s", err)
}
cmd.cert = cmd.encodedCert.String()
}
return m.SetCertificate(ctx, key, cmd.cert)
}

View File

@ -0,0 +1,66 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package extension
import (
"flag"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/object"
"golang.org/x/net/context"
)
type unregister struct {
*flags.ClientFlag
}
func init() {
cli.Register("extension.unregister", &unregister{})
}
func (cmd *unregister) Register(ctx context.Context, f *flag.FlagSet) {
cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
cmd.ClientFlag.Register(ctx, f)
}
func (cmd *unregister) Process(ctx context.Context) error {
if err := cmd.ClientFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *unregister) Run(ctx context.Context, f *flag.FlagSet) error {
c, err := cmd.Client()
if err != nil {
return err
}
m, err := object.GetExtensionManager(c)
if err != nil {
return err
}
for _, key := range f.Args() {
if err = m.Unregister(ctx, key); err != nil {
return err
}
}
return nil
}

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -34,21 +34,27 @@ func init() {
cli.Register("fields.add", &add{})
}
func (cmd *add) Register(f *flag.FlagSet) {}
func (cmd *add) Register(ctx context.Context, f *flag.FlagSet) {
cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
cmd.ClientFlag.Register(ctx, f)
}
func (cmd *add) Process() error { return nil }
func (cmd *add) Process(ctx context.Context) error {
if err := cmd.ClientFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *add) Usage() string {
return "NAME"
}
func (cmd *add) Run(f *flag.FlagSet) error {
func (cmd *add) Run(ctx context.Context, f *flag.FlagSet) error {
if f.NArg() != 1 {
return flag.ErrHelp
}
ctx := context.TODO()
c, err := cmd.Client()
if err != nil {
return err

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -36,13 +36,19 @@ func init() {
cli.Register("fields.ls", &ls{})
}
func (cmd *ls) Register(f *flag.FlagSet) {}
func (cmd *ls) Register(ctx context.Context, f *flag.FlagSet) {
cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
cmd.ClientFlag.Register(ctx, f)
}
func (cmd *ls) Process() error { return nil }
func (cmd *ls) Run(f *flag.FlagSet) error {
ctx := context.TODO()
func (cmd *ls) Process(ctx context.Context) error {
if err := cmd.ClientFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *ls) Run(ctx context.Context, f *flag.FlagSet) error {
c, err := cmd.Client()
if err != nil {
return err

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -33,21 +33,27 @@ func init() {
cli.Register("fields.rename", &rename{})
}
func (cmd *rename) Register(f *flag.FlagSet) {}
func (cmd *rename) Register(ctx context.Context, f *flag.FlagSet) {
cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
cmd.ClientFlag.Register(ctx, f)
}
func (cmd *rename) Process() error { return nil }
func (cmd *rename) Process(ctx context.Context) error {
if err := cmd.ClientFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *rename) Usage() string {
return "KEY NAME"
}
func (cmd *rename) Run(f *flag.FlagSet) error {
func (cmd *rename) Run(ctx context.Context, f *flag.FlagSet) error {
if f.NArg() != 2 {
return flag.ErrHelp
}
ctx := context.TODO()
c, err := cmd.Client()
if err != nil {
return err

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -33,17 +33,23 @@ func init() {
cli.Register("fields.rm", &rm{})
}
func (cmd *rm) Register(f *flag.FlagSet) {}
func (cmd *rm) Register(ctx context.Context, f *flag.FlagSet) {
cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
cmd.ClientFlag.Register(ctx, f)
}
func (cmd *rm) Process() error { return nil }
func (cmd *rm) Process(ctx context.Context) error {
if err := cmd.ClientFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *rm) Usage() string {
return "KEY..."
}
func (cmd *rm) Run(f *flag.FlagSet) error {
ctx := context.TODO()
func (cmd *rm) Run(ctx context.Context, f *flag.FlagSet) error {
c, err := cmd.Client()
if err != nil {
return err

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -21,7 +21,6 @@ import (
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/list"
"github.com/vmware/govmomi/object"
"golang.org/x/net/context"
)
@ -34,26 +33,27 @@ func init() {
cli.Register("fields.set", &set{})
}
func (cmd *set) Register(f *flag.FlagSet) {}
func (cmd *set) Register(ctx context.Context, f *flag.FlagSet) {
cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx)
cmd.DatacenterFlag.Register(ctx, f)
}
func (cmd *set) Process() error { return nil }
func (cmd *set) Process(ctx context.Context) error {
if err := cmd.DatacenterFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *set) Usage() string {
return "KEY VALUE PATH..."
}
func (cmd *set) Run(f *flag.FlagSet) error {
func (cmd *set) Run(ctx context.Context, f *flag.FlagSet) error {
if f.NArg() < 3 {
return flag.ErrHelp
}
ctx := context.TODO()
finder, err := cmd.Finder()
if err != nil {
return err
}
c, err := cmd.Client()
if err != nil {
return err
@ -64,8 +64,6 @@ func (cmd *set) Run(f *flag.FlagSet) error {
return err
}
var objs []list.Element
args := f.Args()
key, err := m.FindKey(ctx, args[0])
@ -75,17 +73,13 @@ func (cmd *set) Run(f *flag.FlagSet) error {
val := args[1]
for _, arg := range args[2:] {
es, err := finder.ManagedObjectList(ctx, arg)
if err != nil {
return err
}
objs = append(objs, es...)
objs, err := cmd.ManagedObjects(ctx, args[2:])
if err != nil {
return err
}
for _, ref := range objs {
err := m.Set(ctx, ref.Object.Reference(), key, val)
err := m.Set(ctx, ref, key, val)
if err != nil {
return err
}

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -18,6 +18,7 @@ package flags
import (
"crypto/sha1"
"crypto/tls"
"encoding/json"
"errors"
"flag"
@ -25,9 +26,7 @@ import (
"net/url"
"os"
"path/filepath"
"regexp"
"strings"
"sync"
"github.com/vmware/govmomi/session"
"github.com/vmware/govmomi/vim25"
@ -39,6 +38,8 @@ const (
envURL = "GOVC_URL"
envUsername = "GOVC_USERNAME"
envPassword = "GOVC_PASSWORD"
envCertificate = "GOVC_CERTIFICATE"
envPrivateKey = "GOVC_PRIVATE_KEY"
envInsecure = "GOVC_INSECURE"
envPersist = "GOVC_PERSIST_SESSION"
envMinAPIVersion = "GOVC_MIN_API_VERSION"
@ -47,13 +48,15 @@ const (
const cDescr = "ESX or vCenter URL"
type ClientFlag struct {
*DebugFlag
common
register sync.Once
*DebugFlag
url *url.URL
username string
password string
cert string
key string
insecure bool
persist bool
minAPIVersion string
@ -61,6 +64,19 @@ type ClientFlag struct {
client *vim25.Client
}
var clientFlagKey = flagKey("client")
func NewClientFlag(ctx context.Context) (*ClientFlag, context.Context) {
if v := ctx.Value(clientFlagKey); v != nil {
return v.(*ClientFlag), ctx
}
v := &ClientFlag{}
v.DebugFlag, ctx = NewDebugFlag(ctx)
ctx = context.WithValue(ctx, clientFlagKey, v)
return v, ctx
}
func (flag *ClientFlag) URLWithoutPassword() *url.URL {
if flag.url == nil {
return nil
@ -80,37 +96,18 @@ func (flag *ClientFlag) String() string {
return url.String()
}
var schemeMatch = regexp.MustCompile(`^\w+://`)
func (flag *ClientFlag) Set(s string) error {
var err error
if s != "" {
// Default the scheme to https
if !schemeMatch.MatchString(s) {
s = "https://" + s
}
flag.url, err = soap.ParseURL(s)
flag.url, err = url.Parse(s)
if err != nil {
return err
}
// Default the path to /sdk
if flag.url.Path == "" {
flag.url.Path = "/sdk"
}
if flag.url.User == nil {
flag.url.User = url.UserPassword("", "")
}
}
return nil
return err
}
func (flag *ClientFlag) Register(f *flag.FlagSet) {
flag.register.Do(func() {
func (flag *ClientFlag) Register(ctx context.Context, f *flag.FlagSet) {
flag.RegisterOnce(func() {
flag.DebugFlag.Register(ctx, f)
{
flag.Set(os.Getenv(envURL))
usage := fmt.Sprintf("%s [%s]", cDescr, envURL)
@ -122,6 +119,18 @@ func (flag *ClientFlag) Register(f *flag.FlagSet) {
flag.password = os.Getenv(envPassword)
}
{
value := os.Getenv(envCertificate)
usage := fmt.Sprintf("Certificate [%s]", envCertificate)
f.StringVar(&flag.cert, "cert", value, usage)
}
{
value := os.Getenv(envPrivateKey)
usage := fmt.Sprintf("Private key [%s]", envPrivateKey)
f.StringVar(&flag.key, "key", value, usage)
}
{
insecure := false
switch env := strings.ToLower(os.Getenv(envInsecure)); env {
@ -155,39 +164,45 @@ func (flag *ClientFlag) Register(f *flag.FlagSet) {
})
}
func (flag *ClientFlag) Process() error {
if flag.url == nil {
return errors.New("specify an " + cDescr)
}
// Override username if set
if flag.username != "" {
var password string
var ok bool
if flag.url.User != nil {
password, ok = flag.url.User.Password()
func (flag *ClientFlag) Process(ctx context.Context) error {
return flag.ProcessOnce(func() error {
if err := flag.DebugFlag.Process(ctx); err != nil {
return err
}
if ok {
flag.url.User = url.UserPassword(flag.username, password)
} else {
flag.url.User = url.User(flag.username)
}
}
// Override password if set
if flag.password != "" {
var username string
if flag.url.User != nil {
username = flag.url.User.Username()
if flag.url == nil {
return errors.New("specify an " + cDescr)
}
flag.url.User = url.UserPassword(username, flag.password)
}
// Override username if set
if flag.username != "" {
var password string
var ok bool
return nil
if flag.url.User != nil {
password, ok = flag.url.User.Password()
}
if ok {
flag.url.User = url.UserPassword(flag.username, password)
} else {
flag.url.User = url.User(flag.username)
}
}
// Override password if set
if flag.password != "" {
var username string
if flag.url.User != nil {
username = flag.url.User.Username()
}
flag.url.User = url.UserPassword(username, flag.password)
}
return nil
})
}
// Retry twice when a temporary I/O error occurs.
@ -221,11 +236,9 @@ func (flag *ClientFlag) saveClient(c *vim25.Client) error {
if err != nil {
return err
}
defer f.Close()
enc := json.NewEncoder(f)
err = enc.Encode(c)
err = json.NewEncoder(f).Encode(c)
if err != nil {
return err
}
@ -288,6 +301,17 @@ func (flag *ClientFlag) loadClient() (*vim25.Client, error) {
func (flag *ClientFlag) newClient() (*vim25.Client, error) {
sc := soap.NewClient(flag.url, flag.insecure)
isTunnel := false
if flag.cert != "" {
isTunnel = true
cert, err := tls.LoadX509KeyPair(flag.cert, flag.key)
if err != nil {
return nil, err
}
sc.SetCertificate(cert)
}
// Add retry functionality before making any calls
rt := attachRetries(sc)
@ -300,9 +324,17 @@ func (flag *ClientFlag) newClient() (*vim25.Client, error) {
c.Client = sc
m := session.NewManager(c)
err = m.Login(context.TODO(), flag.url.User)
if err != nil {
return nil, err
u := flag.url.User
if isTunnel {
err = m.LoginExtensionByCertificate(context.TODO(), u.Username(), "")
if err != nil {
return nil, err
}
} else {
err = m.Login(context.TODO(), u)
if err != nil {
return nil, err
}
}
err = flag.saveClient(c)
@ -316,7 +348,18 @@ func (flag *ClientFlag) newClient() (*vim25.Client, error) {
// apiVersionValid returns whether or not the API version supported by the
// server the client is connected to is not recent enough.
func apiVersionValid(c *vim25.Client, minVersionString string) error {
realVersion, err := ParseVersion(c.ServiceContent.About.ApiVersion)
if minVersionString == "-" {
// Disable version check
return nil
}
apiVersion := c.ServiceContent.About.ApiVersion
if strings.HasSuffix(apiVersion, ".x") {
// Skip version check for development builds
return nil
}
realVersion, err := ParseVersion(apiVersion)
if err != nil {
return err
}

23
vendor/github.com/vmware/govmomi/govc/flags/common.go generated vendored Normal file
View File

@ -0,0 +1,23 @@
package flags
import "sync"
// Key type for storing flag instances in a context.Context.
type flagKey string
// Type to help flags out with only registering/processing once.
type common struct {
register sync.Once
process sync.Once
}
func (c *common) RegisterOnce(fn func()) {
c.register.Do(fn)
}
func (c *common) ProcessOnce(fn func() error) (err error) {
c.process.Do(func() {
err = fn()
})
return err
}

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -20,26 +20,44 @@ import (
"flag"
"fmt"
"os"
"sync"
"github.com/vmware/govmomi/find"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type DatacenterFlag struct {
common
*ClientFlag
*OutputFlag
register sync.Once
path string
dc *object.Datacenter
finder *find.Finder
err error
path string
dc *object.Datacenter
finder *find.Finder
err error
}
func (flag *DatacenterFlag) Register(f *flag.FlagSet) {
flag.register.Do(func() {
var datacenterFlagKey = flagKey("datacenter")
func NewDatacenterFlag(ctx context.Context) (*DatacenterFlag, context.Context) {
if v := ctx.Value(datacenterFlagKey); v != nil {
return v.(*DatacenterFlag), ctx
}
v := &DatacenterFlag{}
v.ClientFlag, ctx = NewClientFlag(ctx)
v.OutputFlag, ctx = NewOutputFlag(ctx)
ctx = context.WithValue(ctx, datacenterFlagKey, v)
return v, ctx
}
func (flag *DatacenterFlag) Register(ctx context.Context, f *flag.FlagSet) {
flag.RegisterOnce(func() {
flag.ClientFlag.Register(ctx, f)
flag.OutputFlag.Register(ctx, f)
env := "GOVC_DATACENTER"
value := os.Getenv(env)
usage := fmt.Sprintf("Datacenter [%s]", env)
@ -47,7 +65,17 @@ func (flag *DatacenterFlag) Register(f *flag.FlagSet) {
})
}
func (flag *DatacenterFlag) Process() error { return nil }
func (flag *DatacenterFlag) Process(ctx context.Context) error {
return flag.ProcessOnce(func() error {
if err := flag.ClientFlag.Process(ctx); err != nil {
return err
}
if err := flag.OutputFlag.Process(ctx); err != nil {
return err
}
return nil
})
}
func (flag *DatacenterFlag) Finder() (*find.Finder, error) {
if flag.finder != nil {
@ -64,12 +92,8 @@ func (flag *DatacenterFlag) Finder() (*find.Finder, error) {
// Datacenter is not required (ls command for example).
// Set for relative func if dc flag is given or
// if there is a single (default) Datacenter
if flag.path == "" {
flag.dc, flag.err = finder.DefaultDatacenter(context.TODO())
} else {
if flag.dc, err = finder.Datacenter(context.TODO(), flag.path); err != nil {
return nil, err
}
if flag.dc, err = finder.DatacenterOrDefault(context.TODO(), flag.path); err != nil {
return nil, err
}
finder.SetDatacenter(flag.dc)
@ -96,3 +120,35 @@ func (flag *DatacenterFlag) Datacenter() (*object.Datacenter, error) {
return flag.dc, err
}
func (flag *DatacenterFlag) ManagedObjects(ctx context.Context, args []string) ([]types.ManagedObjectReference, error) {
var refs []types.ManagedObjectReference
c, err := flag.Client()
if err != nil {
return nil, err
}
if len(args) == 0 {
refs = append(refs, c.ServiceContent.RootFolder)
return refs, nil
}
finder, err := flag.Finder()
if err != nil {
return nil, err
}
for _, arg := range args {
elements, err := finder.ManagedObjectList(ctx, arg)
if err != nil {
return nil, err
}
for _, e := range elements {
refs = append(refs, e.Object.Reference())
}
}
return refs, nil
}

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -17,34 +17,41 @@ limitations under the License.
package flags
import (
"errors"
"flag"
"fmt"
"net/url"
"os"
"path"
"sync"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
var (
ErrDatastoreDirNotExist = errors.New("datastore directory does not exist")
ErrDatastoreFileNotExist = errors.New("datastore file does not exist")
)
type DatastoreFlag struct {
common
*DatacenterFlag
register sync.Once
name string
ds *object.Datastore
name string
ds *object.Datastore
}
func (flag *DatastoreFlag) Register(f *flag.FlagSet) {
flag.register.Do(func() {
var datastoreFlagKey = flagKey("datastore")
func NewDatastoreFlag(ctx context.Context) (*DatastoreFlag, context.Context) {
if v := ctx.Value(datastoreFlagKey); v != nil {
return v.(*DatastoreFlag), ctx
}
v := &DatastoreFlag{}
v.DatacenterFlag, ctx = NewDatacenterFlag(ctx)
ctx = context.WithValue(ctx, datastoreFlagKey, v)
return v, ctx
}
func (flag *DatastoreFlag) Register(ctx context.Context, f *flag.FlagSet) {
flag.RegisterOnce(func() {
flag.DatacenterFlag.Register(ctx, f)
env := "GOVC_DATASTORE"
value := os.Getenv(env)
usage := fmt.Sprintf("Datastore [%s]", env)
@ -52,7 +59,14 @@ func (flag *DatastoreFlag) Register(f *flag.FlagSet) {
})
}
func (flag *DatastoreFlag) Process() error { return nil }
func (flag *DatastoreFlag) Process(ctx context.Context) error {
return flag.ProcessOnce(func() error {
if err := flag.DatacenterFlag.Process(ctx); err != nil {
return err
}
return nil
})
}
func (flag *DatastoreFlag) Datastore() (*object.Datastore, error) {
if flag.ds != nil {
@ -64,13 +78,11 @@ func (flag *DatastoreFlag) Datastore() (*object.Datastore, error) {
return nil, err
}
if flag.name == "" {
flag.ds, err = finder.DefaultDatastore(context.TODO())
} else {
flag.ds, err = finder.Datastore(context.TODO(), flag.name)
if flag.ds, err = finder.DatastoreOrDefault(context.TODO(), flag.name); err != nil {
return nil, err
}
return flag.ds, err
return flag.ds, nil
}
func (flag *DatastoreFlag) DatastorePath(name string) (string, error) {
@ -100,50 +112,3 @@ func (flag *DatastoreFlag) DatastoreURL(path string) (*url.URL, error) {
return u, nil
}
func (flag *DatastoreFlag) Stat(file string) (types.BaseFileInfo, error) {
ds, err := flag.Datastore()
if err != nil {
return nil, err
}
b, err := ds.Browser(context.TODO())
if err != nil {
return nil, err
}
spec := types.HostDatastoreBrowserSearchSpec{
Details: &types.FileQueryFlags{
FileType: true,
FileOwner: types.NewBool(true), // TODO: omitempty is generated, but seems to be required
},
MatchPattern: []string{path.Base(file)},
}
dsPath := ds.Path(path.Dir(file))
task, err := b.SearchDatastore(context.TODO(), dsPath, &spec)
if err != nil {
return nil, err
}
info, err := task.WaitForResult(context.TODO(), nil)
if err != nil {
if info != nil && info.Error != nil {
_, ok := info.Error.Fault.(*types.FileNotFound)
if ok {
// FileNotFound means the base path doesn't exist.
return nil, ErrDatastoreDirNotExist
}
}
return nil, err
}
res := info.Result.(types.HostDatastoreBrowserSearchResults)
if len(res.File) == 0 {
// File doesn't exist
return nil, ErrDatastoreFileNotExist
}
return res.File[0], nil
}

View File

@ -24,27 +24,49 @@ import (
"strings"
"time"
"golang.org/x/net/context"
"github.com/vmware/govmomi/vim25/debug"
)
type DebugFlag struct {
common
enable bool
}
func (flag *DebugFlag) Register(f *flag.FlagSet) {
env := "GOVC_DEBUG"
enable := false
switch env := strings.ToLower(os.Getenv(env)); env {
case "1", "true":
enable = true
var debugFlagKey = flagKey("debug")
func NewDebugFlag(ctx context.Context) (*DebugFlag, context.Context) {
if v := ctx.Value(debugFlagKey); v != nil {
return v.(*DebugFlag), ctx
}
usage := fmt.Sprintf("Store debug logs [%s]", env)
f.BoolVar(&flag.enable, "debug", enable, usage)
v := &DebugFlag{}
ctx = context.WithValue(ctx, debugFlagKey, v)
return v, ctx
}
func (flag *DebugFlag) Process() error {
if flag.enable {
func (flag *DebugFlag) Register(ctx context.Context, f *flag.FlagSet) {
flag.RegisterOnce(func() {
env := "GOVC_DEBUG"
enable := false
switch env := strings.ToLower(os.Getenv(env)); env {
case "1", "true":
enable = true
}
usage := fmt.Sprintf("Store debug logs [%s]", env)
f.BoolVar(&flag.enable, "debug", enable, usage)
})
}
func (flag *DebugFlag) Process(ctx context.Context) error {
if !flag.enable {
return nil
}
return flag.ProcessOnce(func() error {
// Base path for storing debug logs.
r := os.Getenv("GOVC_DEBUG_PATH")
if r == "" {
@ -66,7 +88,6 @@ func (flag *DebugFlag) Process() error {
}
debug.SetProvider(&p)
}
return nil
return nil
})
}

View File

@ -16,10 +16,17 @@ limitations under the License.
package flags
import "flag"
import (
"flag"
"golang.org/x/net/context"
)
type EmptyFlag struct{}
func (flag *EmptyFlag) Register(f *flag.FlagSet) {}
func (flag *EmptyFlag) Register(ctx context.Context, f *flag.FlagSet) {
}
func (flag *EmptyFlag) Process() error { return nil }
func (flag *EmptyFlag) Process(ctx context.Context) error {
return nil
}

View File

@ -0,0 +1,79 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package flags
import (
"flag"
"fmt"
"golang.org/x/net/context"
"github.com/vmware/govmomi/vim25/types"
)
type HostConnectFlag struct {
common
types.HostConnectSpec
noverify bool
}
var hostConnectFlagKey = flagKey("hostConnect")
func NewHostConnectFlag(ctx context.Context) (*HostConnectFlag, context.Context) {
if v := ctx.Value(hostConnectFlagKey); v != nil {
return v.(*HostConnectFlag), ctx
}
v := &HostConnectFlag{}
ctx = context.WithValue(ctx, hostConnectFlagKey, v)
return v, ctx
}
func (flag *HostConnectFlag) Register(ctx context.Context, f *flag.FlagSet) {
flag.RegisterOnce(func() {
f.StringVar(&flag.HostName, "hostname", "", "Hostname or IP address of the host")
f.StringVar(&flag.UserName, "username", "", "Username of administration account on the host")
f.StringVar(&flag.Password, "password", "", "Password of administration account on the host")
f.StringVar(&flag.SslThumbprint, "fingerprint", "", "Fingerprint of the host's SSL certificate")
f.BoolVar(&flag.Force, "force", false, "Force when host is managed by another VC")
f.BoolVar(&flag.noverify, "noverify", false, "When true, ignore host SSL certificate verification error")
})
}
func (flag *HostConnectFlag) Process(ctx context.Context) error {
return nil
}
// AcceptThumbprint returns nil if the given error is an SSLVerifyFault and -noverify is true.
// In which case, flag.SslThumbprint is set to fault.Thumbprint and the caller should retry the task.
func (flag *HostConnectFlag) AcceptThumbprint(err error) error {
if f, ok := err.(types.HasFault); ok {
switch fault := f.Fault().(type) {
case *types.SSLVerifyFault:
if flag.noverify {
flag.SslThumbprint = fault.Thumbprint
return nil
}
return fmt.Errorf("%s Fingerprint is %s", err, fault.Thumbprint)
}
}
return err
}

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -20,27 +20,44 @@ import (
"flag"
"fmt"
"os"
"sync"
"github.com/vmware/govmomi/object"
"golang.org/x/net/context"
)
type HostSystemFlag struct {
common
*ClientFlag
*DatacenterFlag
*SearchFlag
register sync.Once
name string
host *object.HostSystem
pool *object.ResourcePool
name string
host *object.HostSystem
pool *object.ResourcePool
}
func (flag *HostSystemFlag) Register(f *flag.FlagSet) {
flag.SearchFlag = NewSearchFlag(SearchHosts)
var hostSystemFlagKey = flagKey("hostSystem")
func NewHostSystemFlag(ctx context.Context) (*HostSystemFlag, context.Context) {
if v := ctx.Value(hostSystemFlagKey); v != nil {
return v.(*HostSystemFlag), ctx
}
v := &HostSystemFlag{}
v.ClientFlag, ctx = NewClientFlag(ctx)
v.DatacenterFlag, ctx = NewDatacenterFlag(ctx)
v.SearchFlag, ctx = NewSearchFlag(ctx, SearchHosts)
ctx = context.WithValue(ctx, hostSystemFlagKey, v)
return v, ctx
}
func (flag *HostSystemFlag) Register(ctx context.Context, f *flag.FlagSet) {
flag.RegisterOnce(func() {
flag.ClientFlag.Register(ctx, f)
flag.DatacenterFlag.Register(ctx, f)
flag.SearchFlag.Register(ctx, f)
flag.register.Do(func() {
env := "GOVC_HOST"
value := os.Getenv(env)
usage := fmt.Sprintf("Host system [%s]", env)
@ -48,7 +65,20 @@ func (flag *HostSystemFlag) Register(f *flag.FlagSet) {
})
}
func (flag *HostSystemFlag) Process() error { return nil }
func (flag *HostSystemFlag) Process(ctx context.Context) error {
return flag.ProcessOnce(func() error {
if err := flag.ClientFlag.Process(ctx); err != nil {
return err
}
if err := flag.DatacenterFlag.Process(ctx); err != nil {
return err
}
if err := flag.SearchFlag.Process(ctx); err != nil {
return err
}
return nil
})
}
func (flag *HostSystemFlag) HostSystemIfSpecified() (*object.HostSystem, error) {
if flag.host != nil {

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -20,7 +20,6 @@ import (
"flag"
"fmt"
"os"
"sync"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/types"
@ -28,21 +27,33 @@ import (
)
type NetworkFlag struct {
common
*DatacenterFlag
register sync.Once
name string
net object.NetworkReference
adapter string
address string
name string
net object.NetworkReference
adapter string
address string
}
func NewNetworkFlag() *NetworkFlag {
return &NetworkFlag{}
var networkFlagKey = flagKey("network")
func NewNetworkFlag(ctx context.Context) (*NetworkFlag, context.Context) {
if v := ctx.Value(networkFlagKey); v != nil {
return v.(*NetworkFlag), ctx
}
v := &NetworkFlag{}
v.DatacenterFlag, ctx = NewDatacenterFlag(ctx)
ctx = context.WithValue(ctx, networkFlagKey, v)
return v, ctx
}
func (flag *NetworkFlag) Register(f *flag.FlagSet) {
flag.register.Do(func() {
func (flag *NetworkFlag) Register(ctx context.Context, f *flag.FlagSet) {
flag.RegisterOnce(func() {
flag.DatacenterFlag.Register(ctx, f)
env := "GOVC_NETWORK"
value := os.Getenv(env)
flag.Set(value)
@ -53,7 +64,14 @@ func (flag *NetworkFlag) Register(f *flag.FlagSet) {
})
}
func (flag *NetworkFlag) Process() error { return nil }
func (flag *NetworkFlag) Process(ctx context.Context) error {
return flag.ProcessOnce(func() error {
if err := flag.DatacenterFlag.Process(ctx); err != nil {
return err
}
return nil
})
}
func (flag *NetworkFlag) String() string {
return flag.name
@ -74,13 +92,11 @@ func (flag *NetworkFlag) Network() (object.NetworkReference, error) {
return nil, err
}
if flag.name == "" {
flag.net, err = finder.DefaultNetwork(context.TODO())
} else {
flag.net, err = finder.Network(context.TODO(), flag.name)
if flag.net, err = finder.NetworkOrDefault(context.TODO(), flag.name); err != nil {
return nil, err
}
return flag.net, err
return flag.net, nil
}
func (flag *NetworkFlag) Device() (types.BaseVirtualDevice, error) {

View File

@ -0,0 +1,55 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package flags
import (
"flag"
"fmt"
"strconv"
)
type optionalBool struct {
val **bool
}
func (b *optionalBool) Set(s string) error {
v, err := strconv.ParseBool(s)
*b.val = &v
return err
}
func (b *optionalBool) Get() interface{} {
if *b.val == nil {
return nil
}
return **b.val
}
func (b *optionalBool) String() string {
if *b.val == nil {
return "<nil>"
}
return fmt.Sprintf("%v", **b.val)
}
func (b *optionalBool) IsBoolFlag() bool { return true }
// NewOptionalBool returns a flag.Value implementation where there is no default value.
// This avoids sending a default value over the wire as using flag.BoolVar() would.
func NewOptionalBool(v **bool) flag.Value {
return &optionalBool{v}
}

View File

@ -25,6 +25,8 @@ import (
"sync"
"time"
"golang.org/x/net/context"
"github.com/vmware/govmomi/vim25/progress"
)
@ -33,21 +35,39 @@ type OutputWriter interface {
}
type OutputFlag struct {
common
JSON bool
TTY bool
}
func (flag *OutputFlag) Register(f *flag.FlagSet) {
f.BoolVar(&flag.JSON, "json", false, "Enable JSON output")
}
var outputFlagKey = flagKey("output")
func (flag *OutputFlag) Process() error {
if !flag.JSON {
// Assume we have a tty if not outputting JSON
flag.TTY = true
func NewOutputFlag(ctx context.Context) (*OutputFlag, context.Context) {
if v := ctx.Value(outputFlagKey); v != nil {
return v.(*OutputFlag), ctx
}
return nil
v := &OutputFlag{}
ctx = context.WithValue(ctx, outputFlagKey, v)
return v, ctx
}
func (flag *OutputFlag) Register(ctx context.Context, f *flag.FlagSet) {
flag.RegisterOnce(func() {
f.BoolVar(&flag.JSON, "json", false, "Enable JSON output")
})
}
func (flag *OutputFlag) Process(ctx context.Context) error {
return flag.ProcessOnce(func() error {
if !flag.JSON {
// Assume we have a tty if not outputting JSON
flag.TTY = true
}
return nil
})
}
// Log outputs the specified string, prefixed with the current time.
@ -81,8 +101,7 @@ func (flag *OutputFlag) WriteResult(result OutputWriter) error {
var out = os.Stdout
if flag.JSON {
enc := json.NewEncoder(out)
err = enc.Encode(result)
err = json.NewEncoder(out).Encode(result)
} else {
err = result.Write(out)
}

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -20,22 +20,37 @@ import (
"flag"
"fmt"
"os"
"sync"
"github.com/vmware/govmomi/object"
"golang.org/x/net/context"
)
type ResourcePoolFlag struct {
common
*DatacenterFlag
register sync.Once
name string
pool *object.ResourcePool
name string
pool *object.ResourcePool
}
func (flag *ResourcePoolFlag) Register(f *flag.FlagSet) {
flag.register.Do(func() {
var resourcePoolFlagKey = flagKey("resourcePool")
func NewResourcePoolFlag(ctx context.Context) (*ResourcePoolFlag, context.Context) {
if v := ctx.Value(resourcePoolFlagKey); v != nil {
return v.(*ResourcePoolFlag), ctx
}
v := &ResourcePoolFlag{}
v.DatacenterFlag, ctx = NewDatacenterFlag(ctx)
ctx = context.WithValue(ctx, resourcePoolFlagKey, v)
return v, ctx
}
func (flag *ResourcePoolFlag) Register(ctx context.Context, f *flag.FlagSet) {
flag.RegisterOnce(func() {
flag.DatacenterFlag.Register(ctx, f)
env := "GOVC_RESOURCE_POOL"
value := os.Getenv(env)
usage := fmt.Sprintf("Resource pool [%s]", env)
@ -43,7 +58,14 @@ func (flag *ResourcePoolFlag) Register(f *flag.FlagSet) {
})
}
func (flag *ResourcePoolFlag) Process() error { return nil }
func (flag *ResourcePoolFlag) Process(ctx context.Context) error {
return flag.ProcessOnce(func() error {
if err := flag.DatacenterFlag.Process(ctx); err != nil {
return err
}
return nil
})
}
func (flag *ResourcePoolFlag) ResourcePool() (*object.ResourcePool, error) {
if flag.pool != nil {
@ -55,11 +77,9 @@ func (flag *ResourcePoolFlag) ResourcePool() (*object.ResourcePool, error) {
return nil, err
}
if flag.name == "" {
flag.pool, err = finder.DefaultResourcePool(context.TODO())
} else {
flag.pool, err = finder.ResourcePool(context.TODO(), flag.name)
if flag.pool, err = finder.ResourcePoolOrDefault(context.TODO(), flag.name); err != nil {
return nil, err
}
return flag.pool, err
return flag.pool, nil
}

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -22,6 +22,7 @@ import (
"fmt"
"strings"
"github.com/vmware/govmomi/find"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25"
"golang.org/x/net/context"
@ -30,9 +31,12 @@ import (
const (
SearchVirtualMachines = iota + 1
SearchHosts
SearchVirtualApps
)
type SearchFlag struct {
common
*ClientFlag
*DatacenterFlag
@ -48,65 +52,91 @@ type SearchFlag struct {
isset bool
}
func NewSearchFlag(t int) *SearchFlag {
s := SearchFlag{
var searchFlagKey = flagKey("search")
func NewSearchFlag(ctx context.Context, t int) (*SearchFlag, context.Context) {
if v := ctx.Value(searchFlagKey); v != nil {
return v.(*SearchFlag), ctx
}
v := &SearchFlag{
t: t,
}
v.ClientFlag, ctx = NewClientFlag(ctx)
v.DatacenterFlag, ctx = NewDatacenterFlag(ctx)
switch t {
case SearchVirtualMachines:
s.entity = "VM"
v.entity = "VM"
case SearchHosts:
s.entity = "host"
v.entity = "host"
case SearchVirtualApps:
v.entity = "vapp"
default:
panic("invalid search type")
}
return &s
ctx = context.WithValue(ctx, searchFlagKey, v)
return v, ctx
}
func (flag *SearchFlag) Register(fs *flag.FlagSet) {
register := func(v *string, f string, d string) {
f = fmt.Sprintf("%s.%s", strings.ToLower(flag.entity), f)
d = fmt.Sprintf(d, flag.entity)
fs.StringVar(v, f, "", d)
}
func (flag *SearchFlag) Register(ctx context.Context, fs *flag.FlagSet) {
flag.RegisterOnce(func() {
flag.ClientFlag.Register(ctx, fs)
flag.DatacenterFlag.Register(ctx, fs)
switch flag.t {
case SearchVirtualMachines:
register(&flag.byDatastorePath, "path", "Find %s by path to .vmx file")
}
switch flag.t {
case SearchVirtualMachines, SearchHosts:
register(&flag.byDNSName, "dns", "Find %s by FQDN")
register(&flag.byIP, "ip", "Find %s by IP address")
register(&flag.byUUID, "uuid", "Find %s by instance UUID")
}
register(&flag.byInventoryPath, "ipath", "Find %s by inventory path")
}
func (flag *SearchFlag) Process() error {
flags := []string{
flag.byDatastorePath,
flag.byDNSName,
flag.byInventoryPath,
flag.byIP,
flag.byUUID,
}
flag.isset = false
for _, f := range flags {
if f != "" {
if flag.isset {
return errors.New("cannot use more than one search flag")
}
flag.isset = true
register := func(v *string, f string, d string) {
f = fmt.Sprintf("%s.%s", strings.ToLower(flag.entity), f)
d = fmt.Sprintf(d, flag.entity)
fs.StringVar(v, f, "", d)
}
}
return nil
switch flag.t {
case SearchVirtualMachines:
register(&flag.byDatastorePath, "path", "Find %s by path to .vmx file")
}
switch flag.t {
case SearchVirtualMachines, SearchHosts:
register(&flag.byDNSName, "dns", "Find %s by FQDN")
register(&flag.byIP, "ip", "Find %s by IP address")
register(&flag.byUUID, "uuid", "Find %s by instance UUID")
}
register(&flag.byInventoryPath, "ipath", "Find %s by inventory path")
})
}
func (flag *SearchFlag) Process(ctx context.Context) error {
return flag.ProcessOnce(func() error {
if err := flag.ClientFlag.Process(ctx); err != nil {
return err
}
if err := flag.DatacenterFlag.Process(ctx); err != nil {
return err
}
flags := []string{
flag.byDatastorePath,
flag.byDNSName,
flag.byInventoryPath,
flag.byIP,
flag.byUUID,
}
flag.isset = false
for _, f := range flags {
if f != "" {
if flag.isset {
return errors.New("cannot use more than one search flag")
}
flag.isset = true
}
}
return nil
})
}
func (flag *SearchFlag) IsSet() bool {
@ -156,9 +186,9 @@ func (flag *SearchFlag) searchByIP(c *vim25.Client, dc *object.Datacenter) (obje
func (flag *SearchFlag) searchByUUID(c *vim25.Client, dc *object.Datacenter) (object.Reference, error) {
switch flag.t {
case SearchVirtualMachines:
return flag.searchIndex(c).FindByUuid(context.TODO(), dc, flag.byUUID, true)
return flag.searchIndex(c).FindByUuid(context.TODO(), dc, flag.byUUID, true, nil)
case SearchHosts:
return flag.searchIndex(c).FindByUuid(context.TODO(), dc, flag.byUUID, false)
return flag.searchIndex(c).FindByUuid(context.TODO(), dc, flag.byUUID, false, nil)
default:
panic("unsupported type")
}
@ -241,16 +271,73 @@ func (flag *SearchFlag) VirtualMachines(args []string) ([]*object.VirtualMachine
return nil, err
}
var nfe error
// List virtual machines for every argument
for _, arg := range args {
vms, err := finder.VirtualMachineList(context.TODO(), arg)
if err != nil {
if _, ok := err.(*find.NotFoundError); ok {
// Let caller decide how to handle NotFoundError
nfe = err
continue
}
return nil, err
}
out = append(out, vms...)
}
return out, nfe
}
func (flag *SearchFlag) VirtualApp() (*object.VirtualApp, error) {
ref, err := flag.search()
if err != nil {
return nil, err
}
app, ok := ref.(*object.VirtualApp)
if !ok {
return nil, fmt.Errorf("expected VirtualApp entity, got %s", ref.Reference().Type)
}
return app, nil
}
func (flag *SearchFlag) VirtualApps(args []string) ([]*object.VirtualApp, error) {
var out []*object.VirtualApp
if flag.IsSet() {
app, err := flag.VirtualApp()
if err != nil {
return nil, err
}
out = append(out, app)
return out, nil
}
// List virtual apps
if len(args) == 0 {
return nil, errors.New("no argument")
}
finder, err := flag.Finder()
if err != nil {
return nil, err
}
// List virtual apps for every argument
for _, arg := range args {
apps, err := finder.VirtualAppList(context.TODO(), arg)
if err != nil {
return nil, err
}
out = append(out, apps...)
}
return out, nil
}

View File

@ -0,0 +1,104 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package flags
import (
"flag"
"fmt"
"os"
"github.com/vmware/govmomi/object"
"golang.org/x/net/context"
)
type VirtualAppFlag struct {
common
*DatacenterFlag
*SearchFlag
name string
app *object.VirtualApp
}
var virtualAppFlagKey = flagKey("virtualApp")
func NewVirtualAppFlag(ctx context.Context) (*VirtualAppFlag, context.Context) {
if v := ctx.Value(virtualAppFlagKey); v != nil {
return v.(*VirtualAppFlag), ctx
}
v := &VirtualAppFlag{}
v.DatacenterFlag, ctx = NewDatacenterFlag(ctx)
v.SearchFlag, ctx = NewSearchFlag(ctx, SearchVirtualApps)
ctx = context.WithValue(ctx, virtualAppFlagKey, v)
return v, ctx
}
func (flag *VirtualAppFlag) Register(ctx context.Context, f *flag.FlagSet) {
flag.RegisterOnce(func() {
flag.DatacenterFlag.Register(ctx, f)
flag.SearchFlag.Register(ctx, f)
env := "GOVC_VAPP"
value := os.Getenv(env)
usage := fmt.Sprintf("Virtual App [%s]", env)
f.StringVar(&flag.name, "vapp", value, usage)
})
}
func (flag *VirtualAppFlag) Process(ctx context.Context) error {
return flag.ProcessOnce(func() error {
if err := flag.DatacenterFlag.Process(ctx); err != nil {
return err
}
if err := flag.SearchFlag.Process(ctx); err != nil {
return err
}
return nil
})
}
func (flag *VirtualAppFlag) VirtualApp() (*object.VirtualApp, error) {
if flag.app != nil {
return flag.app, nil
}
// Use search flags if specified.
if flag.SearchFlag.IsSet() {
app, err := flag.SearchFlag.VirtualApp()
if err != nil {
return nil, err
}
flag.app = app
return flag.app, nil
}
// Never look for a default virtual app.
if flag.name == "" {
return nil, nil
}
finder, err := flag.Finder()
if err != nil {
return nil, err
}
flag.app, err = finder.VirtualApp(context.TODO(), flag.name)
return flag.app, err
}

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -20,26 +20,43 @@ import (
"flag"
"fmt"
"os"
"sync"
"github.com/vmware/govmomi/object"
"golang.org/x/net/context"
)
type VirtualMachineFlag struct {
common
*ClientFlag
*DatacenterFlag
*SearchFlag
register sync.Once
name string
vm *object.VirtualMachine
name string
vm *object.VirtualMachine
}
func (flag *VirtualMachineFlag) Register(f *flag.FlagSet) {
flag.SearchFlag = NewSearchFlag(SearchVirtualMachines)
var virtualMachineFlagKey = flagKey("virtualMachine")
func NewVirtualMachineFlag(ctx context.Context) (*VirtualMachineFlag, context.Context) {
if v := ctx.Value(virtualMachineFlagKey); v != nil {
return v.(*VirtualMachineFlag), ctx
}
v := &VirtualMachineFlag{}
v.ClientFlag, ctx = NewClientFlag(ctx)
v.DatacenterFlag, ctx = NewDatacenterFlag(ctx)
v.SearchFlag, ctx = NewSearchFlag(ctx, SearchVirtualMachines)
ctx = context.WithValue(ctx, virtualMachineFlagKey, v)
return v, ctx
}
func (flag *VirtualMachineFlag) Register(ctx context.Context, f *flag.FlagSet) {
flag.RegisterOnce(func() {
flag.ClientFlag.Register(ctx, f)
flag.DatacenterFlag.Register(ctx, f)
flag.SearchFlag.Register(ctx, f)
flag.register.Do(func() {
env := "GOVC_VM"
value := os.Getenv(env)
usage := fmt.Sprintf("Virtual machine [%s]", env)
@ -47,7 +64,20 @@ func (flag *VirtualMachineFlag) Register(f *flag.FlagSet) {
})
}
func (flag *VirtualMachineFlag) Process() error { return nil }
func (flag *VirtualMachineFlag) Process(ctx context.Context) error {
return flag.ProcessOnce(func() error {
if err := flag.ClientFlag.Process(ctx); err != nil {
return err
}
if err := flag.DatacenterFlag.Process(ctx); err != nil {
return err
}
if err := flag.SearchFlag.Process(ctx); err != nil {
return err
}
return nil
})
}
func (flag *VirtualMachineFlag) VirtualMachine() (*object.VirtualMachine, error) {
if flag.vm != nil {

View File

@ -1,6 +1,7 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
@ -17,7 +18,6 @@ limitations under the License.
package host
import (
"errors"
"flag"
"fmt"
@ -32,63 +32,88 @@ import (
type add struct {
*flags.ClientFlag
*flags.DatacenterFlag
*flags.HostConnectFlag
parent string
host string
username string
password string
connect bool
fingerprint string
parent string
connect bool
}
func init() {
cli.Register("host.add", &add{})
}
func (cmd *add) Register(f *flag.FlagSet) {
f.StringVar(&cmd.parent, "parent", "", "Path to folder to add the host to")
func (cmd *add) Register(ctx context.Context, f *flag.FlagSet) {
cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
cmd.ClientFlag.Register(ctx, f)
f.StringVar(&cmd.host, "host", "", "Hostname or IP address of the host")
f.StringVar(&cmd.username, "username", "", "Username of administration account on the host")
f.StringVar(&cmd.password, "password", "", "Password of administration account on the host")
cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx)
cmd.DatacenterFlag.Register(ctx, f)
cmd.HostConnectFlag, ctx = flags.NewHostConnectFlag(ctx)
cmd.HostConnectFlag.Register(ctx, f)
f.StringVar(&cmd.parent, "parent", "", "Path to folder to add the host to")
f.BoolVar(&cmd.connect, "connect", true, "Immediately connect to host")
f.StringVar(&cmd.fingerprint, "fingerprint", "", "Fingerprint of the host's SSL certificate")
}
func (cmd *add) Process() error {
if cmd.host == "" {
func (cmd *add) Process(ctx context.Context) error {
if err := cmd.ClientFlag.Process(ctx); err != nil {
return err
}
if err := cmd.DatacenterFlag.Process(ctx); err != nil {
return err
}
if err := cmd.HostConnectFlag.Process(ctx); err != nil {
return err
}
if cmd.HostName == "" {
return flag.ErrHelp
}
if cmd.username == "" {
if cmd.UserName == "" {
return flag.ErrHelp
}
if cmd.password == "" {
if cmd.Password == "" {
return flag.ErrHelp
}
return nil
}
func (cmd *add) Usage() string {
return "HOST"
}
func (cmd *add) Description() string {
return `Add HOST to datacenter.
return `Add host to datacenter.
The host is added to the folder specified by the 'parent' flag. If not given,
this defaults to the hosts folder in the specified or default datacenter.`
}
func (cmd *add) Run(f *flag.FlagSet) error {
var ctx = context.Background()
var parent *object.Folder
func (cmd *add) Add(ctx context.Context, parent *object.Folder) error {
spec := cmd.HostConnectSpec
client, err := cmd.Client()
req := types.AddStandaloneHost_Task{
This: parent.Reference(),
Spec: spec,
AddConnected: cmd.connect,
}
res, err := methods.AddStandaloneHost_Task(ctx, parent.Client(), &req)
if err != nil {
return err
}
logger := cmd.ProgressLogger(fmt.Sprintf("adding %s to folder %s... ", spec.HostName, parent.InventoryPath))
defer logger.Wait()
task := object.NewTask(parent.Client(), res.Returnval)
_, err = task.WaitForResult(ctx, logger)
return err
}
func (cmd *add) Run(ctx context.Context, f *flag.FlagSet) error {
var parent *object.Folder
if f.NArg() != 0 {
return flag.ErrHelp
}
if cmd.parent == "" {
dc, err := cmd.Datacenter()
if err != nil {
@ -107,59 +132,22 @@ func (cmd *add) Run(f *flag.FlagSet) error {
return err
}
mo, err := finder.ManagedObjectList(ctx, cmd.parent)
parent, err = finder.Folder(ctx, cmd.parent)
if err != nil {
return err
}
if len(mo) == 0 {
return errors.New("parent does not resolve to object")
}
if len(mo) > 1 {
return errors.New("parent resolves to more than one object")
}
ref := mo[0].Object.Reference()
if ref.Type != "Folder" {
return errors.New("parent does not resolve to folder")
}
parent = object.NewFolder(client, ref)
}
req := types.AddStandaloneHost_Task{
This: parent.Reference(),
Spec: types.HostConnectSpec{
HostName: cmd.host,
UserName: cmd.username,
Password: cmd.password,
SslThumbprint: cmd.fingerprint,
},
AddConnected: cmd.connect,
err := cmd.Add(ctx, parent)
if err == nil {
return nil
}
res, err := methods.AddStandaloneHost_Task(ctx, client, &req)
if err != nil {
// Check if we failed due to SSLVerifyFault and -noverify is set
if err := cmd.AcceptThumbprint(err); err != nil {
return err
}
task := object.NewTask(client, res.Returnval)
_, err = task.WaitForResult(ctx, nil)
if err != nil {
f, ok := err.(types.HasFault)
if !ok {
return err
}
switch fault := f.Fault().(type) {
case *types.SSLVerifyFault:
// Add fingerprint to error message
return fmt.Errorf("%s Fingerprint is %s.", err.Error(), fault.Thumbprint)
default:
return err
}
}
return nil
// Accepted unverified thumbprint, try again
return cmd.Add(ctx, parent)
}

View File

@ -19,6 +19,8 @@ package autostart
import (
"flag"
"golang.org/x/net/context"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/vim25/types"
)
@ -31,15 +33,23 @@ func init() {
cli.Register("host.autostart.add", &add{})
}
func (cmd *add) Register(f *flag.FlagSet) {}
func (cmd *add) Register(ctx context.Context, f *flag.FlagSet) {
cmd.AutostartFlag, ctx = newAutostartFlag(ctx)
cmd.AutostartFlag.Register(ctx, f)
}
func (cmd *add) Process() error { return nil }
func (cmd *add) Process(ctx context.Context) error {
if err := cmd.AutostartFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *add) Usage() string {
return "VM..."
}
func (cmd *add) Run(f *flag.FlagSet) error {
func (cmd *add) Run(ctx context.Context, f *flag.FlagSet) error {
var powerInfo = types.AutoStartPowerInfo{
StartAction: "powerOn",
StartDelay: -1,

View File

@ -34,9 +34,32 @@ type AutostartFlag struct {
*flags.HostSystemFlag
}
func (f *AutostartFlag) Register(fs *flag.FlagSet) {}
func newAutostartFlag(ctx context.Context) (*AutostartFlag, context.Context) {
f := &AutostartFlag{}
f.ClientFlag, ctx = flags.NewClientFlag(ctx)
f.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx)
f.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
return f, ctx
}
func (f *AutostartFlag) Process() error { return nil }
func (f *AutostartFlag) Register(ctx context.Context, fs *flag.FlagSet) {
f.ClientFlag.Register(ctx, fs)
f.DatacenterFlag.Register(ctx, fs)
f.HostSystemFlag.Register(ctx, fs)
}
func (f *AutostartFlag) Process(ctx context.Context) error {
if err := f.ClientFlag.Process(ctx); err != nil {
return err
}
if err := f.DatacenterFlag.Process(ctx); err != nil {
return err
}
if err := f.HostSystemFlag.Process(ctx); err != nil {
return err
}
return nil
}
// VirtualMachines returns list of virtual machine objects based on the
// arguments specified on the command line. This helper is defined in

View File

@ -19,41 +19,45 @@ package autostart
import (
"flag"
"golang.org/x/net/context"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/vim25/types"
)
type configure struct {
*AutostartFlag
defaults types.AutoStartDefaults
types.AutoStartDefaults
}
func init() {
cli.Register("host.autostart.configure", &configure{})
}
func (cmd *configure) Register(f *flag.FlagSet) {
cmd.defaults.Enabled = types.NewBool(false)
f.BoolVar(cmd.defaults.Enabled, "enabled", false, "")
func (cmd *configure) Register(ctx context.Context, f *flag.FlagSet) {
cmd.AutostartFlag, ctx = newAutostartFlag(ctx)
cmd.AutostartFlag.Register(ctx, f)
f.IntVar(&cmd.defaults.StartDelay, "start-delay", 0, "")
f.StringVar(&cmd.defaults.StopAction, "stop-action", "", "")
f.IntVar(&cmd.defaults.StopDelay, "stop-delay", 0, "")
cmd.defaults.WaitForHeartbeat = types.NewBool(false)
f.BoolVar(cmd.defaults.WaitForHeartbeat, "wait-for-heartbeat", false, "")
f.Var(flags.NewOptionalBool(&cmd.Enabled), "enabled", "")
f.IntVar(&cmd.StartDelay, "start-delay", 0, "")
f.StringVar(&cmd.StopAction, "stop-action", "", "")
f.IntVar(&cmd.StopDelay, "stop-delay", 0, "")
f.Var(flags.NewOptionalBool(&cmd.WaitForHeartbeat), "wait-for-heartbeat", "")
}
func (cmd *configure) Process() error { return nil }
func (cmd *configure) Process(ctx context.Context) error {
if err := cmd.AutostartFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *configure) Usage() string {
return ""
}
func (cmd *configure) Run(f *flag.FlagSet) error {
// Note: this command cannot DISABLE autostart because the "Enabled" field is
// marked "omitempty", which means that it is not included when it is false.
// Also see: https://github.com/vmware/govmomi/issues/240
return cmd.ReconfigureDefaults(cmd.defaults)
func (cmd *configure) Run(ctx context.Context, f *flag.FlagSet) error {
return cmd.ReconfigureDefaults(cmd.AutoStartDefaults)
}

View File

@ -32,8 +32,9 @@ import (
)
type info struct {
*AutostartFlag
cli.Command
*AutostartFlag
*flags.OutputFlag
}
@ -41,15 +42,28 @@ func init() {
cli.Register("host.autostart.info", &info{})
}
func (cmd *info) Register(f *flag.FlagSet) {}
func (cmd *info) Register(ctx context.Context, f *flag.FlagSet) {
cmd.AutostartFlag, ctx = newAutostartFlag(ctx)
cmd.AutostartFlag.Register(ctx, f)
cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
cmd.OutputFlag.Register(ctx, f)
}
func (cmd *info) Process() error { return nil }
func (cmd *info) Process(ctx context.Context) error {
if err := cmd.AutostartFlag.Process(ctx); err != nil {
return err
}
if err := cmd.OutputFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *info) Usage() string {
return ""
}
func (cmd *info) Run(f *flag.FlagSet) error {
func (cmd *info) Run(ctx context.Context, f *flag.FlagSet) error {
client, err := cmd.Client()
if err != nil {
return err

View File

@ -19,6 +19,8 @@ package autostart
import (
"flag"
"golang.org/x/net/context"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/vim25/types"
)
@ -31,15 +33,23 @@ func init() {
cli.Register("host.autostart.remove", &remove{})
}
func (cmd *remove) Register(f *flag.FlagSet) {}
func (cmd *remove) Register(ctx context.Context, f *flag.FlagSet) {
cmd.AutostartFlag, ctx = newAutostartFlag(ctx)
cmd.AutostartFlag.Register(ctx, f)
}
func (cmd *remove) Process() error { return nil }
func (cmd *remove) Process(ctx context.Context) error {
if err := cmd.AutostartFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *remove) Usage() string {
return "VM..."
}
func (cmd *remove) Run(f *flag.FlagSet) error {
func (cmd *remove) Run(ctx context.Context, f *flag.FlagSet) error {
var powerInfo = types.AutoStartPowerInfo{
StartAction: "none",
StartDelay: -1,

View File

@ -0,0 +1,81 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package host
import (
"flag"
"fmt"
"golang.org/x/net/context"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/object"
)
type disconnect struct {
*flags.HostSystemFlag
}
func init() {
cli.Register("host.disconnect", &disconnect{})
}
func (cmd *disconnect) Register(ctx context.Context, f *flag.FlagSet) {
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
cmd.HostSystemFlag.Register(ctx, f)
}
func (cmd *disconnect) Process(ctx context.Context) error {
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *disconnect) Description() string {
return `Disconnect host from vCenter and instruct the host to stop sending heartbeats.`
}
func (cmd *disconnect) Disconnect(ctx context.Context, host *object.HostSystem) error {
task, err := host.Disconnect(ctx)
if err != nil {
return err
}
logger := cmd.ProgressLogger(fmt.Sprintf("%s disconnecting... ", host.InventoryPath))
defer logger.Wait()
_, err = task.WaitForResult(ctx, logger)
return err
}
func (cmd *disconnect) Run(ctx context.Context, f *flag.FlagSet) error {
hosts, err := cmd.HostSystems(f.Args())
if err != nil {
return err
}
for _, host := range hosts {
err = cmd.Disconnect(ctx, host)
if err != nil {
return err
}
}
return nil
}

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -24,6 +24,8 @@ import (
"strings"
"text/tabwriter"
"golang.org/x/net/context"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
)
@ -42,13 +44,21 @@ func (cmd *esxcli) Usage() string {
return "COMMAND [ARG]..."
}
func (cmd *esxcli) Register(f *flag.FlagSet) {
func (cmd *esxcli) Register(ctx context.Context, f *flag.FlagSet) {
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
cmd.HostSystemFlag.Register(ctx, f)
f.BoolVar(&cmd.hints, "hints", true, "Use command info hints when formatting output")
}
func (cmd *esxcli) Process() error { return nil }
func (cmd *esxcli) Process(ctx context.Context) error {
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *esxcli) Run(f *flag.FlagSet) error {
func (cmd *esxcli) Run(ctx context.Context, f *flag.FlagSet) error {
c, err := cmd.Client()
if err != nil {
return nil

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@ -0,0 +1,45 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package esxcli
import "github.com/vmware/govmomi/object"
type FirewallInfo struct {
Loaded bool
Enabled bool
DefaultAction string
}
// GetFirewallInfo via 'esxcli network firewall get'
// The HostFirewallSystem type does not expose this data.
// This helper can be useful in particular to determine if the firewall is enabled or disabled.
func GetFirewallInfo(s *object.HostSystem) (*FirewallInfo, error) {
x, err := NewExecutor(s.Client(), s)
res, err := x.Run([]string{"network", "firewall", "get"})
if err != nil {
return nil, err
}
info := &FirewallInfo{
Loaded: res.Values[0]["Loaded"][0] == "true",
Enabled: res.Values[0]["Enabled"][0] == "true",
DefaultAction: res.Values[0]["DefaultAction"][0],
}
return info, nil
}

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@ -1,3 +1,18 @@
/*
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package esxcli
import (

View File

@ -0,0 +1,128 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package firewall
import (
"flag"
"fmt"
"os"
"golang.org/x/net/context"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/govc/host/esxcli"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/types"
)
type find struct {
*flags.ClientFlag
*flags.OutputFlag
*flags.HostSystemFlag
enabled bool
check bool
types.HostFirewallRule
}
func init() {
cli.Register("firewall.ruleset.find", &find{})
}
func (cmd *find) Register(ctx context.Context, f *flag.FlagSet) {
cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
cmd.ClientFlag.Register(ctx, f)
cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
cmd.OutputFlag.Register(ctx, f)
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
cmd.HostSystemFlag.Register(ctx, f)
f.BoolVar(&cmd.check, "c", true, "Check if esx firewall is enabled")
f.BoolVar(&cmd.enabled, "enabled", true, "Find enabled rule sets if true, disabled if false")
f.StringVar((*string)(&cmd.Direction), "direction", string(types.HostFirewallRuleDirectionOutbound), "Direction")
f.StringVar((*string)(&cmd.PortType), "type", string(types.HostFirewallRulePortTypeDst), "Port type")
f.StringVar((*string)(&cmd.Protocol), "proto", string(types.HostFirewallRuleProtocolTcp), "Protocol")
f.IntVar(&cmd.Port, "port", 0, "Port")
}
func (cmd *find) Process(ctx context.Context) error {
if err := cmd.ClientFlag.Process(ctx); err != nil {
return err
}
if err := cmd.OutputFlag.Process(ctx); err != nil {
return err
}
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *find) Description() string {
return `Find firewall rulesets matching the given rule.
For a complete list of rulesets: govc host.esxcli network firewall ruleset list
For a complete list of rules: govc host.esxcli network firewall ruleset rule list`
}
func (cmd *find) Run(ctx context.Context, f *flag.FlagSet) error {
host, err := cmd.HostSystem()
if err != nil {
return err
}
fs, err := host.ConfigManager().FirewallSystem(ctx)
if err != nil {
return err
}
if cmd.check {
esxfw, err := esxcli.GetFirewallInfo(host)
if err != nil {
return err
}
if !esxfw.Enabled {
fmt.Fprintln(os.Stderr, "host firewall is disabled")
}
}
info, err := fs.Info(ctx)
if err != nil {
return err
}
if f.NArg() != 0 {
// TODO: f.Args() -> types.HostFirewallRulesetIpList
return flag.ErrHelp
}
rs := object.HostFirewallRulesetList(info.Ruleset)
matched, err := rs.EnabledByRule(cmd.HostFirewallRule, cmd.enabled)
if err != nil {
return err
}
for _, r := range matched {
fmt.Println(r.Key)
}
return nil
}

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -23,12 +23,14 @@ import (
"os"
"text/tabwriter"
"golang.org/x/net/context"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/vim25/mo"
"golang.org/x/net/context"
"github.com/vmware/govmomi/vim25/types"
)
type info struct {
@ -41,73 +43,100 @@ func init() {
cli.Register("host.info", &info{})
}
func (c *info) Register(f *flag.FlagSet) {}
func (cmd *info) Register(ctx context.Context, f *flag.FlagSet) {
cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
cmd.ClientFlag.Register(ctx, f)
func (c *info) Process() error { return nil }
cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
cmd.OutputFlag.Register(ctx, f)
func (c *info) Run(f *flag.FlagSet) error {
client, err := c.Client()
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
cmd.HostSystemFlag.Register(ctx, f)
}
func (cmd *info) Process(ctx context.Context) error {
if err := cmd.ClientFlag.Process(ctx); err != nil {
return err
}
if err := cmd.OutputFlag.Process(ctx); err != nil {
return err
}
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *info) Run(ctx context.Context, f *flag.FlagSet) error {
c, err := cmd.Client()
if err != nil {
return err
}
var hosts []*object.HostSystem
var res infoResult
var props []string
if cmd.OutputFlag.JSON {
props = nil // Load everything
} else {
props = []string{"summary"} // Load summary
}
// We could do without the -host flag, leaving it for compat
host, err := c.HostSystemIfSpecified()
host, err := cmd.HostSystemIfSpecified()
if err != nil {
return err
}
// Default only if there is a single host
if host == nil && f.NArg() == 0 {
host, err = c.HostSystem()
host, err = cmd.HostSystem()
if err != nil {
return err
}
}
if host != nil {
hosts = append(hosts, host)
res.objects = append(res.objects, host)
} else {
hosts, err = c.HostSystems(f.Args())
res.objects, err = cmd.HostSystems(f.Args())
if err != nil {
return err
}
}
var res infoResult
var props []string
if len(res.objects) != 0 {
refs := make([]types.ManagedObjectReference, 0, len(res.objects))
for _, o := range res.objects {
refs = append(refs, o.Reference())
}
if c.OutputFlag.JSON {
props = nil // Load everything
} else {
props = []string{"summary"} // Load summary
}
for _, host := range hosts {
var h mo.HostSystem
pc := property.DefaultCollector(client)
err = pc.RetrieveOne(context.TODO(), host.Reference(), props, &h)
pc := property.DefaultCollector(c)
err = pc.Retrieve(ctx, refs, props, &res.HostSystems)
if err != nil {
return err
}
res.HostSystems = append(res.HostSystems, h)
}
return c.WriteResult(&res)
return cmd.WriteResult(&res)
}
type infoResult struct {
HostSystems []mo.HostSystem
objects []*object.HostSystem
}
func (r *infoResult) Write(w io.Writer) error {
// Maintain order via r.objects as Property collector does not always return results in order.
objects := make(map[types.ManagedObjectReference]mo.HostSystem, len(r.HostSystems))
for _, o := range r.HostSystems {
objects[o.Reference()] = o
}
tw := tabwriter.NewWriter(os.Stdout, 2, 0, 2, ' ', 0)
for _, host := range r.HostSystems {
for _, o := range r.objects {
host := objects[o.Reference()]
s := host.Summary
h := s.Hardware
z := s.QuickStats
@ -116,6 +145,7 @@ func (r *infoResult) Write(w io.Writer) error {
memUsage := 100 * float64(z.OverallMemoryUsage<<20) / float64(h.MemorySize)
fmt.Fprintf(tw, "Name:\t%s\n", s.Config.Name)
fmt.Fprintf(tw, " Path:\t%s\n", o.InventoryPath)
fmt.Fprintf(tw, " Manufacturer:\t%s\n", h.Vendor)
fmt.Fprintf(tw, " Logical CPUs:\t%d CPUs @ %dMHz\n", ncpu, h.CpuMhz)
fmt.Fprintf(tw, " Processor type:\t%s\n", h.CpuModel)

View File

@ -0,0 +1,94 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package maintenancec
import (
"flag"
"fmt"
"golang.org/x/net/context"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/object"
)
type enter struct {
*flags.HostSystemFlag
timeout int
evacuate bool
}
func init() {
cli.Register("host.maintenance.enter", &enter{})
}
func (cmd *enter) Register(ctx context.Context, f *flag.FlagSet) {
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
cmd.HostSystemFlag.Register(ctx, f)
f.IntVar(&cmd.timeout, "timeout", 0, "Timeout")
f.BoolVar(&cmd.evacuate, "evacuate", false, "Evacuate powered off VMs")
}
func (cmd *enter) Process(ctx context.Context) error {
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *enter) Usage() string {
return "HOST..."
}
func (cmd *enter) Description() string {
return `Put the hosts in maintenance mode.
While this task is running and when the host is in maintenance mode,
no virtual machines can be powered on and no provisioning operations can be performed on the host.`
}
func (cmd *enter) EnterMaintenanceMode(ctx context.Context, host *object.HostSystem) error {
task, err := host.EnterMaintenanceMode(ctx, cmd.timeout, cmd.evacuate, nil) // TODO: spec param
if err != nil {
return err
}
logger := cmd.ProgressLogger(fmt.Sprintf("%s entering maintenance mode... ", host.InventoryPath))
defer logger.Wait()
_, err = task.WaitForResult(ctx, logger)
return err
}
func (cmd *enter) Run(ctx context.Context, f *flag.FlagSet) error {
hosts, err := cmd.HostSystems(f.Args())
if err != nil {
return err
}
for _, host := range hosts {
err = cmd.EnterMaintenanceMode(ctx, host)
if err != nil {
return err
}
}
return nil
}

View File

@ -0,0 +1,95 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package maintenancec
import (
"flag"
"fmt"
"golang.org/x/net/context"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/object"
)
type exit struct {
*flags.HostSystemFlag
timeout int
}
func init() {
cli.Register("host.maintenance.exit", &exit{})
}
func (cmd *exit) Register(ctx context.Context, f *flag.FlagSet) {
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
cmd.HostSystemFlag.Register(ctx, f)
f.IntVar(&cmd.timeout, "timeout", 0, "Timeout")
}
func (cmd *exit) Process(ctx context.Context) error {
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *exit) Usage() string {
return "HOST..."
}
func (cmd *exit) Description() string {
return `Take hosts out of maintenance mode.
This blocks if any concurrent running maintenance-only host configurations operations are being performed.
For example, if VMFS volumes are being upgraded.
The 'timeout' flag is the number of seconds to wait for the exit maintenance mode to succeed.
If the timeout is less than or equal to zero, there is no timeout.`
}
func (cmd *exit) ExitMaintenanceMode(ctx context.Context, host *object.HostSystem) error {
task, err := host.ExitMaintenanceMode(ctx, cmd.timeout)
if err != nil {
return err
}
logger := cmd.ProgressLogger(fmt.Sprintf("%s exiting maintenance mode... ", host.InventoryPath))
defer logger.Wait()
_, err = task.WaitForResult(ctx, logger)
return err
}
func (cmd *exit) Run(ctx context.Context, f *flag.FlagSet) error {
hosts, err := cmd.HostSystems(f.Args())
if err != nil {
return err
}
for _, host := range hosts {
err = cmd.ExitMaintenanceMode(ctx, host)
if err != nil {
return err
}
}
return nil
}

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -35,18 +35,26 @@ func init() {
cli.Register("host.portgroup.add", &add{})
}
func (cmd *add) Register(f *flag.FlagSet) {
func (cmd *add) Register(ctx context.Context, f *flag.FlagSet) {
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
cmd.HostSystemFlag.Register(ctx, f)
f.StringVar(&cmd.spec.VswitchName, "vswitch", "", "vSwitch Name")
f.IntVar(&cmd.spec.VlanId, "vlan", 0, "VLAN ID")
}
func (cmd *add) Process() error { return nil }
func (cmd *add) Process(ctx context.Context) error {
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *add) Usage() string {
return "NAME"
}
func (cmd *add) Run(f *flag.FlagSet) error {
func (cmd *add) Run(ctx context.Context, f *flag.FlagSet) error {
ns, err := cmd.HostNetworkSystem()
if err != nil {
return err

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -32,15 +32,23 @@ func init() {
cli.Register("host.portgroup.remove", &remove{})
}
func (cmd *remove) Register(f *flag.FlagSet) {}
func (cmd *remove) Register(ctx context.Context, f *flag.FlagSet) {
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
cmd.HostSystemFlag.Register(ctx, f)
}
func (cmd *remove) Process() error { return nil }
func (cmd *remove) Process(ctx context.Context) error {
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *remove) Usage() string {
return "NAME"
}
func (cmd *remove) Run(f *flag.FlagSet) error {
func (cmd *remove) Run(ctx context.Context, f *flag.FlagSet) error {
ns, err := cmd.HostNetworkSystem()
if err != nil {
return err

View File

@ -0,0 +1,97 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package host
import (
"flag"
"fmt"
"golang.org/x/net/context"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/types"
)
type reconnect struct {
*flags.HostSystemFlag
*flags.HostConnectFlag
types.HostSystemReconnectSpec
}
func init() {
cli.Register("host.reconnect", &reconnect{})
}
func (cmd *reconnect) Register(ctx context.Context, f *flag.FlagSet) {
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
cmd.HostSystemFlag.Register(ctx, f)
cmd.HostConnectFlag, ctx = flags.NewHostConnectFlag(ctx)
cmd.HostConnectFlag.Register(ctx, f)
cmd.HostSystemReconnectSpec.SyncState = types.NewBool(false)
f.BoolVar(cmd.HostSystemReconnectSpec.SyncState, "sync-state", false, "Sync state")
}
func (cmd *reconnect) Process(ctx context.Context) error {
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
return err
}
if err := cmd.HostConnectFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *reconnect) Description() string {
return `Reconnect host to vCenter.
This command can also be used to change connection properties (hostname, fingerprint, username, password),
without disconnecting the host.`
}
func (cmd *reconnect) Reconnect(ctx context.Context, host *object.HostSystem) error {
task, err := host.Reconnect(ctx, &cmd.HostConnectSpec, &cmd.HostSystemReconnectSpec)
if err != nil {
return err
}
logger := cmd.ProgressLogger(fmt.Sprintf("%s reconnecting... ", host.InventoryPath))
defer logger.Wait()
_, err = task.WaitForResult(ctx, logger)
return err
}
func (cmd *reconnect) Run(ctx context.Context, f *flag.FlagSet) error {
hosts, err := cmd.HostSystems(f.Args())
if err != nil {
return err
}
for _, host := range hosts {
err = cmd.Reconnect(ctx, host)
if err != nil {
return err
}
}
return nil
}

101
vendor/github.com/vmware/govmomi/govc/host/remove.go generated vendored Normal file
View File

@ -0,0 +1,101 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package host
import (
"flag"
"fmt"
"golang.org/x/net/context"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/mo"
)
type remove struct {
*flags.HostSystemFlag
}
func init() {
cli.Register("host.remove", &remove{})
}
func (cmd *remove) Register(ctx context.Context, f *flag.FlagSet) {
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
cmd.HostSystemFlag.Register(ctx, f)
}
func (cmd *remove) Process(ctx context.Context) error {
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *remove) Usage() string {
return "HOST..."
}
func (cmd *remove) Description() string {
return `Remove hosts from vCenter.`
}
func (cmd *remove) Remove(ctx context.Context, host *object.HostSystem) error {
var h mo.HostSystem
err := host.Properties(ctx, host.Reference(), []string{"parent"}, &h)
if err != nil {
return err
}
remove := host.Destroy
if h.Parent.Type == "ComputeResource" {
// Standalone host. From the docs:
// "Invoking remove on a HostSystem of standalone type throws a NotSupported fault.
// A standalone HostSystem can be removeed only by invoking remove on its parent ComputeResource."
remove = object.NewComputeResource(host.Client(), *h.Parent).Destroy
}
task, err := remove(ctx)
if err != nil {
return err
}
logger := cmd.ProgressLogger(fmt.Sprintf("%s removing... ", host.InventoryPath))
defer logger.Wait()
_, err = task.WaitForResult(ctx, logger)
return err
}
func (cmd *remove) Run(ctx context.Context, f *flag.FlagSet) error {
hosts, err := cmd.HostSystems(f.Args())
if err != nil {
return err
}
for _, host := range hosts {
err = cmd.Remove(ctx, host)
if err != nil {
return err
}
}
return nil
}

View File

@ -0,0 +1,188 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package storage
import (
"flag"
"fmt"
"io"
"strings"
"text/tabwriter"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/units"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
var infoTypes = []string{"hba", "lun"}
type infoType string
func (t *infoType) Set(s string) error {
s = strings.ToLower(s)
for _, e := range infoTypes {
if s == e {
*t = infoType(s)
return nil
}
}
return fmt.Errorf("invalid type")
}
func (t *infoType) String() string {
return string(*t)
}
func (t *infoType) Result(hss mo.HostStorageSystem) flags.OutputWriter {
switch string(*t) {
case "hba":
return hbaResult(hss)
case "lun":
return lunResult(hss)
default:
panic("unsupported")
}
}
type info struct {
*flags.HostSystemFlag
*flags.OutputFlag
typ infoType
}
func init() {
cli.Register("host.storage.info", &info{})
}
func (cmd *info) Register(ctx context.Context, f *flag.FlagSet) {
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
cmd.HostSystemFlag.Register(ctx, f)
cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
cmd.OutputFlag.Register(ctx, f)
err := cmd.typ.Set("lun")
if err != nil {
panic(err)
}
f.Var(&cmd.typ, "t", fmt.Sprintf("Type (%s)", strings.Join(infoTypes, ",")))
}
func (cmd *info) Process(ctx context.Context) error {
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
return err
}
if err := cmd.OutputFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *info) Usage() string {
return "[-t TYPE]"
}
func (cmd *info) Description() string {
return `Show information about a host's storage system.`
}
func (cmd *info) Run(ctx context.Context, f *flag.FlagSet) error {
host, err := cmd.HostSystem()
if err != nil {
return err
}
ss, err := host.ConfigManager().StorageSystem(ctx)
if err != nil {
return err
}
var hss mo.HostStorageSystem
err = ss.Properties(ctx, ss.Reference(), nil, &hss)
if err != nil {
return nil
}
return cmd.WriteResult(cmd.typ.Result(hss))
}
type hbaResult mo.HostStorageSystem
func (r hbaResult) Write(w io.Writer) error {
tw := tabwriter.NewWriter(w, 2, 0, 2, ' ', 0)
fmt.Fprintf(tw, "Device\t")
fmt.Fprintf(tw, "PCI\t")
fmt.Fprintf(tw, "Driver\t")
fmt.Fprintf(tw, "Status\t")
fmt.Fprintf(tw, "Model\t")
fmt.Fprintf(tw, "\n")
for _, e := range r.StorageDeviceInfo.HostBusAdapter {
hba := e.GetHostHostBusAdapter()
fmt.Fprintf(tw, "%s\t", hba.Device)
fmt.Fprintf(tw, "%s\t", hba.Pci)
fmt.Fprintf(tw, "%s\t", hba.Driver)
fmt.Fprintf(tw, "%s\t", hba.Status)
fmt.Fprintf(tw, "%s\t", hba.Model)
fmt.Fprintf(tw, "\n")
}
return tw.Flush()
}
type lunResult mo.HostStorageSystem
func (r lunResult) Write(w io.Writer) error {
tw := tabwriter.NewWriter(w, 2, 0, 2, ' ', 0)
fmt.Fprintf(tw, "Name\t")
fmt.Fprintf(tw, "Type\t")
fmt.Fprintf(tw, "Capacity\t")
fmt.Fprintf(tw, "Model\t")
fmt.Fprintf(tw, "\n")
for _, e := range r.StorageDeviceInfo.ScsiLun {
var capacity int64
lun := e.GetScsiLun()
if disk, ok := e.(*types.HostScsiDisk); ok {
capacity = int64(disk.Capacity.Block) * int64(disk.Capacity.BlockSize)
}
fmt.Fprintf(tw, "%s\t", lun.DeviceName)
fmt.Fprintf(tw, "%s\t", lun.DeviceType)
if capacity == 0 {
fmt.Fprintf(tw, "-\t")
} else {
fmt.Fprintf(tw, "%s\t", units.ByteSize(capacity))
}
fmt.Fprintf(tw, "%s\t", lun.Model)
fmt.Fprintf(tw, "\n")
}
return tw.Flush()
}

View File

@ -0,0 +1,127 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package storage
import (
"flag"
"fmt"
"io"
"text/tabwriter"
"golang.org/x/net/context"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/units"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
)
type partition struct {
*flags.HostSystemFlag
*flags.OutputFlag
}
func init() {
cli.Register("host.storage.partition", &partition{})
}
func (cmd *partition) Register(ctx context.Context, f *flag.FlagSet) {
cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
cmd.HostSystemFlag.Register(ctx, f)
cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
cmd.OutputFlag.Register(ctx, f)
}
func (cmd *partition) Process(ctx context.Context) error {
if err := cmd.HostSystemFlag.Process(ctx); err != nil {
return err
}
if err := cmd.OutputFlag.Process(ctx); err != nil {
return err
}
return nil
}
func (cmd *partition) Usage() string {
return "DEVICE_PATH"
}
func (cmd *partition) Description() string {
return `Show partition table for device at DEVICE_PATH.`
}
func (cmd *partition) Run(ctx context.Context, f *flag.FlagSet) error {
if f.NArg() != 1 {
return fmt.Errorf("specify device path")
}
path := f.Args()[0]
host, err := cmd.HostSystem()
if err != nil {
return err
}
ss, err := host.ConfigManager().StorageSystem(ctx)
if err != nil {
return err
}
var hss mo.HostStorageSystem
err = ss.Properties(ctx, ss.Reference(), nil, &hss)
if err != nil {
return nil
}
info, err := ss.RetrieveDiskPartitionInfo(ctx, path)
if err != nil {
return err
}
return cmd.WriteResult(partitionInfo(*info))
}
type partitionInfo types.HostDiskPartitionInfo
func (p partitionInfo) Write(w io.Writer) error {
tw := tabwriter.NewWriter(w, 2, 0, 2, ' ', 0)
fmt.Fprintf(tw, "Table format: %s\n", p.Spec.PartitionFormat)
fmt.Fprintf(tw, "Number of sectors: %d\n", p.Spec.TotalSectors)
fmt.Fprintf(tw, "\n")
fmt.Fprintf(tw, "Number\t")
fmt.Fprintf(tw, "Start\t")
fmt.Fprintf(tw, "End\t")
fmt.Fprintf(tw, "Size\t")
fmt.Fprintf(tw, "Type\t")
fmt.Fprintf(tw, "\n")
for _, e := range p.Spec.Partition {
sectors := e.EndSector - e.StartSector
fmt.Fprintf(tw, "%d\t", e.Partition)
fmt.Fprintf(tw, "%d\t", e.StartSector)
fmt.Fprintf(tw, "%d\t", e.EndSector)
fmt.Fprintf(tw, "%s\t", units.ByteSize(sectors*512))
fmt.Fprintf(tw, "%s\t", e.Type)
fmt.Fprintf(tw, "\n")
}
return tw.Flush()
}

Some files were not shown because too many files have changed in this diff Show More