diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 3001c94560..1fd96a964d 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -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", diff --git a/drivers/vmwarevsphere/vsphere.go b/drivers/vmwarevsphere/vsphere.go index f2e646782c..5f0178f3e4 100644 --- a/drivers/vmwarevsphere/vsphere.go +++ b/drivers/vmwarevsphere/vsphere.go @@ -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 -} diff --git a/vendor/github.com/vmware/govmomi/CHANGELOG.md b/vendor/github.com/vmware/govmomi/CHANGELOG.md index 96c84c1f3f..29f28ce525 100644 --- a/vendor/github.com/vmware/govmomi/CHANGELOG.md +++ b/vendor/github.com/vmware/govmomi/CHANGELOG.md @@ -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 diff --git a/vendor/github.com/vmware/govmomi/CONTRIBUTORS b/vendor/github.com/vmware/govmomi/CONTRIBUTORS index 5a99a51ba0..8813540f16 100644 --- a/vendor/github.com/vmware/govmomi/CONTRIBUTORS +++ b/vendor/github.com/vmware/govmomi/CONTRIBUTORS @@ -4,19 +4,23 @@ # Alvaro Miranda +Amit Bathla Bob Killen Bruce Downs Clint Greenwood Danny Lockard Doug MacEachern +Eloy Coto Eric Yutao Faiyaz Ahmed Gavin Gray Gavrie Philipson +Louie Jiang Mevan Samaratunga Pieter Noordhuis +runner.mei S.Çağlar Onur -Takaaki Furukawa +Takaaki Furukawa Yang Yang Yuya Kusakabe Zee Yang diff --git a/vendor/github.com/vmware/govmomi/README.md b/vendor/github.com/vmware/govmomi/README.md index 26a2b6c018..6831d64bea 100644 --- a/vendor/github.com/vmware/govmomi/README.md +++ b/vendor/github.com/vmware/govmomi/README.md @@ -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 diff --git a/vendor/github.com/vmware/govmomi/client.go b/vendor/github.com/vmware/govmomi/client.go index 56809c8bc5..37624952b7 100644 --- a/vendor/github.com/vmware/govmomi/client.go +++ b/vendor/github.com/vmware/govmomi/client.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/event/history_collector.go b/vendor/github.com/vmware/govmomi/event/history_collector.go index ca48948875..543c1ea8cd 100644 --- a/vendor/github.com/vmware/govmomi/event/history_collector.go +++ b/vendor/github.com/vmware/govmomi/event/history_collector.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/event/manager.go b/vendor/github.com/vmware/govmomi/event/manager.go index a807d119d7..c137f4a44e 100644 --- a/vendor/github.com/vmware/govmomi/event/manager.go +++ b/vendor/github.com/vmware/govmomi/event/manager.go @@ -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 } diff --git a/vendor/github.com/vmware/govmomi/event/sort.go b/vendor/github.com/vmware/govmomi/event/sort.go index f24c755ede..ac87b0eda0 100644 --- a/vendor/github.com/vmware/govmomi/event/sort.go +++ b/vendor/github.com/vmware/govmomi/event/sort.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/find/error.go b/vendor/github.com/vmware/govmomi/find/error.go index aa54d7c7ef..684526dab7 100644 --- a/vendor/github.com/vmware/govmomi/find/error.go +++ b/vendor/github.com/vmware/govmomi/find/error.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/find/finder.go b/vendor/github.com/vmware/govmomi/find/finder.go index 39a4837a4c..165a330c1f 100644 --- a/vendor/github.com/vmware/govmomi/find/finder.go +++ b/vendor/github.com/vmware/govmomi/find/finder.go @@ -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 +} diff --git a/vendor/github.com/vmware/govmomi/gen/Gemfile.lock b/vendor/github.com/vmware/govmomi/gen/Gemfile.lock new file mode 100644 index 0000000000..6cdeaae5a3 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/gen/Gemfile.lock @@ -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 diff --git a/vendor/github.com/vmware/govmomi/gen/vim_wsdl.rb b/vendor/github.com/vmware/govmomi/gen/vim_wsdl.rb index a032ce94e1..285a30b851 100644 --- a/vendor/github.com/vmware/govmomi/gen/vim_wsdl.rb +++ b/vendor/github.com/vmware/govmomi/gen/vim_wsdl.rb @@ -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 < /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 diff --git a/vendor/github.com/vmware/govmomi/govc/cli/command.go b/vendor/github.com/vmware/govmomi/govc/cli/command.go index 761c6cc766..77b17ed178 100644 --- a/vendor/github.com/vmware/govmomi/govc/cli/command.go +++ b/vendor/github.com/vmware/govmomi/govc/cli/command.go @@ -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 + } diff --git a/vendor/github.com/vmware/govmomi/govc/cli/register.go b/vendor/github.com/vmware/govmomi/govc/cli/register.go index 9fdbccb317..a20fc3ad0e 100644 --- a/vendor/github.com/vmware/govmomi/govc/cli/register.go +++ b/vendor/github.com/vmware/govmomi/govc/cli/register.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/govc/cli/walk.go b/vendor/github.com/vmware/govmomi/govc/cli/walk.go deleted file mode 100644 index 77ab3acad5..0000000000 --- a/vendor/github.com/vmware/govmomi/govc/cli/walk.go +++ /dev/null @@ -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) -} diff --git a/vendor/github.com/vmware/govmomi/govc/cluster/add.go b/vendor/github.com/vmware/govmomi/govc/cluster/add.go new file mode 100644 index 0000000000..027e0c2542 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/cluster/add.go @@ -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) +} diff --git a/vendor/github.com/vmware/govmomi/govc/cluster/change.go b/vendor/github.com/vmware/govmomi/govc/cluster/change.go new file mode 100644 index 0000000000..ea21a27dc2 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/cluster/change.go @@ -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 +} diff --git a/vendor/github.com/vmware/govmomi/govc/cluster/create.go b/vendor/github.com/vmware/govmomi/govc/cluster/create.go new file mode 100644 index 0000000000..3d92f01f0b --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/cluster/create.go @@ -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 +} diff --git a/vendor/github.com/vmware/govmomi/govc/datacenter/create.go b/vendor/github.com/vmware/govmomi/govc/datacenter/create.go index 5c664f759a..2b2065432d 100644 --- a/vendor/github.com/vmware/govmomi/govc/datacenter/create.go +++ b/vendor/github.com/vmware/govmomi/govc/datacenter/create.go @@ -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 diff --git a/vendor/github.com/vmware/govmomi/govc/datacenter/destroy.go b/vendor/github.com/vmware/govmomi/govc/datacenter/destroy.go index 12362ede49..eed333bb0c 100644 --- a/vendor/github.com/vmware/govmomi/govc/datacenter/destroy.go +++ b/vendor/github.com/vmware/govmomi/govc/datacenter/destroy.go @@ -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 } diff --git a/vendor/github.com/vmware/govmomi/govc/datastore/cp.go b/vendor/github.com/vmware/govmomi/govc/datastore/cp.go index d289fb64f0..7e206ade48 100644 --- a/vendor/github.com/vmware/govmomi/govc/datastore/cp.go +++ b/vendor/github.com/vmware/govmomi/govc/datastore/cp.go @@ -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") diff --git a/vendor/github.com/vmware/govmomi/govc/datastore/create.go b/vendor/github.com/vmware/govmomi/govc/datastore/create.go new file mode 100644 index 0000000000..ce5b06b52c --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/datastore/create.go @@ -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 +} diff --git a/vendor/github.com/vmware/govmomi/govc/datastore/download.go b/vendor/github.com/vmware/govmomi/govc/datastore/download.go index 65a9c0c179..27bfa93c8c 100644 --- a/vendor/github.com/vmware/govmomi/govc/datastore/download.go +++ b/vendor/github.com/vmware/govmomi/govc/datastore/download.go @@ -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) } diff --git a/vendor/github.com/vmware/govmomi/govc/datastore/info.go b/vendor/github.com/vmware/govmomi/govc/datastore/info.go index 8bea6ed018..6e9dd79971 100644 --- a/vendor/github.com/vmware/govmomi/govc/datastore/info.go +++ b/vendor/github.com/vmware/govmomi/govc/datastore/info.go @@ -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)) diff --git a/vendor/github.com/vmware/govmomi/govc/datastore/ls.go b/vendor/github.com/vmware/govmomi/govc/datastore/ls.go index f681be78db..570c592a14 100644 --- a/vendor/github.com/vmware/govmomi/govc/datastore/ls.go +++ b/vendor/github.com/vmware/govmomi/govc/datastore/ls.go @@ -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) diff --git a/vendor/github.com/vmware/govmomi/govc/datastore/mkdir.go b/vendor/github.com/vmware/govmomi/govc/datastore/mkdir.go index 3ee546f549..cfa7e39331 100644 --- a/vendor/github.com/vmware/govmomi/govc/datastore/mkdir.go +++ b/vendor/github.com/vmware/govmomi/govc/datastore/mkdir.go @@ -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") diff --git a/vendor/github.com/vmware/govmomi/govc/datastore/mv.go b/vendor/github.com/vmware/govmomi/govc/datastore/mv.go index 0e5f2ad012..023ef393e6 100644 --- a/vendor/github.com/vmware/govmomi/govc/datastore/mv.go +++ b/vendor/github.com/vmware/govmomi/govc/datastore/mv.go @@ -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") diff --git a/vendor/github.com/vmware/govmomi/govc/datastore/remove.go b/vendor/github.com/vmware/govmomi/govc/datastore/remove.go new file mode 100644 index 0000000000..772803446b --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/datastore/remove.go @@ -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 +} diff --git a/vendor/github.com/vmware/govmomi/govc/datastore/rm.go b/vendor/github.com/vmware/govmomi/govc/datastore/rm.go index 1207f7cc92..09ef57d2fa 100644 --- a/vendor/github.com/vmware/govmomi/govc/datastore/rm.go +++ b/vendor/github.com/vmware/govmomi/govc/datastore/rm.go @@ -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") diff --git a/vendor/github.com/vmware/govmomi/govc/datastore/upload.go b/vendor/github.com/vmware/govmomi/govc/datastore/upload.go index 7dca76b24e..77d3d8dcd6 100644 --- a/vendor/github.com/vmware/govmomi/govc/datastore/upload.go +++ b/vendor/github.com/vmware/govmomi/govc/datastore/upload.go @@ -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) } diff --git a/vendor/github.com/vmware/govmomi/govc/device/boot.go b/vendor/github.com/vmware/govmomi/govc/device/boot.go index a43beb817c..268acacbf1 100644 --- a/vendor/github.com/vmware/govmomi/govc/device/boot.go +++ b/vendor/github.com/vmware/govmomi/govc/device/boot.go @@ -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 diff --git a/vendor/github.com/vmware/govmomi/govc/device/cdrom/add.go b/vendor/github.com/vmware/govmomi/govc/device/cdrom/add.go index 6d18cb0968..122789a93d 100644 --- a/vendor/github.com/vmware/govmomi/govc/device/cdrom/add.go +++ b/vendor/github.com/vmware/govmomi/govc/device/cdrom/add.go @@ -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 diff --git a/vendor/github.com/vmware/govmomi/govc/device/cdrom/eject.go b/vendor/github.com/vmware/govmomi/govc/device/cdrom/eject.go index edbd291079..ea8a161a8b 100644 --- a/vendor/github.com/vmware/govmomi/govc/device/cdrom/eject.go +++ b/vendor/github.com/vmware/govmomi/govc/device/cdrom/eject.go @@ -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 diff --git a/vendor/github.com/vmware/govmomi/govc/device/cdrom/insert.go b/vendor/github.com/vmware/govmomi/govc/device/cdrom/insert.go index 018c13582e..cd4532ddcd 100644 --- a/vendor/github.com/vmware/govmomi/govc/device/cdrom/insert.go +++ b/vendor/github.com/vmware/govmomi/govc/device/cdrom/insert.go @@ -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 diff --git a/vendor/github.com/vmware/govmomi/govc/device/connect.go b/vendor/github.com/vmware/govmomi/govc/device/connect.go index f6a8a19a96..65f93aa2bc 100644 --- a/vendor/github.com/vmware/govmomi/govc/device/connect.go +++ b/vendor/github.com/vmware/govmomi/govc/device/connect.go @@ -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 diff --git a/vendor/github.com/vmware/govmomi/govc/device/disconnect.go b/vendor/github.com/vmware/govmomi/govc/device/disconnect.go index 9fd95fb759..fc23086216 100644 --- a/vendor/github.com/vmware/govmomi/govc/device/disconnect.go +++ b/vendor/github.com/vmware/govmomi/govc/device/disconnect.go @@ -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 diff --git a/vendor/github.com/vmware/govmomi/govc/device/floppy/add.go b/vendor/github.com/vmware/govmomi/govc/device/floppy/add.go index 660fa3cbd6..36b8196169 100644 --- a/vendor/github.com/vmware/govmomi/govc/device/floppy/add.go +++ b/vendor/github.com/vmware/govmomi/govc/device/floppy/add.go @@ -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 diff --git a/vendor/github.com/vmware/govmomi/govc/device/floppy/eject.go b/vendor/github.com/vmware/govmomi/govc/device/floppy/eject.go index dd9541adf4..a2271ea6da 100644 --- a/vendor/github.com/vmware/govmomi/govc/device/floppy/eject.go +++ b/vendor/github.com/vmware/govmomi/govc/device/floppy/eject.go @@ -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 diff --git a/vendor/github.com/vmware/govmomi/govc/device/floppy/insert.go b/vendor/github.com/vmware/govmomi/govc/device/floppy/insert.go index 62160f89ea..213db69204 100644 --- a/vendor/github.com/vmware/govmomi/govc/device/floppy/insert.go +++ b/vendor/github.com/vmware/govmomi/govc/device/floppy/insert.go @@ -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 diff --git a/vendor/github.com/vmware/govmomi/govc/device/info.go b/vendor/github.com/vmware/govmomi/govc/device/info.go index 9324be9519..e1707a9100 100644 --- a/vendor/github.com/vmware/govmomi/govc/device/info.go +++ b/vendor/github.com/vmware/govmomi/govc/device/info.go @@ -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) + } } } diff --git a/vendor/github.com/vmware/govmomi/govc/device/ls.go b/vendor/github.com/vmware/govmomi/govc/device/ls.go index c88591ed11..c4eafa3180 100644 --- a/vendor/github.com/vmware/govmomi/govc/device/ls.go +++ b/vendor/github.com/vmware/govmomi/govc/device/ls.go @@ -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 diff --git a/vendor/github.com/vmware/govmomi/govc/device/remove.go b/vendor/github.com/vmware/govmomi/govc/device/remove.go index 8589b1ed06..0e03b7197f 100644 --- a/vendor/github.com/vmware/govmomi/govc/device/remove.go +++ b/vendor/github.com/vmware/govmomi/govc/device/remove.go @@ -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 diff --git a/vendor/github.com/vmware/govmomi/govc/device/scsi/add.go b/vendor/github.com/vmware/govmomi/govc/device/scsi/add.go index 95fd626476..276391da85 100644 --- a/vendor/github.com/vmware/govmomi/govc/device/scsi/add.go +++ b/vendor/github.com/vmware/govmomi/govc/device/scsi/add.go @@ -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 diff --git a/vendor/github.com/vmware/govmomi/govc/device/serial/add.go b/vendor/github.com/vmware/govmomi/govc/device/serial/add.go index 1723600972..564ef27ab2 100644 --- a/vendor/github.com/vmware/govmomi/govc/device/serial/add.go +++ b/vendor/github.com/vmware/govmomi/govc/device/serial/add.go @@ -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 diff --git a/vendor/github.com/vmware/govmomi/govc/device/serial/connect.go b/vendor/github.com/vmware/govmomi/govc/device/serial/connect.go index 73278256a0..ec90883874 100644 --- a/vendor/github.com/vmware/govmomi/govc/device/serial/connect.go +++ b/vendor/github.com/vmware/govmomi/govc/device/serial/connect.go @@ -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 diff --git a/vendor/github.com/vmware/govmomi/govc/device/serial/disconnect.go b/vendor/github.com/vmware/govmomi/govc/device/serial/disconnect.go index 706def9e3a..108006fc11 100644 --- a/vendor/github.com/vmware/govmomi/govc/device/serial/disconnect.go +++ b/vendor/github.com/vmware/govmomi/govc/device/serial/disconnect.go @@ -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 diff --git a/vendor/github.com/vmware/govmomi/govc/dvs/add.go b/vendor/github.com/vmware/govmomi/govc/dvs/add.go new file mode 100644 index 0000000000..671b7e13b8 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/dvs/add.go @@ -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 +} diff --git a/vendor/github.com/vmware/govmomi/govc/dvs/create.go b/vendor/github.com/vmware/govmomi/govc/dvs/create.go new file mode 100644 index 0000000000..cab77f6bc7 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/dvs/create.go @@ -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 +} diff --git a/vendor/github.com/vmware/govmomi/govc/dvs/portgroup/add.go b/vendor/github.com/vmware/govmomi/govc/dvs/portgroup/add.go new file mode 100644 index 0000000000..01b7ceb8ad --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/dvs/portgroup/add.go @@ -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 +} diff --git a/vendor/github.com/vmware/govmomi/govc/events/command.go b/vendor/github.com/vmware/govmomi/govc/events/command.go index 8d8598a50e..c3a11e4adc 100644 --- a/vendor/github.com/vmware/govmomi/govc/events/command.go +++ b/vendor/github.com/vmware/govmomi/govc/events/command.go @@ -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 } diff --git a/vendor/github.com/vmware/govmomi/govc/extension/info.go b/vendor/github.com/vmware/govmomi/govc/extension/info.go new file mode 100644 index 0000000000..f759036665 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/extension/info.go @@ -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() +} diff --git a/vendor/github.com/vmware/govmomi/govc/extension/register.go b/vendor/github.com/vmware/govmomi/govc/extension/register.go new file mode 100644 index 0000000000..b5f4b1410e --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/extension/register.go @@ -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", ®ister{}) +} + +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) +} diff --git a/vendor/github.com/vmware/govmomi/govc/extension/setcert.go b/vendor/github.com/vmware/govmomi/govc/extension/setcert.go new file mode 100644 index 0000000000..2c10923817 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/extension/setcert.go @@ -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) +} diff --git a/vendor/github.com/vmware/govmomi/govc/extension/unregister.go b/vendor/github.com/vmware/govmomi/govc/extension/unregister.go new file mode 100644 index 0000000000..da7dfa3f94 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/extension/unregister.go @@ -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 +} diff --git a/vendor/github.com/vmware/govmomi/govc/fields/add.go b/vendor/github.com/vmware/govmomi/govc/fields/add.go index cf746b1793..6cf1ba4ebd 100644 --- a/vendor/github.com/vmware/govmomi/govc/fields/add.go +++ b/vendor/github.com/vmware/govmomi/govc/fields/add.go @@ -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 diff --git a/vendor/github.com/vmware/govmomi/govc/fields/ls.go b/vendor/github.com/vmware/govmomi/govc/fields/ls.go index 6f86eb40f7..789817ab75 100644 --- a/vendor/github.com/vmware/govmomi/govc/fields/ls.go +++ b/vendor/github.com/vmware/govmomi/govc/fields/ls.go @@ -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 diff --git a/vendor/github.com/vmware/govmomi/govc/fields/rename.go b/vendor/github.com/vmware/govmomi/govc/fields/rename.go index 63172b7169..8fd06ed664 100644 --- a/vendor/github.com/vmware/govmomi/govc/fields/rename.go +++ b/vendor/github.com/vmware/govmomi/govc/fields/rename.go @@ -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 diff --git a/vendor/github.com/vmware/govmomi/govc/fields/rm.go b/vendor/github.com/vmware/govmomi/govc/fields/rm.go index 9b69528c35..d2a0593d05 100644 --- a/vendor/github.com/vmware/govmomi/govc/fields/rm.go +++ b/vendor/github.com/vmware/govmomi/govc/fields/rm.go @@ -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 diff --git a/vendor/github.com/vmware/govmomi/govc/fields/set.go b/vendor/github.com/vmware/govmomi/govc/fields/set.go index 08db914c82..19aedb2fc3 100644 --- a/vendor/github.com/vmware/govmomi/govc/fields/set.go +++ b/vendor/github.com/vmware/govmomi/govc/fields/set.go @@ -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 } diff --git a/vendor/github.com/vmware/govmomi/govc/flags/client.go b/vendor/github.com/vmware/govmomi/govc/flags/client.go index d20a1158dd..572efd3fde 100644 --- a/vendor/github.com/vmware/govmomi/govc/flags/client.go +++ b/vendor/github.com/vmware/govmomi/govc/flags/client.go @@ -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 } diff --git a/vendor/github.com/vmware/govmomi/govc/flags/common.go b/vendor/github.com/vmware/govmomi/govc/flags/common.go new file mode 100644 index 0000000000..a11eb30e3e --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/flags/common.go @@ -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 +} diff --git a/vendor/github.com/vmware/govmomi/govc/flags/datacenter.go b/vendor/github.com/vmware/govmomi/govc/flags/datacenter.go index 46d60d8c42..c28aefae60 100644 --- a/vendor/github.com/vmware/govmomi/govc/flags/datacenter.go +++ b/vendor/github.com/vmware/govmomi/govc/flags/datacenter.go @@ -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 +} diff --git a/vendor/github.com/vmware/govmomi/govc/flags/datastore.go b/vendor/github.com/vmware/govmomi/govc/flags/datastore.go index c7753dbf4e..d339f7d1f1 100644 --- a/vendor/github.com/vmware/govmomi/govc/flags/datastore.go +++ b/vendor/github.com/vmware/govmomi/govc/flags/datastore.go @@ -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 -} diff --git a/vendor/github.com/vmware/govmomi/govc/flags/debug.go b/vendor/github.com/vmware/govmomi/govc/flags/debug.go index 98551c15b5..d8e910ea00 100644 --- a/vendor/github.com/vmware/govmomi/govc/flags/debug.go +++ b/vendor/github.com/vmware/govmomi/govc/flags/debug.go @@ -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 + }) } diff --git a/vendor/github.com/vmware/govmomi/govc/flags/empty.go b/vendor/github.com/vmware/govmomi/govc/flags/empty.go index a0be0dca8b..0a1a438cab 100644 --- a/vendor/github.com/vmware/govmomi/govc/flags/empty.go +++ b/vendor/github.com/vmware/govmomi/govc/flags/empty.go @@ -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 +} diff --git a/vendor/github.com/vmware/govmomi/govc/flags/host_connect.go b/vendor/github.com/vmware/govmomi/govc/flags/host_connect.go new file mode 100644 index 0000000000..be39dbd0ac --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/flags/host_connect.go @@ -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 +} diff --git a/vendor/github.com/vmware/govmomi/govc/flags/host_system.go b/vendor/github.com/vmware/govmomi/govc/flags/host_system.go index f43336baf7..a0d847239f 100644 --- a/vendor/github.com/vmware/govmomi/govc/flags/host_system.go +++ b/vendor/github.com/vmware/govmomi/govc/flags/host_system.go @@ -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 { diff --git a/vendor/github.com/vmware/govmomi/govc/flags/network.go b/vendor/github.com/vmware/govmomi/govc/flags/network.go index 97077022f2..602dd0f617 100644 --- a/vendor/github.com/vmware/govmomi/govc/flags/network.go +++ b/vendor/github.com/vmware/govmomi/govc/flags/network.go @@ -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) { diff --git a/vendor/github.com/vmware/govmomi/govc/flags/optional_bool.go b/vendor/github.com/vmware/govmomi/govc/flags/optional_bool.go new file mode 100644 index 0000000000..6adef51813 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/flags/optional_bool.go @@ -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 "" + } + 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} +} diff --git a/vendor/github.com/vmware/govmomi/govc/flags/output.go b/vendor/github.com/vmware/govmomi/govc/flags/output.go index 8ced5c862c..d6446f2065 100644 --- a/vendor/github.com/vmware/govmomi/govc/flags/output.go +++ b/vendor/github.com/vmware/govmomi/govc/flags/output.go @@ -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) } diff --git a/vendor/github.com/vmware/govmomi/govc/flags/resource_pool.go b/vendor/github.com/vmware/govmomi/govc/flags/resource_pool.go index 93ae5c4fa7..c7459c9782 100644 --- a/vendor/github.com/vmware/govmomi/govc/flags/resource_pool.go +++ b/vendor/github.com/vmware/govmomi/govc/flags/resource_pool.go @@ -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 } diff --git a/vendor/github.com/vmware/govmomi/govc/flags/search.go b/vendor/github.com/vmware/govmomi/govc/flags/search.go index 6a8649331f..c43912ffeb 100644 --- a/vendor/github.com/vmware/govmomi/govc/flags/search.go +++ b/vendor/github.com/vmware/govmomi/govc/flags/search.go @@ -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 } diff --git a/vendor/github.com/vmware/govmomi/govc/flags/virtual_app.go b/vendor/github.com/vmware/govmomi/govc/flags/virtual_app.go new file mode 100644 index 0000000000..e85819fa01 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/flags/virtual_app.go @@ -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 +} diff --git a/vendor/github.com/vmware/govmomi/govc/flags/virtual_machine.go b/vendor/github.com/vmware/govmomi/govc/flags/virtual_machine.go index 326a9165ea..0d3cc9a118 100644 --- a/vendor/github.com/vmware/govmomi/govc/flags/virtual_machine.go +++ b/vendor/github.com/vmware/govmomi/govc/flags/virtual_machine.go @@ -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 { diff --git a/vendor/github.com/vmware/govmomi/govc/host/add.go b/vendor/github.com/vmware/govmomi/govc/host/add.go index 48b9ccb64c..583f64cf76 100644 --- a/vendor/github.com/vmware/govmomi/govc/host/add.go +++ b/vendor/github.com/vmware/govmomi/govc/host/add.go @@ -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) } diff --git a/vendor/github.com/vmware/govmomi/govc/host/autostart/add.go b/vendor/github.com/vmware/govmomi/govc/host/autostart/add.go index 85949ae8ae..ec1fe3459a 100644 --- a/vendor/github.com/vmware/govmomi/govc/host/autostart/add.go +++ b/vendor/github.com/vmware/govmomi/govc/host/autostart/add.go @@ -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, diff --git a/vendor/github.com/vmware/govmomi/govc/host/autostart/autostart.go b/vendor/github.com/vmware/govmomi/govc/host/autostart/autostart.go index ef6d7f1722..4e260db32d 100644 --- a/vendor/github.com/vmware/govmomi/govc/host/autostart/autostart.go +++ b/vendor/github.com/vmware/govmomi/govc/host/autostart/autostart.go @@ -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 diff --git a/vendor/github.com/vmware/govmomi/govc/host/autostart/configure.go b/vendor/github.com/vmware/govmomi/govc/host/autostart/configure.go index 44994e3e39..405a26ce88 100644 --- a/vendor/github.com/vmware/govmomi/govc/host/autostart/configure.go +++ b/vendor/github.com/vmware/govmomi/govc/host/autostart/configure.go @@ -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) } diff --git a/vendor/github.com/vmware/govmomi/govc/host/autostart/info.go b/vendor/github.com/vmware/govmomi/govc/host/autostart/info.go index daa88cc756..33bd9ec89b 100644 --- a/vendor/github.com/vmware/govmomi/govc/host/autostart/info.go +++ b/vendor/github.com/vmware/govmomi/govc/host/autostart/info.go @@ -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 diff --git a/vendor/github.com/vmware/govmomi/govc/host/autostart/remove.go b/vendor/github.com/vmware/govmomi/govc/host/autostart/remove.go index b6e2dfd6ad..b41d5ec11b 100644 --- a/vendor/github.com/vmware/govmomi/govc/host/autostart/remove.go +++ b/vendor/github.com/vmware/govmomi/govc/host/autostart/remove.go @@ -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, diff --git a/vendor/github.com/vmware/govmomi/govc/host/disconnect.go b/vendor/github.com/vmware/govmomi/govc/host/disconnect.go new file mode 100644 index 0000000000..6c8ed9b800 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/host/disconnect.go @@ -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 +} diff --git a/vendor/github.com/vmware/govmomi/govc/host/esxcli/esxcli.go b/vendor/github.com/vmware/govmomi/govc/host/esxcli/esxcli.go index 0ef5c3b9b0..010d3b8850 100644 --- a/vendor/github.com/vmware/govmomi/govc/host/esxcli/esxcli.go +++ b/vendor/github.com/vmware/govmomi/govc/host/esxcli/esxcli.go @@ -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 diff --git a/vendor/github.com/vmware/govmomi/govc/host/esxcli/executor.go b/vendor/github.com/vmware/govmomi/govc/host/esxcli/executor.go index 5bcc18012b..0557910562 100644 --- a/vendor/github.com/vmware/govmomi/govc/host/esxcli/executor.go +++ b/vendor/github.com/vmware/govmomi/govc/host/esxcli/executor.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/govc/host/esxcli/firewall_info.go b/vendor/github.com/vmware/govmomi/govc/host/esxcli/firewall_info.go new file mode 100644 index 0000000000..ee4477a2f4 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/host/esxcli/firewall_info.go @@ -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 +} diff --git a/vendor/github.com/vmware/govmomi/govc/host/esxcli/guest_info.go b/vendor/github.com/vmware/govmomi/govc/host/esxcli/guest_info.go index 2cdc9babbd..5669793383 100644 --- a/vendor/github.com/vmware/govmomi/govc/host/esxcli/guest_info.go +++ b/vendor/github.com/vmware/govmomi/govc/host/esxcli/guest_info.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/govc/host/esxcli/response.go b/vendor/github.com/vmware/govmomi/govc/host/esxcli/response.go index f4d4fb1797..2957748c6c 100644 --- a/vendor/github.com/vmware/govmomi/govc/host/esxcli/response.go +++ b/vendor/github.com/vmware/govmomi/govc/host/esxcli/response.go @@ -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 ( diff --git a/vendor/github.com/vmware/govmomi/govc/host/firewall/find.go b/vendor/github.com/vmware/govmomi/govc/host/firewall/find.go new file mode 100644 index 0000000000..fd649fbd21 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/host/firewall/find.go @@ -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 +} diff --git a/vendor/github.com/vmware/govmomi/govc/host/info.go b/vendor/github.com/vmware/govmomi/govc/host/info.go index f5d3c8b43e..956791f3e6 100644 --- a/vendor/github.com/vmware/govmomi/govc/host/info.go +++ b/vendor/github.com/vmware/govmomi/govc/host/info.go @@ -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) diff --git a/vendor/github.com/vmware/govmomi/govc/host/maintenance/enter.go b/vendor/github.com/vmware/govmomi/govc/host/maintenance/enter.go new file mode 100644 index 0000000000..16405fdf62 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/host/maintenance/enter.go @@ -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 +} diff --git a/vendor/github.com/vmware/govmomi/govc/host/maintenance/exit.go b/vendor/github.com/vmware/govmomi/govc/host/maintenance/exit.go new file mode 100644 index 0000000000..ff51cb6f20 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/host/maintenance/exit.go @@ -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 +} diff --git a/vendor/github.com/vmware/govmomi/govc/host/portgroup/add.go b/vendor/github.com/vmware/govmomi/govc/host/portgroup/add.go index 811e1f5f5c..f1cb863788 100644 --- a/vendor/github.com/vmware/govmomi/govc/host/portgroup/add.go +++ b/vendor/github.com/vmware/govmomi/govc/host/portgroup/add.go @@ -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 diff --git a/vendor/github.com/vmware/govmomi/govc/host/portgroup/remove.go b/vendor/github.com/vmware/govmomi/govc/host/portgroup/remove.go index bb6e98d8c0..174455ae55 100644 --- a/vendor/github.com/vmware/govmomi/govc/host/portgroup/remove.go +++ b/vendor/github.com/vmware/govmomi/govc/host/portgroup/remove.go @@ -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 diff --git a/vendor/github.com/vmware/govmomi/govc/host/reconnect.go b/vendor/github.com/vmware/govmomi/govc/host/reconnect.go new file mode 100644 index 0000000000..26f0c3225b --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/host/reconnect.go @@ -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 +} diff --git a/vendor/github.com/vmware/govmomi/govc/host/remove.go b/vendor/github.com/vmware/govmomi/govc/host/remove.go new file mode 100644 index 0000000000..c9235e0fb4 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/host/remove.go @@ -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 +} diff --git a/vendor/github.com/vmware/govmomi/govc/host/storage/info.go b/vendor/github.com/vmware/govmomi/govc/host/storage/info.go new file mode 100644 index 0000000000..9d132399d7 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/host/storage/info.go @@ -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() +} diff --git a/vendor/github.com/vmware/govmomi/govc/host/storage/partition.go b/vendor/github.com/vmware/govmomi/govc/host/storage/partition.go new file mode 100644 index 0000000000..5e3d4d5d72 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/host/storage/partition.go @@ -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() +} diff --git a/vendor/github.com/vmware/govmomi/govc/host/vnic/info.go b/vendor/github.com/vmware/govmomi/govc/host/vnic/info.go new file mode 100644 index 0000000000..7631b64eee --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/host/vnic/info.go @@ -0,0 +1,146 @@ +/* +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 vnic + +import ( + "flag" + "fmt" + "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/mo" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type info struct { + *flags.HostSystemFlag +} + +func init() { + cli.Register("host.vnic.info", &info{}) +} + +func (cmd *info) Register(ctx context.Context, f *flag.FlagSet) { + cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx) + cmd.HostSystemFlag.Register(ctx, f) +} + +func (cmd *info) Process(ctx context.Context) error { + if err := cmd.HostSystemFlag.Process(ctx); err != nil { + return err + } + return nil +} + +func (cmd *info) Run(ctx context.Context, f *flag.FlagSet) error { + host, err := cmd.HostSystem() + if err != nil { + return err + } + + ns, err := cmd.HostNetworkSystem() + if err != nil { + return err + } + + var mns mo.HostNetworkSystem + + m, err := host.ConfigManager().VirtualNicManager(ctx) + if err != nil { + return err + } + + info, err := m.Info(ctx) + if err != nil { + return err + } + + err = ns.Properties(ctx, ns.Reference(), []string{"networkInfo"}, &mns) + if err != nil { + return err + } + + tw := tabwriter.NewWriter(os.Stdout, 2, 0, 2, ' ', 0) + + type dnet struct { + dvp mo.DistributedVirtualPortgroup + dvs mo.VmwareDistributedVirtualSwitch + } + + dnets := make(map[string]*dnet) + + for _, nic := range mns.NetworkInfo.Vnic { + fmt.Fprintf(tw, "Device:\t%s\n", nic.Device) + + if dvp := nic.Spec.DistributedVirtualPort; dvp != nil { + dn, ok := dnets[dvp.PortgroupKey] + + if !ok { + dn = new(dnet) + o := object.NewDistributedVirtualPortgroup(host.Client(), types.ManagedObjectReference{ + Type: "DistributedVirtualPortgroup", + Value: dvp.PortgroupKey, + }) + + err = o.Properties(ctx, o.Reference(), []string{"name", "config.distributedVirtualSwitch"}, &dn.dvp) + if err != nil { + return err + } + + err = o.Properties(ctx, *dn.dvp.Config.DistributedVirtualSwitch, []string{"name"}, &dn.dvs) + if err != nil { + return err + } + + dnets[dvp.PortgroupKey] = dn + } + + fmt.Fprintf(tw, "Network label:\t%s\n", dn.dvp.Name) + fmt.Fprintf(tw, "Switch:\t%s\n", dn.dvs.Name) + } else { + fmt.Fprintf(tw, "Network label:\t%s\n", nic.Portgroup) + for _, pg := range mns.NetworkInfo.Portgroup { + if pg.Spec.Name == nic.Portgroup { + fmt.Fprintf(tw, "Switch:\t%s\n", pg.Spec.VswitchName) + break + } + } + } + + fmt.Fprintf(tw, "IP address:\t%s\n", nic.Spec.Ip.IpAddress) + fmt.Fprintf(tw, "TCP/IP stack:\t%s\n", nic.Spec.NetStackInstanceKey) + + var services []string + for _, nc := range info.NetConfig { + for _, dev := range nc.SelectedVnic { + key := nc.NicType + "." + nic.Key + if dev == key { + services = append(services, nc.NicType) + } + } + + } + fmt.Fprintf(tw, "Enabled services:\t%s\n", strings.Join(services, ", ")) + } + + return tw.Flush() +} diff --git a/vendor/github.com/vmware/govmomi/govc/host/vnic/service.go b/vendor/github.com/vmware/govmomi/govc/host/vnic/service.go new file mode 100644 index 0000000000..3198974c34 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/host/vnic/service.go @@ -0,0 +1,112 @@ +/* +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 vnic + +import ( + "flag" + "fmt" + "strings" + + "github.com/vmware/govmomi/govc/cli" + "github.com/vmware/govmomi/govc/flags" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type service struct { + *flags.HostSystemFlag + + Enable bool + Disable bool +} + +func init() { + cli.Register("host.vnic.service", &service{}) +} + +func (cmd *service) Register(ctx context.Context, f *flag.FlagSet) { + cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx) + cmd.HostSystemFlag.Register(ctx, f) + + f.BoolVar(&cmd.Enable, "enable", false, "Enable service") + f.BoolVar(&cmd.Disable, "disable", false, "Disable service") +} + +func (cmd *service) Process(ctx context.Context) error { + if err := cmd.HostSystemFlag.Process(ctx); err != nil { + return err + } + // Either may be true or none may be true. + if cmd.Enable && cmd.Disable { + return flag.ErrHelp + } + + return nil +} + +func (cmd *service) Usage() string { + return "SERVICE DEVICE" +} + +func (cmd *service) Description() string { + nicTypes := []string{ + string(types.HostVirtualNicManagerNicTypeVmotion), + string(types.HostVirtualNicManagerNicTypeFaultToleranceLogging), + string(types.HostVirtualNicManagerNicTypeVSphereReplication), + string(types.HostVirtualNicManagerNicTypeVSphereReplicationNFC), + string(types.HostVirtualNicManagerNicTypeManagement), + string(types.HostVirtualNicManagerNicTypeVsan), + string(types.HostVirtualNicManagerNicTypeVSphereProvisioning), + } + + return fmt.Sprintf(` +Enable or disable service on a virtual nic device. Example: +SERVICE [%s] DEVICE [%s]`, strings.Join(nicTypes, "|"), strings.Join([]string{"vmk0", "vmk1", "..."}, "|")) +} + +func (cmd *service) Run(ctx context.Context, f *flag.FlagSet) error { + if f.NArg() != 2 { + return flag.ErrHelp + } + + service := f.Arg(0) + device := f.Arg(1) + + host, err := cmd.HostSystem() + if err != nil { + return err + } + + m, err := host.ConfigManager().VirtualNicManager(ctx) + if err != nil { + return err + } + + var method func(context.Context, string, string) error + + if cmd.Enable { + method = m.SelectVnic + } else if cmd.Disable { + method = m.DeselectVnic + } + + if method == nil { + return flag.ErrHelp + } + + return method(ctx, service, device) +} diff --git a/vendor/github.com/vmware/govmomi/govc/host/vswitch/add.go b/vendor/github.com/vmware/govmomi/govc/host/vswitch/add.go index 44a61819dc..0f1edd3404 100644 --- a/vendor/github.com/vmware/govmomi/govc/host/vswitch/add.go +++ b/vendor/github.com/vmware/govmomi/govc/host/vswitch/add.go @@ -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,19 +36,27 @@ func init() { cli.Register("host.vswitch.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.IntVar(&cmd.spec.NumPorts, "ports", 128, "Number of ports") f.IntVar(&cmd.spec.Mtu, "mtu", 0, "MTU") f.StringVar(&cmd.nic, "nic", "", "Bridge nic device") } -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 diff --git a/vendor/github.com/vmware/govmomi/govc/host/vswitch/info.go b/vendor/github.com/vmware/govmomi/govc/host/vswitch/info.go index 7dfe2484f0..589be13021 100644 --- a/vendor/github.com/vmware/govmomi/govc/host/vswitch/info.go +++ b/vendor/github.com/vmware/govmomi/govc/host/vswitch/info.go @@ -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,11 +40,29 @@ func init() { cli.Register("host.vswitch.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) + cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx) + cmd.OutputFlag.Register(ctx, f) + cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx) + cmd.HostSystemFlag.Register(ctx, f) +} -func (cmd *info) Process() error { return nil } +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(f *flag.FlagSet) error { +func (cmd *info) Run(ctx context.Context, f *flag.FlagSet) error { client, err := cmd.Client() if err != nil { return err diff --git a/vendor/github.com/vmware/govmomi/govc/host/vswitch/remove.go b/vendor/github.com/vmware/govmomi/govc/host/vswitch/remove.go index 26e41396f6..c5660d3225 100644 --- a/vendor/github.com/vmware/govmomi/govc/host/vswitch/remove.go +++ b/vendor/github.com/vmware/govmomi/govc/host/vswitch/remove.go @@ -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.vswitch.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 diff --git a/vendor/github.com/vmware/govmomi/govc/importx/archive.go b/vendor/github.com/vmware/govmomi/govc/importx/archive.go index ec540545fe..92722549c5 100644 --- a/vendor/github.com/vmware/govmomi/govc/importx/archive.go +++ b/vendor/github.com/vmware/govmomi/govc/importx/archive.go @@ -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,12 +18,65 @@ package importx import ( "archive/tar" + "flag" + "fmt" "io" + "io/ioutil" "os" "path" "path/filepath" + + "golang.org/x/net/context" + + "github.com/vmware/govmomi/ovf" ) +// ArchiveFlag doesn't register any flags; +// only encapsulates some common archive related functionality. +type ArchiveFlag struct { + Archive +} + +func newArchiveFlag(ctx context.Context) (*ArchiveFlag, context.Context) { + return &ArchiveFlag{}, ctx +} + +func (f *ArchiveFlag) Register(ctx context.Context, fs *flag.FlagSet) { +} + +func (f *ArchiveFlag) Process(ctx context.Context) error { + return nil +} + +func (f *ArchiveFlag) ReadOvf(fpath string) ([]byte, error) { + r, _, err := f.Archive.Open(fpath) + if err != nil { + return nil, err + } + defer r.Close() + + return ioutil.ReadAll(r) +} + +func (f *ArchiveFlag) ReadEnvelope(fpath string) (*ovf.Envelope, error) { + if fpath == "" { + return nil, nil + } + + r, _, err := f.Open(fpath) + if err != nil { + return nil, err + } + defer r.Close() + + e, err := ovf.Unmarshal(r) + if err != nil { + return nil, fmt.Errorf("failed to parse ovf: %s", err.Error()) + } + + return e, nil +} + type Archive interface { Open(string) (io.ReadCloser, int64, error) } diff --git a/vendor/github.com/vmware/govmomi/govc/importx/folder.go b/vendor/github.com/vmware/govmomi/govc/importx/folder.go new file mode 100644 index 0000000000..924e75f2ca --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/importx/folder.go @@ -0,0 +1,91 @@ +/* +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 importx + +import ( + "errors" + "flag" + + "golang.org/x/net/context" + + "github.com/vmware/govmomi/govc/flags" + "github.com/vmware/govmomi/object" +) + +type FolderFlag struct { + *flags.DatacenterFlag + + folder string +} + +func newFolderFlag(ctx context.Context) (*FolderFlag, context.Context) { + f := &FolderFlag{} + f.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx) + return f, ctx +} + +func (flag *FolderFlag) Register(ctx context.Context, f *flag.FlagSet) { + flag.DatacenterFlag.Register(ctx, f) + + f.StringVar(&flag.folder, "folder", "", "Path to folder to add the VM to") +} + +func (flag *FolderFlag) Process(ctx context.Context) error { + return flag.DatacenterFlag.Process(ctx) +} + +func (flag *FolderFlag) Folder() (*object.Folder, error) { + if len(flag.folder) == 0 { + dc, err := flag.Datacenter() + if err != nil { + return nil, err + } + folders, err := dc.Folders(context.TODO()) + if err != nil { + return nil, err + } + return folders.VmFolder, nil + } + + finder, err := flag.Finder() + if err != nil { + return nil, err + } + + mo, err := finder.ManagedObjectList(context.TODO(), flag.folder) + if err != nil { + return nil, err + } + if len(mo) == 0 { + return nil, errors.New("folder argument does not resolve to object") + } + if len(mo) > 1 { + return nil, errors.New("folder argument resolves to more than one object") + } + + ref := mo[0].Object.Reference() + if ref.Type != "Folder" { + return nil, errors.New("folder argument does not resolve to folder") + } + + c, err := flag.Client() + if err != nil { + return nil, err + } + + return object.NewFolder(c, ref), nil +} diff --git a/vendor/github.com/vmware/govmomi/govc/importx/lease_updater.go b/vendor/github.com/vmware/govmomi/govc/importx/lease_updater.go index 236e8c6297..6f1f1d1504 100644 --- a/vendor/github.com/vmware/govmomi/govc/importx/lease_updater.go +++ b/vendor/github.com/vmware/govmomi/govc/importx/lease_updater.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/govc/importx/options.go b/vendor/github.com/vmware/govmomi/govc/importx/options.go index eec51810fd..76c61786a8 100644 --- a/vendor/github.com/vmware/govmomi/govc/importx/options.go +++ b/vendor/github.com/vmware/govmomi/govc/importx/options.go @@ -18,108 +18,67 @@ package importx import ( "encoding/json" - "errors" "flag" - "io/ioutil" "os" - "github.com/vmware/govmomi/govc/flags" - "github.com/vmware/govmomi/object" - "github.com/vmware/govmomi/vim25/types" "golang.org/x/net/context" + + "github.com/vmware/govmomi/ovf" + "github.com/vmware/govmomi/vim25/types" ) +type Property struct { + types.KeyValue + Spec *ovf.Property `json:",omitempty"` +} + type Options struct { - AllDeploymentOptions []string + AllDeploymentOptions []string `json:",omitempty"` Deployment string - AllDiskProvisioningOptions []string + AllDiskProvisioningOptions []string `json:",omitempty"` DiskProvisioning string - AllIPAllocationPolicyOptions []string + AllIPAllocationPolicyOptions []string `json:",omitempty"` IPAllocationPolicy string - AllIPProtocolOptions []string + AllIPProtocolOptions []string `json:",omitempty"` IPProtocol string - PropertyMapping []types.KeyValue + PropertyMapping []Property `json:",omitempty"` PowerOn bool InjectOvfEnv bool WaitForIP bool + Name *string } -type ImportFlag struct { - *flags.DatacenterFlag +type OptionsFlag struct { + Options Options - folder string - optionsFpath string - Options Options + path string } -func (flag *ImportFlag) Register(f *flag.FlagSet) { - f.StringVar(&flag.folder, "folder", "", "Path to folder to add the vm to") - f.StringVar(&flag.optionsFpath, "options", "", "Options spec file path for vm deployment") +func newOptionsFlag(ctx context.Context) (*OptionsFlag, context.Context) { + return &OptionsFlag{}, ctx } -func (flag *ImportFlag) Process() error { - if len(flag.optionsFpath) > 0 { - f, err := os.Open(flag.optionsFpath) +func (flag *OptionsFlag) Register(ctx context.Context, f *flag.FlagSet) { + f.StringVar(&flag.path, "options", "", "Options spec file path for VM deployment") +} + +func (flag *OptionsFlag) Process(ctx context.Context) error { + if len(flag.path) > 0 { + f, err := os.Open(flag.path) if err != nil { return err } defer f.Close() - o, err := ioutil.ReadAll(f) - if err != nil { - return err - } - - if err := json.Unmarshal(o, &flag.Options); err != nil { + if err := json.NewDecoder(f).Decode(&flag.Options); err != nil { return err } } return nil } - -func (flag *ImportFlag) Folder() (*object.Folder, error) { - if len(flag.folder) == 0 { - dc, err := flag.Datacenter() - if err != nil { - return nil, err - } - folders, err := dc.Folders(context.TODO()) - if err != nil { - return nil, err - } - return folders.VmFolder, nil - } - - finder, err := flag.Finder() - if err != nil { - return nil, err - } - - mo, err := finder.ManagedObjectList(context.TODO(), flag.folder) - if err != nil { - return nil, err - } - if len(mo) == 0 { - return nil, errors.New("folder argument does not resolve to object") - } - if len(mo) > 1 { - return nil, errors.New("folder argument resolves to more than one object") - } - - ref := mo[0].Object.Reference() - if ref.Type != "Folder" { - return nil, errors.New("folder argument does not resolve to folder") - } - - c, err := flag.Client() - if err != nil { - return nil, err - } - return object.NewFolder(c, ref), nil -} diff --git a/vendor/github.com/vmware/govmomi/govc/importx/ova.go b/vendor/github.com/vmware/govmomi/govc/importx/ova.go index 4fefae0928..ce33484f6c 100644 --- a/vendor/github.com/vmware/govmomi/govc/importx/ova.go +++ b/vendor/github.com/vmware/govmomi/govc/importx/ova.go @@ -1,5 +1,5 @@ /* -Copyright (c) 2015 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,8 +18,8 @@ package importx import ( "flag" - "path" - "strings" + + "golang.org/x/net/context" "github.com/vmware/govmomi/govc/cli" "github.com/vmware/govmomi/object" @@ -38,9 +38,7 @@ func (cmd *ova) Usage() string { return "PATH_TO_OVA" } -func (cmd *ova) Register(f *flag.FlagSet) {} - -func (cmd *ova) Run(f *flag.FlagSet) error { +func (cmd *ova) Run(ctx context.Context, f *flag.FlagSet) error { fpath, err := cmd.Prepare(f) if err != nil { return err @@ -54,13 +52,10 @@ func (cmd *ova) Run(f *flag.FlagSet) error { } vm := object.NewVirtualMachine(cmd.Client, *moref) - return cmd.Deploy(vm) } func (cmd *ova) Import(fpath string) (*types.ManagedObjectReference, error) { - // basename i | sed -e s/\.ova$/*.ovf/ - ovf := strings.TrimSuffix(path.Base(fpath), path.Ext(fpath)) + ".ovf" - + ovf := "*.ovf" return cmd.ovfx.Import(ovf) } diff --git a/vendor/github.com/vmware/govmomi/govc/importx/ovf.go b/vendor/github.com/vmware/govmomi/govc/importx/ovf.go index 64293295c3..9f1aafcda2 100644 --- a/vendor/github.com/vmware/govmomi/govc/importx/ovf.go +++ b/vendor/github.com/vmware/govmomi/govc/importx/ovf.go @@ -1,5 +1,5 @@ /* -Copyright (c) 2015 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 ( "errors" "flag" "fmt" - "io/ioutil" "path" "strings" @@ -36,33 +35,77 @@ import ( ) type ovfx struct { - *ImportFlag *flags.DatastoreFlag *flags.HostSystemFlag *flags.OutputFlag *flags.ResourcePoolFlag + *ArchiveFlag + *OptionsFlag + *FolderFlag + + Name string + Client *vim25.Client Datacenter *object.Datacenter Datastore *object.Datastore ResourcePool *object.ResourcePool - - Archive } func init() { cli.Register("import.ovf", &ovfx{}) } -func (cmd *ovfx) Register(f *flag.FlagSet) {} +func (cmd *ovfx) Register(ctx context.Context, f *flag.FlagSet) { + cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx) + cmd.DatastoreFlag.Register(ctx, f) + cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx) + cmd.HostSystemFlag.Register(ctx, f) + cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx) + cmd.OutputFlag.Register(ctx, f) + cmd.ResourcePoolFlag, ctx = flags.NewResourcePoolFlag(ctx) + cmd.ResourcePoolFlag.Register(ctx, f) -func (cmd *ovfx) Process() error { return nil } + cmd.ArchiveFlag, ctx = newArchiveFlag(ctx) + cmd.ArchiveFlag.Register(ctx, f) + cmd.OptionsFlag, ctx = newOptionsFlag(ctx) + cmd.OptionsFlag.Register(ctx, f) + cmd.FolderFlag, ctx = newFolderFlag(ctx) + cmd.FolderFlag.Register(ctx, f) + + f.StringVar(&cmd.Name, "name", "", "Name to use for new entity") +} + +func (cmd *ovfx) Process(ctx context.Context) error { + if err := cmd.DatastoreFlag.Process(ctx); err != nil { + return err + } + if err := cmd.HostSystemFlag.Process(ctx); err != nil { + return err + } + if err := cmd.OutputFlag.Process(ctx); err != nil { + return err + } + if err := cmd.ResourcePoolFlag.Process(ctx); err != nil { + return err + } + if err := cmd.ArchiveFlag.Process(ctx); err != nil { + return err + } + if err := cmd.OptionsFlag.Process(ctx); err != nil { + return err + } + if err := cmd.FolderFlag.Process(ctx); err != nil { + return err + } + return nil +} func (cmd *ovfx) Usage() string { return "PATH_TO_OVF" } -func (cmd *ovfx) Run(f *flag.FlagSet) error { +func (cmd *ovfx) Run(ctx context.Context, f *flag.FlagSet) error { fpath, err := cmd.Prepare(f) if err != nil { return err @@ -76,7 +119,6 @@ func (cmd *ovfx) Run(f *flag.FlagSet) error { } vm := object.NewVirtualMachine(cmd.Client, *moref) - return cmd.Deploy(vm) } @@ -127,33 +169,12 @@ func (cmd *ovfx) Deploy(vm *object.VirtualMachine) error { return nil } -func (cmd *ovfx) ReadOvf(fpath string) ([]byte, error) { - f, _, err := cmd.Open(fpath) - if err != nil { - return nil, err - } - defer f.Close() - - return ioutil.ReadAll(f) -} - -func (cmd *ovfx) ReadEnvelope(fpath string) (*ovf.Envelope, error) { - if fpath == "" { - return nil, nil +func (cmd *ovfx) Map(op []Property) (p []types.KeyValue) { + for _, v := range op { + p = append(p, v.KeyValue) } - f, _, err := cmd.Open(fpath) - if err != nil { - return nil, err - } - defer f.Close() - - e, err := ovf.Unmarshal(f) - if err != nil { - return nil, fmt.Errorf("failed to parse ovf: %s", err.Error()) - } - - return e, nil + return } func (cmd *ovfx) Import(fpath string) (*types.ManagedObjectReference, error) { @@ -170,6 +191,19 @@ func (cmd *ovfx) Import(fpath string) (*types.ManagedObjectReference, error) { name := "Govc Virtual Appliance" if e.VirtualSystem != nil { name = e.VirtualSystem.ID + if e.VirtualSystem.Name != nil { + name = *e.VirtualSystem.Name + } + } + + // Override name from options if specified + if cmd.Options.Name != nil { + name = *cmd.Options.Name + } + + // Override name from arguments if specified + if cmd.Name != "" { + name = cmd.Name } cisp := types.OvfCreateImportSpecParams{ @@ -180,7 +214,7 @@ func (cmd *ovfx) Import(fpath string) (*types.ManagedObjectReference, error) { OvfManagerCommonParams: types.OvfManagerCommonParams{ DeploymentOption: cmd.Options.Deployment, Locale: "US"}, - PropertyMapping: cmd.Options.PropertyMapping, + PropertyMapping: cmd.Map(cmd.Options.PropertyMapping), } m := object.NewOvfManager(cmd.Client) @@ -305,7 +339,7 @@ func (cmd *ovfx) PowerOn(vm *object.VirtualMachine) error { return nil } - cmd.Log("Powering on vm...\n") + cmd.Log("Powering on VM...\n") task, err := vm.PowerOn(context.TODO()) if err != nil { @@ -326,7 +360,7 @@ func (cmd *ovfx) InjectOvfEnv(vm *object.VirtualMachine) error { a := cmd.Client.ServiceContent.About if strings.EqualFold(a.ProductLineId, "esx") || strings.EqualFold(a.ProductLineId, "embeddedEsx") { - cmd.Log("Injecting ovf env...\n") + cmd.Log("Injecting OVF environment...\n") // build up Environment in order to marshal to xml var epa []ovf.EnvProperty @@ -347,7 +381,7 @@ func (cmd *ovfx) InjectOvfEnv(vm *object.VirtualMachine) error { Properties: epa}, } - xenv := ovf.MarshalManual(env) + xenv := env.MarshalManual() vmConfigSpec := types.VirtualMachineConfigSpec{ ExtraConfig: []types.BaseOptionValue{&types.OptionValue{ Key: "guestinfo.ovfEnv", @@ -370,13 +404,12 @@ func (cmd *ovfx) WaitForIP(vm *object.VirtualMachine) error { return nil } - cmd.Log("Waiting for ip...\n") - + cmd.Log("Waiting for IP address...\n") ip, err := vm.WaitForIP(context.TODO()) if err != nil { return err } - cmd.Log(fmt.Sprintf("Received IP address: %s\n", ip)) + cmd.Log(fmt.Sprintf("Received IP address: %s\n", ip)) return nil } diff --git a/vendor/github.com/vmware/govmomi/govc/importx/spec.go b/vendor/github.com/vmware/govmomi/govc/importx/spec.go index 08f78a901f..cc7776442f 100644 --- a/vendor/github.com/vmware/govmomi/govc/importx/spec.go +++ b/vendor/github.com/vmware/govmomi/govc/importx/spec.go @@ -21,7 +21,8 @@ import ( "flag" "fmt" "path" - "strings" + + "golang.org/x/net/context" "github.com/vmware/govmomi/govc/cli" "github.com/vmware/govmomi/ovf" @@ -31,7 +32,6 @@ import ( var ( // all possible ovf property values // the first element being the default value - allDeploymentOptions = []string{"small", "medium", "large"} allDiskProvisioningOptions = []string{"thin", "monolithicSparse", "monolithicFlat", "twoGbMaxExtentSparse", "twoGbMaxExtentFlat", "seSparse", "eagerZeroedThick", "thick", "sparse", "flat"} allIPAllocationPolicyOptions = []string{"dhcpPolicy", "transientPolicy", "fixedPolicy", "fixedAllocatedPolicy"} @@ -39,60 +39,87 @@ var ( ) type spec struct { - *ovfx + *ArchiveFlag + + verbose bool } func init() { cli.Register("import.spec", &spec{}) } -func (cmd *spec) Register(f *flag.FlagSet) {} +func (cmd *spec) Register(ctx context.Context, f *flag.FlagSet) { + cmd.ArchiveFlag, ctx = newArchiveFlag(ctx) + cmd.ArchiveFlag.Register(ctx, f) -func (cmd *spec) Process() error { return nil } - -func (cmd *spec) Usage() string { - return "PATH_TO_OVF or PATH_TO_OVA" + f.BoolVar(&cmd.verbose, "verbose", false, "Verbose spec output") } -func (cmd *spec) Run(f *flag.FlagSet) error { +func (cmd *spec) Process(ctx context.Context) error { + if err := cmd.ArchiveFlag.Process(ctx); err != nil { + return err + } + return nil +} + +func (cmd *spec) Usage() string { + return "PATH_TO_OVF_OR_OVA" +} + +func (cmd *spec) Run(ctx context.Context, f *flag.FlagSet) error { fpath := "" args := f.Args() if len(args) == 1 { fpath = f.Arg(0) } - switch path.Ext(fpath) { - case "": - case ".ovf": - cmd.Archive = &FileArchive{fpath} - case ".ova": - cmd.Archive = &TapeArchive{fpath} - fpath = strings.TrimSuffix(path.Base(fpath), path.Ext(fpath)) + ".ovf" - default: - return fmt.Errorf("invalid file extension %s", path.Ext(fpath)) + if len(fpath) > 0 { + switch path.Ext(fpath) { + case ".ovf": + cmd.Archive = &FileArchive{fpath} + case "", ".ova": + cmd.Archive = &TapeArchive{fpath} + fpath = "*.ovf" + default: + return fmt.Errorf("invalid file extension %s", path.Ext(fpath)) + } } return cmd.Spec(fpath) } -func (cmd *spec) Map(e *ovf.Envelope) []types.KeyValue { +func (cmd *spec) Map(e *ovf.Envelope) (res []Property) { if e == nil { return nil } - var p []types.KeyValue - for _, v := range e.VirtualSystem.Product.Property { - d := "" - if v.Default != nil { - d = *v.Default - } + for _, p := range e.VirtualSystem.Product { + for i, v := range p.Property { + d := "" + if v.Default != nil { + d = *v.Default + } - p = append(p, types.KeyValue{ - Key: v.Key, - Value: d}) + // From OVF spec, section 9.5.1: + // key-value-env = [class-value "."] key-value-prod ["." instance-value] + k := v.Key + if p.Class != nil { + k = fmt.Sprintf("%s.%s", *p.Class, k) + } + if p.Instance != nil { + k = fmt.Sprintf("%s.%s", k, *p.Instance) + } + + np := Property{KeyValue: types.KeyValue{Key: k, Value: d}} + if cmd.verbose { + np.Spec = &p.Property[i] + } + + res = append(res, np) + } } - return p + return } func (cmd *spec) Spec(fpath string) error { @@ -102,14 +129,16 @@ func (cmd *spec) Spec(fpath string) error { } var deploymentOptions = allDeploymentOptions - if e != nil && e.DeploymentOption.Configuration != nil { + if e != nil && e.DeploymentOption != nil && e.DeploymentOption.Configuration != nil { deploymentOptions = nil + // add default first for _, c := range e.DeploymentOption.Configuration { if c.Default != nil && *c.Default { deploymentOptions = append(deploymentOptions, c.ID) } } + for _, c := range e.DeploymentOption.Configuration { if c.Default == nil || !*c.Default { deploymentOptions = append(deploymentOptions, c.ID) @@ -118,24 +147,26 @@ func (cmd *spec) Spec(fpath string) error { } o := Options{ - AllDeploymentOptions: deploymentOptions, - Deployment: deploymentOptions[0], - AllDiskProvisioningOptions: allDiskProvisioningOptions, - DiskProvisioning: allDiskProvisioningOptions[0], - AllIPAllocationPolicyOptions: allIPAllocationPolicyOptions, - IPAllocationPolicy: allIPAllocationPolicyOptions[0], - AllIPProtocolOptions: allIPProtocolOptions, - IPProtocol: allIPProtocolOptions[0], - PowerOn: false, - WaitForIP: false, - InjectOvfEnv: false, - PropertyMapping: cmd.Map(e)} + Deployment: deploymentOptions[0], + DiskProvisioning: allDiskProvisioningOptions[0], + IPAllocationPolicy: allIPAllocationPolicyOptions[0], + IPProtocol: allIPProtocolOptions[0], + PowerOn: false, + WaitForIP: false, + InjectOvfEnv: false, + PropertyMapping: cmd.Map(e)} + if cmd.verbose { + o.AllDeploymentOptions = deploymentOptions + o.AllDiskProvisioningOptions = allDiskProvisioningOptions + o.AllIPAllocationPolicyOptions = allIPAllocationPolicyOptions + o.AllIPProtocolOptions = allIPProtocolOptions + } j, err := json.Marshal(&o) if err != nil { return err } - fmt.Println(string(j)) + fmt.Println(string(j)) return nil } diff --git a/vendor/github.com/vmware/govmomi/govc/importx/vmdk.go b/vendor/github.com/vmware/govmomi/govc/importx/vmdk.go index 31c4496db3..6952532cce 100644 --- a/vendor/github.com/vmware/govmomi/govc/importx/vmdk.go +++ b/vendor/github.com/vmware/govmomi/govc/importx/vmdk.go @@ -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. @@ -56,19 +56,37 @@ func init() { cli.Alias("import.vmdk", "datastore.import") } -func (cmd *vmdk) Register(f *flag.FlagSet) { +func (cmd *vmdk) Register(ctx context.Context, f *flag.FlagSet) { + cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx) + cmd.DatastoreFlag.Register(ctx, f) + cmd.ResourcePoolFlag, ctx = flags.NewResourcePoolFlag(ctx) + cmd.ResourcePoolFlag.Register(ctx, f) + cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx) + cmd.OutputFlag.Register(ctx, f) + f.BoolVar(&cmd.upload, "upload", true, "Upload specified disk") f.BoolVar(&cmd.force, "force", false, "Overwrite existing disk") f.BoolVar(&cmd.keep, "keep", false, "Keep uploaded disk after import") } -func (cmd *vmdk) Process() error { return nil } +func (cmd *vmdk) Process(ctx context.Context) error { + if err := cmd.DatastoreFlag.Process(ctx); err != nil { + return err + } + if err := cmd.ResourcePoolFlag.Process(ctx); err != nil { + return err + } + if err := cmd.OutputFlag.Process(ctx); err != nil { + return err + } + return nil +} func (cmd *vmdk) Usage() string { return "PATH_TO_VMDK [REMOTE_DIRECTORY]" } -func (cmd *vmdk) Run(f *flag.FlagSet) error { +func (cmd *vmdk) Run(ctx context.Context, f *flag.FlagSet) error { var err error args := f.Args() @@ -129,15 +147,15 @@ func (cmd *vmdk) Run(f *flag.FlagSet) error { // func (cmd *vmdk) PrepareDestination(i importable) error { vmdkPath := i.RemoteDstVMDK() - res, err := cmd.Stat(vmdkPath) + res, err := cmd.Datastore.Stat(context.TODO(), vmdkPath) if err != nil { - switch err { - case flags.ErrDatastoreDirNotExist: + switch err.(type) { + case object.DatastoreNoSuchDirectoryError: // The base path doesn't exist. Create it. dsPath := cmd.Datastore.Path(path.Dir(vmdkPath)) m := object.NewFileManager(cmd.Client) return m.MakeDirectory(context.TODO(), dsPath, cmd.Datacenter, true) - case flags.ErrDatastoreFileNotExist: + case object.DatastoreNoSuchFileError: // Destination path doesn't exist; all good to continue with import. return nil } @@ -170,11 +188,6 @@ func (cmd *vmdk) PrepareDestination(i importable) error { } func (cmd *vmdk) Upload(i importable) error { - u, err := cmd.Datastore.URL(context.TODO(), cmd.Datacenter, i.RemoteSrcVMDK()) - if err != nil { - return err - } - p := soap.DefaultUpload if cmd.OutputFlag.TTY { logger := cmd.ProgressLogger("Uploading... ") @@ -182,7 +195,7 @@ func (cmd *vmdk) Upload(i importable) error { defer logger.Wait() } - return cmd.Client.Client.UploadFile(i.localPath, u, &p) + return cmd.Datastore.UploadFile(context.TODO(), i.localPath, i.RemoteSrcVMDK(), &p) } func (cmd *vmdk) Import(i importable) error { diff --git a/vendor/github.com/vmware/govmomi/govc/license/add.go b/vendor/github.com/vmware/govmomi/govc/license/add.go index f6e7df6264..a161c3d87e 100644 --- a/vendor/github.com/vmware/govmomi/govc/license/add.go +++ b/vendor/github.com/vmware/govmomi/govc/license/add.go @@ -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,15 +36,29 @@ func init() { cli.Register("license.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 } + cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx) + cmd.OutputFlag.Register(ctx, f) +} + +func (cmd *add) 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 *add) Usage() string { return "KEY..." } -func (cmd *add) Run(f *flag.FlagSet) error { +func (cmd *add) Run(ctx context.Context, f *flag.FlagSet) error { client, err := cmd.Client() if err != nil { return err diff --git a/vendor/github.com/vmware/govmomi/govc/license/assign.go b/vendor/github.com/vmware/govmomi/govc/license/assign.go new file mode 100644 index 0000000000..aedf239bc7 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/license/assign.go @@ -0,0 +1,114 @@ +/* +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 license + +import ( + "flag" + + "github.com/vmware/govmomi/govc/cli" + "github.com/vmware/govmomi/govc/flags" + "github.com/vmware/govmomi/license" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type assign struct { + *flags.ClientFlag + *flags.OutputFlag + *flags.HostSystemFlag + + name string + remove bool +} + +func init() { + cli.Register("license.assign", &assign{}) +} + +func (cmd *assign) 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.StringVar(&cmd.name, "name", "", "Display name") + f.BoolVar(&cmd.remove, "remove", false, "Remove assignment") +} + +func (cmd *assign) 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 *assign) Usage() string { + return "KEY" +} + +func (cmd *assign) Run(ctx context.Context, f *flag.FlagSet) error { + if f.NArg() != 1 { + return flag.ErrHelp + } + + key := f.Arg(0) + + client, err := cmd.Client() + if err != nil { + return err + } + + m, err := license.NewManager(client).AssignmentManager(ctx) + if err != nil { + return err + } + + host, err := cmd.HostSystemIfSpecified() + if err != nil { + return err + } + + var id string + + if host == nil { + // Default to vCenter UUID + id = client.ServiceContent.About.InstanceUuid + } else { + id = host.Reference().Value + } + + if cmd.remove { + return m.Remove(ctx, id) + } + + info, err := m.Update(ctx, id, key, cmd.name) + if err != nil { + return err + } + + return cmd.WriteResult(licenseOutput([]types.LicenseManagerLicenseInfo{*info})) +} diff --git a/vendor/github.com/vmware/govmomi/govc/license/assigned.go b/vendor/github.com/vmware/govmomi/govc/license/assigned.go new file mode 100644 index 0000000000..682e831a79 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/license/assigned.go @@ -0,0 +1,96 @@ +/* +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 license + +import ( + "flag" + "fmt" + "io" + "os" + "text/tabwriter" + + "github.com/vmware/govmomi/govc/cli" + "github.com/vmware/govmomi/govc/flags" + "github.com/vmware/govmomi/license" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type assigned struct { + *flags.ClientFlag + *flags.OutputFlag + + id string +} + +func init() { + cli.Register("license.assigned.list", &assigned{}) +} + +func (cmd *assigned) 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) + + f.StringVar(&cmd.id, "id", "", "Entity ID") +} + +func (cmd *assigned) 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 *assigned) Run(ctx context.Context, f *flag.FlagSet) error { + client, err := cmd.Client() + if err != nil { + return err + } + + m, err := license.NewManager(client).AssignmentManager(context.TODO()) + if err != nil { + return err + } + + assigned, err := m.QueryAssigned(context.TODO(), cmd.id) + if err != nil { + return err + } + + return cmd.WriteResult(assignedOutput(assigned)) +} + +type assignedOutput []types.LicenseAssignmentManagerLicenseAssignment + +func (res assignedOutput) Write(w io.Writer) error { + tw := tabwriter.NewWriter(os.Stdout, 4, 0, 2, ' ', 0) + fmt.Fprintf(tw, "Id:\tScope:\tName:\tLicense:\n") + for _, v := range res { + fmt.Fprintf(tw, "%s\t", v.EntityId) + fmt.Fprintf(tw, "%s\t", v.Scope) + fmt.Fprintf(tw, "%s\t", v.EntityDisplayName) + fmt.Fprintf(tw, "%s\t", v.AssignedLicense.LicenseKey) + fmt.Fprintf(tw, "\n") + } + return tw.Flush() +} diff --git a/vendor/github.com/vmware/govmomi/govc/license/decode.go b/vendor/github.com/vmware/govmomi/govc/license/decode.go new file mode 100644 index 0000000000..aadbed3193 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/license/decode.go @@ -0,0 +1,85 @@ +/* +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 license + +import ( + "flag" + + "github.com/vmware/govmomi/govc/cli" + "github.com/vmware/govmomi/govc/flags" + "github.com/vmware/govmomi/license" + "golang.org/x/net/context" +) + +type decode struct { + *flags.ClientFlag + *flags.OutputFlag + + feature string +} + +func init() { + cli.Register("license.decode", &decode{}) +} + +func (cmd *decode) 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) + + f.StringVar(&cmd.feature, "feature", "", featureUsage) +} + +func (cmd *decode) 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 *decode) Usage() string { + return "KEY..." +} + +func (cmd *decode) Run(ctx context.Context, f *flag.FlagSet) error { + client, err := cmd.Client() + if err != nil { + return err + } + + var result license.InfoList + m := license.NewManager(client) + for _, v := range f.Args() { + license, err := m.Decode(context.TODO(), v) + if err != nil { + return err + } + + result = append(result, license) + } + + if cmd.feature != "" { + result = result.WithFeature(cmd.feature) + } + + return cmd.WriteResult(licenseOutput(result)) +} diff --git a/vendor/github.com/vmware/govmomi/govc/license/list.go b/vendor/github.com/vmware/govmomi/govc/license/list.go index 9f8837a89d..382d75441e 100644 --- a/vendor/github.com/vmware/govmomi/govc/license/list.go +++ b/vendor/github.com/vmware/govmomi/govc/license/list.go @@ -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. @@ -25,20 +25,40 @@ import ( "golang.org/x/net/context" ) +var featureUsage = "List licenses with given feature" + type list struct { *flags.ClientFlag *flags.OutputFlag + + feature string } func init() { cli.Register("license.list", &list{}) } -func (cmd *list) Register(f *flag.FlagSet) {} +func (cmd *list) Register(ctx context.Context, f *flag.FlagSet) { + cmd.ClientFlag, ctx = flags.NewClientFlag(ctx) + cmd.ClientFlag.Register(ctx, f) -func (cmd *list) Process() error { return nil } + cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx) + cmd.OutputFlag.Register(ctx, f) -func (cmd *list) Run(f *flag.FlagSet) error { + f.StringVar(&cmd.feature, "feature", "", featureUsage) +} + +func (cmd *list) 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 *list) Run(ctx context.Context, f *flag.FlagSet) error { client, err := cmd.Client() if err != nil { return err @@ -50,5 +70,9 @@ func (cmd *list) Run(f *flag.FlagSet) error { return err } + if cmd.feature != "" { + result = result.WithFeature(cmd.feature) + } + return cmd.WriteResult(licenseOutput(result)) } diff --git a/vendor/github.com/vmware/govmomi/govc/license/output.go b/vendor/github.com/vmware/govmomi/govc/license/output.go index 8a2f0c3534..e4cfe42a5f 100644 --- a/vendor/github.com/vmware/govmomi/govc/license/output.go +++ b/vendor/github.com/vmware/govmomi/govc/license/output.go @@ -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. @@ -28,7 +28,7 @@ import ( type licenseOutput []types.LicenseManagerLicenseInfo func (res licenseOutput) Write(w io.Writer) error { - tw := tabwriter.NewWriter(os.Stdout, 2, 0, 2, ' ', 0) + tw := tabwriter.NewWriter(os.Stdout, 4, 0, 2, ' ', 0) fmt.Fprintf(tw, "Key:\tEdition:\tUsed:\tTotal:\n") for _, v := range res { fmt.Fprintf(tw, "%s\t", v.LicenseKey) diff --git a/vendor/github.com/vmware/govmomi/govc/license/remove.go b/vendor/github.com/vmware/govmomi/govc/license/remove.go index 634641652c..886a2bbb94 100644 --- a/vendor/github.com/vmware/govmomi/govc/license/remove.go +++ b/vendor/github.com/vmware/govmomi/govc/license/remove.go @@ -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,29 @@ func init() { cli.Register("license.remove", &remove{}) } -func (cmd *remove) Register(f *flag.FlagSet) {} +func (cmd *remove) Register(ctx context.Context, f *flag.FlagSet) { + cmd.ClientFlag, ctx = flags.NewClientFlag(ctx) + cmd.ClientFlag.Register(ctx, f) -func (cmd *remove) Process() error { return nil } + cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx) + cmd.OutputFlag.Register(ctx, f) +} + +func (cmd *remove) 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 *remove) Usage() string { return "KEY..." } -func (cmd *remove) Run(f *flag.FlagSet) error { +func (cmd *remove) Run(ctx context.Context, f *flag.FlagSet) error { client, err := cmd.Client() if err != nil { return err diff --git a/vendor/github.com/vmware/govmomi/govc/logs/command.go b/vendor/github.com/vmware/govmomi/govc/logs/command.go new file mode 100644 index 0000000000..4feeff7a78 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/logs/command.go @@ -0,0 +1,110 @@ +/* +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 logs + +import ( + "flag" + "fmt" + "math" + + "golang.org/x/net/context" + + "github.com/vmware/govmomi/govc/cli" + "github.com/vmware/govmomi/govc/flags" + "github.com/vmware/govmomi/object" +) + +type logs struct { + *flags.HostSystemFlag + + Max int + Key string +} + +func init() { + cli.Register("logs", &logs{}) +} + +func (cmd *logs) Register(ctx context.Context, f *flag.FlagSet) { + cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx) + cmd.HostSystemFlag.Register(ctx, f) + + f.IntVar(&cmd.Max, "n", 25, "Output the last N logs") + f.StringVar(&cmd.Key, "log", "", "Log file key") +} + +func (cmd *logs) Process(ctx context.Context) error { + if err := cmd.HostSystemFlag.Process(ctx); err != nil { + return err + } + return nil +} + +func (cmd *logs) Description() string { + return ` +The '-log' option defaults to "hostd" when connected directly to a host or +when connected to VirtualCenter and a '-host' option is given. Otherwise, +the '-log' option defaults to "vpxd:vpxd.log". The '-host' option is ignored +when connected directly to host. +See 'govc logs.ls' for other '-log' options.` +} + +func (cmd *logs) Run(ctx context.Context, f *flag.FlagSet) error { + c, err := cmd.Client() + if err != nil { + return err + } + + defaultKey := "hostd" + var host *object.HostSystem + + if c.ServiceContent.About.ApiType == "VirtualCenter" { + host, err = cmd.HostSystemIfSpecified() + if err != nil { + return err + } + + if host == nil { + defaultKey = "vpxd:vpxd.log" + } + } + + m := object.NewDiagnosticManager(c) + + key := cmd.Key + if key == "" { + key = defaultKey + } + + // get LineEnd without any LineText + h, err := m.BrowseLog(ctx, host, key, math.MaxInt32, 0) + if err != nil { + return err + } + + start := h.LineEnd - cmd.Max + h, err = m.BrowseLog(ctx, host, key, start, 0) + if err != nil { + return err + } + + for _, line := range h.LineText { + fmt.Println(line) + } + + return nil +} diff --git a/vendor/github.com/vmware/govmomi/govc/logs/download.go b/vendor/github.com/vmware/govmomi/govc/logs/download.go new file mode 100644 index 0000000000..5fa709c0c2 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/logs/download.go @@ -0,0 +1,133 @@ +/* +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 logs + +import ( + "flag" + "fmt" + "path" + + "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" + "github.com/vmware/govmomi/vim25/soap" + "github.com/vmware/govmomi/vim25/types" +) + +type download struct { + *flags.DatacenterFlag + + IncludeDefault bool +} + +func init() { + cli.Register("logs.download", &download{}) +} + +func (cmd *download) Register(ctx context.Context, f *flag.FlagSet) { + cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx) + cmd.DatacenterFlag.Register(ctx, f) + + f.BoolVar(&cmd.IncludeDefault, "default", true, "Specifies if the bundle should include the default server") +} + +func (cmd *download) Process(ctx context.Context) error { + if err := cmd.DatacenterFlag.Process(ctx); err != nil { + return err + } + return nil +} + +func (cmd *download) Usage() string { + return "[PATH]..." +} + +func (cmd *download) DownloadFile(c *vim25.Client, b string) error { + u, err := c.Client.ParseURL(b) + if err != nil { + return err + } + + dst := path.Base(u.Path) + p := soap.DefaultDownload + if cmd.OutputFlag.TTY { + logger := cmd.ProgressLogger(fmt.Sprintf("Downloading %s... ", dst)) + defer logger.Wait() + p.Progress = logger + } + + return c.Client.DownloadFile(dst, u, &p) +} + +func (cmd *download) GenerateLogBundles(m *object.DiagnosticManager, host []*object.HostSystem) ([]types.DiagnosticManagerBundleInfo, error) { + logger := cmd.ProgressLogger("Generating log bundles... ") + defer logger.Wait() + + task, err := m.GenerateLogBundles(context.TODO(), cmd.IncludeDefault, host) + if err != nil { + return nil, err + } + + r, err := task.WaitForResult(context.TODO(), logger) + if err != nil { + return nil, err + } + + return r.Result.(types.ArrayOfDiagnosticManagerBundleInfo).DiagnosticManagerBundleInfo, nil +} + +func (cmd *download) Run(ctx context.Context, f *flag.FlagSet) error { + finder, err := cmd.Finder() + if err != nil { + return err + } + + var host []*object.HostSystem + + for _, arg := range f.Args() { + hs, err := finder.HostSystemList(context.TODO(), arg) + if err != nil { + return err + } + + host = append(host, hs...) + } + + c, err := cmd.Client() + if err != nil { + return err + } + + m := object.NewDiagnosticManager(c) + + bundles, err := cmd.GenerateLogBundles(m, host) + if err != nil { + return err + } + + for _, bundle := range bundles { + err := cmd.DownloadFile(c, bundle.Url) + if err != nil { + return err + } + } + + return nil +} diff --git a/vendor/github.com/vmware/govmomi/govc/logs/ls.go b/vendor/github.com/vmware/govmomi/govc/logs/ls.go new file mode 100644 index 0000000000..4abd9311d6 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/logs/ls.go @@ -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 logs + +import ( + "flag" + "fmt" + "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" +) + +type ls struct { + *flags.HostSystemFlag +} + +func init() { + cli.Register("logs.ls", &ls{}) +} + +func (cmd *ls) Register(ctx context.Context, f *flag.FlagSet) { + cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx) + cmd.HostSystemFlag.Register(ctx, f) +} + +func (cmd *ls) Process(ctx context.Context) error { + if err := cmd.HostSystemFlag.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 + } + + var host *object.HostSystem + + if c.ServiceContent.About.ApiType == "VirtualCenter" { + host, err = cmd.HostSystemIfSpecified() + if err != nil { + return err + } + } + + m := object.NewDiagnosticManager(c) + + desc, err := m.QueryDescriptions(ctx, host) + if err != nil { + return err + } + + tw := tabwriter.NewWriter(os.Stdout, 2, 0, 2, ' ', 0) + + for _, d := range desc { + fmt.Fprintf(tw, "%s\t%s\n", d.Key, d.FileName) + } + + return tw.Flush() +} diff --git a/vendor/github.com/vmware/govmomi/govc/ls/command.go b/vendor/github.com/vmware/govmomi/govc/ls/command.go index 519be2b736..91b95ca3e0 100644 --- a/vendor/github.com/vmware/govmomi/govc/ls/command.go +++ b/vendor/github.com/vmware/govmomi/govc/ls/command.go @@ -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,11 +20,13 @@ import ( "flag" "fmt" "io" + "strings" "github.com/vmware/govmomi/govc/cli" "github.com/vmware/govmomi/govc/flags" "github.com/vmware/govmomi/list" "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/types" "golang.org/x/net/context" ) @@ -32,23 +34,41 @@ type ls struct { *flags.DatacenterFlag Long bool + Type string } func init() { cli.Register("ls", &ls{}) } -func (cmd *ls) Register(f *flag.FlagSet) { +func (cmd *ls) Register(ctx context.Context, f *flag.FlagSet) { + cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx) + cmd.DatacenterFlag.Register(ctx, f) + f.BoolVar(&cmd.Long, "l", false, "Long listing format") + f.StringVar(&cmd.Type, "t", "", "Object type") } -func (cmd *ls) Process() error { return nil } +func (cmd *ls) Process(ctx context.Context) error { + if err := cmd.DatacenterFlag.Process(ctx); err != nil { + return err + } + return nil +} func (cmd *ls) Usage() string { return "[PATH]..." } -func (cmd *ls) Run(f *flag.FlagSet) error { +func (cmd *ls) typeMatch(ref types.ManagedObjectReference) bool { + if cmd.Type == "" { + return true + } + + return strings.ToLower(cmd.Type) == strings.ToLower(ref.Type) +} + +func (cmd *ls) Run(ctx context.Context, f *flag.FlagSet) error { finder, err := cmd.Finder() if err != nil { return err @@ -70,7 +90,11 @@ func (cmd *ls) Run(f *flag.FlagSet) error { return err } - lr.Elements = append(lr.Elements, es...) + for _, e := range es { + if cmd.typeMatch(e.Object.Reference()) { + lr.Elements = append(lr.Elements, e) + } + } } return cmd.WriteResult(lr) diff --git a/vendor/github.com/vmware/govmomi/govc/main.go b/vendor/github.com/vmware/govmomi/govc/main.go index 4e8bacb557..3212d8634e 100644 --- a/vendor/github.com/vmware/govmomi/govc/main.go +++ b/vendor/github.com/vmware/govmomi/govc/main.go @@ -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 ( "github.com/vmware/govmomi/govc/cli" _ "github.com/vmware/govmomi/govc/about" + _ "github.com/vmware/govmomi/govc/cluster" _ "github.com/vmware/govmomi/govc/datacenter" _ "github.com/vmware/govmomi/govc/datastore" _ "github.com/vmware/govmomi/govc/device" @@ -29,17 +30,27 @@ import ( _ "github.com/vmware/govmomi/govc/device/floppy" _ "github.com/vmware/govmomi/govc/device/scsi" _ "github.com/vmware/govmomi/govc/device/serial" + _ "github.com/vmware/govmomi/govc/dvs" + _ "github.com/vmware/govmomi/govc/dvs/portgroup" _ "github.com/vmware/govmomi/govc/events" + _ "github.com/vmware/govmomi/govc/extension" _ "github.com/vmware/govmomi/govc/fields" _ "github.com/vmware/govmomi/govc/host" _ "github.com/vmware/govmomi/govc/host/autostart" _ "github.com/vmware/govmomi/govc/host/esxcli" + _ "github.com/vmware/govmomi/govc/host/firewall" + _ "github.com/vmware/govmomi/govc/host/maintenance" _ "github.com/vmware/govmomi/govc/host/portgroup" + _ "github.com/vmware/govmomi/govc/host/storage" + _ "github.com/vmware/govmomi/govc/host/vnic" _ "github.com/vmware/govmomi/govc/host/vswitch" _ "github.com/vmware/govmomi/govc/importx" _ "github.com/vmware/govmomi/govc/license" + _ "github.com/vmware/govmomi/govc/logs" _ "github.com/vmware/govmomi/govc/ls" + _ "github.com/vmware/govmomi/govc/permissions" _ "github.com/vmware/govmomi/govc/pool" + _ "github.com/vmware/govmomi/govc/vapp" _ "github.com/vmware/govmomi/govc/version" _ "github.com/vmware/govmomi/govc/vm" _ "github.com/vmware/govmomi/govc/vm/disk" diff --git a/vendor/github.com/vmware/govmomi/govc/permissions/ls.go b/vendor/github.com/vmware/govmomi/govc/permissions/ls.go new file mode 100644 index 0000000000..665809366a --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/permissions/ls.go @@ -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 cluster + +import ( + "flag" + "fmt" + "os" + "text/tabwriter" + + "github.com/vmware/govmomi/govc/cli" + "github.com/vmware/govmomi/govc/flags" + "github.com/vmware/govmomi/object" + "golang.org/x/net/context" +) + +type ls struct { + *flags.DatacenterFlag + *flags.OutputFlag +} + +func init() { + cli.Register("permissions.ls", &ls{}) +} + +func (cmd *ls) Register(ctx context.Context, f *flag.FlagSet) { + cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx) + cmd.DatacenterFlag.Register(ctx, f) + + cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx) + cmd.OutputFlag.Register(ctx, f) +} + +func (cmd *ls) Process(ctx context.Context) error { + if err := cmd.DatacenterFlag.Process(ctx); err != nil { + return err + } + if err := cmd.OutputFlag.Process(ctx); err != nil { + return err + } + return nil +} + +func (cmd *ls) Usage() string { + return "[PATH]..." +} + +func (cmd *ls) Description() string { + return `List the permissions defined on or effective on managed entities.` +} + +func (cmd *ls) Run(ctx context.Context, f *flag.FlagSet) error { + c, err := cmd.Client() + if err != nil { + return err + } + + refs, err := cmd.ManagedObjects(ctx, f.Args()) + if err != nil { + return err + } + + m := object.NewAuthorizationManager(c) + rl, err := m.RoleList(ctx) + if err != nil { + return err + } + + tw := tabwriter.NewWriter(os.Stdout, 2, 0, 2, ' ', 0) + + for _, ref := range refs { + perms, err := m.RetrieveEntityPermissions(ctx, ref, true) + if err != nil { + return err + } + + for _, perm := range perms { + fmt.Fprintf(tw, "%s\t%s\n", perm.Principal, rl.ById(perm.RoleId).Name) + } + } + + return tw.Flush() +} diff --git a/vendor/github.com/vmware/govmomi/govc/permissions/remove.go b/vendor/github.com/vmware/govmomi/govc/permissions/remove.go new file mode 100644 index 0000000000..becec48931 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/permissions/remove.go @@ -0,0 +1,85 @@ +/* +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" + + "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 remove struct { + *flags.DatacenterFlag + + types.Permission + + role string +} + +func init() { + cli.Register("permissions.remove", &remove{}) +} + +func (cmd *remove) Register(ctx context.Context, f *flag.FlagSet) { + cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx) + cmd.DatacenterFlag.Register(ctx, f) + + f.StringVar(&cmd.Principal, "principal", "", "User or group for which the permission is defined") + f.BoolVar(&cmd.Group, "group", false, "True, if principal refers to a group name; false, for a user name") +} + +func (cmd *remove) Process(ctx context.Context) error { + if err := cmd.DatacenterFlag.Process(ctx); err != nil { + return err + } + return nil +} + +func (cmd *remove) Usage() string { + return "[PATH]..." +} + +func (cmd *remove) Description() string { + return `Removes a permission rule from managed entities.` +} + +func (cmd *remove) Run(ctx context.Context, f *flag.FlagSet) error { + c, err := cmd.Client() + if err != nil { + return err + } + + refs, err := cmd.ManagedObjects(ctx, f.Args()) + if err != nil { + return err + } + + m := object.NewAuthorizationManager(c) + + for _, ref := range refs { + err = m.RemoveEntityPermission(ctx, ref, cmd.Principal, cmd.Group) + if err != nil { + return err + } + } + + return nil +} diff --git a/vendor/github.com/vmware/govmomi/govc/permissions/set.go b/vendor/github.com/vmware/govmomi/govc/permissions/set.go new file mode 100644 index 0000000000..6b58e7e476 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/permissions/set.go @@ -0,0 +1,103 @@ +/* +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" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type set struct { + *flags.DatacenterFlag + + types.Permission + + role string +} + +func init() { + cli.Register("permissions.set", &set{}) +} + +func (cmd *set) Register(ctx context.Context, f *flag.FlagSet) { + cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx) + cmd.DatacenterFlag.Register(ctx, f) + + f.StringVar(&cmd.Principal, "principal", "", "User or group for which the permission is defined") + f.BoolVar(&cmd.Group, "group", false, "True, if principal refers to a group name; false, for a user name") + f.BoolVar(&cmd.Propagate, "propagate", true, "Whether or not this permission propagates down the hierarchy to sub-entities") + f.StringVar(&cmd.role, "role", "Admin", "Permission role name") +} + +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 "[PATH]..." +} + +func (cmd *set) Description() string { + return `Set the permissions managed entities. +Example: +govc permissions.set -principal root -role Admin +` +} + +func (cmd *set) Run(ctx context.Context, f *flag.FlagSet) error { + c, err := cmd.Client() + if err != nil { + return err + } + + refs, err := cmd.ManagedObjects(ctx, f.Args()) + if err != nil { + return err + } + + m := object.NewAuthorizationManager(c) + rl, err := m.RoleList(ctx) + if err != nil { + return err + } + + role := rl.ByName(cmd.role) + if role == nil { + return fmt.Errorf("role '%s' not found", cmd.role) + } + cmd.Permission.RoleId = role.RoleId + + perms := []types.Permission{cmd.Permission} + + for _, ref := range refs { + err = m.SetEntityPermissions(ctx, ref, perms) + if err != nil { + return err + } + } + + return nil +} diff --git a/vendor/github.com/vmware/govmomi/govc/pool/change.go b/vendor/github.com/vmware/govmomi/govc/pool/change.go index 957d8f51c4..126733aea4 100644 --- a/vendor/github.com/vmware/govmomi/govc/pool/change.go +++ b/vendor/github.com/vmware/govmomi/govc/pool/change.go @@ -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. @@ -28,19 +28,32 @@ import ( type change struct { *flags.DatacenterFlag *ResourceConfigSpecFlag + name string } func init() { - spec := NewResourceConfigSpecFlag() - cli.Register("pool.change", &change{ResourceConfigSpecFlag: spec}) + cli.Register("pool.change", &change{}) } -func (cmd *change) Register(f *flag.FlagSet) { +func (cmd *change) Register(ctx context.Context, f *flag.FlagSet) { + cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx) + cmd.DatacenterFlag.Register(ctx, f) + cmd.ResourceConfigSpecFlag = NewResourceConfigSpecFlag() + cmd.ResourceConfigSpecFlag.Register(ctx, f) + f.StringVar(&cmd.name, "name", "", "Resource pool name") } -func (cmd *change) Process() error { return nil } +func (cmd *change) Process(ctx context.Context) error { + if err := cmd.DatacenterFlag.Process(ctx); err != nil { + return err + } + if err := cmd.ResourceConfigSpecFlag.Process(ctx); err != nil { + return err + } + return nil +} func (cmd *change) Usage() string { return "POOL..." @@ -50,7 +63,7 @@ func (cmd *change) Description() string { return "Change the configuration of one or more resource POOLs.\n" + poolNameHelp } -func (cmd *change) Run(f *flag.FlagSet) error { +func (cmd *change) Run(ctx context.Context, f *flag.FlagSet) error { if f.NArg() == 0 { return flag.ErrHelp } diff --git a/vendor/github.com/vmware/govmomi/govc/pool/create.go b/vendor/github.com/vmware/govmomi/govc/pool/create.go index b3636d06a1..affad74205 100644 --- a/vendor/github.com/vmware/govmomi/govc/pool/create.go +++ b/vendor/github.com/vmware/govmomi/govc/pool/create.go @@ -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,19 +34,31 @@ type create struct { } func init() { - spec := NewResourceConfigSpecFlag() - spec.SetAllocation(func(a types.BaseResourceAllocationInfo) { + cli.Register("pool.create", &create{}) +} + +func (cmd *create) Register(ctx context.Context, f *flag.FlagSet) { + cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx) + cmd.DatacenterFlag.Register(ctx, f) + + cmd.ResourceConfigSpecFlag = NewResourceConfigSpecFlag() + cmd.ResourceConfigSpecFlag.SetAllocation(func(a types.BaseResourceAllocationInfo) { ra := a.GetResourceAllocationInfo() ra.Shares.Level = types.SharesLevelNormal ra.ExpandableReservation = types.NewBool(true) }) - - cli.Register("pool.create", &create{ResourceConfigSpecFlag: spec}) + cmd.ResourceConfigSpecFlag.Register(ctx, f) } -func (cmd *create) Register(f *flag.FlagSet) {} - -func (cmd *create) Process() error { return nil } +func (cmd *create) Process(ctx context.Context) error { + if err := cmd.DatacenterFlag.Process(ctx); err != nil { + return err + } + if err := cmd.ResourceConfigSpecFlag.Process(ctx); err != nil { + return err + } + return nil +} func (cmd *create) Usage() string { return "POOL..." @@ -56,7 +68,7 @@ func (cmd *create) Description() string { return "Create one or more resource POOLs.\n" + poolCreateHelp } -func (cmd *create) Run(f *flag.FlagSet) error { +func (cmd *create) Run(ctx context.Context, f *flag.FlagSet) error { if f.NArg() == 0 { return flag.ErrHelp } diff --git a/vendor/github.com/vmware/govmomi/govc/pool/destroy.go b/vendor/github.com/vmware/govmomi/govc/pool/destroy.go index ad7d9a0dbb..6e1fe2668b 100644 --- a/vendor/github.com/vmware/govmomi/govc/pool/destroy.go +++ b/vendor/github.com/vmware/govmomi/govc/pool/destroy.go @@ -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. @@ -27,6 +27,7 @@ import ( type destroy struct { *flags.DatacenterFlag + recursive bool } @@ -34,11 +35,19 @@ func init() { cli.Register("pool.destroy", &destroy{}) } -func (cmd *destroy) Register(f *flag.FlagSet) { +func (cmd *destroy) Register(ctx context.Context, f *flag.FlagSet) { + cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx) + cmd.DatacenterFlag.Register(ctx, f) + f.BoolVar(&cmd.recursive, "r", false, "Remove all child resource pools recursively") } -func (cmd *destroy) Process() error { return nil } +func (cmd *destroy) Process(ctx context.Context) error { + if err := cmd.DatacenterFlag.Process(ctx); err != nil { + return err + } + return nil +} func (cmd *destroy) Usage() string { return "POOL..." @@ -48,7 +57,7 @@ func (cmd *destroy) Description() string { return "Destroy one or more resource POOLs.\n" + poolNameHelp } -func (cmd *destroy) Run(f *flag.FlagSet) error { +func (cmd *destroy) Run(ctx context.Context, f *flag.FlagSet) error { if f.NArg() == 0 { return flag.ErrHelp } diff --git a/vendor/github.com/vmware/govmomi/govc/pool/help.go b/vendor/github.com/vmware/govmomi/govc/pool/help.go index 951d48b353..dbd8ca23bd 100644 --- a/vendor/github.com/vmware/govmomi/govc/pool/help.go +++ b/vendor/github.com/vmware/govmomi/govc/pool/help.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/govc/pool/info.go b/vendor/github.com/vmware/govmomi/govc/pool/info.go index 83c17eb45e..7fcd28185a 100644 --- a/vendor/github.com/vmware/govmomi/govc/pool/info.go +++ b/vendor/github.com/vmware/govmomi/govc/pool/info.go @@ -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. @@ -22,8 +22,10 @@ import ( "io" "text/tabwriter" + "github.com/vmware/govmomi/find" "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" @@ -33,15 +35,34 @@ import ( type info struct { *flags.DatacenterFlag *flags.OutputFlag + + pools bool + apps bool } func init() { cli.Register("pool.info", &info{}) } -func (cmd *info) Register(f *flag.FlagSet) {} +func (cmd *info) Register(ctx context.Context, f *flag.FlagSet) { + cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx) + cmd.DatacenterFlag.Register(ctx, f) + cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx) + cmd.OutputFlag.Register(ctx, f) -func (cmd *info) Process() error { return nil } + f.BoolVar(&cmd.pools, "p", true, "List resource pools") + f.BoolVar(&cmd.apps, "a", false, "List virtual app resource pools") +} + +func (cmd *info) Process(ctx context.Context) error { + if err := cmd.DatacenterFlag.Process(ctx); err != nil { + return err + } + if err := cmd.OutputFlag.Process(ctx); err != nil { + return err + } + return nil +} func (cmd *info) Usage() string { return "POOL..." @@ -51,7 +72,7 @@ func (cmd *info) Description() string { return "Retrieve information about one or more resource POOLs.\n" + poolNameHelp } -func (cmd *info) Run(f *flag.FlagSet) error { +func (cmd *info) Run(ctx context.Context, f *flag.FlagSet) error { if f.NArg() == 0 { return flag.ErrHelp } @@ -81,22 +102,61 @@ func (cmd *info) Run(f *flag.FlagSet) error { } } + var vapps []*object.VirtualApp + for _, arg := range f.Args() { - pools, err := finder.ResourcePoolList(context.TODO(), arg) + if cmd.pools { + objects, err := finder.ResourcePoolList(ctx, arg) + if err != nil { + if _, ok := err.(*find.NotFoundError); !ok { + return err + } + } + res.objects = append(res.objects, objects...) + } + + if cmd.apps { + apps, err := finder.VirtualAppList(ctx, arg) + if err != nil { + if _, ok := err.(*find.NotFoundError); !ok { + return err + } + } + vapps = append(vapps, apps...) + } + } + + 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.ResourcePools) + if err != nil { + return err + } + } + + if len(vapps) != 0 { + var apps []mo.VirtualApp + refs := make([]types.ManagedObjectReference, 0, len(vapps)) + for _, o := range vapps { + refs = append(refs, o.Reference()) + p := object.NewResourcePool(c, o.Reference()) + p.InventoryPath = o.InventoryPath + res.objects = append(res.objects, p) + } + + pc := property.DefaultCollector(c) + err = pc.Retrieve(ctx, refs, props, &apps) if err != nil { return err } - for _, pool := range pools { - var p mo.ResourcePool - - pc := property.DefaultCollector(c) - err = pc.RetrieveOne(context.TODO(), pool.Reference(), props, &p) - if err != nil { - return err - } - - res.ResourcePools = append(res.ResourcePools, p) + for _, app := range apps { + res.ResourcePools = append(res.ResourcePools, app.ResourcePool) } } @@ -105,15 +165,26 @@ func (cmd *info) Run(f *flag.FlagSet) error { type infoResult struct { ResourcePools []mo.ResourcePool + objects []*object.ResourcePool } 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.ResourcePool, len(r.ResourcePools)) + for _, o := range r.ResourcePools { + objects[o.Reference()] = o + } + tw := tabwriter.NewWriter(w, 2, 0, 2, ' ', 0) - for _, pool := range r.ResourcePools { + for _, o := range r.objects { + pool := objects[o.Reference()] fmt.Fprintf(tw, "Name:\t%s\n", pool.Name) + fmt.Fprintf(tw, " Path:\t%s\n", o.InventoryPath) writeInfo(tw, "CPU", "MHz", &pool.Runtime.Cpu, pool.Config.CpuAllocation) + pool.Runtime.Memory.MaxUsage >>= 20 + pool.Runtime.Memory.OverallUsage >>= 20 writeInfo(tw, "Mem", "MB", &pool.Runtime.Memory, pool.Config.MemoryAllocation) } diff --git a/vendor/github.com/vmware/govmomi/govc/pool/resource_config_spec.go b/vendor/github.com/vmware/govmomi/govc/pool/resource_config_spec.go index 6086e3a1c2..5fd61fd967 100644 --- a/vendor/github.com/vmware/govmomi/govc/pool/resource_config_spec.go +++ b/vendor/github.com/vmware/govmomi/govc/pool/resource_config_spec.go @@ -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,6 +21,9 @@ import ( "strconv" "strings" + "golang.org/x/net/context" + + "github.com/vmware/govmomi/govc/flags" "github.com/vmware/govmomi/vim25/types" ) @@ -54,7 +57,6 @@ func NewResourceConfigSpecFlag() *ResourceConfigSpecFlag { f.SetAllocation(func(a types.BaseResourceAllocationInfo) { a.GetResourceAllocationInfo().Shares = new(types.SharesInfo) - a.GetResourceAllocationInfo().ExpandableReservation = types.NewBool(false) }) return f } @@ -63,9 +65,7 @@ type ResourceConfigSpecFlag struct { types.ResourceConfigSpec } -func (s *ResourceConfigSpecFlag) Process() error { return nil } - -func (s *ResourceConfigSpecFlag) Register(f *flag.FlagSet) { +func (s *ResourceConfigSpecFlag) Register(ctx context.Context, f *flag.FlagSet) { opts := []struct { name string units string @@ -80,18 +80,17 @@ func (s *ResourceConfigSpecFlag) Register(f *flag.FlagSet) { ra := opt.GetResourceAllocationInfo() shares := (*sharesInfo)(ra.Shares) - expandableReservation := false - if v := ra.ExpandableReservation; v != nil { - expandableReservation = *v - } - f.Int64Var(&ra.Limit, prefix+".limit", 0, opt.name+" limit in "+opt.units) f.Int64Var(&ra.Reservation, prefix+".reservation", 0, opt.name+" reservation in "+opt.units) - f.BoolVar(ra.ExpandableReservation, prefix+".expandable", expandableReservation, opt.name+" expandable reservation") + f.Var(flags.NewOptionalBool(&ra.ExpandableReservation), prefix+".expandable", opt.name+" expandable reservation") f.Var(shares, prefix+".shares", opt.name+" shares level or number") } } +func (s *ResourceConfigSpecFlag) Process(ctx context.Context) error { + return nil +} + func (s *ResourceConfigSpecFlag) SetAllocation(f func(types.BaseResourceAllocationInfo)) { for _, a := range []types.BaseResourceAllocationInfo{s.CpuAllocation, s.MemoryAllocation} { f(a) diff --git a/vendor/github.com/vmware/govmomi/govc/release.sh b/vendor/github.com/vmware/govmomi/govc/release.sh index 43e3de6f17..f934ad3429 100644 --- a/vendor/github.com/vmware/govmomi/govc/release.sh +++ b/vendor/github.com/vmware/govmomi/govc/release.sh @@ -17,7 +17,19 @@ export GITHUB_USER="${GITHUB_USER:-vmware}" export GITHUB_REPO="${GITHUB_REPO:-govmomi}" name="$(git describe)" -tag="prerelease-${name}" + +case "$1" in + release) + tag="${name}" + ;; + prerelease) + tag="prerelease-${name}" + ;; + *) + echo "Usage: $0 [release|prerelease]" + exit 1 + ;; +esac echo "Building govc..." rm -f govc_* diff --git a/vendor/github.com/vmware/govmomi/govc/test/README.md b/vendor/github.com/vmware/govmomi/govc/test/README.md index 2b48596463..d48e8fc869 100644 --- a/vendor/github.com/vmware/govmomi/govc/test/README.md +++ b/vendor/github.com/vmware/govmomi/govc/test/README.md @@ -4,6 +4,15 @@ Install [Bats](https://github.com/sstephenson/bats/) +## coreutils + +Install gxargs, greadlink and gmktemp on Darwin + +``` +brew install coreutils +brew install findutils +``` + ## Download test images Some tests depend on [ttylinux](http://ttylinux.net) images, these can be downloaded by running: @@ -46,7 +55,7 @@ running. To enable these tests: ## Running tests -The *govc* binary should be in your `PATH`; the test helper also prepends ../govc to `PATH`. +The test helper prepends ../govc to `PATH`. The tests can be run from any directory, as *govc* is found related to `PATH` and *images* are found relative to `$BATS_TEST_DIRNAME`. diff --git a/vendor/github.com/vmware/govmomi/govc/test/cli.bats b/vendor/github.com/vmware/govmomi/govc/test/cli.bats index 2973677841..72ea52406d 100644 --- a/vendor/github.com/vmware/govmomi/govc/test/cli.bats +++ b/vendor/github.com/vmware/govmomi/govc/test/cli.bats @@ -10,23 +10,16 @@ load test_helper @test "login attempt without credentials" { run govc about -u $(echo $GOVC_URL | awk -F@ '{print $2}') - assert_failure "Error: ServerFaultCode: Cannot complete login due to an incorrect user name or password." + assert_failure "govc: ServerFaultCode: Cannot complete login due to an incorrect user name or password." } @test "login attempt with GOVC_URL, GOVC_USERNAME, and GOVC_PASSWORD" { - local url - local username - local password - - url=$(echo $GOVC_URL | awk -F@ '{print $2}') - username=$(echo $GOVC_URL | awk -F@ '{print $1}' | awk -F: '{print $1}') - password=$(echo $GOVC_URL | awk -F@ '{print $1}' | awk -F: '{print $2}') - - run env GOVC_URL="${url}" GOVC_USERNAME="${username}" GOVC_PASSWORD="${password}" govc about + govc_url_to_vars + run govc about assert_success } @test "connect to an endpoint with a non-supported API version" { run env GOVC_MIN_API_VERSION=24.4 govc about - assert grep -q "^Error: Require API version 24.4," <<<${output} + assert grep -q "^govc: Require API version 24.4," <<<${output} } diff --git a/vendor/github.com/vmware/govmomi/govc/test/datacenter.bats b/vendor/github.com/vmware/govmomi/govc/test/datacenter.bats index 687af69f59..9a1a94a01b 100644 --- a/vendor/github.com/vmware/govmomi/govc/test/datacenter.bats +++ b/vendor/github.com/vmware/govmomi/govc/test/datacenter.bats @@ -75,11 +75,11 @@ load test_helper @test "fails when operation attempted on standalone ESX host" { run govc datacenter.create something assert_failure - assert_output "Error: ServerFaultCode: The operation is not supported on the object." + assert_output "govc: ServerFaultCode: The operation is not supported on the object." } @test "fails when attempting to destroy ha-datacenter" { run govc datacenter.destroy ha-datacenter assert_failure - assert_output "Error: The operation is not supported on the object." + assert_output "govc: The operation is not supported on the object." } diff --git a/vendor/github.com/vmware/govmomi/govc/test/datastore.bats b/vendor/github.com/vmware/govmomi/govc/test/datastore.bats index 8258153698..c1d4acac6c 100644 --- a/vendor/github.com/vmware/govmomi/govc/test/datastore.bats +++ b/vendor/github.com/vmware/govmomi/govc/test/datastore.bats @@ -3,7 +3,7 @@ load test_helper upload_file() { - file=$(mktemp --tmpdir govc-test-XXXXX) + file=$($mktemp --tmpdir govc-test-XXXXX) name=$(basename ${file}) echo "Hello world!" > ${file} @@ -35,7 +35,7 @@ upload_file() { # Long listing run govc datastore.ls -l "./govc-test-*" assert_success - assert_equal "13" $(awk '{ print $1 }' <<<${output}) + assert_equal "13B" $(awk '{ print $1 }' <<<${output}) } @test "datastore.rm" { @@ -44,7 +44,7 @@ upload_file() { # Not found is a failure run govc datastore.rm "${name}.notfound" assert_failure - assert_matches "Error: File .* was not found" "${output}" + assert_matches "govc: File .* was not found" "${output}" # Not found is NOT a failure with the force flag run govc datastore.rm -f "${name}.notfound" diff --git a/vendor/github.com/vmware/govmomi/govc/test/device.bats b/vendor/github.com/vmware/govmomi/govc/test/device.bats index c014acd569..b764830a68 100644 --- a/vendor/github.com/vmware/govmomi/govc/test/device.bats +++ b/vendor/github.com/vmware/govmomi/govc/test/device.bats @@ -76,13 +76,13 @@ load test_helper assert_success run govc device.disconnect -vm $vm $id - assert_failure "Error: device '$id' not found" + assert_failure "govc: device '$id' not found" run govc device.cdrom.insert -vm $vm -device $id x.iso - assert_failure "Error: device '$id' not found" + assert_failure "govc: device '$id' not found" run govc device.remove -vm $vm $id - assert_failure "Error: device '$id' not found" + assert_failure "govc: device '$id' not found" } @test "device.floppy" { @@ -117,13 +117,13 @@ load test_helper assert_success run govc device.disconnect -vm $vm $id - assert_failure "Error: device '$id' not found" + assert_failure "govc: device '$id' not found" run govc device.floppy.insert -vm $vm -device $id x.img - assert_failure "Error: device '$id' not found" + assert_failure "govc: device '$id' not found" run govc device.remove -vm $vm $id - assert_failure "Error: device '$id' not found" + assert_failure "govc: device '$id' not found" } @test "device.serial" { @@ -165,13 +165,13 @@ load test_helper assert_success run govc device.disconnect -vm $vm $id - assert_failure "Error: device '$id' not found" + assert_failure "govc: device '$id' not found" run govc device.serial.connect -vm $vm -device $id $uri - assert_failure "Error: device '$id' not found" + assert_failure "govc: device '$id' not found" run govc device.remove -vm $vm $id - assert_failure "Error: device '$id' not found" + assert_failure "govc: device '$id' not found" } @test "device.scsi" { diff --git a/vendor/github.com/vmware/govmomi/govc/test/extension.bats b/vendor/github.com/vmware/govmomi/govc/test/extension.bats new file mode 100644 index 0000000000..92b32f2d36 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/test/extension.bats @@ -0,0 +1,75 @@ +#!/usr/bin/env bats + +load test_helper + +@test "extension" { + vcsim_env + + govc extension.info | grep Name: | grep govc-test | awk '{print $2}' | $xargs -r govc extension.unregister + + run govc extension.info enoent + assert_failure + + id=$(new_id) + + result=$(govc extension.info | grep $id | wc -l) + [ $result -eq 0 ] + + # register extension + run govc extension.register $id < ${file} + + run govc import.ovf -options="${file}" $GOVC_IMAGES/${TTYLINUX_NAME}.ovf + assert_success + + run govc vm.destroy "${name}" + assert_success + + rm -f ${file} +} + +@test "import.ovf with name as argument" { + name=$(new_id) + + run govc import.ova -name="${name}" $GOVC_IMAGES/${TTYLINUX_NAME}.ova + assert_success + + run govc vm.destroy "${name}" + assert_success +} diff --git a/vendor/github.com/vmware/govmomi/govc/test/license.bats b/vendor/github.com/vmware/govmomi/govc/test/license.bats index 3e20363dba..6132eb11d4 100644 --- a/vendor/github.com/vmware/govmomi/govc/test/license.bats +++ b/vendor/github.com/vmware/govmomi/govc/test/license.bats @@ -44,3 +44,10 @@ get_property() { # Expect the test instance to run in evaluation mode assert_equal "Evaluation Mode" $(get_key 00000-00000-00000-00000-00000 <<<$output | jq -r ".Name") } + +@test "license.decode" { + verify_evaluation + + key=00000-00000-00000-00000-00000 + assert_equal "eval" $(govc license.decode $key | grep $key | awk '{print $2}') +} diff --git a/vendor/github.com/vmware/govmomi/govc/test/logs.bats b/vendor/github.com/vmware/govmomi/govc/test/logs.bats new file mode 100644 index 0000000000..733cd8f9c2 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/govc/test/logs.bats @@ -0,0 +1,38 @@ +#!/usr/bin/env bats + +load test_helper + +@test "logs" { + run govc logs + assert_success + nlogs=${#lines[@]} + # there should be plenty more than 1 line of hostd logs + [ $nlogs -ge 1 ] + + # test -n flag + run govc logs -n $((nlogs - 1)) + assert_success + [ ${#lines[@]} -le $nlogs ] + + run govc logs -log vmkernel + assert_success + nlogs=${#lines[@]} + # there should be plenty more than 1 line of vmkernel logs + [ $nlogs -ge 1 ] + + # -host ignored against ESX + run govc logs -host enoent + assert_success + + run govc logs -log enoent + assert_failure +} + +@test "logs.ls" { + run govc logs.ls + assert_success + + # -host ignored against ESX + run govc logs.ls -host enoent + assert_success +} diff --git a/vendor/github.com/vmware/govmomi/govc/test/network.bats b/vendor/github.com/vmware/govmomi/govc/test/network.bats index f13e05fd69..242e013c89 100644 --- a/vendor/github.com/vmware/govmomi/govc/test/network.bats +++ b/vendor/github.com/vmware/govmomi/govc/test/network.bats @@ -37,7 +37,7 @@ load test_helper assert_success run govc device.remove -vm $vm $eth0 - assert_failure "Error: device '$eth0' not found" + assert_failure "govc: device '$eth0' not found" } @test "network change backing" { @@ -47,10 +47,10 @@ load test_helper eth0=$(govc device.ls -vm $vm | grep ethernet- | awk '{print $1}') run govc vm.network.change -vm $vm $eth0 enoent - assert_failure "Error: network 'enoent' not found" + assert_failure "govc: network 'enoent' not found" run govc vm.network.change -vm $vm enoent "VM Network" - assert_failure "Error: device 'enoent' not found" + assert_failure "govc: device 'enoent' not found" run govc vm.network.change -vm $vm $eth0 "VM Network" assert_success @@ -60,7 +60,7 @@ load test_helper unset GOVC_NETWORK run govc vm.network.change -vm $vm $eth0 - assert_failure "Error: default network resolves to multiple instances, please specify" + assert_failure "govc: default network resolves to multiple instances, please specify" run govc vm.power -on $vm assert_success @@ -89,7 +89,7 @@ load test_helper assert_failure run govc vm.network.add -vm $vm enoent - assert_failure "Error: network 'enoent' not found" + assert_failure "govc: network 'enoent' not found" run govc vm.network.add -vm $vm "VM Network" assert_success @@ -101,7 +101,7 @@ load test_helper @test "network adapter" { vm=$(new_id) run govc vm.create -on=false -net.adapter=enoent $vm - assert_failure "Error: unknown ethernet card type 'enoent'" + assert_failure "govc: unknown ethernet card type 'enoent'" vm=$(new_id) run govc vm.create -on=false -net.adapter=vmxnet3 $vm @@ -125,7 +125,7 @@ load test_helper # -net flag is required when there are multiple networks unset GOVC_NETWORK run govc vm.create -on=false $(new_id) - assert_failure "Error: default network resolves to multiple instances, please specify" + assert_failure "govc: default network resolves to multiple instances, please specify" } @test "network change hardware address" { diff --git a/vendor/github.com/vmware/govmomi/govc/test/pool.bats b/vendor/github.com/vmware/govmomi/govc/test/pool.bats index 3c243b2e16..d2b551c1b2 100644 --- a/vendor/github.com/vmware/govmomi/govc/test/pool.bats +++ b/vendor/github.com/vmware/govmomi/govc/test/pool.bats @@ -6,7 +6,7 @@ load test_helper path="*/Resources/$(new_id)/$(new_id)" run govc pool.create $path assert_failure - assert_line "Error: cannot create resource pool '$(basename ${path})': parent not found" + assert_line "govc: cannot create resource pool '$(basename ${path})': parent not found" id=$(new_id) path="*/Resources/$id" @@ -186,10 +186,19 @@ load test_helper for path in $parent_path $child_path $grand_child_path do - run govc vm.create -on=false -pool $path $(new_id) + run govc vm.create -pool $path $(new_id) assert_success done + run govc pool.change -debug -mem.limit 100 -mem.expandable=false $child_path + assert_failure + + run govc pool.change -debug -mem.limit 100 $child_path + assert_success + + run govc pool.change -debug -mem.limit 120 -mem.expandable $child_path + assert_success + # test with glob inventory path to pools parent_path="*/$parent_name" child_path="$parent_path/$child_name" @@ -208,7 +217,7 @@ load test_helper path=$(govc ls host) run govc vm.create -on=false -pool enoent $id - assert_failure "Error: resource pool 'enoent' not found" + assert_failure "govc: resource pool 'enoent' not found" run govc vm.create -on=false -pool $path $id assert_success @@ -225,7 +234,7 @@ load test_helper unset GOVC_RESOURCE_POOL run govc vm.create -on=false -pool enoent $id - assert_failure "Error: resource pool 'enoent' not found" + assert_failure "govc: resource pool 'enoent' not found" run govc vm.create -on=false -pool $path $id assert_success diff --git a/vendor/github.com/vmware/govmomi/govc/test/test_helper.bash b/vendor/github.com/vmware/govmomi/govc/test/test_helper.bash index 3437b318d9..233aaae1c1 100644 --- a/vendor/github.com/vmware/govmomi/govc/test/test_helper.bash +++ b/vendor/github.com/vmware/govmomi/govc/test/test_helper.bash @@ -3,14 +3,19 @@ export GOVC_URL=$GOVC_TEST_URL export GOVC_DATASTORE=datastore1 export GOVC_NETWORK="VM Network" export GOVC_INSECURE=true +unset GOVC_DATACENTER +unset GOVC_USERNAME +unset GOVC_PASSWORD -if [ -z "$BATS_TEST_DIRNAME" ] -then +if [ -z "$BATS_TEST_DIRNAME" ]; then BATS_TEST_DIRNAME=$(dirname ${BASH_SOURCE}) fi -# canonicalize +# gnu core utils readlink=$(type -p greadlink readlink | head -1) +xargs=$(type -p gxargs xargs | head -1) +mktemp=$(type -p gmktemp mktemp | head -1) + BATS_TEST_DIRNAME=$($readlink -nf $BATS_TEST_DIRNAME) GOVC_IMAGES=$BATS_TEST_DIRNAME/images @@ -28,8 +33,8 @@ GOVC_TEST_IMG=$(basename $GOVC_TEST_IMG_SRC) PATH="$(dirname $BATS_TEST_DIRNAME):$PATH" teardown() { - govc ls vm | grep govc-test- | xargs -r govc vm.destroy - govc datastore.ls | grep govc-test- | awk '{print ($NF)}' | xargs -n1 -r govc datastore.rm + govc ls vm | grep govc-test- | $xargs -r govc vm.destroy + govc datastore.ls | grep govc-test- | awk '{print ($NF)}' | $xargs -n1 -r govc datastore.rm } new_id() { @@ -81,13 +86,11 @@ vm_mac() { # exports an enviroment for using vcsim if running, otherwise skips the calling test. vcsim_env() { - if [ "$(uname)" == "Darwin" ] - then + if [ "$(uname)" == "Darwin" ]; then PATH="/Applications/VMware Fusion.app/Contents/Library:$PATH" fi - if [ "$(vmrun list | grep $BATS_TEST_DIRNAME/vcsim | wc -l)" -eq 1 ] - then + if [ "$(vmrun list | grep $BATS_TEST_DIRNAME/vcsim | wc -l)" -eq 1 ]; then export GOVC_URL=https://root:vmware@localhost:16443/sdk \ GOVC_DATACENTER=DC0 \ GOVC_DATASTORE=GlobalDS_0 \ @@ -99,9 +102,21 @@ vcsim_env() { fi } +# remove username/password from $GOVC_URL and set $GOVC_{USERNAME,PASSWORD} +govc_url_to_vars() { + local url=$(awk -F@ '{print $2}' <<<"$GOVC_URL") + local userpass=$(awk -F// '{print $2}' <<<"$GOVC_URL" | awk -F@ '{print $1}') + local username=$(awk -F: '{print $1}' <<<"$userpass") + local password=$(awk -F: '{print $2}' <<<"$userpass") + + export GOVC_URL="$url" GOVC_USERNAME="$username" GOVC_PASSWORD="$password" + + # double check that we removed user/pass + grep -q -v @ <<<"$GOVC_URL" +} + quit_vnc() { - if [ "$(uname)" = "Darwin" ] - then + if [ "$(uname)" = "Darwin" ]; then osascript <=") + + f.Var(flags.NewOptionalBool(&cmd.NestedHVEnabled), "nested-hv-enabled", "Enable nested hardware-assisted virtualization") } -func (cmd *change) Process() error { return nil } +func (cmd *change) Process(ctx context.Context) error { + if err := cmd.VirtualMachineFlag.Process(ctx); err != nil { + return err + } + return nil +} -func (cmd *change) Run(f *flag.FlagSet) error { +func (cmd *change) Run(ctx context.Context, f *flag.FlagSet) error { vm, err := cmd.VirtualMachine() if err != nil { return err diff --git a/vendor/github.com/vmware/govmomi/govc/vm/create.go b/vendor/github.com/vmware/govmomi/govc/vm/create.go index 1aa6185b9b..fdb49eb95d 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/create.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/create.go @@ -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,7 +57,25 @@ func init() { cli.Register("vm.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) + + cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx) + cmd.DatacenterFlag.Register(ctx, f) + + cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx) + cmd.DatastoreFlag.Register(ctx, f) + + cmd.ResourcePoolFlag, ctx = flags.NewResourcePoolFlag(ctx) + cmd.ResourcePoolFlag.Register(ctx, f) + + cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx) + cmd.HostSystemFlag.Register(ctx, f) + + cmd.NetworkFlag, ctx = flags.NewNetworkFlag(ctx) + cmd.NetworkFlag.Register(ctx, f) + f.IntVar(&cmd.memory, "m", 1024, "Size in MB of memory") f.IntVar(&cmd.cpus, "c", 1, "Number of CPUs") f.StringVar(&cmd.guestID, "g", "otherGuest", "Guest OS") @@ -69,9 +87,29 @@ func (cmd *create) Register(f *flag.FlagSet) { f.StringVar(&cmd.disk, "disk", "", "Disk path 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 + } + if err := cmd.DatacenterFlag.Process(ctx); err != nil { + return err + } + if err := cmd.DatastoreFlag.Process(ctx); err != nil { + return err + } + if err := cmd.ResourcePoolFlag.Process(ctx); err != nil { + return err + } + if err := cmd.HostSystemFlag.Process(ctx); err != nil { + return err + } + if err := cmd.NetworkFlag.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 { var err error if len(f.Args()) != 1 { @@ -111,7 +149,7 @@ func (cmd *create) Run(f *flag.FlagSet) error { for _, file := range []*string{&cmd.iso, &cmd.disk} { if *file != "" { - _, err = cmd.Stat(*file) + _, err = cmd.Datastore.Stat(context.TODO(), *file) if err != nil { return err } @@ -208,7 +246,7 @@ func (cmd *create) createVM(name string) (*object.Task, error) { if !cmd.force { vmxPath := fmt.Sprintf("%s/%s.vmx", name, name) - _, err := cmd.Stat(vmxPath) + _, err := cmd.Datastore.Stat(context.TODO(), vmxPath) if err == nil { dsPath := cmd.Datastore.Path(vmxPath) return nil, fmt.Errorf("File %s already exists", dsPath) diff --git a/vendor/github.com/vmware/govmomi/govc/vm/destroy.go b/vendor/github.com/vmware/govmomi/govc/vm/destroy.go index dbef53d1ab..9796a87ed3 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/destroy.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/destroy.go @@ -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,13 +33,25 @@ func init() { cli.Register("vm.destroy", &destroy{}) } -func (cmd *destroy) Register(f *flag.FlagSet) { - cmd.SearchFlag = flags.NewSearchFlag(flags.SearchVirtualMachines) +func (cmd *destroy) Register(ctx context.Context, f *flag.FlagSet) { + cmd.ClientFlag, ctx = flags.NewClientFlag(ctx) + cmd.ClientFlag.Register(ctx, f) + + cmd.SearchFlag, ctx = flags.NewSearchFlag(ctx, flags.SearchVirtualMachines) + cmd.SearchFlag.Register(ctx, f) } -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 + } + if err := cmd.SearchFlag.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 { vms, err := cmd.VirtualMachines(f.Args()) if err != nil { return err diff --git a/vendor/github.com/vmware/govmomi/govc/vm/disk/attach.go b/vendor/github.com/vmware/govmomi/govc/vm/disk/attach.go index 79058b46b8..c001260229 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/disk/attach.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/disk/attach.go @@ -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. @@ -39,16 +39,29 @@ func init() { cli.Register("vm.disk.attach", &attach{}) } -func (cmd *attach) Register(f *flag.FlagSet) { +func (cmd *attach) 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.BoolVar(&cmd.persist, "persist", true, "Persist attached disk") f.BoolVar(&cmd.link, "link", true, "Link specified disk") f.StringVar(&cmd.controller, "controller", "", "Disk controller") f.StringVar(&cmd.disk, "disk", "", "Disk path name") } -func (cmd *attach) Process() error { return nil } +func (cmd *attach) 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 *attach) Run(f *flag.FlagSet) error { +func (cmd *attach) Run(ctx context.Context, f *flag.FlagSet) error { vm, err := cmd.VirtualMachine() if err != nil { return err diff --git a/vendor/github.com/vmware/govmomi/govc/vm/disk/create.go b/vendor/github.com/vmware/govmomi/govc/vm/disk/create.go index 12b8f58b59..7a97577f46 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/disk/create.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/disk/create.go @@ -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,14 @@ func init() { cli.Register("vm.disk.create", &create{}) } -func (cmd *create) Register(f *flag.FlagSet) { +func (cmd *create) 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) + cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx) + cmd.VirtualMachineFlag.Register(ctx, f) + err := (&cmd.Bytes).Set("10G") if err != nil { panic(err) @@ -51,9 +58,20 @@ func (cmd *create) Register(f *flag.FlagSet) { f.Var(&cmd.Bytes, "size", "Size of new disk") } -func (cmd *create) Process() error { return nil } +func (cmd *create) 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 + } + if err := cmd.VirtualMachineFlag.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 { if len(cmd.Name) == 0 { return errors.New("please specify a disk name") } diff --git a/vendor/github.com/vmware/govmomi/govc/vm/guest/auth.go b/vendor/github.com/vmware/govmomi/govc/vm/guest/auth.go index 9c69a46e8e..beab7f1c97 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/guest/auth.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/guest/auth.go @@ -22,6 +22,8 @@ import ( "os" "strings" + "golang.org/x/net/context" + "github.com/vmware/govmomi/vim25/types" ) @@ -29,6 +31,10 @@ type AuthFlag struct { auth types.NamePasswordAuthentication } +func newAuthFlag(ctx context.Context) (*AuthFlag, context.Context) { + return &AuthFlag{}, ctx +} + func (flag *AuthFlag) String() string { return fmt.Sprintf("%s:%s", flag.auth.Username, strings.Repeat("x", len(flag.auth.Password))) } @@ -45,7 +51,7 @@ func (flag *AuthFlag) Set(s string) error { return nil } -func (flag *AuthFlag) Register(f *flag.FlagSet) { +func (flag *AuthFlag) Register(ctx context.Context, f *flag.FlagSet) { env := "GOVC_GUEST_LOGIN" value := os.Getenv(env) flag.Set(value) @@ -53,7 +59,7 @@ func (flag *AuthFlag) Register(f *flag.FlagSet) { f.Var(flag, "l", usage) } -func (flag *AuthFlag) Process() error { +func (flag *AuthFlag) Process(ctx context.Context) error { return nil } diff --git a/vendor/github.com/vmware/govmomi/govc/vm/guest/chmod.go b/vendor/github.com/vmware/govmomi/govc/vm/guest/chmod.go index bd3f53d4ca..4243af51fd 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/guest/chmod.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/guest/chmod.go @@ -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,11 +32,24 @@ func init() { cli.Register("guest.chmod", &chmod{}) } -func (cmd *chmod) Register(f *flag.FlagSet) {} +func (cmd *chmod) Register(ctx context.Context, f *flag.FlagSet) { + cmd.GuestFlag, ctx = newGuestFlag(ctx) + cmd.GuestFlag.Register(ctx, f) + cmd.FileAttrFlag, ctx = newFileAttrFlag(ctx) + cmd.FileAttrFlag.Register(ctx, f) +} -func (cmd *chmod) Process() error { return nil } +func (cmd *chmod) Process(ctx context.Context) error { + if err := cmd.GuestFlag.Process(ctx); err != nil { + return err + } + if err := cmd.FileAttrFlag.Process(ctx); err != nil { + return err + } + return nil +} -func (cmd *chmod) Run(f *flag.FlagSet) error { +func (cmd *chmod) Run(ctx context.Context, f *flag.FlagSet) error { m, err := cmd.FileManager() if err != nil { return err diff --git a/vendor/github.com/vmware/govmomi/govc/vm/guest/download.go b/vendor/github.com/vmware/govmomi/govc/vm/guest/download.go index e0143feb2a..336c9fd131 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/guest/download.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/guest/download.go @@ -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,15 +35,21 @@ func init() { cli.Register("guest.download", &download{}) } -func (cmd *download) Register(f *flag.FlagSet) { +func (cmd *download) Register(ctx context.Context, f *flag.FlagSet) { + cmd.GuestFlag, ctx = newGuestFlag(ctx) + cmd.GuestFlag.Register(ctx, f) + f.BoolVar(&cmd.overwrite, "f", false, "If set, the local destination file is clobbered") } -func (cmd *download) Process() error { +func (cmd *download) Process(ctx context.Context) error { + if err := cmd.GuestFlag.Process(ctx); err != nil { + return err + } return nil } -func (cmd *download) Run(f *flag.FlagSet) error { +func (cmd *download) Run(ctx context.Context, f *flag.FlagSet) error { m, err := cmd.FileManager() if err != nil { return err diff --git a/vendor/github.com/vmware/govmomi/govc/vm/guest/file_attr.go b/vendor/github.com/vmware/govmomi/govc/vm/guest/file_attr.go index a7586b8164..3c943c02df 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/guest/file_attr.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/guest/file_attr.go @@ -19,6 +19,8 @@ package guest import ( "flag" + "golang.org/x/net/context" + "github.com/vmware/govmomi/vim25/types" ) @@ -26,13 +28,17 @@ type FileAttrFlag struct { types.GuestPosixFileAttributes } -func (flag *FileAttrFlag) Register(f *flag.FlagSet) { +func newFileAttrFlag(ctx context.Context) (*FileAttrFlag, context.Context) { + return &FileAttrFlag{}, ctx +} + +func (flag *FileAttrFlag) Register(ctx context.Context, f *flag.FlagSet) { f.IntVar(&flag.OwnerId, "uid", 0, "User ID") f.IntVar(&flag.GroupId, "gid", 0, "Group ID") f.Int64Var(&flag.Permissions, "perm", 0, "File permissions") } -func (flag *FileAttrFlag) Process() error { +func (flag *FileAttrFlag) Process(ctx context.Context) error { return nil } diff --git a/vendor/github.com/vmware/govmomi/govc/vm/guest/getenv.go b/vendor/github.com/vmware/govmomi/govc/vm/guest/getenv.go index 2d84d966be..193b03f6ee 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/guest/getenv.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/guest/getenv.go @@ -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,11 +32,19 @@ func init() { cli.Register("guest.getenv", &getenv{}) } -func (cmd *getenv) Register(f *flag.FlagSet) {} +func (cmd *getenv) Register(ctx context.Context, f *flag.FlagSet) { + cmd.GuestFlag, ctx = newGuestFlag(ctx) + cmd.GuestFlag.Register(ctx, f) +} -func (cmd *getenv) Process() error { return nil } +func (cmd *getenv) Process(ctx context.Context) error { + if err := cmd.GuestFlag.Process(ctx); err != nil { + return err + } + return nil +} -func (cmd *getenv) Run(f *flag.FlagSet) error { +func (cmd *getenv) Run(ctx context.Context, f *flag.FlagSet) error { m, err := cmd.ProcessManager() if err != nil { return err diff --git a/vendor/github.com/vmware/govmomi/govc/vm/guest/guest.go b/vendor/github.com/vmware/govmomi/govc/vm/guest/guest.go index 6ffe9873cf..f9f6a0172a 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/guest/guest.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/guest/guest.go @@ -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,9 +35,32 @@ type GuestFlag struct { *AuthFlag } -func (flag *GuestFlag) Register(f *flag.FlagSet) {} +func newGuestFlag(ctx context.Context) (*GuestFlag, context.Context) { + f := &GuestFlag{} + f.ClientFlag, ctx = flags.NewClientFlag(ctx) + f.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx) + f.AuthFlag, ctx = newAuthFlag(ctx) + return f, ctx +} -func (flag *GuestFlag) Process() error { return nil } +func (flag *GuestFlag) Register(ctx context.Context, f *flag.FlagSet) { + flag.ClientFlag.Register(ctx, f) + flag.VirtualMachineFlag.Register(ctx, f) + flag.AuthFlag.Register(ctx, f) +} + +func (flag *GuestFlag) Process(ctx context.Context) error { + if err := flag.ClientFlag.Process(ctx); err != nil { + return err + } + if err := flag.VirtualMachineFlag.Process(ctx); err != nil { + return err + } + if err := flag.AuthFlag.Process(ctx); err != nil { + return err + } + return nil +} func (flag *GuestFlag) FileManager() (*guest.FileManager, error) { c, err := flag.Client() diff --git a/vendor/github.com/vmware/govmomi/govc/vm/guest/kill.go b/vendor/github.com/vmware/govmomi/govc/vm/guest/kill.go index c2478ef60e..bb7f667239 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/guest/kill.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/guest/kill.go @@ -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,13 +33,21 @@ func init() { cli.Register("guest.kill", &kill{}) } -func (cmd *kill) Register(f *flag.FlagSet) { +func (cmd *kill) Register(ctx context.Context, f *flag.FlagSet) { + cmd.GuestFlag, ctx = newGuestFlag(ctx) + cmd.GuestFlag.Register(ctx, f) + f.Var(&cmd.pids, "p", "Process ID") } -func (cmd *kill) Process() error { return nil } +func (cmd *kill) Process(ctx context.Context) error { + if err := cmd.GuestFlag.Process(ctx); err != nil { + return err + } + return nil +} -func (cmd *kill) Run(f *flag.FlagSet) error { +func (cmd *kill) Run(ctx context.Context, f *flag.FlagSet) error { m, err := cmd.ProcessManager() if err != nil { return err diff --git a/vendor/github.com/vmware/govmomi/govc/vm/guest/ls.go b/vendor/github.com/vmware/govmomi/govc/vm/guest/ls.go index 005023e88a..1e39f7d9db 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/guest/ls.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/guest/ls.go @@ -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("guest.ls", &ls{}) } -func (cmd *ls) Register(f *flag.FlagSet) {} +func (cmd *ls) Register(ctx context.Context, f *flag.FlagSet) { + cmd.GuestFlag, ctx = newGuestFlag(ctx) + cmd.GuestFlag.Register(ctx, f) +} -func (cmd *ls) Process() error { return nil } +func (cmd *ls) Process(ctx context.Context) error { + if err := cmd.GuestFlag.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 { m, err := cmd.FileManager() if err != nil { return err diff --git a/vendor/github.com/vmware/govmomi/govc/vm/guest/mkdir.go b/vendor/github.com/vmware/govmomi/govc/vm/guest/mkdir.go index b05e62ec46..28859b0401 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/guest/mkdir.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/guest/mkdir.go @@ -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("guest.mkdir", &mkdir{}) } -func (cmd *mkdir) Register(f *flag.FlagSet) { +func (cmd *mkdir) Register(ctx context.Context, f *flag.FlagSet) { + cmd.GuestFlag, ctx = newGuestFlag(ctx) + cmd.GuestFlag.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.GuestFlag.Process(ctx); err != nil { + return err + } + return nil +} -func (cmd *mkdir) Run(f *flag.FlagSet) error { +func (cmd *mkdir) Run(ctx context.Context, f *flag.FlagSet) error { m, err := cmd.FileManager() if err != nil { return err diff --git a/vendor/github.com/vmware/govmomi/govc/vm/guest/mktemp.go b/vendor/github.com/vmware/govmomi/govc/vm/guest/mktemp.go index 56fbde879f..ed0af945d9 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/guest/mktemp.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/guest/mktemp.go @@ -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,15 +36,23 @@ func init() { cli.Register("guest.mktemp", &mktemp{}) } -func (cmd *mktemp) Register(f *flag.FlagSet) { +func (cmd *mktemp) Register(ctx context.Context, f *flag.FlagSet) { + cmd.GuestFlag, ctx = newGuestFlag(ctx) + cmd.GuestFlag.Register(ctx, f) + f.BoolVar(&cmd.dir, "d", false, "Make a directory instead of a file") f.StringVar(&cmd.prefix, "t", "", "Prefix") f.StringVar(&cmd.suffix, "s", "", "Suffix") } -func (cmd *mktemp) Process() error { return nil } +func (cmd *mktemp) Process(ctx context.Context) error { + if err := cmd.GuestFlag.Process(ctx); err != nil { + return err + } + return nil +} -func (cmd *mktemp) Run(f *flag.FlagSet) error { +func (cmd *mktemp) Run(ctx context.Context, f *flag.FlagSet) error { m, err := cmd.FileManager() if err != nil { return err diff --git a/vendor/github.com/vmware/govmomi/govc/vm/guest/ps.go b/vendor/github.com/vmware/govmomi/govc/vm/guest/ps.go index 6c92eb3b81..c443b3bf1d 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/guest/ps.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/guest/ps.go @@ -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. @@ -66,16 +66,24 @@ func init() { cli.Register("guest.ps", &ps{}) } -func (cmd *ps) Register(f *flag.FlagSet) { +func (cmd *ps) Register(ctx context.Context, f *flag.FlagSet) { + cmd.GuestFlag, ctx = newGuestFlag(ctx) + cmd.GuestFlag.Register(ctx, f) + cmd.uids = make(map[string]bool) f.BoolVar(&cmd.every, "e", false, "Select all processes") f.Var(&cmd.pids, "p", "Select by process ID") f.Var(&cmd.uids, "U", "Select by process UID") } -func (cmd *ps) Process() error { return nil } +func (cmd *ps) Process(ctx context.Context) error { + if err := cmd.GuestFlag.Process(ctx); err != nil { + return err + } + return nil +} -func (cmd *ps) Run(f *flag.FlagSet) error { +func (cmd *ps) Run(ctx context.Context, f *flag.FlagSet) error { m, err := cmd.ProcessManager() if err != nil { return err diff --git a/vendor/github.com/vmware/govmomi/govc/vm/guest/rm.go b/vendor/github.com/vmware/govmomi/govc/vm/guest/rm.go index 23920004bf..4c7c85f74d 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/guest/rm.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/guest/rm.go @@ -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. @@ -31,12 +31,19 @@ func init() { cli.Register("guest.rm", &rm{}) } -func (cmd *rm) Register(f *flag.FlagSet) { +func (cmd *rm) Register(ctx context.Context, f *flag.FlagSet) { + cmd.GuestFlag, ctx = newGuestFlag(ctx) + cmd.GuestFlag.Register(ctx, f) } -func (cmd *rm) Process() error { return nil } +func (cmd *rm) Process(ctx context.Context) error { + if err := cmd.GuestFlag.Process(ctx); err != nil { + return err + } + return nil +} -func (cmd *rm) Run(f *flag.FlagSet) error { +func (cmd *rm) Run(ctx context.Context, f *flag.FlagSet) error { m, err := cmd.FileManager() if err != nil { return err diff --git a/vendor/github.com/vmware/govmomi/govc/vm/guest/rmdir.go b/vendor/github.com/vmware/govmomi/govc/vm/guest/rmdir.go index 7938592d3c..723fe89324 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/guest/rmdir.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/guest/rmdir.go @@ -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,13 +33,21 @@ func init() { cli.Register("guest.rmdir", &rmdir{}) } -func (cmd *rmdir) Register(f *flag.FlagSet) { +func (cmd *rmdir) Register(ctx context.Context, f *flag.FlagSet) { + cmd.GuestFlag, ctx = newGuestFlag(ctx) + cmd.GuestFlag.Register(ctx, f) + f.BoolVar(&cmd.recursive, "p", false, "Recursive removal") } -func (cmd *rmdir) Process() error { return nil } +func (cmd *rmdir) Process(ctx context.Context) error { + if err := cmd.GuestFlag.Process(ctx); err != nil { + return err + } + return nil +} -func (cmd *rmdir) Run(f *flag.FlagSet) error { +func (cmd *rmdir) Run(ctx context.Context, f *flag.FlagSet) error { m, err := cmd.FileManager() if err != nil { return err diff --git a/vendor/github.com/vmware/govmomi/govc/vm/guest/start.go b/vendor/github.com/vmware/govmomi/govc/vm/guest/start.go index e6d8f9edd8..49818d0985 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/guest/start.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/guest/start.go @@ -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. @@ -48,14 +48,22 @@ func init() { cli.Register("guest.start", &start{}) } -func (cmd *start) Register(f *flag.FlagSet) { +func (cmd *start) Register(ctx context.Context, f *flag.FlagSet) { + cmd.GuestFlag, ctx = newGuestFlag(ctx) + cmd.GuestFlag.Register(ctx, f) + f.StringVar(&cmd.dir, "C", "", "The absolute path of the working directory for the program to start") f.Var(&cmd.vars, "e", "Set environment variable (key=val)") } -func (cmd *start) Process() error { return nil } +func (cmd *start) Process(ctx context.Context) error { + if err := cmd.GuestFlag.Process(ctx); err != nil { + return err + } + return nil +} -func (cmd *start) Run(f *flag.FlagSet) error { +func (cmd *start) Run(ctx context.Context, f *flag.FlagSet) error { m, err := cmd.ProcessManager() if err != nil { return err diff --git a/vendor/github.com/vmware/govmomi/govc/vm/guest/upload.go b/vendor/github.com/vmware/govmomi/govc/vm/guest/upload.go index ab8e1bd5a9..fb19a9a5cc 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/guest/upload.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/guest/upload.go @@ -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,26 @@ func init() { cli.Register("guest.upload", &upload{}) } -func (cmd *upload) Register(f *flag.FlagSet) { +func (cmd *upload) Register(ctx context.Context, f *flag.FlagSet) { + cmd.GuestFlag, ctx = newGuestFlag(ctx) + cmd.GuestFlag.Register(ctx, f) + cmd.FileAttrFlag, ctx = newFileAttrFlag(ctx) + cmd.FileAttrFlag.Register(ctx, f) + f.BoolVar(&cmd.overwrite, "f", false, "If set, the guest destination file is clobbered") } -func (cmd *upload) Process() error { return nil } +func (cmd *upload) Process(ctx context.Context) error { + if err := cmd.GuestFlag.Process(ctx); err != nil { + return err + } + if err := cmd.FileAttrFlag.Process(ctx); err != nil { + return err + } + return nil +} -func (cmd *upload) Run(f *flag.FlagSet) error { +func (cmd *upload) Run(ctx context.Context, f *flag.FlagSet) error { m, err := cmd.FileManager() if err != nil { return err diff --git a/vendor/github.com/vmware/govmomi/govc/vm/info.go b/vendor/github.com/vmware/govmomi/govc/vm/info.go index e2366ceeec..494bb8a262 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/info.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/info.go @@ -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,12 +21,16 @@ import ( "fmt" "io" "os" + "strings" "text/tabwriter" "github.com/vmware/govmomi/find" "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/units" "github.com/vmware/govmomi/vim25/mo" "github.com/vmware/govmomi/vim25/types" "golang.org/x/net/context" @@ -38,23 +42,45 @@ type info struct { *flags.SearchFlag WaitForIP bool + General bool ExtraConfig bool + Resources bool } func init() { cli.Register("vm.info", &info{}) } -func (cmd *info) Register(f *flag.FlagSet) { - cmd.SearchFlag = flags.NewSearchFlag(flags.SearchVirtualMachines) +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) + + cmd.SearchFlag, ctx = flags.NewSearchFlag(ctx, flags.SearchVirtualMachines) + cmd.SearchFlag.Register(ctx, f) f.BoolVar(&cmd.WaitForIP, "waitip", false, "Wait for VM to acquire IP address") + f.BoolVar(&cmd.General, "g", true, "Show general summary") f.BoolVar(&cmd.ExtraConfig, "e", false, "Show ExtraConfig") + f.BoolVar(&cmd.Resources, "r", false, "Show resource summary") } -func (cmd *info) Process() error { return nil } +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.SearchFlag.Process(ctx); err != nil { + return err + } + return nil +} -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 @@ -80,17 +106,24 @@ func (cmd *info) Run(f *flag.FlagSet) error { if cmd.OutputFlag.JSON { props = nil // Load everything } else { - props = []string{"summary", "guest.ipAddress"} // Load summary + props = []string{"summary"} // Load summary + if cmd.General { + props = append(props, "guest.ipAddress") + } if cmd.ExtraConfig { props = append(props, "config.extraConfig") } + if cmd.Resources { + props = append(props, "datastore", "network") + } } - ctx := context.TODO() pc := property.DefaultCollector(c) - err = pc.Retrieve(ctx, refs, props, &res.VirtualMachines) - if err != nil { - return err + if len(refs) != 0 { + err = pc.Retrieve(ctx, refs, props, &res.VirtualMachines) + if err != nil { + return err + } } if cmd.WaitForIP { @@ -109,32 +142,12 @@ func (cmd *info) Run(f *flag.FlagSet) error { } } - // Build a list of host system references and fetch host properties for all hosts in one call - xrefs := make(map[string]bool) - refs = nil - var hosts []mo.HostSystem - - for _, vm := range res.VirtualMachines { - href := vm.Summary.Runtime.Host - if href == nil { - continue + if !cmd.OutputFlag.JSON { + res.objects = vms + res.cmd = cmd + if err = res.collectReferences(pc, ctx); err != nil { + return err } - if _, exists := xrefs[href.Value]; exists { - continue - } - xrefs[href.Value] = true - refs = append(refs, *href) - } - - err = pc.Retrieve(ctx, refs, []string{"name"}, &hosts) - if err != nil { - return err - } - - res.hostSystems = make(map[string]*mo.HostSystem) - - for i, ref := range refs { - res.hostSystems[ref.Value] = &hosts[i] } return cmd.WriteResult(&res) @@ -142,33 +155,154 @@ func (cmd *info) Run(f *flag.FlagSet) error { type infoResult struct { VirtualMachines []mo.VirtualMachine - hostSystems map[string]*mo.HostSystem + objects []*object.VirtualMachine + entities map[types.ManagedObjectReference]string + cmd *info } -func (r *infoResult) Write(w io.Writer) error { - tw := tabwriter.NewWriter(os.Stdout, 2, 0, 2, ' ', 0) +// collectReferences builds a unique set of MORs to the set of VirtualMachines, +// so we can collect properties in a single call for each reference type {host,datastore,network}. +func (r *infoResult) collectReferences(pc *property.Collector, ctx context.Context) error { + r.entities = make(map[types.ManagedObjectReference]string) // MOR -> Name map + + var host []mo.HostSystem + var network []mo.Network + var dvp []mo.DistributedVirtualPortgroup + var datastore []mo.Datastore + // Table to drive inflating refs to their mo.* counterparts (dest) + // and save() the Name to r.entities w/o using reflection here. + // Note that we cannot use a []mo.ManagedEntity here, since mo.Network has its own 'Name' field, + // the mo.Network.ManagedEntity.Name field will not be set. + vrefs := map[string]*struct { + dest interface{} + refs []types.ManagedObjectReference + save func() + }{ + "HostSystem": { + &host, nil, func() { + for _, e := range host { + r.entities[e.Reference()] = e.Name + } + }, + }, + "Network": { + &network, nil, func() { + for _, e := range network { + r.entities[e.Reference()] = e.Name + } + }, + }, + "DistributedVirtualPortgroup": { + &dvp, nil, func() { + for _, e := range dvp { + r.entities[e.Reference()] = e.Name + } + }, + }, + "Datastore": { + &datastore, nil, func() { + for _, e := range datastore { + r.entities[e.Reference()] = e.Name + } + }, + }, + } + + xrefs := make(map[types.ManagedObjectReference]bool) + // Add MOR to vrefs[kind].refs avoiding any duplicates. + addRef := func(refs ...types.ManagedObjectReference) { + for _, ref := range refs { + if _, exists := xrefs[ref]; exists { + return + } + xrefs[ref] = true + vref := vrefs[ref.Type] + vref.refs = append(vref.refs, ref) + } + } for _, vm := range r.VirtualMachines { - s := vm.Summary - hostName := "" - - if href := vm.Summary.Runtime.Host; href != nil { - if h, ok := r.hostSystems[href.Value]; ok { - hostName = h.Name + if r.cmd.General { + if ref := vm.Summary.Runtime.Host; ref != nil { + addRef(*ref) } } - fmt.Fprintf(tw, "Name:\t%s\n", s.Config.Name) - fmt.Fprintf(tw, " UUID:\t%s\n", s.Config.Uuid) - fmt.Fprintf(tw, " Guest name:\t%s\n", s.Config.GuestFullName) - fmt.Fprintf(tw, " Memory:\t%dMB\n", s.Config.MemorySizeMB) - fmt.Fprintf(tw, " CPU:\t%d vCPU(s)\n", s.Config.NumCpu) - fmt.Fprintf(tw, " Power state:\t%s\n", s.Runtime.PowerState) - fmt.Fprintf(tw, " Boot time:\t%s\n", s.Runtime.BootTime) - fmt.Fprintf(tw, " IP address:\t%s\n", s.Guest.IpAddress) - fmt.Fprintf(tw, " Host:\t%s\n", hostName) + if r.cmd.Resources { + addRef(vm.Datastore...) + addRef(vm.Network...) + } + } - if vm.Config != nil && vm.Config.ExtraConfig != nil { + for _, vref := range vrefs { + if vref.refs == nil { + continue + } + err := pc.Retrieve(ctx, vref.refs, []string{"name"}, vref.dest) + if err != nil { + return err + } + vref.save() + } + + return nil +} + +func (r *infoResult) entityNames(refs []types.ManagedObjectReference) string { + var names []string + for _, ref := range refs { + names = append(names, r.entities[ref]) + } + return strings.Join(names, ", ") +} + +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.VirtualMachine, len(r.VirtualMachines)) + for _, o := range r.VirtualMachines { + objects[o.Reference()] = o + } + + tw := tabwriter.NewWriter(os.Stdout, 2, 0, 2, ' ', 0) + + for _, o := range r.objects { + vm := objects[o.Reference()] + s := vm.Summary + + fmt.Fprintf(tw, "Name:\t%s\n", s.Config.Name) + + if r.cmd.General { + hostName := "" + + if href := vm.Summary.Runtime.Host; href != nil { + if name, ok := r.entities[*href]; ok { + hostName = name + } + } + + fmt.Fprintf(tw, " Path:\t%s\n", o.InventoryPath) + fmt.Fprintf(tw, " UUID:\t%s\n", s.Config.Uuid) + fmt.Fprintf(tw, " Guest name:\t%s\n", s.Config.GuestFullName) + fmt.Fprintf(tw, " Memory:\t%dMB\n", s.Config.MemorySizeMB) + fmt.Fprintf(tw, " CPU:\t%d vCPU(s)\n", s.Config.NumCpu) + fmt.Fprintf(tw, " Power state:\t%s\n", s.Runtime.PowerState) + fmt.Fprintf(tw, " Boot time:\t%s\n", s.Runtime.BootTime) + fmt.Fprintf(tw, " IP address:\t%s\n", s.Guest.IpAddress) + fmt.Fprintf(tw, " Host:\t%s\n", hostName) + } + + if r.cmd.Resources { + fmt.Fprintf(tw, " CPU usage:\t%dMHz\n", s.QuickStats.OverallCpuUsage) + fmt.Fprintf(tw, " Host memory usage:\t%dMB\n", s.QuickStats.HostMemoryUsage) + fmt.Fprintf(tw, " Guest memory usage:\t%dMB\n", s.QuickStats.GuestMemoryUsage) + fmt.Fprintf(tw, " Storage uncommitted:\t%s\n", units.ByteSize(s.Storage.Uncommitted)) + fmt.Fprintf(tw, " Storage committed:\t%s\n", units.ByteSize(s.Storage.Committed)) + fmt.Fprintf(tw, " Storage unshared:\t%s\n", units.ByteSize(s.Storage.Unshared)) + fmt.Fprintf(tw, " Storage:\t%s\n", r.entityNames(vm.Datastore)) + fmt.Fprintf(tw, " Network:\t%s\n", r.entityNames(vm.Network)) + } + + if r.cmd.ExtraConfig { fmt.Fprintf(tw, " ExtraConfig:\n") for _, v := range vm.Config.ExtraConfig { fmt.Fprintf(tw, " %s:\t%s\n", v.GetOptionValue().Key, v.GetOptionValue().Value) diff --git a/vendor/github.com/vmware/govmomi/govc/vm/ip.go b/vendor/github.com/vmware/govmomi/govc/vm/ip.go index 580026f914..6c0992cc2f 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/ip.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/ip.go @@ -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. @@ -39,14 +39,27 @@ func init() { cli.Register("vm.ip", &ip{}) } -func (cmd *ip) Register(f *flag.FlagSet) { - cmd.SearchFlag = flags.NewSearchFlag(flags.SearchVirtualMachines) +func (cmd *ip) Register(ctx context.Context, f *flag.FlagSet) { + cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx) + cmd.OutputFlag.Register(ctx, f) + + cmd.SearchFlag, ctx = flags.NewSearchFlag(ctx, flags.SearchVirtualMachines) + cmd.SearchFlag.Register(ctx, f) + f.BoolVar(&cmd.esx, "esxcli", false, "Use esxcli instead of guest tools") } -func (cmd *ip) Process() error { return nil } +func (cmd *ip) Process(ctx context.Context) error { + if err := cmd.OutputFlag.Process(ctx); err != nil { + return err + } + if err := cmd.SearchFlag.Process(ctx); err != nil { + return err + } + return nil +} -func (cmd *ip) Run(f *flag.FlagSet) error { +func (cmd *ip) Run(ctx context.Context, f *flag.FlagSet) error { c, err := cmd.Client() if err != nil { return err diff --git a/vendor/github.com/vmware/govmomi/govc/vm/network/add.go b/vendor/github.com/vmware/govmomi/govc/vm/network/add.go index cee82c8b75..8f6006ebc6 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/network/add.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/network/add.go @@ -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,24 @@ func init() { cli.Register("vm.network.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) + cmd.NetworkFlag, ctx = flags.NewNetworkFlag(ctx) + cmd.NetworkFlag.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 + } + if err := cmd.NetworkFlag.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.VirtualMachineFlag.VirtualMachine() if err != nil { return err diff --git a/vendor/github.com/vmware/govmomi/govc/vm/network/change.go b/vendor/github.com/vmware/govmomi/govc/vm/network/change.go index 3818546533..f7b4035064 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/network/change.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/network/change.go @@ -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,11 +36,24 @@ func init() { cli.Register("vm.network.change", &change{}) } -func (cmd *change) Register(f *flag.FlagSet) {} +func (cmd *change) Register(ctx context.Context, f *flag.FlagSet) { + cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx) + cmd.VirtualMachineFlag.Register(ctx, f) + cmd.NetworkFlag, ctx = flags.NewNetworkFlag(ctx) + cmd.NetworkFlag.Register(ctx, f) +} -func (cmd *change) Process() error { return nil } +func (cmd *change) Process(ctx context.Context) error { + if err := cmd.VirtualMachineFlag.Process(ctx); err != nil { + return err + } + if err := cmd.NetworkFlag.Process(ctx); err != nil { + return err + } + return nil +} -func (cmd *change) Run(f *flag.FlagSet) error { +func (cmd *change) Run(ctx context.Context, f *flag.FlagSet) error { vm, err := cmd.VirtualMachineFlag.VirtualMachine() if err != nil { return err diff --git a/vendor/github.com/vmware/govmomi/govc/vm/power.go b/vendor/github.com/vmware/govmomi/govc/vm/power.go index e34d189cff..dbbeed8f4a 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/power.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/power.go @@ -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. @@ -7,6 +7,7 @@ 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. @@ -23,6 +24,8 @@ import ( "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" ) @@ -43,8 +46,12 @@ func init() { cli.Register("vm.power", &power{}) } -func (cmd *power) Register(f *flag.FlagSet) { - cmd.SearchFlag = flags.NewSearchFlag(flags.SearchVirtualMachines) +func (cmd *power) Register(ctx context.Context, f *flag.FlagSet) { + cmd.ClientFlag, ctx = flags.NewClientFlag(ctx) + cmd.ClientFlag.Register(ctx, f) + + cmd.SearchFlag, ctx = flags.NewSearchFlag(ctx, flags.SearchVirtualMachines) + cmd.SearchFlag.Register(ctx, f) f.BoolVar(&cmd.On, "on", false, "Power on") f.BoolVar(&cmd.Off, "off", false, "Power off") @@ -52,10 +59,16 @@ func (cmd *power) Register(f *flag.FlagSet) { f.BoolVar(&cmd.Suspend, "suspend", false, "Power suspend") f.BoolVar(&cmd.Reboot, "r", false, "Reboot guest") f.BoolVar(&cmd.Shutdown, "s", false, "Shutdown guest") - f.BoolVar(&cmd.Force, "force", false, "Force (ignore state error)") + f.BoolVar(&cmd.Force, "force", false, "Force (ignore state error and hard shutdown/reboot if tools unavailable)") } -func (cmd *power) Process() error { +func (cmd *power) Process(ctx context.Context) error { + if err := cmd.ClientFlag.Process(ctx); err != nil { + return err + } + if err := cmd.SearchFlag.Process(ctx); err != nil { + return err + } opts := []bool{cmd.On, cmd.Off, cmd.Reset, cmd.Suspend, cmd.Reboot, cmd.Shutdown} selected := false @@ -75,7 +88,18 @@ func (cmd *power) Process() error { return nil } -func (cmd *power) Run(f *flag.FlagSet) error { +func isToolsUnavailable(err error) bool { + if soap.IsSoapFault(err) { + soapFault := soap.ToSoapFault(err) + if _, ok := soapFault.VimFault().(types.ToolsUnavailable); ok { + return ok + } + } + + return false +} + +func (cmd *power) Run(ctx context.Context, f *flag.FlagSet) error { vms, err := cmd.VirtualMachines(f.Args()) if err != nil { return err @@ -100,9 +124,17 @@ func (cmd *power) Run(f *flag.FlagSet) error { case cmd.Reboot: fmt.Fprintf(cmd, "Reboot guest %s... ", vm.Reference()) err = vm.RebootGuest(context.TODO()) + + if err != nil && cmd.Force && isToolsUnavailable(err) { + task, err = vm.Reset(context.TODO()) + } case cmd.Shutdown: fmt.Fprintf(cmd, "Shutdown guest %s... ", vm.Reference()) err = vm.ShutdownGuest(context.TODO()) + + if err != nil && cmd.Force && isToolsUnavailable(err) { + task, err = vm.PowerOff(context.TODO()) + } } if err != nil { diff --git a/vendor/github.com/vmware/govmomi/govc/vm/question.go b/vendor/github.com/vmware/govmomi/govc/vm/question.go index 59268533dc..1ea6dc5a68 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/question.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/question.go @@ -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. @@ -39,15 +39,21 @@ func init() { cli.Register("vm.question", &question{}) } -func (cmd *question) Register(f *flag.FlagSet) { +func (cmd *question) Register(ctx context.Context, f *flag.FlagSet) { + cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx) + cmd.VirtualMachineFlag.Register(ctx, f) + f.StringVar(&cmd.answer, "answer", "", "Answer to question") } -func (cmd *question) Process() error { +func (cmd *question) Process(ctx context.Context) error { + if err := cmd.VirtualMachineFlag.Process(ctx); err != nil { + return err + } return nil } -func (cmd *question) Run(f *flag.FlagSet) error { +func (cmd *question) Run(ctx context.Context, f *flag.FlagSet) error { c, err := cmd.Client() if err != nil { return err diff --git a/vendor/github.com/vmware/govmomi/govc/vm/vnc.go b/vendor/github.com/vmware/govmomi/govc/vm/vnc.go index 8dc6e3ad9d..55fe719758 100644 --- a/vendor/github.com/vmware/govmomi/govc/vm/vnc.go +++ b/vendor/github.com/vmware/govmomi/govc/vm/vnc.go @@ -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. @@ -79,8 +79,9 @@ func init() { cli.Register("vm.vnc", cmd) } -func (cmd *vnc) Register(f *flag.FlagSet) { - cmd.SearchFlag = flags.NewSearchFlag(flags.SearchVirtualMachines) +func (cmd *vnc) Register(ctx context.Context, f *flag.FlagSet) { + cmd.SearchFlag, ctx = flags.NewSearchFlag(ctx, flags.SearchVirtualMachines) + cmd.SearchFlag.Register(ctx, f) f.BoolVar(&cmd.Enable, "enable", false, "Enable VNC") f.BoolVar(&cmd.Disable, "disable", false, "Disable VNC") @@ -89,7 +90,10 @@ func (cmd *vnc) Register(f *flag.FlagSet) { f.StringVar(&cmd.Password, "password", "", "VNC password") } -func (cmd *vnc) Process() error { +func (cmd *vnc) Process(ctx context.Context) error { + if err := cmd.SearchFlag.Process(ctx); err != nil { + return err + } // Either may be true or none may be true. if cmd.Enable && cmd.Disable { return flag.ErrHelp @@ -110,7 +114,7 @@ Port numbers are automatically chosen from a range if not specified. If neither -enable or -disable is specified, the current state is returned.` } -func (cmd *vnc) Run(f *flag.FlagSet) error { +func (cmd *vnc) Run(ctx context.Context, f *flag.FlagSet) error { vms, err := cmd.loadVMs(f.Args()) if err != nil { return err diff --git a/vendor/github.com/vmware/govmomi/guest/auth_manager.go b/vendor/github.com/vmware/govmomi/guest/auth_manager.go index 93911279d0..c62f012ce5 100644 --- a/vendor/github.com/vmware/govmomi/guest/auth_manager.go +++ b/vendor/github.com/vmware/govmomi/guest/auth_manager.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/guest/file_manager.go b/vendor/github.com/vmware/govmomi/guest/file_manager.go index 04b5e956ff..43931e662c 100644 --- a/vendor/github.com/vmware/govmomi/guest/file_manager.go +++ b/vendor/github.com/vmware/govmomi/guest/file_manager.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/guest/operations_manager.go b/vendor/github.com/vmware/govmomi/guest/operations_manager.go index 4db6e89592..3c5394d9da 100644 --- a/vendor/github.com/vmware/govmomi/guest/operations_manager.go +++ b/vendor/github.com/vmware/govmomi/guest/operations_manager.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/guest/process_manager.go b/vendor/github.com/vmware/govmomi/guest/process_manager.go index efee2420a5..159a571d71 100644 --- a/vendor/github.com/vmware/govmomi/guest/process_manager.go +++ b/vendor/github.com/vmware/govmomi/guest/process_manager.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/license/assignment_manager.go b/vendor/github.com/vmware/govmomi/license/assignment_manager.go new file mode 100644 index 0000000000..509c94f991 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/license/assignment_manager.go @@ -0,0 +1,69 @@ +/* +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 license + +import ( + "github.com/vmware/govmomi/object" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type AssignmentManager struct { + object.Common +} + +func (m AssignmentManager) QueryAssigned(ctx context.Context, id string) ([]types.LicenseAssignmentManagerLicenseAssignment, error) { + req := types.QueryAssignedLicenses{ + This: m.Reference(), + EntityId: id, + } + + res, err := methods.QueryAssignedLicenses(ctx, m.Client(), &req) + if err != nil { + return nil, err + } + + return res.Returnval, nil +} + +func (m AssignmentManager) Remove(ctx context.Context, id string) error { + req := types.RemoveAssignedLicense{ + This: m.Reference(), + EntityId: id, + } + + _, err := methods.RemoveAssignedLicense(ctx, m.Client(), &req) + + return err +} + +func (m AssignmentManager) Update(ctx context.Context, id string, key string, name string) (*types.LicenseManagerLicenseInfo, error) { + req := types.UpdateAssignedLicense{ + This: m.Reference(), + Entity: id, + LicenseKey: key, + EntityDisplayName: name, + } + + res, err := methods.UpdateAssignedLicense(ctx, m.Client(), &req) + if err != nil { + return nil, err + } + + return &res.Returnval, nil +} diff --git a/vendor/github.com/vmware/govmomi/license/manager.go b/vendor/github.com/vmware/govmomi/license/manager.go index 7dadcb964b..1e268f29dd 100644 --- a/vendor/github.com/vmware/govmomi/license/manager.go +++ b/vendor/github.com/vmware/govmomi/license/manager.go @@ -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. @@ -17,7 +17,10 @@ limitations under the License. package license import ( - "github.com/vmware/govmomi/property" + "strconv" + "strings" + + "github.com/vmware/govmomi/object" "github.com/vmware/govmomi/vim25" "github.com/vmware/govmomi/vim25/methods" "github.com/vmware/govmomi/vim25/mo" @@ -26,25 +29,17 @@ import ( ) type Manager struct { - reference types.ManagedObjectReference - - c *vim25.Client + object.Common } func NewManager(c *vim25.Client) *Manager { m := Manager{ - reference: *c.ServiceContent.LicenseManager, - - c: c, + object.NewCommon(c, *c.ServiceContent.LicenseManager), } return &m } -func (m Manager) Reference() types.ManagedObjectReference { - return m.reference -} - func mapToKeyValueSlice(m map[string]string) []types.KeyValue { r := make([]types.KeyValue, len(m)) for k, v := range m { @@ -60,7 +55,21 @@ func (m Manager) Add(ctx context.Context, key string, labels map[string]string) Labels: mapToKeyValueSlice(labels), } - res, err := methods.AddLicense(ctx, m.c, &req) + res, err := methods.AddLicense(ctx, m.Client(), &req) + if err != nil { + return types.LicenseManagerLicenseInfo{}, err + } + + return res.Returnval, nil +} + +func (m Manager) Decode(ctx context.Context, key string) (types.LicenseManagerLicenseInfo, error) { + req := types.DecodeLicense{ + This: m.Reference(), + LicenseKey: key, + } + + res, err := methods.DecodeLicense(ctx, m.Client(), &req) if err != nil { return types.LicenseManagerLicenseInfo{}, err } @@ -74,7 +83,7 @@ func (m Manager) Remove(ctx context.Context, key string) error { LicenseKey: key, } - _, err := methods.RemoveLicense(ctx, m.c, &req) + _, err := methods.RemoveLicense(ctx, m.Client(), &req) return err } @@ -85,7 +94,7 @@ func (m Manager) Update(ctx context.Context, key string, labels map[string]strin Labels: mapToKeyValueSlice(labels), } - res, err := methods.UpdateLicense(ctx, m.c, &req) + res, err := methods.UpdateLicense(ctx, m.Client(), &req) if err != nil { return types.LicenseManagerLicenseInfo{}, err } @@ -93,13 +102,94 @@ func (m Manager) Update(ctx context.Context, key string, labels map[string]strin return res.Returnval, nil } -func (m Manager) List(ctx context.Context) ([]types.LicenseManagerLicenseInfo, error) { +func (m Manager) List(ctx context.Context) (InfoList, error) { var mlm mo.LicenseManager - err := property.DefaultCollector(m.c).RetrieveOne(ctx, m.Reference(), []string{"licenses"}, &mlm) + err := m.Properties(ctx, m.Reference(), []string{"licenses"}, &mlm) if err != nil { return nil, err } - return mlm.Licenses, nil + return InfoList(mlm.Licenses), nil +} + +func (m Manager) AssignmentManager(ctx context.Context) (*AssignmentManager, error) { + var mlm mo.LicenseManager + + err := m.Properties(ctx, m.Reference(), []string{"licenseAssignmentManager"}, &mlm) + if err != nil { + return nil, err + } + + if mlm.LicenseAssignmentManager == nil { + return nil, object.ErrNotSupported + } + + am := AssignmentManager{ + object.NewCommon(m.Client(), *mlm.LicenseAssignmentManager), + } + + return &am, nil +} + +type licenseFeature struct { + name string + level int +} + +func parseLicenseFeature(feature string) *licenseFeature { + lf := new(licenseFeature) + + f := strings.Split(feature, ":") + + lf.name = f[0] + + if len(f) > 1 { + var err error + lf.level, err = strconv.Atoi(f[1]) + if err != nil { + lf.name = feature + } + } + + return lf +} + +func HasFeature(license types.LicenseManagerLicenseInfo, key string) bool { + feature := parseLicenseFeature(key) + + for _, p := range license.Properties { + if p.Key != "feature" { + continue + } + + kv, ok := p.Value.(types.KeyValue) + + if !ok { + continue + } + + lf := parseLicenseFeature(kv.Key) + + if lf.name == feature.name && lf.level >= feature.level { + return true + } + } + + return false +} + +// InfoList provides helper methods for []types.LicenseManagerLicenseInfo +type InfoList []types.LicenseManagerLicenseInfo + +func (l InfoList) WithFeature(key string) InfoList { + var result InfoList + + for _, license := range l { + if HasFeature(license, key) { + result = append(result, license) + } + } + + return result } diff --git a/vendor/github.com/vmware/govmomi/list/lister.go b/vendor/github.com/vmware/govmomi/list/lister.go index f354eca7c3..fd632010cb 100644 --- a/vendor/github.com/vmware/govmomi/list/lister.go +++ b/vendor/github.com/vmware/govmomi/list/lister.go @@ -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. @@ -83,6 +83,8 @@ func ToElement(r mo.Reference, prefix string) Element { name = m.Name case mo.DistributedVirtualPortgroup: name = m.Name + case mo.VmwareDistributedVirtualSwitch: + name = m.Name // { "vim.Datastore" } - Identifies a datastore folder. Datastore folders can // contain child datastore folders and Datastore managed objects. @@ -115,6 +117,8 @@ func traversable(ref types.ManagedObjectReference) bool { case "ComputeResource", "ClusterComputeResource": // Treat ComputeResource and ClusterComputeResource as one and the same. // It doesn't matter from the perspective of the lister. + case "HostSystem": + case "VirtualApp": default: return false } @@ -167,6 +171,10 @@ func (l Lister) List(ctx context.Context) ([]Element, error) { return l.ListComputeResource(ctx) case "ResourcePool": return l.ListResourcePool(ctx) + case "HostSystem": + return l.ListHostSystem(ctx) + case "VirtualApp": + return l.ListVirtualApp(ctx) default: return nil, fmt.Errorf("cannot traverse type " + l.Reference.Type) } @@ -193,11 +201,13 @@ func (l Lister) ListFolder(ctx context.Context) ([]Element, error) { childTypes := []string{ "Folder", "Datacenter", + "VirtualApp", "VirtualMachine", "Network", "ComputeResource", "ClusterComputeResource", "Datastore", + "DistributedVirtualSwitch", } for _, t := range childTypes { @@ -427,3 +437,135 @@ func (l Lister) ListResourcePool(ctx context.Context) ([]Element, error) { return es, nil } + +func (l Lister) ListHostSystem(ctx context.Context) ([]Element, error) { + ospec := types.ObjectSpec{ + Obj: l.Reference, + Skip: types.NewBool(true), + } + + fields := []string{ + "datastore", + "network", + "vm", + } + + for _, f := range fields { + tspec := types.TraversalSpec{ + Path: f, + Skip: types.NewBool(false), + Type: "HostSystem", + } + + ospec.SelectSet = append(ospec.SelectSet, &tspec) + } + + childTypes := []string{ + "Datastore", + "Network", + "VirtualMachine", + } + + var pspecs []types.PropertySpec + for _, t := range childTypes { + pspec := types.PropertySpec{ + Type: t, + } + + if l.All { + pspec.All = types.NewBool(true) + } else { + pspec.PathSet = []string{"name"} + } + + pspecs = append(pspecs, pspec) + } + + req := types.RetrieveProperties{ + SpecSet: []types.PropertyFilterSpec{ + { + ObjectSet: []types.ObjectSpec{ospec}, + PropSet: pspecs, + }, + }, + } + + var dst []interface{} + + err := l.retrieveProperties(ctx, req, &dst) + if err != nil { + return nil, err + } + + es := []Element{} + for _, v := range dst { + es = append(es, ToElement(v.(mo.Reference), l.Prefix)) + } + + return es, nil +} + +func (l Lister) ListVirtualApp(ctx context.Context) ([]Element, error) { + ospec := types.ObjectSpec{ + Obj: l.Reference, + Skip: types.NewBool(true), + } + + fields := []string{ + "resourcePool", + "vm", + } + + for _, f := range fields { + tspec := types.TraversalSpec{ + Path: f, + Skip: types.NewBool(false), + Type: "VirtualApp", + } + + ospec.SelectSet = append(ospec.SelectSet, &tspec) + } + + childTypes := []string{ + "ResourcePool", + "VirtualMachine", + } + + var pspecs []types.PropertySpec + for _, t := range childTypes { + pspec := types.PropertySpec{ + Type: t, + } + + if l.All { + pspec.All = types.NewBool(true) + } else { + pspec.PathSet = []string{"name"} + } + + pspecs = append(pspecs, pspec) + } + + req := types.RetrieveProperties{ + SpecSet: []types.PropertyFilterSpec{ + { + ObjectSet: []types.ObjectSpec{ospec}, + PropSet: pspecs, + }, + }, + } + + var dst []interface{} + + err := l.retrieveProperties(ctx, req, &dst) + if err != nil { + return nil, err + } + + es := []Element{} + for _, v := range dst { + es = append(es, ToElement(v.(mo.Reference), l.Prefix)) + } + + return es, nil +} diff --git a/vendor/github.com/vmware/govmomi/list/recurser.go b/vendor/github.com/vmware/govmomi/list/recurser.go index c91c20f781..4b78415b33 100644 --- a/vendor/github.com/vmware/govmomi/list/recurser.go +++ b/vendor/github.com/vmware/govmomi/list/recurser.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/object/authorization_manager.go b/vendor/github.com/vmware/govmomi/object/authorization_manager.go new file mode 100644 index 0000000000..60f063b9dc --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/authorization_manager.go @@ -0,0 +1,108 @@ +/* +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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type AuthorizationManager struct { + Common +} + +func NewAuthorizationManager(c *vim25.Client) *AuthorizationManager { + m := AuthorizationManager{ + Common: NewCommon(c, *c.ServiceContent.AuthorizationManager), + } + + return &m +} + +type AuthorizationRoleList []types.AuthorizationRole + +func (l AuthorizationRoleList) ById(id int) *types.AuthorizationRole { + for _, role := range l { + if role.RoleId == id { + return &role + } + } + + return nil +} + +func (l AuthorizationRoleList) ByName(name string) *types.AuthorizationRole { + for _, role := range l { + if role.Name == name { + return &role + } + } + + return nil +} + +func (m AuthorizationManager) RoleList(ctx context.Context) (AuthorizationRoleList, error) { + var am mo.AuthorizationManager + + err := m.Properties(ctx, m.Reference(), []string{"roleList"}, &am) + if err != nil { + return nil, err + } + + return AuthorizationRoleList(am.RoleList), nil +} + +func (m AuthorizationManager) RetrieveEntityPermissions(ctx context.Context, entity types.ManagedObjectReference, inherited bool) ([]types.Permission, error) { + req := types.RetrieveEntityPermissions{ + This: m.Reference(), + Entity: entity, + Inherited: inherited, + } + + res, err := methods.RetrieveEntityPermissions(ctx, m.Client(), &req) + if err != nil { + return nil, err + } + + return res.Returnval, nil +} + +func (m AuthorizationManager) RemoveEntityPermission(ctx context.Context, entity types.ManagedObjectReference, user string, isGroup bool) error { + req := types.RemoveEntityPermission{ + This: m.Reference(), + Entity: entity, + User: user, + IsGroup: isGroup, + } + + _, err := methods.RemoveEntityPermission(ctx, m.Client(), &req) + return err +} + +func (m AuthorizationManager) SetEntityPermissions(ctx context.Context, entity types.ManagedObjectReference, permission []types.Permission) error { + req := types.SetEntityPermissions{ + This: m.Reference(), + Entity: entity, + Permission: permission, + } + + _, err := methods.SetEntityPermissions(ctx, m.Client(), &req) + return err +} diff --git a/vendor/github.com/vmware/govmomi/object/cluster_compute_resource.go b/vendor/github.com/vmware/govmomi/object/cluster_compute_resource.go index 67b511a8b8..3cd52f705f 100644 --- a/vendor/github.com/vmware/govmomi/object/cluster_compute_resource.go +++ b/vendor/github.com/vmware/govmomi/object/cluster_compute_resource.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/object/common.go b/vendor/github.com/vmware/govmomi/object/common.go index bd3fd8e650..3e641441ab 100644 --- a/vendor/github.com/vmware/govmomi/object/common.go +++ b/vendor/github.com/vmware/govmomi/object/common.go @@ -17,14 +17,20 @@ limitations under the License. package object import ( + "errors" "fmt" "github.com/vmware/govmomi/property" "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" "github.com/vmware/govmomi/vim25/types" "golang.org/x/net/context" ) +var ( + ErrNotSupported = errors.New("not supported (vCenter only)") +) + // Common contains the fields and functions common to all objects. type Common struct { c *vim25.Client @@ -50,3 +56,16 @@ func (c Common) Client() *vim25.Client { func (c Common) Properties(ctx context.Context, r types.ManagedObjectReference, ps []string, dst interface{}) error { return property.DefaultCollector(c.c).RetrieveOne(ctx, r, ps, dst) } + +func (c Common) Destroy(ctx context.Context) (*Task, error) { + req := types.Destroy_Task{ + This: c.Reference(), + } + + res, err := methods.Destroy_Task(ctx, c.c, &req) + if err != nil { + return nil, err + } + + return NewTask(c.c, res.Returnval), nil +} diff --git a/vendor/github.com/vmware/govmomi/object/compute_resource.go b/vendor/github.com/vmware/govmomi/object/compute_resource.go index 7ac1beb801..328c2e07cb 100644 --- a/vendor/github.com/vmware/govmomi/object/compute_resource.go +++ b/vendor/github.com/vmware/govmomi/object/compute_resource.go @@ -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. @@ -17,6 +17,9 @@ limitations under the License. package object import ( + "path" + + "github.com/vmware/govmomi/property" "github.com/vmware/govmomi/vim25" "github.com/vmware/govmomi/vim25/methods" "github.com/vmware/govmomi/vim25/mo" @@ -36,7 +39,7 @@ func NewComputeResource(c *vim25.Client, ref types.ManagedObjectReference) *Comp } } -func (c ComputeResource) Hosts(ctx context.Context) ([]types.ManagedObjectReference, error) { +func (c ComputeResource) Hosts(ctx context.Context) ([]*HostSystem, error) { var cr mo.ComputeResource err := c.Properties(ctx, c.Reference(), []string{"host"}, &cr) @@ -44,7 +47,26 @@ func (c ComputeResource) Hosts(ctx context.Context) ([]types.ManagedObjectRefere return nil, err } - return cr.Host, nil + if len(cr.Host) == 0 { + return nil, nil + } + + var hs []mo.HostSystem + pc := property.DefaultCollector(c.Client()) + err = pc.Retrieve(ctx, cr.Host, []string{"name"}, &hs) + if err != nil { + return nil, err + } + + var hosts []*HostSystem + + for _, h := range hs { + host := NewHostSystem(c.Client(), h.Reference()) + host.InventoryPath = path.Join(c.InventoryPath, h.Name) + hosts = append(hosts, host) + } + + return hosts, nil } func (c ComputeResource) Datastores(ctx context.Context) ([]*Datastore, error) { @@ -75,6 +97,21 @@ func (c ComputeResource) ResourcePool(ctx context.Context) (*ResourcePool, error return NewResourcePool(c.c, *cr.ResourcePool), nil } +func (c ComputeResource) Reconfigure(ctx context.Context, spec types.BaseComputeResourceConfigSpec, modify bool) (*Task, error) { + req := types.ReconfigureComputeResource_Task{ + This: c.Reference(), + Spec: spec, + Modify: modify, + } + + res, err := methods.ReconfigureComputeResource_Task(ctx, c.c, &req) + if err != nil { + return nil, err + } + + return NewTask(c.c, res.Returnval), nil +} + func (c ComputeResource) Destroy(ctx context.Context) (*Task, error) { req := types.Destroy_Task{ This: c.Reference(), diff --git a/vendor/github.com/vmware/govmomi/object/custom_fields_manager.go b/vendor/github.com/vmware/govmomi/object/custom_fields_manager.go index 9404dc4a61..5b5e918297 100644 --- a/vendor/github.com/vmware/govmomi/object/custom_fields_manager.go +++ b/vendor/github.com/vmware/govmomi/object/custom_fields_manager.go @@ -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. @@ -29,7 +29,6 @@ import ( var ( ErrKeyNameNotFound = errors.New("key name not found") - ErrNotSupported = errors.New("custom fields not supported") // VC only ) type CustomFieldsManager struct { diff --git a/vendor/github.com/vmware/govmomi/object/customization_spec_manager.go b/vendor/github.com/vmware/govmomi/object/customization_spec_manager.go index c9cff6161a..aebe73e844 100644 --- a/vendor/github.com/vmware/govmomi/object/customization_spec_manager.go +++ b/vendor/github.com/vmware/govmomi/object/customization_spec_manager.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/object/datacenter.go b/vendor/github.com/vmware/govmomi/object/datacenter.go index 12efcee365..fa522fb053 100644 --- a/vendor/github.com/vmware/govmomi/object/datacenter.go +++ b/vendor/github.com/vmware/govmomi/object/datacenter.go @@ -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. @@ -17,6 +17,8 @@ limitations under the License. package object import ( + "fmt" + "github.com/vmware/govmomi/vim25" "github.com/vmware/govmomi/vim25/methods" "github.com/vmware/govmomi/vim25/mo" @@ -44,7 +46,7 @@ func NewDatacenter(c *vim25.Client, ref types.ManagedObjectReference) *Datacente func (d *Datacenter) Folders(ctx context.Context) (*DatacenterFolders, error) { var md mo.Datacenter - ps := []string{"vmFolder", "hostFolder", "datastoreFolder", "networkFolder"} + ps := []string{"name", "vmFolder", "hostFolder", "datastoreFolder", "networkFolder"} err := d.Properties(ctx, d.Reference(), ps, &md) if err != nil { return nil, err @@ -57,6 +59,20 @@ func (d *Datacenter) Folders(ctx context.Context) (*DatacenterFolders, error) { NetworkFolder: NewFolder(d.c, md.NetworkFolder), } + paths := []struct { + name string + path *string + }{ + {"vm", &df.VmFolder.InventoryPath}, + {"host", &df.HostFolder.InventoryPath}, + {"datastore", &df.DatastoreFolder.InventoryPath}, + {"network", &df.NetworkFolder.InventoryPath}, + } + + for _, p := range paths { + *p.path = fmt.Sprintf("/%s/%s", md.Name, p.name) + } + return df, nil } diff --git a/vendor/github.com/vmware/govmomi/object/datastore.go b/vendor/github.com/vmware/govmomi/object/datastore.go index 279e90ffc2..df25f07d6c 100644 --- a/vendor/github.com/vmware/govmomi/object/datastore.go +++ b/vendor/github.com/vmware/govmomi/object/datastore.go @@ -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. @@ -18,16 +18,43 @@ package object import ( "fmt" + "io" + "math/rand" "path" + "strings" + "net/http" "net/url" + "github.com/vmware/govmomi/property" + "github.com/vmware/govmomi/session" "github.com/vmware/govmomi/vim25" "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/soap" "github.com/vmware/govmomi/vim25/types" "golang.org/x/net/context" ) +// DatastoreNoSuchDirectoryError is returned when a directory could not be found. +type DatastoreNoSuchDirectoryError struct { + verb string + subject string +} + +func (e DatastoreNoSuchDirectoryError) Error() string { + return fmt.Sprintf("cannot %s '%s': No such directory", e.verb, e.subject) +} + +// DatastoreNoSuchFileError is returned when a file could not be found. +type DatastoreNoSuchFileError struct { + verb string + subject string +} + +func (e DatastoreNoSuchFileError) Error() string { + return fmt.Sprintf("cannot %s '%s': No such file", e.verb, e.subject) +} + type Datastore struct { Common @@ -88,3 +115,199 @@ func (d Datastore) Browser(ctx context.Context) (*HostDatastoreBrowser, error) { return NewHostDatastoreBrowser(d.c, do.Browser), nil } + +// ServiceTicket obtains a ticket via AcquireGenericServiceTicket and returns it an http.Cookie with the url.URL +// that can be used along with the ticket cookie to access the given path. +func (d Datastore) ServiceTicket(ctx context.Context, path string, method string) (*url.URL, *http.Cookie, error) { + // We are uploading to an ESX host + u := &url.URL{ + Scheme: d.c.URL().Scheme, + Host: d.c.URL().Host, + Path: fmt.Sprintf("/folder/%s", path), + RawQuery: url.Values{ + "dsName": []string{d.Name()}, + }.Encode(), + } + + // If connected to VC, the ticket request must be for an ESX host. + if d.c.ServiceContent.About.ApiType == "VirtualCenter" { + hosts, err := d.AttachedHosts(ctx) + if err != nil { + return nil, nil, err + } + + if len(hosts) == 0 { + return nil, nil, fmt.Errorf("no hosts attached to datastore %#v", d.Reference()) + } + + // Pick a random attached host + host := hosts[rand.Intn(len(hosts))] + name, err := host.Name(ctx) + if err != nil { + return nil, nil, err + } + u.Host = name + } + + spec := types.SessionManagerHttpServiceRequestSpec{ + Url: u.String(), + // See SessionManagerHttpServiceRequestSpecMethod enum + Method: fmt.Sprintf("http%s%s", method[0:1], strings.ToLower(method[1:])), + } + + sm := session.NewManager(d.Client()) + + ticket, err := sm.AcquireGenericServiceTicket(ctx, &spec) + if err != nil { + return nil, nil, err + } + + cookie := &http.Cookie{ + Name: "vmware_cgi_ticket", + Value: ticket.Id, + } + + return u, cookie, nil +} + +func (d Datastore) uploadTicket(ctx context.Context, path string, param *soap.Upload) (*url.URL, *soap.Upload, error) { + p := soap.DefaultUpload + if param != nil { + p = *param // copy + } + + u, ticket, err := d.ServiceTicket(ctx, path, p.Method) + if err != nil { + return nil, nil, err + } + + p.Ticket = ticket + + return u, &p, nil +} + +func (d Datastore) downloadTicket(ctx context.Context, path string, param *soap.Download) (*url.URL, *soap.Download, error) { + p := soap.DefaultDownload + if param != nil { + p = *param // copy + } + + u, ticket, err := d.ServiceTicket(ctx, path, p.Method) + if err != nil { + return nil, nil, err + } + + p.Ticket = ticket + + return u, &p, nil +} + +// Upload via soap.Upload with an http service ticket +func (d Datastore) Upload(ctx context.Context, f io.Reader, path string, param *soap.Upload) error { + u, p, err := d.uploadTicket(ctx, path, param) + if err != nil { + return err + } + return d.Client().Upload(f, u, p) +} + +// UploadFile via soap.Upload with an http service ticket +func (d Datastore) UploadFile(ctx context.Context, file string, path string, param *soap.Upload) error { + u, p, err := d.uploadTicket(ctx, path, param) + if err != nil { + return err + } + return d.Client().UploadFile(file, u, p) +} + +// DownloadFile via soap.Upload with an http service ticket +func (d Datastore) DownloadFile(ctx context.Context, path string, file string, param *soap.Download) error { + u, p, err := d.downloadTicket(ctx, path, param) + if err != nil { + return err + } + return d.Client().DownloadFile(file, u, p) +} + +// AttachedHosts returns hosts that have this Datastore attached, accessible and writable. +func (d Datastore) AttachedHosts(ctx context.Context) ([]*HostSystem, error) { + var ds mo.Datastore + var hosts []*HostSystem + + pc := property.DefaultCollector(d.Client()) + err := pc.RetrieveOne(ctx, d.Reference(), []string{"host"}, &ds) + if err != nil { + return nil, err + } + + mounts := make(map[types.ManagedObjectReference]types.DatastoreHostMount) + var refs []types.ManagedObjectReference + for _, host := range ds.Host { + refs = append(refs, host.Key) + mounts[host.Key] = host + } + + var hs []mo.HostSystem + err = pc.Retrieve(ctx, refs, []string{"runtime.connectionState", "runtime.powerState"}, &hs) + if err != nil { + return nil, err + } + + for _, host := range hs { + if host.Runtime.ConnectionState == types.HostSystemConnectionStateConnected && + host.Runtime.PowerState == types.HostSystemPowerStatePoweredOn { + + mount := mounts[host.Reference()] + info := mount.MountInfo + + if *info.Mounted && *info.Accessible && info.AccessMode == string(types.HostMountModeReadWrite) { + hosts = append(hosts, NewHostSystem(d.Client(), mount.Key)) + } + } + } + + return hosts, nil +} + +func (d Datastore) Stat(ctx context.Context, file string) (types.BaseFileInfo, error) { + b, err := d.Browser(ctx) + 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 := d.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, DatastoreNoSuchDirectoryError{"stat", dsPath} + } + } + + return nil, err + } + + res := info.Result.(types.HostDatastoreBrowserSearchResults) + if len(res.File) == 0 { + // File doesn't exist + return nil, DatastoreNoSuchFileError{"stat", d.Path(file)} + } + + return res.File[0], nil + +} diff --git a/vendor/github.com/vmware/govmomi/object/diagnostic_manager.go b/vendor/github.com/vmware/govmomi/object/diagnostic_manager.go new file mode 100644 index 0000000000..b181592cd6 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/diagnostic_manager.go @@ -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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type DiagnosticManager struct { + Common +} + +func NewDiagnosticManager(c *vim25.Client) *DiagnosticManager { + m := DiagnosticManager{ + Common: NewCommon(c, *c.ServiceContent.DiagnosticManager), + } + + return &m +} + +func (m DiagnosticManager) BrowseLog(ctx context.Context, host *HostSystem, key string, start, lines int) (*types.DiagnosticManagerLogHeader, error) { + req := types.BrowseDiagnosticLog{ + This: m.Reference(), + Key: key, + Start: start, + Lines: lines, + } + + if host != nil { + ref := host.Reference() + req.Host = &ref + } + + res, err := methods.BrowseDiagnosticLog(ctx, m.Client(), &req) + if err != nil { + return nil, err + } + + return &res.Returnval, nil +} + +func (m DiagnosticManager) GenerateLogBundles(ctx context.Context, includeDefault bool, host []*HostSystem) (*Task, error) { + req := types.GenerateLogBundles_Task{ + This: m.Reference(), + IncludeDefault: includeDefault, + } + + if host != nil { + for _, h := range host { + req.Host = append(req.Host, h.Reference()) + } + } + + res, err := methods.GenerateLogBundles_Task(ctx, m.c, &req) + if err != nil { + return nil, err + } + + return NewTask(m.c, res.Returnval), nil +} + +func (m DiagnosticManager) QueryDescriptions(ctx context.Context, host *HostSystem) ([]types.DiagnosticManagerLogDescriptor, error) { + req := types.QueryDescriptions{ + This: m.Reference(), + } + + if host != nil { + ref := host.Reference() + req.Host = &ref + } + + res, err := methods.QueryDescriptions(ctx, m.Client(), &req) + if err != nil { + return nil, err + } + + return res.Returnval, nil +} diff --git a/vendor/github.com/vmware/govmomi/object/distributed_virtual_portgroup.go b/vendor/github.com/vmware/govmomi/object/distributed_virtual_portgroup.go index 150eaa87b0..0dbd4b589f 100644 --- a/vendor/github.com/vmware/govmomi/object/distributed_virtual_portgroup.go +++ b/vendor/github.com/vmware/govmomi/object/distributed_virtual_portgroup.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/object/distributed_virtual_switch.go b/vendor/github.com/vmware/govmomi/object/distributed_virtual_switch.go index 987c59818c..f2fb0abeef 100644 --- a/vendor/github.com/vmware/govmomi/object/distributed_virtual_switch.go +++ b/vendor/github.com/vmware/govmomi/object/distributed_virtual_switch.go @@ -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. @@ -18,11 +18,15 @@ package object import ( "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" ) type DistributedVirtualSwitch struct { Common + + InventoryPath string } func NewDistributedVirtualSwitch(c *vim25.Client, ref types.ManagedObjectReference) *DistributedVirtualSwitch { @@ -30,3 +34,35 @@ func NewDistributedVirtualSwitch(c *vim25.Client, ref types.ManagedObjectReferen Common: NewCommon(c, ref), } } + +func (s DistributedVirtualSwitch) EthernetCardBackingInfo(ctx context.Context) (types.BaseVirtualDeviceBackingInfo, error) { + return nil, ErrNotSupported // TODO: just to satisfy NetworkReference interface for the finder +} + +func (s DistributedVirtualSwitch) Reconfigure(ctx context.Context, spec types.BaseDVSConfigSpec) (*Task, error) { + req := types.ReconfigureDvs_Task{ + This: s.Reference(), + Spec: spec, + } + + res, err := methods.ReconfigureDvs_Task(ctx, s.Client(), &req) + if err != nil { + return nil, err + } + + return NewTask(s.Client(), res.Returnval), nil +} + +func (s DistributedVirtualSwitch) AddPortgroup(ctx context.Context, spec []types.DVPortgroupConfigSpec) (*Task, error) { + req := types.AddDVPortgroup_Task{ + This: s.Reference(), + Spec: spec, + } + + res, err := methods.AddDVPortgroup_Task(ctx, s.Client(), &req) + if err != nil { + return nil, err + } + + return NewTask(s.Client(), res.Returnval), nil +} diff --git a/vendor/github.com/vmware/govmomi/object/extension_manager.go b/vendor/github.com/vmware/govmomi/object/extension_manager.go new file mode 100644 index 0000000000..b7ce77c5c5 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/extension_manager.go @@ -0,0 +1,112 @@ +/* +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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type ExtensionManager struct { + Common +} + +// GetExtensionManager wraps NewExtensionManager, returning ErrNotSupported +// when the client is not connected to a vCenter instance. +func GetExtensionManager(c *vim25.Client) (*ExtensionManager, error) { + if c.ServiceContent.ExtensionManager == nil { + return nil, ErrNotSupported + } + return NewExtensionManager(c), nil +} + +func NewExtensionManager(c *vim25.Client) *ExtensionManager { + o := ExtensionManager{ + Common: NewCommon(c, *c.ServiceContent.ExtensionManager), + } + + return &o +} + +func (m ExtensionManager) List(ctx context.Context) ([]types.Extension, error) { + var em mo.ExtensionManager + + err := m.Properties(ctx, m.Reference(), []string{"extensionList"}, &em) + if err != nil { + return nil, err + } + + return em.ExtensionList, nil +} + +func (m ExtensionManager) Find(ctx context.Context, key string) (*types.Extension, error) { + req := types.FindExtension{ + This: m.Reference(), + ExtensionKey: key, + } + + res, err := methods.FindExtension(ctx, m.c, &req) + if err != nil { + return nil, err + } + + return res.Returnval, nil +} + +func (m ExtensionManager) Register(ctx context.Context, extension types.Extension) error { + req := types.RegisterExtension{ + This: m.Reference(), + Extension: extension, + } + + _, err := methods.RegisterExtension(ctx, m.c, &req) + return err +} + +func (m ExtensionManager) SetCertificate(ctx context.Context, key string, certificatePem string) error { + req := types.SetExtensionCertificate{ + This: m.Reference(), + ExtensionKey: key, + CertificatePem: certificatePem, + } + + _, err := methods.SetExtensionCertificate(ctx, m.c, &req) + return err +} + +func (m ExtensionManager) Unregister(ctx context.Context, key string) error { + req := types.UnregisterExtension{ + This: m.Reference(), + ExtensionKey: key, + } + + _, err := methods.UnregisterExtension(ctx, m.c, &req) + return err +} + +func (m ExtensionManager) Update(ctx context.Context, extension types.Extension) error { + req := types.UpdateExtension{ + This: m.Reference(), + Extension: extension, + } + + _, err := methods.UpdateExtension(ctx, m.c, &req) + return err +} diff --git a/vendor/github.com/vmware/govmomi/object/file_manager.go b/vendor/github.com/vmware/govmomi/object/file_manager.go index 38a4eb9728..7164728269 100644 --- a/vendor/github.com/vmware/govmomi/object/file_manager.go +++ b/vendor/github.com/vmware/govmomi/object/file_manager.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/object/folder.go b/vendor/github.com/vmware/govmomi/object/folder.go index 3cf71c89e4..38fddd6da4 100644 --- a/vendor/github.com/vmware/govmomi/object/folder.go +++ b/vendor/github.com/vmware/govmomi/object/folder.go @@ -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. @@ -26,6 +26,8 @@ import ( type Folder struct { Common + + InventoryPath string } func NewFolder(c *vim25.Client, ref types.ManagedObjectReference) *Folder { @@ -180,3 +182,17 @@ func (f Folder) RegisterVM(ctx context.Context, path string, name string, asTemp return NewTask(f.c, res.Returnval), nil } + +func (f Folder) CreateDVS(ctx context.Context, spec types.DVSCreateSpec) (*Task, error) { + req := types.CreateDVS_Task{ + This: f.Reference(), + Spec: spec, + } + + res, err := methods.CreateDVS_Task(ctx, f.c, &req) + if err != nil { + return nil, err + } + + return NewTask(f.c, res.Returnval), nil +} diff --git a/vendor/github.com/vmware/govmomi/object/history_collector.go b/vendor/github.com/vmware/govmomi/object/history_collector.go index 51bb9e657e..a0fb6aabc7 100644 --- a/vendor/github.com/vmware/govmomi/object/history_collector.go +++ b/vendor/github.com/vmware/govmomi/object/history_collector.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/object/host_config_manager.go b/vendor/github.com/vmware/govmomi/object/host_config_manager.go index 606bb39466..6d906e8c52 100644 --- a/vendor/github.com/vmware/govmomi/object/host_config_manager.go +++ b/vendor/github.com/vmware/govmomi/object/host_config_manager.go @@ -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,6 +33,17 @@ func NewHostConfigManager(c *vim25.Client, ref types.ManagedObjectReference) *Ho } } +func (m HostConfigManager) DatastoreSystem(ctx context.Context) (*HostDatastoreSystem, error) { + var h mo.HostSystem + + err := m.Properties(ctx, m.Reference(), []string{"configManager.datastoreSystem"}, &h) + if err != nil { + return nil, err + } + + return NewHostDatastoreSystem(m.c, *h.ConfigManager.DatastoreSystem), nil +} + func (m HostConfigManager) NetworkSystem(ctx context.Context) (*HostNetworkSystem, error) { var h mo.HostSystem @@ -43,3 +54,47 @@ func (m HostConfigManager) NetworkSystem(ctx context.Context) (*HostNetworkSyste return NewHostNetworkSystem(m.c, *h.ConfigManager.NetworkSystem), nil } + +func (m HostConfigManager) FirewallSystem(ctx context.Context) (*HostFirewallSystem, error) { + var h mo.HostSystem + + err := m.Properties(ctx, m.Reference(), []string{"configManager.firewallSystem"}, &h) + if err != nil { + return nil, err + } + + return NewHostFirewallSystem(m.c, *h.ConfigManager.FirewallSystem), nil +} + +func (m HostConfigManager) StorageSystem(ctx context.Context) (*HostStorageSystem, error) { + var h mo.HostSystem + + err := m.Properties(ctx, m.Reference(), []string{"configManager.storageSystem"}, &h) + if err != nil { + return nil, err + } + + return NewHostStorageSystem(m.c, *h.ConfigManager.StorageSystem), nil +} + +func (m HostConfigManager) VirtualNicManager(ctx context.Context) (*HostVirtualNicManager, error) { + var h mo.HostSystem + + err := m.Properties(ctx, m.Reference(), []string{"configManager.virtualNicManager"}, &h) + if err != nil { + return nil, err + } + + return NewHostVirtualNicManager(m.c, *h.ConfigManager.VirtualNicManager, m.Reference()), nil +} + +func (m HostConfigManager) VsanSystem(ctx context.Context) (*HostVsanSystem, error) { + var h mo.HostSystem + + err := m.Properties(ctx, m.Reference(), []string{"configManager.vsanSystem"}, &h) + if err != nil { + return nil, err + } + + return NewHostVsanSystem(m.c, *h.ConfigManager.VsanSystem), nil +} diff --git a/vendor/github.com/vmware/govmomi/object/host_datastore_browser.go b/vendor/github.com/vmware/govmomi/object/host_datastore_browser.go index e243b0fcca..a2e2056634 100644 --- a/vendor/github.com/vmware/govmomi/object/host_datastore_browser.go +++ b/vendor/github.com/vmware/govmomi/object/host_datastore_browser.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/object/host_datastore_system.go b/vendor/github.com/vmware/govmomi/object/host_datastore_system.go new file mode 100644 index 0000000000..632b7d255b --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/host_datastore_system.go @@ -0,0 +1,103 @@ +/* +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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type HostDatastoreSystem struct { + Common +} + +func NewHostDatastoreSystem(c *vim25.Client, ref types.ManagedObjectReference) *HostDatastoreSystem { + return &HostDatastoreSystem{ + Common: NewCommon(c, ref), + } +} + +func (s HostDatastoreSystem) CreateNasDatastore(ctx context.Context, spec types.HostNasVolumeSpec) (*Datastore, error) { + req := types.CreateNasDatastore{ + This: s.Reference(), + Spec: spec, + } + + res, err := methods.CreateNasDatastore(ctx, s.Client(), &req) + if err != nil { + return nil, err + } + + return NewDatastore(s.Client(), res.Returnval), nil +} + +func (s HostDatastoreSystem) CreateVmfsDatastore(ctx context.Context, spec types.VmfsDatastoreCreateSpec) (*Datastore, error) { + req := types.CreateVmfsDatastore{ + This: s.Reference(), + Spec: spec, + } + + res, err := methods.CreateVmfsDatastore(ctx, s.Client(), &req) + if err != nil { + return nil, err + } + + return NewDatastore(s.Client(), res.Returnval), nil +} + +func (s HostDatastoreSystem) Remove(ctx context.Context, ds *Datastore) error { + req := types.RemoveDatastore{ + This: s.Reference(), + Datastore: ds.Reference(), + } + + _, err := methods.RemoveDatastore(ctx, s.Client(), &req) + if err != nil { + return err + } + + return nil +} + +func (s HostDatastoreSystem) QueryAvailableDisksForVmfs(ctx context.Context) ([]types.HostScsiDisk, error) { + req := types.QueryAvailableDisksForVmfs{ + This: s.Reference(), + } + + res, err := methods.QueryAvailableDisksForVmfs(ctx, s.Client(), &req) + if err != nil { + return nil, err + } + + return res.Returnval, nil +} + +func (s HostDatastoreSystem) QueryVmfsDatastoreCreateOptions(ctx context.Context, devicePath string) ([]types.VmfsDatastoreOption, error) { + req := types.QueryVmfsDatastoreCreateOptions{ + This: s.Reference(), + DevicePath: devicePath, + } + + res, err := methods.QueryVmfsDatastoreCreateOptions(ctx, s.Client(), &req) + if err != nil { + return nil, err + } + + return res.Returnval, nil +} diff --git a/vendor/github.com/vmware/govmomi/object/host_firewall_system.go b/vendor/github.com/vmware/govmomi/object/host_firewall_system.go new file mode 100644 index 0000000000..143f0983de --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/host_firewall_system.go @@ -0,0 +1,181 @@ +/* +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 object + +import ( + "errors" + "fmt" + "strings" + + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type HostFirewallSystem struct { + Common +} + +func NewHostFirewallSystem(c *vim25.Client, ref types.ManagedObjectReference) *HostFirewallSystem { + return &HostFirewallSystem{ + Common: NewCommon(c, ref), + } +} + +func (s HostFirewallSystem) DisableRuleset(ctx context.Context, id string) error { + req := types.DisableRuleset{ + This: s.Reference(), + Id: id, + } + + _, err := methods.DisableRuleset(ctx, s.c, &req) + return err +} + +func (s HostFirewallSystem) EnableRuleset(ctx context.Context, id string) error { + req := types.EnableRuleset{ + This: s.Reference(), + Id: id, + } + + _, err := methods.EnableRuleset(ctx, s.c, &req) + return err +} + +func (s HostFirewallSystem) Refresh(ctx context.Context) error { + req := types.RefreshFirewall{ + This: s.Reference(), + } + + _, err := methods.RefreshFirewall(ctx, s.c, &req) + return err +} + +func (s HostFirewallSystem) Info(ctx context.Context) (*types.HostFirewallInfo, error) { + var fs mo.HostFirewallSystem + + err := s.Properties(ctx, s.Reference(), []string{"firewallInfo"}, &fs) + if err != nil { + return nil, err + } + + return fs.FirewallInfo, nil +} + +// HostFirewallRulesetList provides helpers for a slice of types.HostFirewallRuleset +type HostFirewallRulesetList []types.HostFirewallRuleset + +// ByRule returns a HostFirewallRulesetList where Direction, PortType and Protocol are equal and Port is within range +func (l HostFirewallRulesetList) ByRule(rule types.HostFirewallRule) HostFirewallRulesetList { + var matches HostFirewallRulesetList + + for _, rs := range l { + for _, r := range rs.Rule { + if r.PortType != rule.PortType || + r.Protocol != rule.Protocol || + r.Direction != rule.Direction { + continue + } + + if r.EndPort == 0 && rule.Port == r.Port || + rule.Port >= r.Port && rule.Port <= r.EndPort { + matches = append(matches, rs) + break + } + } + } + + return matches +} + +// EnabledByRule returns a HostFirewallRulesetList with Match(rule) applied and filtered via Enabled() +// if enabled param is true, otherwise filtered via Disabled(). +// An error is returned if the resulting list is empty. +func (l HostFirewallRulesetList) EnabledByRule(rule types.HostFirewallRule, enabled bool) (HostFirewallRulesetList, error) { + var matched, skipped HostFirewallRulesetList + var matchedKind, skippedKind string + + l = l.ByRule(rule) + + if enabled { + matched = l.Enabled() + matchedKind = "enabled" + + skipped = l.Disabled() + skippedKind = "disabled" + } else { + matched = l.Disabled() + matchedKind = "disabled" + + skipped = l.Enabled() + skippedKind = "enabled" + } + + if len(matched) == 0 { + msg := fmt.Sprintf("%d %s firewall rulesets match %s %s %s %d, %d %s rulesets match", + len(matched), matchedKind, + rule.Direction, rule.Protocol, rule.PortType, rule.Port, + len(skipped), skippedKind) + + if len(skipped) != 0 { + msg += fmt.Sprintf(": %s", strings.Join(skipped.Keys(), ", ")) + } + + return nil, errors.New(msg) + } + + return matched, nil +} + +// Enabled returns a HostFirewallRulesetList with enabled rules +func (l HostFirewallRulesetList) Enabled() HostFirewallRulesetList { + var matches HostFirewallRulesetList + + for _, rs := range l { + if rs.Enabled { + matches = append(matches, rs) + } + } + + return matches +} + +// Disabled returns a HostFirewallRulesetList with disabled rules +func (l HostFirewallRulesetList) Disabled() HostFirewallRulesetList { + var matches HostFirewallRulesetList + + for _, rs := range l { + if !rs.Enabled { + matches = append(matches, rs) + } + } + + return matches +} + +// Keys returns the HostFirewallRuleset.Key for each ruleset in the list +func (l HostFirewallRulesetList) Keys() []string { + var keys []string + + for _, rs := range l { + keys = append(keys, rs.Key) + } + + return keys +} diff --git a/vendor/github.com/vmware/govmomi/object/host_network_system.go b/vendor/github.com/vmware/govmomi/object/host_network_system.go index 19727b3e4f..1418de42f4 100644 --- a/vendor/github.com/vmware/govmomi/object/host_network_system.go +++ b/vendor/github.com/vmware/govmomi/object/host_network_system.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/object/host_storage_system.go b/vendor/github.com/vmware/govmomi/object/host_storage_system.go new file mode 100644 index 0000000000..36cd68e3ad --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/host_storage_system.go @@ -0,0 +1,80 @@ +/* +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 object + +import ( + "errors" + + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type HostStorageSystem struct { + Common +} + +func NewHostStorageSystem(c *vim25.Client, ref types.ManagedObjectReference) *HostStorageSystem { + return &HostStorageSystem{ + Common: NewCommon(c, ref), + } +} + +func (s HostStorageSystem) RetrieveDiskPartitionInfo(ctx context.Context, devicePath string) (*types.HostDiskPartitionInfo, error) { + req := types.RetrieveDiskPartitionInfo{ + This: s.Reference(), + DevicePath: []string{devicePath}, + } + + res, err := methods.RetrieveDiskPartitionInfo(ctx, s.c, &req) + if err != nil { + return nil, err + } + + if res.Returnval == nil || len(res.Returnval) == 0 { + return nil, errors.New("no partition info") + } + + return &res.Returnval[0], nil +} + +func (s HostStorageSystem) ComputeDiskPartitionInfo(ctx context.Context, devicePath string, layout types.HostDiskPartitionLayout) (*types.HostDiskPartitionInfo, error) { + req := types.ComputeDiskPartitionInfo{ + This: s.Reference(), + DevicePath: devicePath, + Layout: layout, + } + + res, err := methods.ComputeDiskPartitionInfo(ctx, s.c, &req) + if err != nil { + return nil, err + } + + return &res.Returnval, nil +} + +func (s HostStorageSystem) UpdateDiskPartitionInfo(ctx context.Context, devicePath string, spec types.HostDiskPartitionSpec) error { + req := types.UpdateDiskPartitions{ + This: s.Reference(), + DevicePath: devicePath, + Spec: spec, + } + + _, err := methods.UpdateDiskPartitions(ctx, s.c, &req) + return err +} diff --git a/vendor/github.com/vmware/govmomi/object/host_system.go b/vendor/github.com/vmware/govmomi/object/host_system.go index ab4484f258..206b27cac8 100644 --- a/vendor/github.com/vmware/govmomi/object/host_system.go +++ b/vendor/github.com/vmware/govmomi/object/host_system.go @@ -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,6 +21,7 @@ import ( "net" "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" "github.com/vmware/govmomi/vim25/mo" "github.com/vmware/govmomi/vim25/types" "golang.org/x/net/context" @@ -112,3 +113,61 @@ func (h HostSystem) ManagementIPs(ctx context.Context) ([]net.IP, error) { return ips, nil } + +func (h HostSystem) Disconnect(ctx context.Context) (*Task, error) { + req := types.DisconnectHost_Task{ + This: h.Reference(), + } + + res, err := methods.DisconnectHost_Task(ctx, h.c, &req) + if err != nil { + return nil, err + } + + return NewTask(h.c, res.Returnval), nil +} + +func (h HostSystem) Reconnect(ctx context.Context, cnxSpec *types.HostConnectSpec, reconnectSpec *types.HostSystemReconnectSpec) (*Task, error) { + req := types.ReconnectHost_Task{ + This: h.Reference(), + CnxSpec: cnxSpec, + ReconnectSpec: reconnectSpec, + } + + res, err := methods.ReconnectHost_Task(ctx, h.c, &req) + if err != nil { + return nil, err + } + + return NewTask(h.c, res.Returnval), nil +} + +func (h HostSystem) EnterMaintenanceMode(ctx context.Context, timeout int, evacuate bool, spec *types.HostMaintenanceSpec) (*Task, error) { + req := types.EnterMaintenanceMode_Task{ + This: h.Reference(), + Timeout: timeout, + EvacuatePoweredOffVms: types.NewBool(evacuate), + MaintenanceSpec: spec, + } + + res, err := methods.EnterMaintenanceMode_Task(ctx, h.c, &req) + if err != nil { + return nil, err + } + + return NewTask(h.c, res.Returnval), nil +} + +func (h HostSystem) ExitMaintenanceMode(ctx context.Context, timeout int) (*Task, error) { + req := types.ExitMaintenanceMode_Task{ + This: h.Reference(), + Timeout: timeout, + } + + res, err := methods.ExitMaintenanceMode_Task(ctx, h.c, &req) + if err != nil { + return nil, err + } + + return NewTask(h.c, res.Returnval), nil +} diff --git a/vendor/github.com/vmware/govmomi/object/host_virtual_nic_manager.go b/vendor/github.com/vmware/govmomi/object/host_virtual_nic_manager.go new file mode 100644 index 0000000000..05338b82e1 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/host_virtual_nic_manager.go @@ -0,0 +1,92 @@ +/* +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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type HostVirtualNicManager struct { + Common + Host *HostSystem +} + +func NewHostVirtualNicManager(c *vim25.Client, ref types.ManagedObjectReference, host types.ManagedObjectReference) *HostVirtualNicManager { + return &HostVirtualNicManager{ + Common: NewCommon(c, ref), + Host: NewHostSystem(c, host), + } +} + +func (m HostVirtualNicManager) Info(ctx context.Context) (*types.HostVirtualNicManagerInfo, error) { + var vnm mo.HostVirtualNicManager + + err := m.Properties(ctx, m.Reference(), []string{"info"}, &vnm) + if err != nil { + return nil, err + } + + return &vnm.Info, nil +} + +func (m HostVirtualNicManager) DeselectVnic(ctx context.Context, nicType string, device string) error { + if nicType == string(types.HostVirtualNicManagerNicTypeVsan) { + // Avoid fault.NotSupported: + // "Error deselecting device '$device': VSAN interfaces must be deselected using vim.host.VsanSystem" + s, err := m.Host.ConfigManager().VsanSystem(ctx) + if err != nil { + return err + } + + return s.updateVnic(ctx, device, false) + } + + req := types.DeselectVnicForNicType{ + This: m.Reference(), + NicType: nicType, + Device: device, + } + + _, err := methods.DeselectVnicForNicType(ctx, m.Client(), &req) + return err +} + +func (m HostVirtualNicManager) SelectVnic(ctx context.Context, nicType string, device string) error { + if nicType == string(types.HostVirtualNicManagerNicTypeVsan) { + // Avoid fault.NotSupported: + // "Error selecting device '$device': VSAN interfaces must be selected using vim.host.VsanSystem" + s, err := m.Host.ConfigManager().VsanSystem(ctx) + if err != nil { + return err + } + + return s.updateVnic(ctx, device, true) + } + + req := types.SelectVnicForNicType{ + This: m.Reference(), + NicType: nicType, + Device: device, + } + + _, err := methods.SelectVnicForNicType(ctx, m.Client(), &req) + return err +} diff --git a/vendor/github.com/vmware/govmomi/object/host_vsan_system.go b/vendor/github.com/vmware/govmomi/object/host_vsan_system.go new file mode 100644 index 0000000000..8c571421d3 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/host_vsan_system.go @@ -0,0 +1,87 @@ +/* +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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type HostVsanSystem struct { + Common +} + +func NewHostVsanSystem(c *vim25.Client, ref types.ManagedObjectReference) *HostVsanSystem { + return &HostVsanSystem{ + Common: NewCommon(c, ref), + } +} + +func (s HostVsanSystem) Update(ctx context.Context, config types.VsanHostConfigInfo) (*Task, error) { + req := types.UpdateVsan_Task{ + This: s.Reference(), + Config: config, + } + + res, err := methods.UpdateVsan_Task(ctx, s.Client(), &req) + if err != nil { + return nil, err + } + + return NewTask(s.Client(), res.Returnval), nil +} + +// updateVnic in support of the HostVirtualNicManager.{SelectVnic,DeselectVnic} methods +func (s HostVsanSystem) updateVnic(ctx context.Context, device string, enable bool) error { + var vsan mo.HostVsanSystem + + err := s.Properties(ctx, s.Reference(), []string{"config.networkInfo.port"}, &vsan) + if err != nil { + return err + } + + info := vsan.Config + + var port []types.VsanHostConfigInfoNetworkInfoPortConfig + + for _, p := range info.NetworkInfo.Port { + if p.Device == device { + continue + } + + port = append(port, p) + } + + if enable { + port = append(port, types.VsanHostConfigInfoNetworkInfoPortConfig{ + Device: device, + }) + } + + info.NetworkInfo.Port = port + + task, err := s.Update(ctx, info) + if err != nil { + return err + } + + _, err = task.WaitForResult(ctx, nil) + return err +} diff --git a/vendor/github.com/vmware/govmomi/object/http_nfc_lease.go b/vendor/github.com/vmware/govmomi/object/http_nfc_lease.go index c0dd334e79..f100f2088f 100644 --- a/vendor/github.com/vmware/govmomi/object/http_nfc_lease.go +++ b/vendor/github.com/vmware/govmomi/object/http_nfc_lease.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/object/network.go b/vendor/github.com/vmware/govmomi/object/network.go index 59e7048aff..9963744aa7 100644 --- a/vendor/github.com/vmware/govmomi/object/network.go +++ b/vendor/github.com/vmware/govmomi/object/network.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/object/network_reference.go b/vendor/github.com/vmware/govmomi/object/network_reference.go index 9b8b7ebe8e..98dd538130 100644 --- a/vendor/github.com/vmware/govmomi/object/network_reference.go +++ b/vendor/github.com/vmware/govmomi/object/network_reference.go @@ -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. @@ -24,5 +24,7 @@ import ( // The NetworkReference interface is implemented by managed objects // which can be used as the backing for a VirtualEthernetCard. type NetworkReference interface { + Reference + EthernetCardBackingInfo(ctx context.Context) (types.BaseVirtualDeviceBackingInfo, error) } diff --git a/vendor/github.com/vmware/govmomi/object/ovf_manager.go b/vendor/github.com/vmware/govmomi/object/ovf_manager.go index aa20388eaf..e7912d0fd0 100644 --- a/vendor/github.com/vmware/govmomi/object/ovf_manager.go +++ b/vendor/github.com/vmware/govmomi/object/ovf_manager.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/object/resource_pool.go b/vendor/github.com/vmware/govmomi/object/resource_pool.go index cea337bfaa..e03460854e 100644 --- a/vendor/github.com/vmware/govmomi/object/resource_pool.go +++ b/vendor/github.com/vmware/govmomi/object/resource_pool.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/object/search_index.go b/vendor/github.com/vmware/govmomi/object/search_index.go index f44897dbe2..638c8de2a5 100644 --- a/vendor/github.com/vmware/govmomi/object/search_index.go +++ b/vendor/github.com/vmware/govmomi/object/search_index.go @@ -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. @@ -119,11 +119,12 @@ func (s SearchIndex) FindByIp(ctx context.Context, dc *Datacenter, ip string, vm } // FindByUuid finds a virtual machine or host by UUID. -func (s SearchIndex) FindByUuid(ctx context.Context, dc *Datacenter, uuid string, vmSearch bool) (Reference, error) { +func (s SearchIndex) FindByUuid(ctx context.Context, dc *Datacenter, uuid string, vmSearch bool, instanceUuid *bool) (Reference, error) { req := types.FindByUuid{ - This: s.Reference(), - Uuid: uuid, - VmSearch: vmSearch, + This: s.Reference(), + Uuid: uuid, + VmSearch: vmSearch, + InstanceUuid: instanceUuid, } if dc != nil { ref := dc.Reference() diff --git a/vendor/github.com/vmware/govmomi/object/storage_pod.go b/vendor/github.com/vmware/govmomi/object/storage_pod.go index dfb66625d0..18865ff985 100644 --- a/vendor/github.com/vmware/govmomi/object/storage_pod.go +++ b/vendor/github.com/vmware/govmomi/object/storage_pod.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/object/storage_resource_manager.go b/vendor/github.com/vmware/govmomi/object/storage_resource_manager.go index dab9d25490..54fd0d9e1c 100644 --- a/vendor/github.com/vmware/govmomi/object/storage_resource_manager.go +++ b/vendor/github.com/vmware/govmomi/object/storage_resource_manager.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/object/task.go b/vendor/github.com/vmware/govmomi/object/task.go index 81834854a3..d70a417be1 100644 --- a/vendor/github.com/vmware/govmomi/object/task.go +++ b/vendor/github.com/vmware/govmomi/object/task.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/object/types.go b/vendor/github.com/vmware/govmomi/object/types.go index 42c3515212..f61aa362c4 100644 --- a/vendor/github.com/vmware/govmomi/object/types.go +++ b/vendor/github.com/vmware/govmomi/object/types.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/object/virtual_app.go b/vendor/github.com/vmware/govmomi/object/virtual_app.go index 28b2b8be7f..5b93f618f7 100644 --- a/vendor/github.com/vmware/govmomi/object/virtual_app.go +++ b/vendor/github.com/vmware/govmomi/object/virtual_app.go @@ -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. @@ -84,30 +84,43 @@ func (p VirtualApp) UpdateVAppConfig(ctx context.Context, spec types.VAppConfigS return err } -func (p VirtualApp) PowerOnVApp_Task(ctx context.Context) error { +func (p VirtualApp) PowerOnVApp_Task(ctx context.Context) (*Task, error) { req := types.PowerOnVApp_Task{ This: p.Reference(), } - _, err := methods.PowerOnVApp_Task(ctx, p.c, &req) - return err + res, err := methods.PowerOnVApp_Task(ctx, p.c, &req) + if err != nil { + return nil, err + } + + return NewTask(p.c, res.Returnval), nil } -func (p VirtualApp) PowerOffVApp_Task(ctx context.Context, force bool) error { +func (p VirtualApp) PowerOffVApp_Task(ctx context.Context, force bool) (*Task, error) { req := types.PowerOffVApp_Task{ This: p.Reference(), Force: force, } - _, err := methods.PowerOffVApp_Task(ctx, p.c, &req) - return err + res, err := methods.PowerOffVApp_Task(ctx, p.c, &req) + if err != nil { + return nil, err + } + + return NewTask(p.c, res.Returnval), nil + } -func (p VirtualApp) SuspendVApp_Task(ctx context.Context) error { +func (p VirtualApp) SuspendVApp_Task(ctx context.Context) (*Task, error) { req := types.SuspendVApp_Task{ This: p.Reference(), } - _, err := methods.SuspendVApp_Task(ctx, p.c, &req) - return err + res, err := methods.SuspendVApp_Task(ctx, p.c, &req) + if err != nil { + return nil, err + } + + return NewTask(p.c, res.Returnval), nil } diff --git a/vendor/github.com/vmware/govmomi/object/virtual_device_list.go b/vendor/github.com/vmware/govmomi/object/virtual_device_list.go index 21c5a85b88..e80f69910e 100644 --- a/vendor/github.com/vmware/govmomi/object/virtual_device_list.go +++ b/vendor/github.com/vmware/govmomi/object/virtual_device_list.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/object/virtual_disk_manager.go b/vendor/github.com/vmware/govmomi/object/virtual_disk_manager.go index 29e9c8e97f..800cfa0766 100644 --- a/vendor/github.com/vmware/govmomi/object/virtual_disk_manager.go +++ b/vendor/github.com/vmware/govmomi/object/virtual_disk_manager.go @@ -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. @@ -68,6 +68,31 @@ func (m VirtualDiskManager) CopyVirtualDisk( return NewTask(m.c, res.Returnval), nil } +// CreateVirtualDisk creates a new virtual disk. +func (m VirtualDiskManager) CreateVirtualDisk( + ctx context.Context, + name string, datacenter *Datacenter, + spec types.BaseVirtualDiskSpec) (*Task, error) { + + req := types.CreateVirtualDisk_Task{ + This: m.Reference(), + Name: name, + Spec: spec, + } + + if datacenter != nil { + ref := datacenter.Reference() + req.Datacenter = &ref + } + + res, err := methods.CreateVirtualDisk_Task(ctx, m.c, &req) + if err != nil { + return nil, err + } + + return NewTask(m.c, res.Returnval), nil +} + // MoveVirtualDisk moves a virtual disk. func (m VirtualDiskManager) MoveVirtualDisk( ctx context.Context, diff --git a/vendor/github.com/vmware/govmomi/object/virtual_machine.go b/vendor/github.com/vmware/govmomi/object/virtual_machine.go index 34756a4b7a..701b27e4a4 100644 --- a/vendor/github.com/vmware/govmomi/object/virtual_machine.go +++ b/vendor/github.com/vmware/govmomi/object/virtual_machine.go @@ -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. @@ -28,6 +28,10 @@ import ( "golang.org/x/net/context" ) +const ( + PropRuntimePowerState = "summary.runtime.powerState" +) + type VirtualMachine struct { Common @@ -58,6 +62,17 @@ func (v VirtualMachine) Name(ctx context.Context) (string, error) { return o.Name, nil } +func (v VirtualMachine) PowerState(ctx context.Context) (types.VirtualMachinePowerState, error) { + var o mo.VirtualMachine + + err := v.Properties(ctx, v.Reference(), []string{PropRuntimePowerState}, &o) + if err != nil { + return "", err + } + + return o.Summary.Runtime.PowerState, nil +} + func (v VirtualMachine) PowerOn(ctx context.Context) (*Task, error) { req := types.PowerOnVM_Task{ This: v.Reference(), @@ -157,6 +172,20 @@ func (v VirtualMachine) Clone(ctx context.Context, folder *Folder, name string, return NewTask(v.c, res.Returnval), nil } +func (v VirtualMachine) Customize(ctx context.Context, spec types.CustomizationSpec) (*Task, error) { + req := types.CustomizeVM_Task{ + This: v.Reference(), + Spec: spec, + } + + res, err := methods.CustomizeVM_Task(ctx, v.c, &req) + if err != nil { + return nil, err + } + + return NewTask(v.c, res.Returnval), nil +} + func (v VirtualMachine) Relocate(ctx context.Context, config types.VirtualMachineRelocateSpec, priority types.VirtualMachineMovePriority) (*Task, error) { req := types.RelocateVM_Task{ This: v.Reference(), @@ -353,6 +382,24 @@ func (v VirtualMachine) Answer(ctx context.Context, id, answer string) error { return nil } +// CreateSnapshot creates a new snapshot of a virtual machine. +func (v VirtualMachine) CreateSnapshot(ctx context.Context, name string, description string, memory bool, quiesce bool) (*Task, error) { + req := types.CreateSnapshot_Task{ + This: v.Reference(), + Name: name, + Description: description, + Memory: memory, + Quiesce: quiesce, + } + + res, err := methods.CreateSnapshot_Task(ctx, v.c, &req) + if err != nil { + return nil, err + } + + return NewTask(v.c, res.Returnval), nil +} + // IsToolsRunning returns true if VMware Tools is currently running in the guest OS, and false otherwise. func (v VirtualMachine) IsToolsRunning(ctx context.Context) (bool, error) { var o mo.VirtualMachine @@ -365,6 +412,29 @@ func (v VirtualMachine) IsToolsRunning(ctx context.Context) (bool, error) { return o.Guest.ToolsRunningStatus == string(types.VirtualMachineToolsRunningStatusGuestToolsRunning), nil } +// Wait for the VirtualMachine to change to the desired power state. +func (v VirtualMachine) WaitForPowerState(ctx context.Context, state types.VirtualMachinePowerState) error { + p := property.DefaultCollector(v.c) + err := property.Wait(ctx, p, v.Reference(), []string{PropRuntimePowerState}, func(pc []types.PropertyChange) bool { + for _, c := range pc { + if c.Name != PropRuntimePowerState { + continue + } + if c.Val == nil { + continue + } + + ps := c.Val.(types.VirtualMachinePowerState) + if ps == state { + return true + } + } + return false + }) + + return err +} + func (v VirtualMachine) MarkAsTemplate(ctx context.Context) error { req := types.MarkAsTemplate{ This: v.Reference(), diff --git a/vendor/github.com/vmware/govmomi/object/vmware_distributed_virtual_switch.go b/vendor/github.com/vmware/govmomi/object/vmware_distributed_virtual_switch.go index 180a58385e..f6caf98708 100644 --- a/vendor/github.com/vmware/govmomi/object/vmware_distributed_virtual_switch.go +++ b/vendor/github.com/vmware/govmomi/object/vmware_distributed_virtual_switch.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/ovf/doc.go b/vendor/github.com/vmware/govmomi/ovf/doc.go new file mode 100644 index 0000000000..6284b1ac58 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/ovf/doc.go @@ -0,0 +1,25 @@ +/* +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 ovf provides functionality to unmarshal and inspect the structure +of an OVF file. It is not a complete implementation of the specification and +is intended to be used to import virtual infrastructure into vSphere. + +For a complete specification of the OVF standard, refer to: +https://www.dmtf.org/sites/default/files/standards/documents/DSP0243_2.1.0.pdf +*/ +package ovf diff --git a/vendor/github.com/vmware/govmomi/ovf/env.go b/vendor/github.com/vmware/govmomi/ovf/env.go index b50f27d117..5a5fc2f622 100644 --- a/vendor/github.com/vmware/govmomi/ovf/env.go +++ b/vendor/github.com/vmware/govmomi/ovf/env.go @@ -17,7 +17,29 @@ limitations under the License. package ovf import ( + "bytes" "encoding/xml" + "fmt" +) + +const ( + ovfEnvHeader = `` + ovfEnvPlatformSection = ` + %s + %s + %s + %s + ` + ovfEnvPropertyHeader = `` + ovfEnvPropertyEntry = `` + ovfEnvPropertyFooter = `` + ovfEnvFooter = `` ) type Env struct { @@ -44,3 +66,33 @@ type EnvProperty struct { Key string `xml:"key,attr"` Value string `xml:"value,attr"` } + +// Marshal marshals Env to xml by using xml.Marshal. +func (e Env) Marshal() (string, error) { + x, err := xml.Marshal(e) + if err != nil { + return "", err + } + + return fmt.Sprintf("%s%s", xml.Header, x), nil +} + +// MarshalManual manually marshals Env to xml suitable for a vApp guest. +// It exists to overcome the lack of expressiveness in Go's XML namespaces. +func (e Env) MarshalManual() string { + var buffer bytes.Buffer + + buffer.WriteString(xml.Header) + buffer.WriteString(fmt.Sprintf(ovfEnvHeader, e.EsxID)) + buffer.WriteString(fmt.Sprintf(ovfEnvPlatformSection, e.Platform.Kind, e.Platform.Version, e.Platform.Vendor, e.Platform.Locale)) + + buffer.WriteString(fmt.Sprintf(ovfEnvPropertyHeader)) + for _, p := range e.Property.Properties { + buffer.WriteString(fmt.Sprintf(ovfEnvPropertyEntry, p.Key, p.Value)) + } + buffer.WriteString(fmt.Sprintf(ovfEnvPropertyFooter)) + + buffer.WriteString(fmt.Sprintf(ovfEnvFooter)) + + return buffer.String() +} diff --git a/vendor/github.com/vmware/govmomi/ovf/envelope.go b/vendor/github.com/vmware/govmomi/ovf/envelope.go index 4f573fa20b..af96b15481 100644 --- a/vendor/github.com/vmware/govmomi/ovf/envelope.go +++ b/vendor/github.com/vmware/govmomi/ovf/envelope.go @@ -37,15 +37,11 @@ type Envelope struct { type VirtualSystem struct { Content - Annotation *AnnotationSection `xml:"AnnotationSection"` - Product *ProductSection `xml:"ProductSection"` - Network *NetworkSection `xml:"NetworkSection"` - Disk *DiskSection `xml:"DiskSection"` - OperatingSystem *OperatingSystemSection `xml:"OperatingSystemSection"` - Eula *EulaSection `xml:"EulaSection"` - VirtualHardware *VirtualHardwareSection `xml:"VirtualHardwareSection"` - ResourceAllocation *ResourceAllocationSection `xml:"ResourceAllocationSection"` - DeploymentOption *DeploymentOptionSection `xml:"DeploymentOptionSection"` + Annotation []AnnotationSection `xml:"AnnotationSection"` + Product []ProductSection `xml:"ProductSection"` + OperatingSystem []OperatingSystemSection `xml:"OperatingSystemSection"` + Eula []EulaSection `xml:"EulaSection"` + VirtualHardware []VirtualHardwareSection `xml:"VirtualHardwareSection"` } type File struct { diff --git a/vendor/github.com/vmware/govmomi/ovf/ovf.go b/vendor/github.com/vmware/govmomi/ovf/ovf.go index 7c5a372b3d..eea02d6770 100644 --- a/vendor/github.com/vmware/govmomi/ovf/ovf.go +++ b/vendor/github.com/vmware/govmomi/ovf/ovf.go @@ -17,9 +17,7 @@ limitations under the License. package ovf import ( - "bytes" "encoding/xml" - "fmt" "io" ) @@ -34,52 +32,3 @@ func Unmarshal(r io.Reader) (*Envelope, error) { return &e, nil } - -func Marshal(e Env) (string, error) { - x, err := xml.Marshal(e) - if err != nil { - return "", err - } - - return fmt.Sprintf("%s%s", xml.Header, x), nil -} - -const ( - ovfEnvHeader = `` - ovfEnvPlatformSection = ` - %s - %s - %s - %s - ` - ovfEnvPropertyHeader = `` - ovfEnvPropertyEntry = `` - ovfEnvPropertyFooter = `` - ovfEnvFooter = `` -) - -// MarshalManual manually marshals Env to xml suitable for a vApp guest. -// It exists to overcome the lack of expressiveness in golang's xml namespace. -func MarshalManual(e Env) string { - var buffer bytes.Buffer - - buffer.WriteString(xml.Header) - buffer.WriteString(fmt.Sprintf(ovfEnvHeader, e.EsxID)) - buffer.WriteString(fmt.Sprintf(ovfEnvPlatformSection, e.Platform.Kind, e.Platform.Version, e.Platform.Vendor, e.Platform.Locale)) - - buffer.WriteString(fmt.Sprintf(ovfEnvPropertyHeader)) - for _, p := range e.Property.Properties { - buffer.WriteString(fmt.Sprintf(ovfEnvPropertyEntry, p.Key, p.Value)) - } - buffer.WriteString(fmt.Sprintf(ovfEnvPropertyFooter)) - - buffer.WriteString(fmt.Sprintf(ovfEnvFooter)) - - return buffer.String() -} diff --git a/vendor/github.com/vmware/govmomi/property/collector.go b/vendor/github.com/vmware/govmomi/property/collector.go index f9891e58cc..50ea8d8814 100644 --- a/vendor/github.com/vmware/govmomi/property/collector.go +++ b/vendor/github.com/vmware/govmomi/property/collector.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/property/wait.go b/vendor/github.com/vmware/govmomi/property/wait.go index 7b99b0eb79..44f73eda67 100644 --- a/vendor/github.com/vmware/govmomi/property/wait.go +++ b/vendor/github.com/vmware/govmomi/property/wait.go @@ -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. @@ -71,6 +71,11 @@ func Wait(ctx context.Context, c *Collector, obj types.ManagedObjectReference, p return err } + // Retry if the result came back empty + if res == nil { + continue + } + version = res.Version for _, fs := range res.FilterSet { diff --git a/vendor/github.com/vmware/govmomi/scripts/.gitignore b/vendor/github.com/vmware/govmomi/scripts/.gitignore new file mode 100644 index 0000000000..d0153ee292 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/scripts/.gitignore @@ -0,0 +1 @@ +.wireshark-* diff --git a/vendor/github.com/vmware/govmomi/scripts/contributors.sh b/vendor/github.com/vmware/govmomi/scripts/contributors.sh new file mode 100644 index 0000000000..6098738426 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/scripts/contributors.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +set -e + +outfile="CONTRIBUTORS" +tmpfile="CONTRIBUTORS.tmp" +cp "${outfile}" "${tmpfile}" + +# Make sure the email address of every contributor is listed +git shortlog -sne | while read line; do + name=$(perl -pe 's/\d+\s+//' <<<"${line}") + email=$(grep -Po '(?<=<).*(?=>)' <<<"${name}") + if ! grep -q "${email}" "${outfile}"; then + echo "${name}" >> "${tmpfile}" + fi +done + +# Sort entries +( + sed -ne '1,5p' "${tmpfile}" + sed -ne '1,5!p' "${tmpfile}" | sort +) > "${outfile}" + +rm -f "${tmpfile}" diff --git a/vendor/github.com/vmware/govmomi/contrib/debug-ls.sh b/vendor/github.com/vmware/govmomi/scripts/debug-ls.sh similarity index 100% rename from vendor/github.com/vmware/govmomi/contrib/debug-ls.sh rename to vendor/github.com/vmware/govmomi/scripts/debug-ls.sh diff --git a/vendor/github.com/vmware/govmomi/scripts/govc-env.bash b/vendor/github.com/vmware/govmomi/scripts/govc-env.bash new file mode 100644 index 0000000000..ed5fb2fc29 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/scripts/govc-env.bash @@ -0,0 +1,62 @@ +# 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. + +# Provide a simple shell extension to save and load govc +# environments to disk. No more running `export GOVC_ABC=xyz` +# in different shells over and over again. Loading the right +# govc environment variables is now only one short and +# autocompleted command away! +# +# Usage: +# * Source this file from your `~/.bashrc` or running shell. +# * Execute `govc-env` to print GOVC_* variables. +# * Execute `govc-env --save ` to save GOVC_* variables. +# * Execute `govc-env ` to load GOVC_* variables. +# + +_govc_env_dir=$HOME/.govmomi/env +mkdir -p "${_govc_env_dir}" + +_govc-env-complete() { + local w="${COMP_WORDS[COMP_CWORD]}" + local c="$(find ${_govc_env_dir} -mindepth 1 -maxdepth 1 -type f | sort | xargs -r -L1 basename | xargs echo)" + + # Only allow completion if preceding argument if the function itself + if [ "$3" == "govc-env" ]; then + COMPREPLY=( $(compgen -W "${c}" -- "${w}") ) + fi +} + +govc-env() { + # Print current environment + if [ -z "$1" ]; then + for VAR in $(env | grep ^GOVC_ | cut -d= -f1); do + echo "export ${VAR}='${!VAR}'" + done + + return + fi + + # Save current environment + if [ "$1" == "--save" ]; then + govc-env > ${_govc_env_dir}/$2 + return + fi + + # Load specified environment + source ${_govc_env_dir}/$1 +} + +complete -F _govc-env-complete govc-env + diff --git a/vendor/github.com/vmware/govmomi/scripts/headers/go.txt b/vendor/github.com/vmware/govmomi/scripts/headers/go.txt new file mode 100644 index 0000000000..7dfe744e99 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/scripts/headers/go.txt @@ -0,0 +1,15 @@ +/* +Copyright (c) ${YEARS} 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. +*/ diff --git a/vendor/github.com/vmware/govmomi/scripts/headers/rb.txt b/vendor/github.com/vmware/govmomi/scripts/headers/rb.txt new file mode 100644 index 0000000000..1c3bd22d41 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/scripts/headers/rb.txt @@ -0,0 +1,13 @@ +# Copyright (c) ${YEARS} 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. diff --git a/vendor/github.com/vmware/govmomi/scripts/license.sh b/vendor/github.com/vmware/govmomi/scripts/license.sh new file mode 100644 index 0000000000..d47cad02c9 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/scripts/license.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +set -e + +header_dir=$(dirname $0)/headers + +tmpfile=$(mktemp) +trap "rm -f ${tmpfile}" EXIT + +git ls-files | while read file; do + years=( $(git log --format='%ai' $file | cut -d- -f1 | sort -u) ) + num_years=${#years[@]} + + if [ "${num_years}" == 0 ]; then + export YEARS="$(date +%Y)" + else + yearA=${years[0]} + yearB=${years[$((${num_years}-1))]} + + if [ ${yearA} == ${yearB} ]; then + export YEARS="${yearA}" + else + export YEARS="${yearA}-${yearB}" + fi + fi + + case "$file" in + vim25/xml/*) + # Ignore + ;; + *.go) + sed -e "s/\${YEARS}/${YEARS}/" ${header_dir}/go.txt > ${tmpfile} + last_header_line=$(grep -n '\*/' ${file} | head -1 | cut -d: -f1) + tail -n +$((${last_header_line} + 1)) ${file} >> ${tmpfile} + mv ${tmpfile} ${file} + ;; + *.rb) + sed -e "s/\${YEARS}/${YEARS}/" ${header_dir}/rb.txt > ${tmpfile} + last_header_line=$(grep -n '^$' ${file} | head -1 | cut -d: -f1) + tail -n +$((${last_header_line})) ${file} >> ${tmpfile} + mv ${tmpfile} ${file} + ;; + *) + echo "Unhandled file: $file" + ;; + esac +done + diff --git a/vendor/github.com/vmware/govmomi/contrib/vagrant/vcsa/.gitignore b/vendor/github.com/vmware/govmomi/scripts/vagrant/vcsa/.gitignore similarity index 100% rename from vendor/github.com/vmware/govmomi/contrib/vagrant/vcsa/.gitignore rename to vendor/github.com/vmware/govmomi/scripts/vagrant/vcsa/.gitignore diff --git a/vendor/github.com/vmware/govmomi/contrib/vagrant/vcsa/Vagrantfile b/vendor/github.com/vmware/govmomi/scripts/vagrant/vcsa/Vagrantfile similarity index 100% rename from vendor/github.com/vmware/govmomi/contrib/vagrant/vcsa/Vagrantfile rename to vendor/github.com/vmware/govmomi/scripts/vagrant/vcsa/Vagrantfile diff --git a/vendor/github.com/vmware/govmomi/contrib/vagrant/vcsa/create-box.sh b/vendor/github.com/vmware/govmomi/scripts/vagrant/vcsa/create-box.sh similarity index 77% rename from vendor/github.com/vmware/govmomi/contrib/vagrant/vcsa/create-box.sh rename to vendor/github.com/vmware/govmomi/scripts/vagrant/vcsa/create-box.sh index 01ddf4e179..487253b21e 100644 --- a/vendor/github.com/vmware/govmomi/contrib/vagrant/vcsa/create-box.sh +++ b/vendor/github.com/vmware/govmomi/scripts/vagrant/vcsa/create-box.sh @@ -1,27 +1,35 @@ -#!/bin/bash -e +#!/bin/sh -if [ "$(uname -s)" == "Darwin" ] -then +set -e + +if [ "$(uname -s)" == "Darwin" ]; then PATH="/Applications/VMware Fusion.app/Contents/Library:$PATH" PATH="/Applications/VMware Fusion.app/Contents/Library/VMware OVF Tool:$PATH" fi ovf="$1" -if [ -z "$ovf" ] -then +if [ -z "$ovf" ]; then ovf="./VMware-vCenter-Server-Appliance-5.5.0.10300-2000350_OVA10.ova" fi -dir=$(readlink -nf $(dirname $0)) +# check for greadlink and gmktemp +readlink=$(type -p greadlink readlink | head -1) +mktemp=$(type -p gmktemp mktemp | head -1) -tmp=$(mktemp -d) +dir=$($readlink -nf $(dirname $0)) +tmp=$($mktemp -d) trap "rm -rf $tmp" EXIT cd $tmp echo "Converting ovf..." -ovftool $ovf ./vcsa.vmx +ovftool \ + --noSSLVerify \ + --acceptAllEulas \ + --overwrite \ + --powerOffTarget \ + $ovf vcsa.vmx echo "Starting vm..." vmrun start vcsa.vmx nogui @@ -41,9 +49,9 @@ vmrun -gu root -gp vmware deleteFileInGuest vcsa.vmx \ echo "Configuring vCenter Server Appliance..." -ssh_opts="-oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -oLogLevel=quiet" +ssh_opts="-oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -T" -ssh ${ssh_opts} -i ~/.vagrant.d/insecure_private_key vagrant@$ip < ./metadata.json diff --git a/vendor/github.com/vmware/govmomi/contrib/vagrant/vcsa/vagrant.sh b/vendor/github.com/vmware/govmomi/scripts/vagrant/vcsa/vagrant.sh similarity index 53% rename from vendor/github.com/vmware/govmomi/contrib/vagrant/vcsa/vagrant.sh rename to vendor/github.com/vmware/govmomi/scripts/vagrant/vcsa/vagrant.sh index 7faecd07f6..976cc17de3 100644 --- a/vendor/github.com/vmware/govmomi/contrib/vagrant/vcsa/vagrant.sh +++ b/vendor/github.com/vmware/govmomi/scripts/vagrant/vcsa/vagrant.sh @@ -3,7 +3,7 @@ useradd vagrant -m -s /bin/bash groupmod -A vagrant wheel -echo -e "vagrant ALL=(ALL) NOPASSWD: ALL\n" >> /etc/sudoers +echo "vagrant ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers mkdir ~vagrant/.ssh wget --no-check-certificate \ @@ -12,13 +12,12 @@ wget --no-check-certificate \ chown -R vagrant ~vagrant/.ssh chmod -R go-rwsx ~vagrant/.ssh -perl -pi -e 's/^#UseDNS yes/UseDNS no/' /etc/ssh/sshd_config -perl -pi -e 's/^AllowTcpForwarding no//' /etc/ssh/sshd_config -perl -pi -e 's/^PermitTunnel no//' /etc/ssh/sshd_config -perl -pi -e 's/^MaxSessions \d+//' /etc/ssh/sshd_config +sed -i -e 's/^#UseDNS yes/UseDNS no/' /etc/ssh/sshd_config +sed -i -e 's/^AllowTcpForwarding no//' /etc/ssh/sshd_config +sed -i -e 's/^PermitTunnel no//' /etc/ssh/sshd_config +sed -i -e 's/^MaxSessions 1//' /etc/ssh/sshd_config # disable password expiration -for uid in root vagrant -do +for uid in root vagrant; do chage -I -1 -E -1 -m 0 -M -1 $uid done diff --git a/vendor/github.com/vmware/govmomi/scripts/wireshark-esx.sh b/vendor/github.com/vmware/govmomi/scripts/wireshark-esx.sh new file mode 100644 index 0000000000..d1b2427d54 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/scripts/wireshark-esx.sh @@ -0,0 +1,68 @@ +#!/bin/bash -e +# +# Capture ESXi traffic and decrypt SOAP traffic on port 443 via wireshark + +# Device to capture +dev="${1-vmk0}" + +# Device to get the ip for wireshark ssl_keys config +if [ "$dev" = "lo0" ] ; then + ip_dev="vmk0" +else + ip_dev="$dev" +fi + +ip=$(govc host.info -k -json | \ + jq -r ".HostSystems[].Config.Network.Vnic[] | select(.Device == \"${ip_dev}\") | .Spec.Ip.IpAddress") + +scp=(scp) +ssh=(ssh) + +# Check if vagrant ssh-config applies to $ip +if [ -d ".vagrant" ] ; then + vssh_opts=($(vagrant ssh-config | awk NF | awk -v ORS=' ' '{print "-o " $1 "=" $2}')) + if grep "HostName=${ip}" >/dev/null <<<"${vssh_opts[*]}" ; then + ssh_opts=("${vssh_opts[@]}") + fi +fi + +# Otherwise, use default ssh opts + sshpass if available +if [ ${#ssh_opts[@]} -eq 0 ] ; then + userpass=$(awk -F// '{print $NF}' <<<"$GOVC_URL" | awk -F@ '{print $1}') + username=$(awk -F: '{print $1}' <<<"$userpass") + password=$(awk -F: '{print $2}' <<<"$userpass") + + ssh_opts=(-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o LogLevel=FATAL -o User=${username}) + + if [ -x "$(which sshpass)" ] ; then + if [ -z "$password" ] ; then + password="$GOVC_PASSWORD" + fi + scp=(sshpass -p $password scp) + ssh=(sshpass -p $password ssh) + fi +fi + +if [ "$dev" != "lo0" ] ; then + # If you change this filter, be sure to exclude the ssh port (not tcp port 22) + filter="host $ip and \(port 80 or port 443\)" + + dst="$HOME/.wireshark/rui-${ip}.key" + if [ ! -f "$dst" ] ; then + # Copy key from ESX + "${scp[@]}" "${ssh_opts[@]}" "${ip}:/etc/vmware/ssl/rui.key" "$dst" + fi + + if ! grep "$ip" ~/.wireshark/ssl_keys 2>/dev/null ; then + # Add key to wireshark ssl_keys config + echo "adding rui.key for $ip" + + cat <> ~/.wireshark/ssl_keys +"$ip","443","http","$dst","" +EOF + fi +fi + +echo "Capturing $dev on $ip..." + +"${ssh[@]}" "${ssh_opts[@]}" "$ip" tcpdump-uw -i "$dev" -s0 -v -w - "$filter" | wireshark -k -i - diff --git a/vendor/github.com/vmware/govmomi/scripts/wireshark-vcsa.sh b/vendor/github.com/vmware/govmomi/scripts/wireshark-vcsa.sh new file mode 100644 index 0000000000..ea762ebd98 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/scripts/wireshark-vcsa.sh @@ -0,0 +1,65 @@ +#!/bin/bash -e +# +# Capture SOAP traffic between web client and vpxd on 127.0.0.1:8085. +# +# Caveats: tested with VCSA 6.0, unlikely to work for other versions. +# + +set -e + +cache_deb() { + wget $1 + ar x *.deb data.tar.gz + tar zxf data.tar.gz + rm -f data.tar.gz + rm -f *.deb +} + +dirname="$(dirname $0)" +basename="$(basename $0)" +bindir="${dirname}/.${basename}" + +mkdir -p "${bindir}" + +# Cache binaries required to run tcpdump on vcsa +if [ ! -f "${bindir}/.done" ]; then + pushd ${bindir} + cache_deb https://launchpadlibrarian.net/200649143/libssl0.9.8_0.9.8k-7ubuntu8.27_amd64.deb + cache_deb https://launchpadlibrarian.net/37430984/libpcap0.8_1.0.0-6_amd64.deb + cache_deb https://launchpadlibrarian.net/41774869/tcpdump_4.0.0-6ubuntu3_amd64.deb + touch .done + popd +fi + +scp=(scp) +ssh=(ssh) + +# Extract host from GOVC_URL +userpasshost=$(awk -F/ '{print $(NF-1)}' <<<"$GOVC_URL") +host=$(awk -F@ '{print $NF}' <<<"$userpasshost") +username=root +password="$GOVC_PASSWORD" + +if [ -x "$(which sshpass)" ] ; then + scp=(sshpass -p "$password" scp) + ssh=(sshpass -p "$password" ssh) +fi + +ssh_opts=(-o UserKnownHostsFile=/dev/null + -o StrictHostKeyChecking=no + -o LogLevel=FATAL + -o User=${username} + -o ControlMaster=no) +dev="lo" +filter="port 8085" +tcpdump="env LD_LIBRARY_PATH=/tmp /tmp/tcpdump" + +echo "Capturing $dev on $host..." + +"${scp[@]}" "${ssh_opts[@]}" \ + "${bindir}/lib/libcrypto.so.0.9.8" \ + "${bindir}/usr/lib/libpcap.so.0.8" \ + "${bindir}/usr/sbin/tcpdump" \ + "${host}:/tmp" + +"${ssh[@]}" "${ssh_opts[@]}" "$host" ${tcpdump} -i "$dev" -s0 -v -w - "$filter" | wireshark -k -i - 2>/dev/null diff --git a/vendor/github.com/vmware/govmomi/session/keep_alive.go b/vendor/github.com/vmware/govmomi/session/keep_alive.go index 82b4881723..f157b7f6d3 100644 --- a/vendor/github.com/vmware/govmomi/session/keep_alive.go +++ b/vendor/github.com/vmware/govmomi/session/keep_alive.go @@ -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,11 +36,12 @@ type keepAlive struct { // keepAlive executes a request in the background with the purpose of // keeping the session active. The response for this request is discarded. - keepAlive func(soap.RoundTripper) + keepAlive func(soap.RoundTripper) error } -func defaultKeepAlive(roundTripper soap.RoundTripper) { - methods.GetServiceContent(context.Background(), roundTripper) +func defaultKeepAlive(roundTripper soap.RoundTripper) error { + _, _ = methods.GetCurrentTime(context.Background(), roundTripper) + return nil } // KeepAlive wraps the specified soap.RoundTripper and executes a meaningless @@ -48,13 +49,20 @@ func defaultKeepAlive(roundTripper soap.RoundTripper) { // specified amount of idle time. The keep alive process only starts once a // user logs in and runs until the user logs out again. func KeepAlive(roundTripper soap.RoundTripper, idleTime time.Duration) soap.RoundTripper { + return KeepAliveHandler(roundTripper, idleTime, defaultKeepAlive) +} + +// KeepAliveHandler works as KeepAlive() does, but the handler param can decide how to handle errors. +// For example, if connectivity to ESX/VC is down long enough for a session to expire, a handler can choose to +// Login() on a types.NotAuthenticated error. If handler returns non-nil, the keep alive go routine will be stopped. +func KeepAliveHandler(roundTripper soap.RoundTripper, idleTime time.Duration, handler func(soap.RoundTripper) error) soap.RoundTripper { k := &keepAlive{ roundTripper: roundTripper, idleTime: idleTime, notifyRequest: make(chan struct{}), } - k.keepAlive = defaultKeepAlive + k.keepAlive = handler return k } @@ -81,7 +89,9 @@ func (k *keepAlive) start() { case <-k.notifyRequest: t.Reset(k.idleTime) case <-t.C: - k.keepAlive(k.roundTripper) + if err := k.keepAlive(k.roundTripper); err != nil { + k.stop() + } t = time.NewTimer(k.idleTime) } } @@ -107,7 +117,7 @@ func (k *keepAlive) RoundTrip(ctx context.Context, req, res soap.HasFault) error // Start ticker on login, stop ticker on logout. switch req.(type) { - case *methods.LoginBody: + case *methods.LoginBody, *methods.LoginExtensionByCertificateBody: k.start() case *methods.LogoutBody: k.stop() diff --git a/vendor/github.com/vmware/govmomi/session/manager.go b/vendor/github.com/vmware/govmomi/session/manager.go index 2270fa08af..5df6ebfc4b 100644 --- a/vendor/github.com/vmware/govmomi/session/manager.go +++ b/vendor/github.com/vmware/govmomi/session/manager.go @@ -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. @@ -65,6 +65,22 @@ func (sm *Manager) Login(ctx context.Context, u *url.Userinfo) error { return nil } +func (sm *Manager) LoginExtensionByCertificate(ctx context.Context, key string, locale string) error { + req := types.LoginExtensionByCertificate{ + This: sm.Reference(), + ExtensionKey: key, + Locale: locale, + } + + login, err := methods.LoginExtensionByCertificate(ctx, sm.client, &req) + if err != nil { + return err + } + + sm.userSession = &login.Returnval + return nil +} + func (sm *Manager) Logout(ctx context.Context) error { req := types.Logout{ This: sm.Reference(), @@ -101,6 +117,16 @@ func (sm *Manager) UserSession(ctx context.Context) (*types.UserSession, error) return mgr.CurrentSession, nil } +func (sm *Manager) TerminateSession(ctx context.Context, sessionId []string) error { + req := types.TerminateSession{ + This: sm.Reference(), + SessionId: sessionId, + } + + _, err := methods.TerminateSession(ctx, sm.client, &req) + return err +} + // SessionIsActive checks whether the session that was created at login is // still valid. This function only works against vCenter. func (sm *Manager) SessionIsActive(ctx context.Context) (bool, error) { @@ -121,3 +147,17 @@ func (sm *Manager) SessionIsActive(ctx context.Context) (bool, error) { return active.Returnval, err } + +func (sm *Manager) AcquireGenericServiceTicket(ctx context.Context, spec types.BaseSessionManagerServiceRequestSpec) (*types.SessionManagerGenericServiceTicket, error) { + req := types.AcquireGenericServiceTicket{ + This: sm.Reference(), + Spec: spec, + } + + res, err := methods.AcquireGenericServiceTicket(ctx, sm.client, &req) + if err != nil { + return nil, err + } + + return &res.Returnval, nil +} diff --git a/vendor/github.com/vmware/govmomi/task/error.go b/vendor/github.com/vmware/govmomi/task/error.go index 81149a80dd..5f6b8503f5 100644 --- a/vendor/github.com/vmware/govmomi/task/error.go +++ b/vendor/github.com/vmware/govmomi/task/error.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/task/wait.go b/vendor/github.com/vmware/govmomi/task/wait.go index b247fa2ea8..9432ee7346 100644 --- a/vendor/github.com/vmware/govmomi/task/wait.go +++ b/vendor/github.com/vmware/govmomi/task/wait.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/test/helper.go b/vendor/github.com/vmware/govmomi/test/helper.go index 1878db2e61..f69db75009 100644 --- a/vendor/github.com/vmware/govmomi/test/helper.go +++ b/vendor/github.com/vmware/govmomi/test/helper.go @@ -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,7 +34,7 @@ func URL() *url.URL { if s == "" { return nil } - u, err := url.Parse(s) + u, err := soap.ParseURL(s) if err != nil { panic(err) } diff --git a/vendor/github.com/vmware/govmomi/units/size.go b/vendor/github.com/vmware/govmomi/units/size.go index ab9622bf73..48208364a7 100644 --- a/vendor/github.com/vmware/govmomi/units/size.go +++ b/vendor/github.com/vmware/govmomi/units/size.go @@ -19,7 +19,6 @@ package units import ( "errors" "fmt" - "math" "regexp" "strconv" ) @@ -71,17 +70,17 @@ func (b *ByteSize) Set(s string) error { switch m[2] { case "B", "b", "": case "K", "k": - *b *= ByteSize(math.Pow(1024, 1)) + *b *= ByteSize(KB) case "M", "m": - *b *= ByteSize(math.Pow(1024, 2)) + *b *= ByteSize(MB) case "G", "g": - *b *= ByteSize(math.Pow(1024, 3)) + *b *= ByteSize(GB) case "T", "t": - *b *= ByteSize(math.Pow(1024, 4)) + *b *= ByteSize(TB) case "P", "p": - *b *= ByteSize(math.Pow(1024, 5)) + *b *= ByteSize(PB) case "E", "e": - *b *= ByteSize(math.Pow(1024, 6)) + *b *= ByteSize(EB) default: return errors.New("invalid byte suffix") } diff --git a/vendor/github.com/vmware/govmomi/vim25/methods/internal.go b/vendor/github.com/vmware/govmomi/vim25/methods/internal.go index 6e90add6df..e2fb2a22bf 100644 --- a/vendor/github.com/vmware/govmomi/vim25/methods/internal.go +++ b/vendor/github.com/vmware/govmomi/vim25/methods/internal.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/vim25/methods/methods.go b/vendor/github.com/vmware/govmomi/vim25/methods/methods.go index dcc2224176..8356883bf4 100644 --- a/vendor/github.com/vmware/govmomi/vim25/methods/methods.go +++ b/vendor/github.com/vmware/govmomi/vim25/methods/methods.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/vim25/methods/service_content.go b/vendor/github.com/vmware/govmomi/vim25/methods/service_content.go index cfcc48f72b..f685fdc2eb 100644 --- a/vendor/github.com/vmware/govmomi/vim25/methods/service_content.go +++ b/vendor/github.com/vmware/govmomi/vim25/methods/service_content.go @@ -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. @@ -17,6 +17,8 @@ limitations under the License. package methods import ( + "time" + "github.com/vmware/govmomi/vim25/soap" "github.com/vmware/govmomi/vim25/types" "golang.org/x/net/context" @@ -39,3 +41,16 @@ func GetServiceContent(ctx context.Context, r soap.RoundTripper) (types.ServiceC return res.Returnval, nil } + +func GetCurrentTime(ctx context.Context, r soap.RoundTripper) (*time.Time, error) { + req := types.CurrentTime{ + This: serviceInstance, + } + + res, err := CurrentTime(ctx, r, &req) + if err != nil { + return nil, err + } + + return &res.Returnval, nil +} diff --git a/vendor/github.com/vmware/govmomi/vim25/mo/ancestors.go b/vendor/github.com/vmware/govmomi/vim25/mo/ancestors.go index b3428d4397..4bea1552c5 100644 --- a/vendor/github.com/vmware/govmomi/vim25/mo/ancestors.go +++ b/vendor/github.com/vmware/govmomi/vim25/mo/ancestors.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/vim25/mo/fixtures/cluster_host_property.xml b/vendor/github.com/vmware/govmomi/vim25/mo/fixtures/cluster_host_property.xml new file mode 100644 index 0000000000..be218c0521 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/mo/fixtures/cluster_host_property.xml @@ -0,0 +1,15 @@ + + + + domain-c7 + + host + + host-14 + host-17 + host-19 + host-52 + + + + diff --git a/vendor/github.com/vmware/govmomi/vim25/mo/fixtures/hostsystem_list_name_property.xml b/vendor/github.com/vmware/govmomi/vim25/mo/fixtures/hostsystem_list_name_property.xml new file mode 100644 index 0000000000..05d369d85d --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/mo/fixtures/hostsystem_list_name_property.xml @@ -0,0 +1,17 @@ + + + + host-10 + + name + host-01.example.com + + + + host-30 + + name + host-02.example.com + + + diff --git a/vendor/github.com/vmware/govmomi/vim25/mo/reference.go b/vendor/github.com/vmware/govmomi/vim25/mo/reference.go index 1afe07f6b8..465edbe807 100644 --- a/vendor/github.com/vmware/govmomi/vim25/mo/reference.go +++ b/vendor/github.com/vmware/govmomi/vim25/mo/reference.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/vim25/mo/retrieve.go b/vendor/github.com/vmware/govmomi/vim25/mo/retrieve.go index 9760fa26e7..310f720cc6 100644 --- a/vendor/github.com/vmware/govmomi/vim25/mo/retrieve.go +++ b/vendor/github.com/vmware/govmomi/vim25/mo/retrieve.go @@ -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. @@ -90,6 +90,17 @@ func LoadRetrievePropertiesResponse(res *types.RetrievePropertiesResponse, dst i if err != nil { return err } + + vt := reflect.TypeOf(v) + + if !rv.Type().AssignableTo(vt) { + // For example: dst is []ManagedEntity, res is []HostSystem + if field, ok := vt.FieldByName(rt.Elem().Elem().Name()); ok && field.Anonymous { + rv.Set(reflect.Append(rv, reflect.ValueOf(v).FieldByIndex(field.Index))) + continue + } + } + rv.Set(reflect.Append(rv, reflect.ValueOf(v))) } } else { @@ -100,6 +111,17 @@ func LoadRetrievePropertiesResponse(res *types.RetrievePropertiesResponse, dst i if err != nil { return err } + + vt := reflect.TypeOf(v) + + if !rv.Type().AssignableTo(vt) { + // For example: dst is ComputeResource, res is ClusterComputeResource + if field, ok := vt.FieldByName(rt.Elem().Name()); ok && field.Anonymous { + rv.Set(reflect.ValueOf(v).FieldByIndex(field.Index)) + return nil + } + } + rv.Set(reflect.ValueOf(v)) default: // If dst is not a slice, expect to receive 0 or 1 results diff --git a/vendor/github.com/vmware/govmomi/vim25/progress/reader.go b/vendor/github.com/vmware/govmomi/vim25/progress/reader.go index bbc74f1b22..a981cb4e15 100644 --- a/vendor/github.com/vmware/govmomi/vim25/progress/reader.go +++ b/vendor/github.com/vmware/govmomi/vim25/progress/reader.go @@ -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. @@ -97,21 +97,21 @@ func NewReader(s Sinker, r io.Reader, size int64) *reader { // Read calls the Read function on the underlying io.Reader. Additionally, // every read causes a progress report to be sent to the progress reader's // underlying channel. -func (p *reader) Read(b []byte) (int, error) { - n, err := p.r.Read(b) +func (r *reader) Read(b []byte) (int, error) { + n, err := r.r.Read(b) if err != nil { return n, err } - p.pos += int64(n) + r.pos += int64(n) q := readerReport{ t: time.Now(), - pos: p.pos, - size: p.size, - bps: &p.bps, + pos: r.pos, + size: r.size, + bps: &r.bps, } - p.ch <- q + r.ch <- q return n, err } @@ -123,6 +123,7 @@ func (r *reader) Done(err error) { t: time.Now(), pos: r.pos, size: r.size, + bps: &r.bps, err: err, } diff --git a/vendor/github.com/vmware/govmomi/vim25/soap/client.go b/vendor/github.com/vmware/govmomi/vim25/soap/client.go index afd0d534df..74aed0beff 100644 --- a/vendor/github.com/vmware/govmomi/vim25/soap/client.go +++ b/vendor/github.com/vmware/govmomi/vim25/soap/client.go @@ -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. @@ -27,6 +27,7 @@ import ( "net/http/cookiejar" "net/url" "os" + "regexp" "strings" "time" @@ -51,6 +52,38 @@ type Client struct { k bool // Named after curl's -k flag d *debugContainer t *http.Transport + p *url.URL +} + +var schemeMatch = regexp.MustCompile(`^\w+://`) + +// ParseURL is wrapper around url.Parse, where Scheme defaults to "https" and Path defaults to "/sdk" +func ParseURL(s string) (*url.URL, error) { + var err error + var u *url.URL + + if s != "" { + // Default the scheme to https + if !schemeMatch.MatchString(s) { + s = "https://" + s + } + + u, err = url.Parse(s) + if err != nil { + return nil, err + } + + // Default the path to /sdk + if u.Path == "" { + u.Path = "/sdk" + } + + if u.User == nil { + u.User = url.UserPassword("", "") + } + } + + return u, nil } func NewClient(u *url.URL, insecure bool) *Client { @@ -84,6 +117,55 @@ func NewClient(u *url.URL, insecure bool) *Client { return &c } +// splitHostPort is similar to net.SplitHostPort, +// but rather than return error if there isn't a ':port', +// return an empty string for the port. +func splitHostPort(host string) (string, string) { + ix := strings.LastIndex(host, ":") + + if ix <= strings.LastIndex(host, "]") { + return host, "" + } + + name := host[:ix] + port := host[ix+1:] + + return name, port +} + +const sdkTunnel = "sdkTunnel:8089" + +func (c *Client) SetCertificate(cert tls.Certificate) { + t := c.Client.Transport.(*http.Transport) + + // Extension certificate + t.TLSClientConfig.Certificates = []tls.Certificate{cert} + + // Proxy to vCenter host on port 80 + host, _ := splitHostPort(c.u.Host) + + // Should be no reason to change the default port other than testing + port := os.Getenv("GOVC_TUNNEL_PROXY_PORT") + if port != "" { + host += ":" + port + } + + c.p = &url.URL{ + Scheme: "http", + Host: host, + } + t.Proxy = func(r *http.Request) (*url.URL, error) { + // Only sdk requests should be proxied + if r.URL.Path == "/sdk" { + return c.p, nil + } + return http.ProxyFromEnvironment(r) + } + + // Rewrite url Host to use the sdk tunnel, required for a certificate request. + c.u.Host = sdkTunnel +} + func (c *Client) URL() *url.URL { urlCopy := *c.u return &urlCopy @@ -120,6 +202,10 @@ func (c *Client) UnmarshalJSON(b []byte) error { } func (c *Client) do(ctx context.Context, req *http.Request) (*http.Response, error) { + if nil == ctx || nil == ctx.Done() { // ctx.Done() is for context.TODO() + return c.Client.Do(req) + } + var resc = make(chan *http.Response, 1) var errc = make(chan error, 1) @@ -230,8 +316,8 @@ func (c *Client) ParseURL(urlStr string) (*url.URL, error) { return nil, err } - host := strings.Split(u.Host, ":") - if host[0] == "*" { + host, _ := splitHostPort(u.Host) + if host == "*" { // Also use Client's port, to support port forwarding u.Host = c.URL().Host } @@ -244,6 +330,7 @@ type Upload struct { Method string ContentLength int64 Headers map[string]string + Ticket *http.Cookie Progress progress.Sinker } @@ -278,6 +365,10 @@ func (c *Client) Upload(f io.Reader, u *url.URL, param *Upload) error { req.Header.Add(k, v) } + if param.Ticket != nil { + req.AddCookie(param.Ticket) + } + res, err := c.Client.Do(req) if err != nil { return err @@ -318,6 +409,7 @@ func (c *Client) UploadFile(file string, u *url.URL, param *Upload) error { type Download struct { Method string + Ticket *http.Cookie Progress progress.Sinker } @@ -344,6 +436,10 @@ func (c *Client) DownloadFile(file string, u *url.URL, param *Download) error { return err } + if param.Ticket != nil { + req.AddCookie(param.Ticket) + } + res, err := c.Client.Do(req) if err != nil { return err diff --git a/vendor/github.com/vmware/govmomi/vim25/soap/debug.go b/vendor/github.com/vmware/govmomi/vim25/soap/debug.go index 6b59154951..63518abca3 100644 --- a/vendor/github.com/vmware/govmomi/vim25/soap/debug.go +++ b/vendor/github.com/vmware/govmomi/vim25/soap/debug.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/vim25/types/enum.go b/vendor/github.com/vmware/govmomi/vim25/types/enum.go index 50da7c5481..d63a1d54b2 100644 --- a/vendor/github.com/vmware/govmomi/vim25/types/enum.go +++ b/vendor/github.com/vmware/govmomi/vim25/types/enum.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/vim25/types/fault.go b/vendor/github.com/vmware/govmomi/vim25/types/fault.go index 72ae944ecc..c2503fa5cb 100644 --- a/vendor/github.com/vmware/govmomi/vim25/types/fault.go +++ b/vendor/github.com/vmware/govmomi/vim25/types/fault.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/vim25/types/if.go b/vendor/github.com/vmware/govmomi/vim25/types/if.go index 1e94d080cc..f1102e10da 100644 --- a/vendor/github.com/vmware/govmomi/vim25/types/if.go +++ b/vendor/github.com/vmware/govmomi/vim25/types/if.go @@ -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. diff --git a/vendor/github.com/vmware/govmomi/vim25/types/types.go b/vendor/github.com/vmware/govmomi/vim25/types/types.go index 22cc0784a4..e04995e94f 100644 --- a/vendor/github.com/vmware/govmomi/vim25/types/types.go +++ b/vendor/github.com/vmware/govmomi/vim25/types/types.go @@ -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.