Dependencies update

Signed-off-by: Fabio Rapposelli <fabio@vmware.com>
This commit is contained in:
Fabio Rapposelli 2015-12-22 18:59:23 +01:00
parent 2e90b7cb55
commit e7c0ebab5e
268 changed files with 103423 additions and 0 deletions

5
Godeps/Godeps.json generated
View File

@ -181,6 +181,11 @@
{
"ImportPath": "google.golang.org/cloud/internal",
"Rev": "975617b05ea8a58727e6c1a06b6161ff4185a9f2"
},
{
"ImportPath": "github.com/vmware/govmomi",
"Comment": "prerelease-v0.1.0-73-gfc131d4-65-g482cd82",
"Rev": "482cd823716e0fa9bc4e186d262a6ea23d940fbf"
}
]
}

10
vendor/github.com/vmware/govmomi/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,10 @@
sudo: false
language: go
go: 1.4
before_install:
- go get golang.org/x/tools/cmd/vet
- go get golang.org/x/tools/cmd/goimports
script:
- make check test

43
vendor/github.com/vmware/govmomi/CHANGELOG.md generated vendored Normal file
View File

@ -0,0 +1,43 @@
# changelog
### (unreleased)
...
* Stop returning children from `ManagedObjectList`
Change the `ManagedObjectList` function in the `find` package to only
return the managed objects specified by the path argument and not their
children. The original behavior was used by govc's `ls` command and is
now available in the newly added function `ManagedObjectListChildren`.
* Add retry functionality to vim25 package
* Change finder functions to no longer take varargs
The `find` package had functions to return a list of objects, given a
variable number of patterns. This makes it impossible to distinguish which
patterns produced results and which ones didn't.
In particular for govc, where multiple arguments can be passed from the
command line, it is useful to let the user know which ones produce results
and which ones don't.
To evaluate multiple patterns, the user should call the find functions
multiple times (either serially or in parallel).
* Make optional boolean fields pointers (`vim25/types`).
False is the zero value of a boolean field, which means they are not serialized
if the field is marked "omitempty". If the field is a pointer instead, the zero
value will be the nil pointer, and both true and false values are serialized.
### 0.1.0 (2015-03-17)
Prior to this version the API of this library was in flux.
Notable changes w.r.t. the state of this library before March 2015 are:
* All functions that may execute a request take a `context.Context` parameter.
* The `vim25` package contains a minimal client implementation.
* The property collector and its convenience functions live in the `property` package.

22
vendor/github.com/vmware/govmomi/CONTRIBUTORS generated vendored Normal file
View File

@ -0,0 +1,22 @@
# People who can (and typically have) contributed to this repository.
#
# Please keep the list sorted.
#
Alvaro Miranda <kikitux@gmail.com>
Bob Killen <killen.bob@gmail.com>
Bruce Downs <bdowns@vmware.com>
Clint Greenwood <cgreenwood@vmware.com> <clint.greenwood@gmail.com>
Danny Lockard <danny.lockard@banno.com>
Doug MacEachern <dougm@vmware.com>
Eric Yutao <eric.yutao@gmail.com>
Faiyaz Ahmed <ahmedf@vmware.com>
Gavin Gray <gavin@infinio.com>
Gavrie Philipson <gavrie@philipson.co.il> <gavrie.philipson@elastifile.com>
Mevan Samaratunga <mevansam@gmail.com>
Pieter Noordhuis <pnoordhuis@vmware.com> <pcnoordhuis@gmail.com>
S.Çağlar Onur <conur@vmware.com>
Takaaki Furukawa <takaaki.frkw@gmail.com>
Yang Yang <yangy@vmware.com>
Yuya Kusakabe <yuya.kusakabe@gmail.com>
Zee Yang <zeey@vmware.com> <zee.yang@gmail.com>

202
vendor/github.com/vmware/govmomi/LICENSE.txt generated vendored Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.

20
vendor/github.com/vmware/govmomi/Makefile generated vendored Normal file
View File

@ -0,0 +1,20 @@
.PHONY: test
all: check test
check: goimports govet
goimports:
@echo checking go imports...
@! goimports -d . 2>&1 | egrep -v '^$$'
govet:
@echo checking go vet...
@go tool vet -structtags=false -methods=false .
test:
go get
go test -v $(TEST_OPTS) ./...
install:
go install github.com/vmware/govmomi/govc

36
vendor/github.com/vmware/govmomi/README.md generated vendored Normal file
View File

@ -0,0 +1,36 @@
[![Build Status](https://travis-ci.org/vmware/govmomi.png?branch=master)](https://travis-ci.org/vmware/govmomi)
# govmomi
A Go library for interacting with VMware vSphere APIs (ESXi and/or vCenter).
For `govc`, a CLI built on top of govmomi, check out the [govc](./govc) directory.
## Compatibility
This library is built for and tested against ESXi and vCenter 5.5.
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.
## Documentation
The APIs exposed by this library very closely follow the API described in the [VMware vSphere API Reference Documentation][apiref].
Refer to this document to become familiar with the upstream API.
The code in the `govmomi` package is a wrapper for the code that is generated from the vSphere API description.
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
[godoc]:http://godoc.org/github.com/vmware/govmomi
## Status
Changes to the API are subject to [semantic versioning](http://semver.org).
Refer to the [CHANGELOG](CHANGELOG.md) for version to version changes.
## License
govmomi is available under the [Apache 2 license](LICENSE).

131
vendor/github.com/vmware/govmomi/client.go generated vendored Normal file
View File

@ -0,0 +1,131 @@
/*
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.
*/
/*
This package is the root package of the govmomi library.
The library is structured as follows:
Package vim25
The minimal usable functionality is available through the vim25 package.
It contains subpackages that contain generated types, managed objects, and all
available methods. The vim25 package is entirely independent of the other
packages in the govmomi tree -- it has no dependencies on its peers.
The vim25 package itself contains a client structure that is
passed around throughout the entire library. It abstracts a session and its
immutable state. See the vim25 package for more information.
Package session
The session package contains an abstraction for the session manager that allows
a user to login and logout. It also provides access to the current session
(i.e. to determine if the user is in fact logged in)
Package object
The object package contains wrappers for a selection of managed objects. The
constructors of these objects all take a *vim25.Client, which they pass along
to derived objects, if applicable.
Package govc
The govc package contains the govc CLI. The code in this tree is not intended
to be used as a library. Any functionality that govc contains that _could_ be
used as a library function but isn't, _should_ live in a root level package.
Other packages
Other packages, such as "event", "guest", or "license", provide wrappers for
the respective subsystems. They are typically not needed in normal workflows so
are kept outside the object package.
*/
package govmomi
import (
"net/url"
"github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/session"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type Client struct {
*vim25.Client
SessionManager *session.Manager
}
// NewClient creates a new client from a URL. The client authenticates with the
// server 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)
if err != nil {
return nil, err
}
c := &Client{
Client: vimClient,
SessionManager: session.NewManager(vimClient),
}
// Only login if the URL contains user information.
if u.User != nil {
err = c.Login(ctx, u.User)
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)
}
// Logout dispatches to the SessionManager.
func (c *Client) Logout(ctx context.Context) error {
// Close any idle connections after logging out.
defer c.Client.CloseIdleConnections()
return c.SessionManager.Logout(ctx)
}
// PropertyCollector returns the session's default property collector.
func (c *Client) PropertyCollector() *property.Collector {
return property.DefaultCollector(c.Client)
}
// RetrieveOne dispatches to the Retrieve function on the default property collector.
func (c *Client) RetrieveOne(ctx context.Context, obj types.ManagedObjectReference, p []string, dst interface{}) error {
return c.PropertyCollector().RetrieveOne(ctx, obj, p, dst)
}
// Retrieve dispatches to the Retrieve function on the default property collector.
func (c *Client) Retrieve(ctx context.Context, objs []types.ManagedObjectReference, p []string, dst interface{}) error {
return c.PropertyCollector().Retrieve(ctx, objs, p, dst)
}
// Wait dispatches to property.Wait.
func (c *Client) Wait(ctx context.Context, obj types.ManagedObjectReference, ps []string, f func([]types.PropertyChange) bool) error {
return property.Wait(ctx, c.PropertyCollector(), obj, ps, f)
}

43
vendor/github.com/vmware/govmomi/contrib/debug-ls.sh generated vendored Normal file
View File

@ -0,0 +1,43 @@
#!/bin/bash
# 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.
set -e
# This script shows for every request in a debug trace how long it took
# and the name of the request body.
function body-name {
(
xmllint --shell $1 <<EOS
setns soapenv=http://schemas.xmlsoap.org/soap/envelope/
xpath name(//soapenv:Body/*)
EOS
) | head -1 | sed 's/.*Object is a string : \(.*\)$/\1/'
}
if [ -n "$1" ]; then
cd $1
fi
for req in $(find . -name '*.req.xml'); do
base=$(basename $req .req.xml)
session=$(echo $base | awk -F'-' "{printf \"%d\", \$1}")
number=$(echo $base | awk -F'-' "{printf \"%d\", \$2}")
client_log=$(dirname $req)/${session}-client.log
took=$(awk "/ ${number} took / { print \$4 }" ${client_log})
printf "%s %8s: %s\n" ${base} ${took} $(body-name $req)
done

View File

@ -0,0 +1,3 @@
*.box
*.ova
.vagrant

View File

@ -0,0 +1,13 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :
# Using the VCSA base box, no provisioning, inventory will be empty.
Vagrant.configure("2") do |config|
config.vm.hostname = "vcsa"
config.vm.box = "vcsa"
config.vm.synced_folder ".", "/vagrant", disabled: true
config.vm.network "forwarded_port", guest: 443, host: 16443
end

View File

@ -0,0 +1,73 @@
#!/bin/bash -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
ovf="./VMware-vCenter-Server-Appliance-5.5.0.10300-2000350_OVA10.ova"
fi
dir=$(readlink -nf $(dirname $0))
tmp=$(mktemp -d)
trap "rm -rf $tmp" EXIT
cd $tmp
echo "Converting ovf..."
ovftool $ovf ./vcsa.vmx
echo "Starting vm..."
vmrun start vcsa.vmx nogui
echo "Waiting for vm ip..."
ip=$(vmrun getGuestIPAddress vcsa.vmx -wait)
echo "Configuring vm for use with vagrant..."
vmrun -gu root -gp vmware CopyFileFromHostToGuest vcsa.vmx \
$dir/vagrant.sh /tmp/vagrant.sh
vmrun -gu root -gp vmware runProgramInGuest vcsa.vmx \
/bin/sh -e /tmp/vagrant.sh
vmrun -gu root -gp vmware deleteFileInGuest vcsa.vmx \
/tmp/vagrant.sh
echo "Configuring vCenter Server Appliance..."
ssh_opts="-oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -oLogLevel=quiet"
ssh ${ssh_opts} -i ~/.vagrant.d/insecure_private_key vagrant@$ip <<EOF
echo "Accepting EULA ..."
sudo /usr/sbin/vpxd_servicecfg eula accept
echo "Configuring Embedded DB ..."
sudo /usr/sbin/vpxd_servicecfg db write embedded
echo "Configuring SSO..."
sudo /usr/sbin/vpxd_servicecfg sso write embedded
echo "Starting VCSA ..."
sudo /usr/sbin/vpxd_servicecfg service start
EOF
echo "Stopping vm..."
vmrun stop vcsa.vmx
rm -f vmware.log
perl -pi -e 's/"bridged"/"nat"/' vcsa.vmx
echo '{"provider":"vmware_desktop"}' > ./metadata.json
cd $dir
tar -C $tmp -cvzf vcsa.box .
vagrant box add --name vcsa vcsa.box

View File

@ -0,0 +1,24 @@
#!/bin/sh
useradd vagrant -m -s /bin/bash
groupmod -A vagrant wheel
echo -e "vagrant ALL=(ALL) NOPASSWD: ALL\n" >> /etc/sudoers
mkdir ~vagrant/.ssh
wget --no-check-certificate \
https://raw.githubusercontent.com/mitchellh/vagrant/master/keys/vagrant.pub \
-O ~vagrant/.ssh/authorized_keys
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
# disable password expiration
for uid in root vagrant
do
chage -I -1 -E -1 -m 0 -M -1 $uid
done

View File

@ -0,0 +1,75 @@
/*
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 event
import (
"github.com/vmware/govmomi/object"
"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 HistoryCollector struct {
*object.HistoryCollector
}
func NewHistoryCollector(c *vim25.Client, ref types.ManagedObjectReference) *HistoryCollector {
return &HistoryCollector{
HistoryCollector: object.NewHistoryCollector(c, ref),
}
}
func (h HistoryCollector) LatestPage(ctx context.Context) ([]types.BaseEvent, error) {
var o mo.EventHistoryCollector
err := h.Properties(ctx, h.Reference(), []string{"latestPage"}, &o)
if err != nil {
return nil, err
}
return o.LatestPage, nil
}
func (h HistoryCollector) ReadNextEvents(ctx context.Context, maxCount int) ([]types.BaseEvent, error) {
req := types.ReadNextEvents{
This: h.Reference(),
MaxCount: maxCount,
}
res, err := methods.ReadNextEvents(ctx, h.Client(), &req)
if err != nil {
return nil, err
}
return res.Returnval, nil
}
func (h HistoryCollector) ReadPreviousEvents(ctx context.Context, maxCount int) ([]types.BaseEvent, error) {
req := types.ReadPreviousEvents{
This: h.Reference(),
MaxCount: maxCount,
}
res, err := methods.ReadPreviousEvents(ctx, h.Client(), &req)
if err != nil {
return nil, err
}
return res.Returnval, nil
}

162
vendor/github.com/vmware/govmomi/event/manager.go generated vendored Normal file
View File

@ -0,0 +1,162 @@
/*
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 event
import (
"reflect"
"sync"
"github.com/vmware/govmomi/property"
"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 Manager struct {
reference types.ManagedObjectReference
c *vim25.Client
eventCategory map[string]string
eventCategoryMu *sync.Mutex
}
func NewManager(c *vim25.Client) *Manager {
m := Manager{
reference: *c.ServiceContent.EventManager,
c: c,
eventCategoryMu: new(sync.Mutex),
}
return &m
}
func (m Manager) CreateCollectorForEvents(ctx context.Context, filter types.EventFilterSpec) (*HistoryCollector, error) {
req := types.CreateCollectorForEvents{
This: m.reference,
Filter: filter,
}
res, err := methods.CreateCollectorForEvents(ctx, m.c, &req)
if err != nil {
return nil, err
}
return NewHistoryCollector(m.c, res.Returnval), nil
}
func (m Manager) LogUserEvent(ctx context.Context, entity types.ManagedObjectReference, msg string) error {
req := types.LogUserEvent{
This: m.reference,
Entity: entity,
Msg: msg,
}
_, err := methods.LogUserEvent(ctx, m.c, &req)
if err != nil {
return err
}
return nil
}
func (m Manager) PostEvent(ctx context.Context, eventToPost types.BaseEvent, taskInfo types.TaskInfo) error {
req := types.PostEvent{
This: m.reference,
EventToPost: eventToPost,
TaskInfo: &taskInfo,
}
_, err := methods.PostEvent(ctx, m.c, &req)
if err != nil {
return err
}
return nil
}
func (m Manager) QueryEvents(ctx context.Context, filter types.EventFilterSpec) ([]types.BaseEvent, error) {
req := types.QueryEvents{
This: m.reference,
Filter: filter,
}
res, err := methods.QueryEvents(ctx, m.c, &req)
if err != nil {
return nil, err
}
return res.Returnval, nil
}
func (m Manager) RetrieveArgumentDescription(ctx context.Context, eventTypeID string) ([]types.EventArgDesc, error) {
req := types.RetrieveArgumentDescription{
This: m.reference,
EventTypeId: eventTypeID,
}
res, err := methods.RetrieveArgumentDescription(ctx, m.c, &req)
if err != nil {
return nil, err
}
return res.Returnval, nil
}
func (m Manager) eventCategoryMap(ctx context.Context) (map[string]string, error) {
m.eventCategoryMu.Lock()
defer m.eventCategoryMu.Unlock()
if m.eventCategory != nil {
return m.eventCategory, nil
}
var o mo.EventManager
ps := []string{"description.eventInfo"}
err := property.DefaultCollector(m.c).RetrieveOne(ctx, m.reference, ps, &o)
if err != nil {
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
}
return m.eventCategory, nil
}
// EventCategory returns the category for an event, such as "info" or "error" for example.
func (m Manager) EventCategory(ctx context.Context, event types.BaseEvent) (string, error) {
// Most of the event details are included in the Event.FullFormattedMessage, but the category
// is only available via the EventManager description.eventInfo property. The value of this
// property is static, so we fetch and once and cache.
eventCategory, err := m.eventCategoryMap(ctx)
if err != nil {
return "", err
}
class := reflect.TypeOf(event).Elem().Name()
return eventCategory[class], nil
}

45
vendor/github.com/vmware/govmomi/event/sort.go generated vendored Normal file
View File

@ -0,0 +1,45 @@
/*
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 event
import (
"sort"
"github.com/vmware/govmomi/vim25/types"
)
// Sort events in accending order base on Key
// From the EventHistoryCollector.latestPage sdk docs:
// The "oldest event" is the one with the smallest key (event ID).
// The events in the returned page are unordered.
func Sort(events []types.BaseEvent) {
sort.Sort(baseEvent(events))
}
type baseEvent []types.BaseEvent
func (d baseEvent) Len() int {
return len(d)
}
func (d baseEvent) Less(i, j int) bool {
return d[i].GetEvent().Key < d[j].GetEvent().Key
}
func (d baseEvent) Swap(i, j int) {
d[i], d[j] = d[j], d[i]
}

View File

@ -0,0 +1,180 @@
/*
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.
*/
/*
This example program shows how the `finder` and `property` packages can
be used to navigate a vSphere inventory structure using govmomi.
*/
package main
import (
"flag"
"fmt"
"net/url"
"os"
"strings"
"text/tabwriter"
"github.com/vmware/govmomi"
"github.com/vmware/govmomi/find"
"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"
)
// GetEnvString returns string from environment variable.
func GetEnvString(v string, def string) string {
r := os.Getenv(v)
if r == "" {
return def
}
return r
}
// GetEnvBool returns boolean from environment variable.
func GetEnvBool(v string, def bool) bool {
r := os.Getenv(v)
if r == "" {
return def
}
switch strings.ToLower(r[0:1]) {
case "t", "y", "1":
return true
}
return false
}
const (
envURL = "GOVMOMI_URL"
envUserName = "GOVMOMI_USERNAME"
envPassword = "GOVMOMI_PASSWORD"
envInsecure = "GOVMOMI_INSECURE"
)
var urlDescription = fmt.Sprintf("ESX or vCenter URL [%s]", envURL)
var urlFlag = flag.String("url", GetEnvString(envURL, "https://username:password@host/sdk"), urlDescription)
var insecureDescription = fmt.Sprintf("Don't verify the server's certificate chain [%s]", envInsecure)
var insecureFlag = flag.Bool("insecure", GetEnvBool(envInsecure, false), insecureDescription)
func processOverride(u *url.URL) {
envUsername := os.Getenv(envUserName)
envPassword := os.Getenv(envPassword)
// Override username if provided
if envUsername != "" {
var password string
var ok bool
if u.User != nil {
password, ok = u.User.Password()
}
if ok {
u.User = url.UserPassword(envUsername, password)
} else {
u.User = url.User(envUsername)
}
}
// Override password if provided
if envPassword != "" {
var username string
if u.User != nil {
username = u.User.Username()
}
u.User = url.UserPassword(username, envPassword)
}
}
func exit(err error) {
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
os.Exit(1)
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
flag.Parse()
// Parse URL from string
u, err := url.Parse(*urlFlag)
if err != nil {
exit(err)
}
// Override username and/or password as required
processOverride(u)
// Connect and log in to ESX or vCenter
c, err := govmomi.NewClient(ctx, u, *insecureFlag)
if err != nil {
exit(err)
}
f := find.NewFinder(c.Client, true)
// Find one and only datacenter
dc, err := f.DefaultDatacenter(ctx)
if err != nil {
exit(err)
}
// Make future calls local to this datacenter
f.SetDatacenter(dc)
// Find datastores in datacenter
dss, err := f.DatastoreList(ctx, "*")
if err != nil {
exit(err)
}
pc := property.DefaultCollector(c.Client)
// Convert datastores into list of references
var refs []types.ManagedObjectReference
for _, ds := range dss {
refs = append(refs, ds.Reference())
}
// Retrieve summary property for all datastores
var dst []mo.Datastore
err = pc.Retrieve(ctx, refs, []string{"summary"}, &dst)
if err != nil {
exit(err)
}
// Print summary per datastore
tw := tabwriter.NewWriter(os.Stdout, 2, 0, 2, ' ', 0)
fmt.Fprintf(tw, "Name:\tType:\tCapacity:\tFree:\n")
for _, ds := range dst {
fmt.Fprintf(tw, "%s\t", ds.Summary.Name)
fmt.Fprintf(tw, "%s\t", ds.Summary.Type)
fmt.Fprintf(tw, "%s\t", units.ByteSize(ds.Summary.Capacity))
fmt.Fprintf(tw, "%s\t", units.ByteSize(ds.Summary.FreeSpace))
fmt.Fprintf(tw, "\n")
}
tw.Flush()
}

64
vendor/github.com/vmware/govmomi/find/error.go generated vendored Normal file
View File

@ -0,0 +1,64 @@
/*
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 find
import "fmt"
type NotFoundError struct {
kind string
path string
}
func (e *NotFoundError) Error() string {
return fmt.Sprintf("%s '%s' not found", e.kind, e.path)
}
type MultipleFoundError struct {
kind string
path string
}
func (e *MultipleFoundError) Error() string {
return fmt.Sprintf("path '%s' resolves to multiple %ss", e.path, e.kind)
}
type DefaultNotFoundError struct {
kind string
}
func (e *DefaultNotFoundError) Error() string {
return fmt.Sprintf("no default %s found", e.kind)
}
type DefaultMultipleFoundError struct {
kind string
}
func (e DefaultMultipleFoundError) Error() string {
return fmt.Sprintf("default %s resolves to multiple instances, please specify", e.kind)
}
func toDefaultError(err error) error {
switch e := err.(type) {
case *NotFoundError:
return &DefaultNotFoundError{e.kind}
case *MultipleFoundError:
return &DefaultMultipleFoundError{e.kind}
default:
return err
}
}

607
vendor/github.com/vmware/govmomi/find/finder.go generated vendored Normal file
View File

@ -0,0 +1,607 @@
/*
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 find
import (
"errors"
"path"
"github.com/vmware/govmomi/list"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/mo"
"golang.org/x/net/context"
)
type Finder struct {
client *vim25.Client
recurser list.Recurser
dc *object.Datacenter
folders *object.DatacenterFolders
}
func NewFinder(client *vim25.Client, all bool) *Finder {
f := &Finder{
client: client,
recurser: list.Recurser{
Collector: property.DefaultCollector(client),
All: all,
},
}
return f
}
func (f *Finder) SetDatacenter(dc *object.Datacenter) *Finder {
f.dc = dc
f.folders = nil
return f
}
type findRelativeFunc func(ctx context.Context) (object.Reference, error)
func (f *Finder) find(ctx context.Context, fn findRelativeFunc, tl bool, arg string) ([]list.Element, error) {
root := list.Element{
Path: "/",
Object: object.NewRootFolder(f.client),
}
parts := list.ToParts(arg)
if len(parts) > 0 {
switch parts[0] {
case "..": // Not supported; many edge case, little value
return nil, errors.New("cannot traverse up a tree")
case ".": // Relative to whatever
pivot, err := fn(ctx)
if err != nil {
return nil, err
}
mes, err := mo.Ancestors(ctx, f.client, f.client.ServiceContent.PropertyCollector, pivot.Reference())
if err != nil {
return nil, err
}
for _, me := range mes {
// Skip root entity in building inventory path.
if me.Parent == nil {
continue
}
root.Path = path.Join(root.Path, me.Name)
}
root.Object = pivot
parts = parts[1:]
}
}
f.recurser.TraverseLeafs = tl
es, err := f.recurser.Recurse(ctx, root, parts)
if err != nil {
return nil, err
}
return es, nil
}
func (f *Finder) datacenter() (*object.Datacenter, error) {
if f.dc == nil {
return nil, errors.New("please specify a datacenter")
}
return f.dc, nil
}
func (f *Finder) dcFolders(ctx context.Context) (*object.DatacenterFolders, error) {
if f.folders != nil {
return f.folders, nil
}
dc, err := f.datacenter()
if err != nil {
return nil, err
}
folders, err := dc.Folders(ctx)
if err != nil {
return nil, err
}
f.folders = folders
return f.folders, nil
}
func (f *Finder) dcReference(_ context.Context) (object.Reference, error) {
dc, err := f.datacenter()
if err != nil {
return nil, err
}
return dc, nil
}
func (f *Finder) vmFolder(ctx context.Context) (object.Reference, error) {
folders, err := f.dcFolders(ctx)
if err != nil {
return nil, err
}
return folders.VmFolder, nil
}
func (f *Finder) hostFolder(ctx context.Context) (object.Reference, error) {
folders, err := f.dcFolders(ctx)
if err != nil {
return nil, err
}
return folders.HostFolder, nil
}
func (f *Finder) datastoreFolder(ctx context.Context) (object.Reference, error) {
folders, err := f.dcFolders(ctx)
if err != nil {
return nil, err
}
return folders.DatastoreFolder, nil
}
func (f *Finder) networkFolder(ctx context.Context) (object.Reference, error) {
folders, err := f.dcFolders(ctx)
if err != nil {
return nil, err
}
return folders.NetworkFolder, nil
}
func (f *Finder) rootFolder(_ context.Context) (object.Reference, error) {
return object.NewRootFolder(f.client), nil
}
func (f *Finder) managedObjectList(ctx context.Context, path string, tl bool) ([]list.Element, error) {
fn := f.rootFolder
if f.dc != nil {
fn = f.dcReference
}
if len(path) == 0 {
path = "."
}
return f.find(ctx, fn, tl, path)
}
func (f *Finder) ManagedObjectList(ctx context.Context, path string) ([]list.Element, error) {
return f.managedObjectList(ctx, path, false)
}
func (f *Finder) ManagedObjectListChildren(ctx context.Context, path string) ([]list.Element, error) {
return f.managedObjectList(ctx, path, true)
}
func (f *Finder) DatacenterList(ctx context.Context, path string) ([]*object.Datacenter, error) {
es, err := f.find(ctx, f.rootFolder, false, path)
if err != nil {
return nil, err
}
var dcs []*object.Datacenter
for _, e := range es {
ref := e.Object.Reference()
if ref.Type == "Datacenter" {
dcs = append(dcs, object.NewDatacenter(f.client, ref))
}
}
if len(dcs) == 0 {
return nil, &NotFoundError{"datacenter", path}
}
return dcs, nil
}
func (f *Finder) Datacenter(ctx context.Context, path string) (*object.Datacenter, error) {
dcs, err := f.DatacenterList(ctx, path)
if err != nil {
return nil, err
}
if len(dcs) > 1 {
return nil, &MultipleFoundError{"datacenter", path}
}
return dcs[0], nil
}
func (f *Finder) DefaultDatacenter(ctx context.Context) (*object.Datacenter, error) {
dc, err := f.Datacenter(ctx, "*")
if err != nil {
return nil, toDefaultError(err)
}
return dc, nil
}
func (f *Finder) DatastoreList(ctx context.Context, path string) ([]*object.Datastore, error) {
es, err := f.find(ctx, f.datastoreFolder, false, path)
if err != nil {
return nil, err
}
var dss []*object.Datastore
for _, e := range es {
ref := e.Object.Reference()
if ref.Type == "Datastore" {
ds := object.NewDatastore(f.client, ref)
ds.InventoryPath = e.Path
dss = append(dss, ds)
}
}
if len(dss) == 0 {
return nil, &NotFoundError{"datastore", path}
}
return dss, nil
}
func (f *Finder) Datastore(ctx context.Context, path string) (*object.Datastore, error) {
dss, err := f.DatastoreList(ctx, path)
if err != nil {
return nil, err
}
if len(dss) > 1 {
return nil, &MultipleFoundError{"datastore", path}
}
return dss[0], nil
}
func (f *Finder) DefaultDatastore(ctx context.Context) (*object.Datastore, error) {
ds, err := f.Datastore(ctx, "*")
if err != nil {
return nil, toDefaultError(err)
}
return ds, nil
}
func (f *Finder) ComputeResourceList(ctx context.Context, path string) ([]*object.ComputeResource, error) {
es, err := f.find(ctx, f.hostFolder, false, path)
if err != nil {
return nil, err
}
var crs []*object.ComputeResource
for _, e := range es {
var cr *object.ComputeResource
switch o := e.Object.(type) {
case mo.ComputeResource, mo.ClusterComputeResource:
cr = object.NewComputeResource(f.client, o.Reference())
default:
continue
}
cr.InventoryPath = e.Path
crs = append(crs, cr)
}
if len(crs) == 0 {
return nil, &NotFoundError{"compute resource", path}
}
return crs, nil
}
func (f *Finder) ComputeResource(ctx context.Context, path string) (*object.ComputeResource, error) {
crs, err := f.ComputeResourceList(ctx, path)
if err != nil {
return nil, err
}
if len(crs) > 1 {
return nil, &MultipleFoundError{"compute resource", path}
}
return crs[0], nil
}
func (f *Finder) DefaultComputeResource(ctx context.Context) (*object.ComputeResource, error) {
cr, err := f.ComputeResource(ctx, "*")
if err != nil {
return nil, toDefaultError(err)
}
return cr, nil
}
func (f *Finder) ClusterComputeResourceList(ctx context.Context, path string) ([]*object.ClusterComputeResource, error) {
es, err := f.find(ctx, f.hostFolder, false, path)
if err != nil {
return nil, err
}
var ccrs []*object.ClusterComputeResource
for _, e := range es {
var ccr *object.ClusterComputeResource
switch o := e.Object.(type) {
case mo.ClusterComputeResource:
ccr = object.NewClusterComputeResource(f.client, o.Reference())
default:
continue
}
ccr.InventoryPath = e.Path
ccrs = append(ccrs, ccr)
}
if len(ccrs) == 0 {
return nil, &NotFoundError{"cluster", path}
}
return ccrs, nil
}
func (f *Finder) ClusterComputeResource(ctx context.Context, path string) (*object.ClusterComputeResource, error) {
ccrs, err := f.ClusterComputeResourceList(ctx, path)
if err != nil {
return nil, err
}
if len(ccrs) > 1 {
return nil, &MultipleFoundError{"cluster", path}
}
return ccrs[0], nil
}
func (f *Finder) HostSystemList(ctx context.Context, path string) ([]*object.HostSystem, error) {
es, err := f.find(ctx, f.hostFolder, false, path)
if err != nil {
return nil, err
}
var hss []*object.HostSystem
for _, e := range es {
var hs *object.HostSystem
switch o := e.Object.(type) {
case mo.HostSystem:
hs = object.NewHostSystem(f.client, o.Reference())
case mo.ComputeResource:
cr := object.NewComputeResource(f.client, o.Reference())
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)
}
if len(hss) == 0 {
return nil, &NotFoundError{"host", path}
}
return hss, nil
}
func (f *Finder) HostSystem(ctx context.Context, path string) (*object.HostSystem, error) {
hss, err := f.HostSystemList(ctx, path)
if err != nil {
return nil, err
}
if len(hss) > 1 {
return nil, &MultipleFoundError{"host", path}
}
return hss[0], nil
}
func (f *Finder) DefaultHostSystem(ctx context.Context) (*object.HostSystem, error) {
hs, err := f.HostSystem(ctx, "*/*")
if err != nil {
return nil, toDefaultError(err)
}
return hs, nil
}
func (f *Finder) NetworkList(ctx context.Context, path string) ([]object.NetworkReference, error) {
es, err := f.find(ctx, f.networkFolder, false, path)
if err != nil {
return nil, err
}
var ns []object.NetworkReference
for _, e := range es {
ref := e.Object.Reference()
switch ref.Type {
case "Network":
r := object.NewNetwork(f.client, ref)
r.InventoryPath = e.Path
ns = append(ns, r)
case "DistributedVirtualPortgroup":
r := object.NewDistributedVirtualPortgroup(f.client, ref)
r.InventoryPath = e.Path
ns = append(ns, r)
}
}
if len(ns) == 0 {
return nil, &NotFoundError{"network", path}
}
return ns, nil
}
func (f *Finder) Network(ctx context.Context, path string) (object.NetworkReference, error) {
networks, err := f.NetworkList(ctx, path)
if err != nil {
return nil, err
}
if len(networks) > 1 {
return nil, &MultipleFoundError{"network", path}
}
return networks[0], nil
}
func (f *Finder) DefaultNetwork(ctx context.Context) (object.NetworkReference, error) {
network, err := f.Network(ctx, "*")
if err != nil {
return nil, toDefaultError(err)
}
return network, nil
}
func (f *Finder) ResourcePoolList(ctx context.Context, path string) ([]*object.ResourcePool, error) {
es, err := f.find(ctx, f.hostFolder, true, path)
if err != nil {
return nil, err
}
var rps []*object.ResourcePool
for _, e := range es {
var rp *object.ResourcePool
switch o := e.Object.(type) {
case mo.ResourcePool:
rp = object.NewResourcePool(f.client, o.Reference())
rp.InventoryPath = e.Path
rps = append(rps, rp)
}
}
if len(rps) == 0 {
return nil, &NotFoundError{"resource pool", path}
}
return rps, nil
}
func (f *Finder) ResourcePool(ctx context.Context, path string) (*object.ResourcePool, error) {
rps, err := f.ResourcePoolList(ctx, path)
if err != nil {
return nil, err
}
if len(rps) > 1 {
return nil, &MultipleFoundError{"resource pool", path}
}
return rps[0], nil
}
func (f *Finder) DefaultResourcePool(ctx context.Context) (*object.ResourcePool, error) {
rp, err := f.ResourcePool(ctx, "*/Resources")
if err != nil {
return nil, toDefaultError(err)
}
return rp, nil
}
func (f *Finder) VirtualMachineList(ctx context.Context, path string) ([]*object.VirtualMachine, error) {
es, err := f.find(ctx, f.vmFolder, false, path)
if err != nil {
return nil, err
}
var vms []*object.VirtualMachine
for _, e := range es {
switch o := e.Object.(type) {
case mo.VirtualMachine:
vm := object.NewVirtualMachine(f.client, o.Reference())
vm.InventoryPath = e.Path
vms = append(vms, vm)
}
}
if len(vms) == 0 {
return nil, &NotFoundError{"vm", path}
}
return vms, nil
}
func (f *Finder) VirtualMachine(ctx context.Context, path string) (*object.VirtualMachine, error) {
vms, err := f.VirtualMachineList(ctx, path)
if err != nil {
return nil, err
}
if len(vms) > 1 {
return nil, &MultipleFoundError{"vm", path}
}
return vms[0], nil
}
func (f *Finder) VirtualAppList(ctx context.Context, path string) ([]*object.VirtualApp, error) {
es, err := f.find(ctx, f.vmFolder, false, path)
if err != nil {
return nil, err
}
var apps []*object.VirtualApp
for _, e := range es {
switch o := e.Object.(type) {
case mo.VirtualApp:
app := object.NewVirtualApp(f.client, o.Reference())
app.InventoryPath = e.Path
apps = append(apps, app)
}
}
if len(apps) == 0 {
return nil, &NotFoundError{"app", path}
}
return apps, nil
}
func (f *Finder) VirtualApp(ctx context.Context, path string) (*object.VirtualApp, error) {
apps, err := f.VirtualAppList(ctx, path)
if err != nil {
return nil, err
}
if len(apps) > 1 {
return nil, &MultipleFoundError{"app", path}
}
return apps[0], nil
}

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

@ -0,0 +1,3 @@
source "https://rubygems.org"
gem "nokogiri"

38
vendor/github.com/vmware/govmomi/gen/gen.sh generated vendored Normal file
View File

@ -0,0 +1,38 @@
#!/bin/bash
# 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.
set -e
if [ ! -f rbvmomi/vmodl.db ]; then
git clone https://github.com/vmware/rbvmomi
fi
dst=../vim25
pkgs=$(echo $dst/{types,methods,mo})
mkdir -p $pkgs
bundle exec ruby gen_from_wsdl.rb $dst
bundle exec ruby gen_from_vmodl.rb $dst
for p in $pkgs
do
echo $p
cd $p
goimports -w *.go
go install
cd -
done

216
vendor/github.com/vmware/govmomi/gen/gen_from_vmodl.rb generated vendored Normal file
View File

@ -0,0 +1,216 @@
# 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.
$:.unshift(File.expand_path(File.dirname(__FILE__)))
require "vim_wsdl"
require "test/unit"
PATH = File.expand_path("../rbvmomi", __FILE__)
def read(file)
File.open(File.join(PATH, file))
end
class Prop
def initialize(vmodl, data)
@vmodl = vmodl
@data = data
end
def slice?
@data["is-array"]
end
def optional?
@data["is-optional"]
end
def name
@data["name"]
end
def var_field
n = name
n[0].capitalize + n[1..-1]
end
def var_type_prefix(base=false)
if slice?
"[]"
else
if optional? && !base
"*"
else
""
end
end
end
def var_type
type = @data["wsdl_type"]
if @vmodl.managed_hash.has_key?(type)
type = "ManagedObjectReference"
end
# Fix up type from vmodl
case type
when "TypeName", "MethodName"
type = "xsd:string"
when "ManagedObject"
type = "ManagedObjectReference"
when "xsd:anyType"
type = "AnyType"
end
if type =~ /^xsd:(.*)$/
type = $1
case type
when "string"
when "int"
when "boolean"
type ="bool"
when "long"
type ="int64"
when "dateTime"
type ="time.Time"
prefix += "*" if !slice? && optional?
when "byte"
when "double"
type ="float64"
when "float"
type ="float32"
when "short"
type ="int16"
when "base64Binary"
type ="[]byte"
else
raise "unknown type: %s" % type
end
else
if Peek.base?(type)
type = "Base" + type
base = true
end
type = "types." + type
end
var_type_prefix(base) + type
end
def var_tag
"mo:\"%s\"" % name
end
def dump(io)
io.print "%s %s `%s`\n" % [var_field, var_type, var_tag]
end
end
class Managed
def initialize(vmodl, name, data)
@vmodl = vmodl
@name = name
@data = data
end
def name
@name
end
def props
@data["props"].map do |p|
Prop.new(@vmodl, p)
end
end
def dump(io)
include_ref_getter = false
io.print "type %s struct {\n" % name
case @data["wsdl_base"]
when nil, "ManagedObject", "View"
include_ref_getter = true
io.print "Self types.ManagedObjectReference\n\n"
else
io.print "%s\n\n" % @data["wsdl_base"]
end
props.each do |p|
p.dump(io)
end
io.print "}\n\n"
if include_ref_getter
io.print "func (m %s) Reference() types.ManagedObjectReference {\n" % [name]
io.print "return m.Self\n"
io.print "}\n\n"
end
end
def dump_init(io)
io.print "func init() {\n"
io.print "t[\"%s\"] = reflect.TypeOf((*%s)(nil)).Elem()\n" % [name, name]
io.print "}\n\n"
end
end
class Vmodl
def initialize(data)
@data = Marshal.load(data)
end
def managed_hash
@managed_hash ||= begin
h = {}
managed.each do |m|
h[m.name] = m
end
h
end
end
def managed
@data.map do |k,v|
next if !v.is_a?(Hash)
next if v["kind"] != "managed"
next if k =~ /^pbm/i
Managed.new(self, k, v)
end.compact
end
end
if !File.directory?(ARGV.first)
raise "first argument not a directory"
end
wsdl = WSDL.new(WSDL.read "vim.wsdl")
wsdl.validate_assumptions!
wsdl.peek()
File.open(File.join(ARGV.first, "mo/mo.go"), "w") do |io|
io.print WSDL.header("mo")
vmodl = Vmodl.new(read "vmodl.db")
vmodl.
managed.
sort_by { |m| m.name }.
each { |m| m.dump(io); m.dump_init(io); }
end
exit(0)

70
vendor/github.com/vmware/govmomi/gen/gen_from_wsdl.rb generated vendored Normal file
View File

@ -0,0 +1,70 @@
# 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.
$:.unshift(File.expand_path(File.dirname(__FILE__)))
require "vim_wsdl"
if !File.directory?(ARGV.first)
raise "first argument not a directory"
end
wsdl = WSDL.new(WSDL.read "vim.wsdl")
wsdl.validate_assumptions!
wsdl.peek()
ifs = Peek.types.keys.select { |name| Peek.base?(name) }.size()
puts "%d classes, %d interfaces" % [Peek.types.size(), ifs]
File.open(File.join(ARGV.first, "types/enum.go"), "w") do |io|
io.print WSDL.header("types")
wsdl.
types.
sort_by { |x| x.name }.
uniq { |x| x.name }.
select { |x| x.name[0] == x.name[0].upcase }. # Only capitalized methods for now...
select { |t| t.is_enum? }.
each { |e| e.dump(io); e.dump_init(io) }
end
File.open(File.join(ARGV.first, "types/types.go"), "w") do |io|
io.print WSDL.header("types")
wsdl.
types.
sort_by { |x| x.name }.
uniq { |x| x.name }.
select { |x| x.name[0] == x.name[0].upcase }. # Only capitalized methods for now...
select { |t| !t.is_enum? }.
each { |e| e.dump(io); e.dump_init(io) }
end
File.open(File.join(ARGV.first, "types/if.go"), "w") do |io|
io.print WSDL.header("types")
Peek.dump_interfaces(io)
end
File.open(File.join(ARGV.first, "methods/methods.go"), "w") do |io|
io.print WSDL.header("methods")
wsdl.
operations.
sort_by { |x| x.name }.
select { |x| x.name[0] == x.name[0].upcase }. # Only capitalized methods for now...
each { |e| e.dump(io) }
end
exit(0)

761
vendor/github.com/vmware/govmomi/gen/vim_wsdl.rb generated vendored Normal file
View File

@ -0,0 +1,761 @@
# 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.
require "nokogiri"
require "test/unit"
class Peek
class Type
attr_accessor :parent, :children, :klass
def initialize(name)
@name = name
@children = []
end
def base?
return !children.empty?
end
end
@@types = {}
@@refs = {}
@@enums = {}
def self.types
return @@types
end
def self.refs
return @@refs
end
def self.enums
return @@enums
end
def self.ref(type)
refs[type] = true
end
def self.enum(type)
enums[type] = true
end
def self.enum?(type)
enums[type]
end
def self.register(name)
raise unless name
types[name] ||= Type.new(name)
end
def self.base?(name)
return unless c = types[name]
c.base?
end
def self.dump_interfaces(io)
types.keys.sort.each do |name|
next unless base?(name)
types[name].klass.dump_interface(io, name)
end
end
end
class EnumValue
def initialize(type, value)
@type = type
@value = value
end
def type_name
@type.name
end
def var_name
n = @type.name
v = var_value
if v == ""
n += "Null"
else
n += (v[0].capitalize + v[1..-1])
end
return n
end
def var_value
@value
end
def dump(io)
io.print "%s = %s(\"%s\")\n" % [var_name, type_name, var_value]
end
end
class Simple
include Test::Unit::Assertions
attr_accessor :name, :type
def initialize(node)
@node = node
end
def name
@name || @node["name"]
end
def type
@type || @node["type"]
end
def is_enum?
false
end
def dump_init(io)
# noop
end
def var_name
n = self.name
n = n[1..-1] if n[0] == "_" # Strip leading _
n = n[0].capitalize + n[1..-1] # Capitalize
return n
end
def vim_type?
ns, _ = self.type.split(":", 2)
ns == "vim25"
end
def vim_type(t = self.type)
ns, t = t.split(":", 2)
raise if ns != "vim25"
t
end
def base_type?
vim_type? && Peek.base?(vim_type)
end
def enum_type?
vim_type? && Peek.enum?(vim_type)
end
def any_type?
self.type == "xsd:anyType"
end
def var_type
t = self.type
prefix = ""
prefix += "[]" if slice?
if t =~ /^xsd:(.*)$/
t = $1
case t
when "string"
when "int"
when "boolean"
t = "bool"
if !slice? && optional?
prefix += "*"
self.need_omitempty = false
end
when "long"
t = "int64"
when "dateTime"
t = "time.Time"
if !slice? && optional?
prefix += "*"
self.need_omitempty = false
end
when "anyType"
t = "AnyType"
when "byte"
when "double"
t = "float64"
when "float"
t = "float32"
when "short"
t = "int16"
when "base64Binary"
t = "[]byte"
when "anyURI"
t = "url.URL"
else
raise "unknown type: %s" % t
end
else
t = vim_type
if base_type?
prefix += "Base"
else
prefix += "*" if !slice? && !enum_type? && optional?
end
end
prefix + t
end
def slice?
test_attr("maxOccurs", "unbounded")
end
def optional?
test_attr("minOccurs", "0")
end
def need_omitempty=(v)
@need_omitempty = v
end
def need_omitempty?
var_type # HACK: trigger setting need_omitempty if necessary
if @need_omitempty.nil?
@need_omitempty = optional?
else
@need_omitempty
end
end
def need_typeattr?
base_type? || any_type?
end
protected
def test_attr(attr, expected)
actual = @node.attr(attr)
if actual != nil
case actual
when expected
true
else
raise "%s=%s" % [value, type.attr(value)]
end
else
false
end
end
end
class Element < Simple
def initialize(node)
super(node)
end
def has_type?
!@node["type"].nil?
end
def child
cs = @node.element_children
assert_equal 1, cs.length
assert_equal "complexType", cs.first.name
t = ComplexType.new(cs.first)
t.name = self.name
t
end
def dump(io)
if has_type?
io.print "type %s %s\n\n" % [name, var_type]
else
child.dump(io)
end
end
def dump_init(io)
if has_type?
io.print "func init() {\n"
io.print "t[\"%s\"] = reflect.TypeOf((*%s)(nil)).Elem()\n" % [name, name]
io.print "}\n\n"
end
end
def dump_field(io)
tag = name
tag += ",omitempty" if need_omitempty?
tag += ",typeattr" if need_typeattr?
io.print "%s %s `xml:\"%s\"`\n" % [var_name, var_type, tag]
end
def peek(type=nil)
if has_type?
return if self.type =~ /^xsd:/
Peek.ref(vim_type)
else
child.peek()
end
end
end
class Attribute < Simple
def dump_field(io)
tag = name
tag += ",omitempty" if need_omitempty?
tag += ",attr"
io.print "%s %s `xml:\"%s\"`\n" % [var_name, var_type, tag]
end
end
class SimpleType < Simple
def is_enum?
true
end
def dump(io)
enums = @node.xpath(".//xsd:enumeration").map do |n|
EnumValue.new(self, n["value"])
end
io.print "type %s string\n\n" % name
io.print "const (\n"
enums.each { |e| e.dump(io) }
io.print ")\n\n"
end
def dump_init(io)
io.print "func init() {\n"
io.print "t[\"%s\"] = reflect.TypeOf((*%s)(nil)).Elem()\n" % [name, name]
io.print "}\n\n"
end
def peek
Peek.enum(name)
end
end
class ComplexType < Simple
class SimpleContent < Simple
def dump(io)
attr = Attribute.new(@node.at_xpath(".//xsd:attribute"))
attr.dump_field(io)
# HACK DELUXE(PN)
extension = @node.at_xpath(".//xsd:extension")
type = extension["base"].split(":", 2)[1]
io.print "Value %s `xml:\",chardata\"`\n" % type
end
def peek
end
end
class ComplexContent < Simple
def base
extension = @node.at_xpath(".//xsd:extension")
assert_not_nil extension
base = extension["base"]
assert_not_nil base
vim_type(base)
end
def dump(io)
Sequence.new(@node).dump(io, base)
end
def dump_interface(io, name)
Sequence.new(@node).dump_interface(io, name)
end
def peek
Sequence.new(@node).peek(base)
end
end
class Sequence < Simple
def sequence
sequence = @node.at_xpath(".//xsd:sequence")
if sequence != nil
sequence.element_children.map do |n|
Element.new(n)
end
else
nil
end
end
def dump(io, base = nil)
return unless elements = sequence
io.print "%s\n\n" % base
elements.each do |e|
e.dump_field(io)
end
end
def dump_interface(io, name)
method = "Get%s() *%s" % [name, name]
io.print "func (b *%s) %s { return b }\n" % [name, method]
io.print "type Base%s interface {\n" % name
io.print "%s\n" % method
io.print "}\n\n"
io.print "func init() {\n"
io.print "t[\"Base%s\"] = reflect.TypeOf((*%s)(nil)).Elem()\n" % [name, name]
io.print "}\n\n"
end
def peek(base = nil)
return unless elements = sequence
name = @node.attr("name")
return unless name
elements.each do |e|
e.peek(name)
end
c = Peek.register(name)
if base
c.parent = base
Peek.register(c.parent).children << name
end
end
end
def klass
@klass ||= begin
cs = @node.element_children
if !cs.empty?
assert_equal 1, cs.length
case cs.first.name
when "simpleContent"
SimpleContent.new(@node)
when "complexContent"
ComplexContent.new(@node)
when "sequence"
Sequence.new(@node)
else
raise "don't know what to do for element: %s..." % cs.first.name
end
end
end
end
def dump_init(io)
io.print "func init() {\n"
io.print "t[\"%s\"] = reflect.TypeOf((*%s)(nil)).Elem()\n" % [name, name]
io.print "}\n\n"
end
def dump(io)
io.print "type %s struct {\n" % name
klass.dump(io) if klass
io.print "}\n\n"
end
def peek
Peek.register(name).klass = klass
klass.peek if klass
end
end
class Schema
include Test::Unit::Assertions
def initialize(xml, parent = nil)
@xml = Nokogiri::XML.parse(xml)
end
def targetNamespace
@xml.root["targetNamespace"]
end
# We have some assumptions about structure, make sure they hold.
def validate_assumptions!
# Every enumeration is part of a restriction
@xml.xpath(".//xsd:enumeration").each do |n|
assert_equal "restriction", n.parent.name
end
# See type == enum
@xml.xpath(".//xsd:restriction").each do |n|
# Every restriction has type xsd:string (it's an enum)
assert_equal "xsd:string", n["base"]
# Every restriction is part of a simpleType
assert_equal "simpleType", n.parent.name
# Every restriction is alone
assert_equal 1, n.parent.element_children.size
end
# See type == complex_content
@xml.xpath(".//xsd:complexContent").each do |n|
# complexContent is child of complexType
assert_equal "complexType", n.parent.name
end
# See type == complex_type
@xml.xpath(".//xsd:complexType").each do |n|
cc = n.element_children
# OK to have an empty complexType
next if cc.size == 0
# Require 1 element otherwise
assert_equal 1, cc.size
case cc.first.name
when "complexContent"
# complexContent has 1 "extension" element
cc = cc.first.element_children
assert_equal 1, cc.size
assert_equal "extension", cc.first.name
# extension has 1 "sequence" element
ec = cc.first.element_children
assert_equal 1, ec.size
assert_equal "sequence", ec.first.name
# sequence has N "element" elements
sc = ec.first.element_children
assert sc.all? { |e| e.name == "element" }
when "simpleContent"
# simpleContent has 1 "extension" element
cc = cc.first.element_children
assert_equal 1, cc.size
assert_equal "extension", cc.first.name
# extension has 1 or more "attribute" elements
ec = cc.first.element_children
assert_not_equal 0, ec.size
assert_equal "attribute", ec.first.name
when "sequence"
# sequence has N "element" elements
sc = cc.first.element_children
assert sc.all? { |e| e.name == "element" }
else
raise "unknown element: %s" % cc.first.name
end
end
includes.each do |i|
i.validate_assumptions!
end
end
def types
return to_enum(:types) unless block_given?
includes.each do |i|
i.types do |t|
yield t
end
end
@xml.root.children.each do |n|
case n.class.to_s
when "Nokogiri::XML::Text"
next
when "Nokogiri::XML::Element"
case n.name
when "include", "import"
next
when "element"
yield Element.new(n)
when "simpleType"
yield SimpleType.new(n)
when "complexType"
yield ComplexType.new(n)
else
raise "unknown child: %s" % n.name
end
else
raise "unknown type: %s" % n.class
end
end
end
def includes
@includes ||= @xml.root.xpath(".//xmlns:include").map do |n|
Schema.new(WSDL.read n["schemaLocation"])
end
end
end
class Operation
include Test::Unit::Assertions
def initialize(wsdl, operation_node)
@wsdl = wsdl
@operation_node = operation_node
end
def name
@operation_node["name"]
end
def remove_ns(x)
ns, x = x.split(":", 2)
assert_equal "vim25", ns
x
end
def find_type_for(type)
type = remove_ns(type)
message = @wsdl.message(type)
assert_not_nil message
part = message.at_xpath("./xmlns:part")
assert_not_nil message
remove_ns(part["element"])
end
def input
type = @operation_node.at_xpath("./xmlns:input").attr("message")
find_type_for(type)
end
def go_input
"types." + input
end
def output
type = @operation_node.at_xpath("./xmlns:output").attr("message")
find_type_for(type)
end
def go_output
"types." + output
end
def dump(io)
io.print <<EOS
type #{name}Body struct{
Req *#{go_input} `xml:"urn:vim25 #{input},omitempty"`
Res *#{go_output} `xml:"urn:vim25 #{output},omitempty"`
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
}
func (b *#{name}Body) Fault() *soap.Fault { return b.Fault_ }
EOS
io.print "func %s(ctx context.Context, r soap.RoundTripper, req *%s) (*%s, error) {\n" % [name, go_input, go_output]
io.print <<EOS
var reqBody, resBody #{name}Body
reqBody.Req = req
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
return nil, err
}
return resBody.Res, nil
EOS
io.print "}\n\n"
end
end
class WSDL
attr_reader :xml
PATH = File.expand_path("../sdk", __FILE__)
def self.read(file)
File.open(File.join(PATH, file))
end
def initialize(xml)
@xml = Nokogiri::XML.parse(xml)
end
def validate_assumptions!
schemas.each do |s|
s.validate_assumptions!
end
end
def types(&blk)
return to_enum(:types) unless block_given?
schemas.each do |s|
s.types(&blk)
end
end
def schemas
@schemas ||= @xml.xpath('.//xmlns:types/xsd:schema').map do |n|
Schema.new(n.to_xml)
end
end
def operations
@operations ||= @xml.xpath('.//xmlns:portType/xmlns:operation').map do |o|
Operation.new(self, o)
end
end
def message(type)
@messages ||= begin
h = {}
@xml.xpath('.//xmlns:message').each do |n|
h[n.attr("name")] = n
end
h
end
@messages[type]
end
def peek
types.
sort_by { |x| x.name }.
uniq { |x| x.name }.
select { |x| x.name[0] == x.name[0].upcase }. # Only capitalized methods for now...
each { |e| e.peek() }
end
def self.header(name)
return <<EOF
/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package #{name}
EOF
end
end

1
vendor/github.com/vmware/govmomi/govc/.gitignore generated vendored Normal file
View File

@ -0,0 +1 @@
/govc*

28
vendor/github.com/vmware/govmomi/govc/CHANGELOG.md generated vendored Normal file
View File

@ -0,0 +1,28 @@
# changelog
### (unreleased)
* Add `PowerOn, InjectOvfEnv, WaitForIP` options to `import.ovf` and `import.ova` option spec file
* Add `import.spec` to produce an example json document
* Add `-options` to `import.ovf` and `import.ova`
* Add `-folder` to `import.ovf` and `import.ova`
* Add `host.add` command to add host to datacenter.
* Add `GOVC_USERNAME` and `GOVC_PASSWORD` to allow overriding username and/or
password (used when they contain special characters that prevent them from
being embedded in the URL).
* Retry twice on temporary network errors.
* Add `host.autostart` commands to manage VM autostart.
* Add `-persist-session` flag to control whether or not the session is
persisted to disk (defaults to true).
### 0.1.0 (2015-03-17)
Prior to this version the changes to govc's command set were not documented.

116
vendor/github.com/vmware/govmomi/govc/README.md generated vendored Normal file
View File

@ -0,0 +1,116 @@
# govc
govc is a vSphere CLI built on top of govmomi.
## Installation
You can find prebuilt govc binaries on the [releases page](https://github.com/vmware/govmomi/releases).
Download and install a binary locally like this:
```sh
curl $URL_TO_BINARY | gzip -d > /usr/local/bin/govc
chmod +x /usr/local/bin/govc
```
### Source
You can install the latest govc version from source if you have the Go toolchain installed.
```sh
go get github.com/vmware/govmomi/govc
```
(make sure `$GOPATH/bin` is in your `PATH`)
## Usage
govc exposes its functionality through subcommands. Option flags
to these subcommands are often shared.
Common flags include:
* `-u`: ESXi or vCenter URL (ex: `user:pass@host`)
* `-debug`: Trace requests and responses (to `~/.govmomi/debug`)
Managed entities can be referred to by their absolute path or by their relative
path. For example, when specifying a datastore to use for a subcommand, you can
either specify it as `/mydatacenter/datastore/mydatastore`, or as
`mydatastore`. If you're not sure about the name of the datastore, or even the
full path to the datastore, you can specify a pattern to match. Both
`/*center/*/my*` (absolute) and `my*store` (relative) will resolve to the same
datastore, given there are no other datastores that match those globs.
The relative path in this example can only be used if the command can
umambigously resolve a datacenter to use as origin for the query. If no
datacenter is specified, govc defaults to the only datacenter, if there is only
one. The datacenter itself can be specified as a pattern as well, enabling the
following arguments: `-dc='my*' -ds='*store'`. The datastore pattern is looked
up and matched relative to the datacenter which itself is specified as a
pattern.
Besides specifying managed entities as arguments, they can also be specified
using environment variables. The following environment variables are used by govc
to set defaults:
* `GOVC_USERNAME`: USERNAME to use.
* `GOVC_PASSWORD`: PASSWORD to use.
* `GOVC_URL`: URL of ESXi or vCenter instance to connect to.
> The URL scheme defaults to `https` and the URL path defaults to `/sdk`.
> This means that specifying `user:pass@host` is equivalent to
> `https://user:pass@host/sdk`.
> If password include special characters like `#` or `:` you can use
> `GOVC_USERNAME` and `GOVC_PASSWORD` to have a simple `GOVC_URL`
* `GOVC_INSECURE`: Allow establishing insecure connections.
> Use this option when the host you're connecting is using self-signed
> certificates, or is otherwise trusted. Set this option to `1` to enable.
* `GOVC_DATACENTER`
* `GOVC_DATASTORE`
* `GOVC_NETWORK`
* `GOVC_RESOURCE_POOL`
* `GOVC_HOST`
* `GOVC_GUEST_LOGIN`: Guest credentials for guest operations
## Examples
* About
```
$ export GOVC_URL="192.168.1.20"
$ export GOVC_USERNAME="domain\administrator"
$ export GOVC_PASSWORD="Password123#"
$ govc about
Name: VMware vCenter Server
Vendor: VMware, Inc.
Version: 6.0.0
Build: 2656761
OS type: linux-x64
API type: VirtualCenter
API version: 6.0
Product ID: vpx
UUID: c9f0242f-10e3-4e10-85d7-5eea7c855188
```
* [Upload ssh public key to a VM](examples/lib/ssh.sh)
* [Create and configure a vCenter VM](examples/vcsa.sh)
## Projects using govc
* [Kubernetes vSphere Provider](https://github.com/GoogleCloudPlatform/kubernetes/tree/master/cluster/vsphere)
## License
govc is available under the [Apache 2 license](../LICENSE).

59
vendor/github.com/vmware/govmomi/govc/about/command.go generated vendored Normal file
View File

@ -0,0 +1,59 @@
/*
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 about
import (
"flag"
"fmt"
"os"
"text/tabwriter"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
)
type about struct {
*flags.ClientFlag
}
func init() {
cli.Register("about", &about{})
}
func (cmd *about) Register(f *flag.FlagSet) {}
func (cmd *about) Process() error { return nil }
func (cmd *about) Run(f *flag.FlagSet) error {
c, err := cmd.Client()
if err != nil {
return err
}
a := c.ServiceContent.About
tw := tabwriter.NewWriter(os.Stdout, 2, 0, 2, ' ', 0)
fmt.Fprintf(tw, "Name:\t%s\n", a.Name)
fmt.Fprintf(tw, "Vendor:\t%s\n", a.Vendor)
fmt.Fprintf(tw, "Version:\t%s\n", a.Version)
fmt.Fprintf(tw, "Build:\t%s\n", a.Build)
fmt.Fprintf(tw, "OS type:\t%s\n", a.OsType)
fmt.Fprintf(tw, "API type:\t%s\n", a.ApiType)
fmt.Fprintf(tw, "API version:\t%s\n", a.ApiVersion)
fmt.Fprintf(tw, "Product ID:\t%s\n", a.ProductLineId)
fmt.Fprintf(tw, "UUID:\t%s\n", a.InstanceUuid)
return tw.Flush()
}

22
vendor/github.com/vmware/govmomi/govc/build.sh generated vendored Normal file
View File

@ -0,0 +1,22 @@
#!/bin/bash -e
if ! which gox > /dev/null; then
echo "gox is not installed..."
exit 1
fi
git_version=$(git describe)
if git_status=$(git status --porcelain 2>/dev/null) && [ -n "${git_status}" ]; then
git_version="${git_version}-dirty"
fi
ldflags="-X github.com/vmware/govmomi/govc/version.gitVersion ${git_version}"
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

170
vendor/github.com/vmware/govmomi/govc/cli/command.go generated vendored Normal file
View File

@ -0,0 +1,170 @@
/*
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 (
"flag"
"fmt"
"io/ioutil"
"os"
"reflect"
"sort"
"text/tabwriter"
)
type HasFlags interface {
// Register may be called more than once and should be idempotent.
Register(f *flag.FlagSet)
// Process may be called more than once and should be idempotent.
Process() 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
}
func generalHelp() {
fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
cmds := []string{}
for name := range commands {
cmds = append(cmds, name)
}
sort.Strings(cmds)
for _, name := range cmds {
fmt.Fprintf(os.Stderr, " %s\n", name)
}
}
func commandHelp(name string, cmd Command, f *flag.FlagSet) {
type HasUsage interface {
Usage() string
}
fmt.Fprintf(os.Stderr, "Usage: %s %s [OPTIONS]", os.Args[0], name)
if u, ok := cmd.(HasUsage); ok {
fmt.Fprintf(os.Stderr, " %s", u.Usage())
}
fmt.Fprintf(os.Stderr, "\n")
type HasDescription interface {
Description() string
}
if u, ok := cmd.(HasDescription); ok {
fmt.Fprintf(os.Stderr, "%s\n", u.Description())
}
n := 0
f.VisitAll(func(_ *flag.Flag) {
n += 1
})
if n > 0 {
fmt.Fprintf(os.Stderr, "\nOptions:\n")
tw := tabwriter.NewWriter(os.Stderr, 2, 0, 2, ' ', 0)
f.VisitAll(func(f *flag.Flag) {
fmt.Fprintf(tw, "\t-%s=%s\t%s\n", f.Name, f.DefValue, f.Usage)
})
tw.Flush()
}
}
func Run(args []string) int {
if len(args) == 0 {
generalHelp()
return 1
}
// Look up real command name in aliases table.
name, ok := aliases[args[0]]
if !ok {
name = args[0]
}
cmd, ok := commands[name]
if !ok {
generalHelp()
return 1
}
f := flag.NewFlagSet("", flag.ContinueOnError)
f.SetOutput(ioutil.Discard)
RegisterCommand(cmd, f)
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 := 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.Run(f); err != nil {
if err == flag.ErrHelp {
commandHelp(args[0], cmd, f)
} else {
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
}
return 1
}
return 0
}

33
vendor/github.com/vmware/govmomi/govc/cli/register.go generated vendored Normal file
View File

@ -0,0 +1,33 @@
/*
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
var commands = map[string]Command{}
var aliases = map[string]string{}
func Register(name string, c Command) {
commands[name] = c
}
func Alias(name string, alias string) {
aliases[alias] = name
}
func Commands() map[string]Command {
return commands
}

108
vendor/github.com/vmware/govmomi/govc/cli/walk.go generated vendored Normal file
View File

@ -0,0 +1,108 @@
/*
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)
}

View File

@ -0,0 +1,77 @@
/*
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 datacenter
import (
"flag"
"github.com/vmware/govmomi/find"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/object"
"golang.org/x/net/context"
)
type create struct {
*flags.ClientFlag
}
func init() {
cli.Register("datacenter.create", &create{})
}
func (cmd *create) Register(f *flag.FlagSet) {}
func (cmd *create) Usage() string {
return "[DATACENTER NAME]..."
}
func (cmd *create) Process() error { return nil }
func (cmd *create) Run(f *flag.FlagSet) error {
datacenters := f.Args()
if len(datacenters) < 1 {
return flag.ErrHelp
}
client, err := cmd.ClientFlag.Client()
if err != nil {
return err
}
finder := find.NewFinder(client, false)
rootFolder := object.NewRootFolder(client)
for _, datacenterToCreate := range datacenters {
_, err := finder.Datacenter(context.TODO(), datacenterToCreate)
if err == nil {
// The datacenter was found, no need to create it
continue
}
switch err.(type) {
case *find.NotFoundError:
_, err = rootFolder.CreateDatacenter(context.TODO(), datacenterToCreate)
if err != nil {
return err
}
default:
return err
}
}
return nil
}

View File

@ -0,0 +1,73 @@
/*
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 datacenter
import (
"flag"
"github.com/vmware/govmomi/find"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"golang.org/x/net/context"
)
type destroy struct {
*flags.ClientFlag
}
func init() {
cli.Register("datacenter.destroy", &destroy{})
}
func (cmd *destroy) Register(f *flag.FlagSet) {}
func (cmd *destroy) Usage() string {
return "[DATACENTER NAME]..."
}
func (cmd *destroy) Process() error { return nil }
func (cmd *destroy) Run(f *flag.FlagSet) error {
if len(f.Args()) < 1 {
return flag.ErrHelp
}
datacentersToDestroy := f.Args()
client, err := cmd.ClientFlag.Client()
if err != nil {
return err
}
finder := find.NewFinder(client, false)
for _, datacenterToDestroy := range datacentersToDestroy {
foundDatacenters, err := finder.DatacenterList(context.TODO(), datacenterToDestroy)
if err != nil {
return err
}
for _, foundDatacenter := range foundDatacenters {
task, err := foundDatacenter.Destroy(context.TODO())
if err != nil {
return err
}
if err := task.Wait(context.TODO()); err != nil {
return err
}
}
}
return nil
}

85
vendor/github.com/vmware/govmomi/govc/datastore/cp.go generated vendored Normal file
View File

@ -0,0 +1,85 @@
/*
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 datastore
import (
"errors"
"flag"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/object"
"golang.org/x/net/context"
)
type cp struct {
*flags.OutputFlag
*flags.DatastoreFlag
force bool
}
func init() {
cli.Register("datastore.cp", &cp{})
}
func (cmd *cp) Register(f *flag.FlagSet) {
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) Usage() string {
return "SRC DST"
}
func (cmd *cp) Run(f *flag.FlagSet) error {
args := f.Args()
if len(args) != 2 {
return errors.New("SRC and DST arguments are required")
}
c, err := cmd.Client()
if err != nil {
return err
}
dc, err := cmd.Datacenter()
if err != nil {
return err
}
// TODO: support cross-datacenter copy
src, err := cmd.DatastorePath(args[0])
if err != nil {
return err
}
dst, err := cmd.DatastorePath(args[1])
if err != nil {
return err
}
m := object.NewFileManager(c)
task, err := m.CopyDatastoreFile(context.TODO(), src, dc, dst, dc, cmd.force)
if err != nil {
return err
}
return task.Wait(context.TODO())
}

View File

@ -0,0 +1,68 @@
/*
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 datastore
import (
"errors"
"flag"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/vim25/soap"
)
type download struct {
*flags.DatastoreFlag
}
func init() {
cli.Register("datastore.download", &download{})
}
func (cmd *download) Register(f *flag.FlagSet) {}
func (cmd *download) Process() error { return nil }
func (cmd *download) Usage() string {
return "REMOTE LOCAL"
}
func (cmd *download) Run(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])
if err != nil {
return err
}
p := soap.DefaultDownload
if cmd.OutputFlag.TTY {
logger := cmd.ProgressLogger("Downloading... ")
p.Progress = logger
defer logger.Wait()
}
return c.Client.DownloadFile(args[1], u, &p)
}

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

@ -0,0 +1,120 @@
/*
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 datastore
import (
"flag"
"fmt"
"io"
"os"
"text/tabwriter"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type info struct {
*flags.ClientFlag
*flags.OutputFlag
*flags.DatacenterFlag
}
func init() {
cli.Register("datastore.info", &info{})
}
func (cmd *info) Register(f *flag.FlagSet) {}
func (cmd *info) Process() error { return nil }
func (cmd *info) Usage() string {
return "[PATH]..."
}
func (cmd *info) Run(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
}
args := f.Args()
if len(args) == 0 {
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
if cmd.OutputFlag.JSON {
props = nil // Load everything
} else {
props = []string{"info", "summary"} // Load summary
}
pc := property.DefaultCollector(c)
err = pc.Retrieve(ctx, refs, props, &res.Datastores)
if err != nil {
return err
}
return cmd.WriteResult(&res)
}
type infoResult struct {
Datastores []mo.Datastore
}
func (r *infoResult) Write(w io.Writer) error {
tw := tabwriter.NewWriter(os.Stdout, 2, 0, 2, ' ', 0)
for _, ds := range r.Datastores {
s := ds.Summary
fmt.Fprintf(tw, "Name:\t%s\n", s.Name)
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))
fmt.Fprintf(tw, " Free:\t%.1f GB\n", float64(s.FreeSpace)/(1<<30))
switch info := ds.Info.(type) {
case *types.NasDatastoreInfo:
fmt.Fprintf(tw, " Remote:\t%s:%s\n", info.Nas.RemoteHost, info.Nas.RemotePath)
}
}
return tw.Flush()
}

197
vendor/github.com/vmware/govmomi/govc/datastore/ls.go generated vendored Normal file
View File

@ -0,0 +1,197 @@
/*
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 datastore
import (
"encoding/json"
"flag"
"fmt"
"io"
"path"
"text/tabwriter"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/units"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type ls struct {
*flags.DatastoreFlag
*flags.OutputFlag
long bool
}
func init() {
cli.Register("datastore.ls", &ls{})
}
func (cmd *ls) Register(f *flag.FlagSet) {
f.BoolVar(&cmd.long, "l", false, "Long listing format")
}
func (cmd *ls) Process() error { return nil }
func (cmd *ls) Usage() string {
return "[FILE]..."
}
func (cmd *ls) Run(f *flag.FlagSet) error {
ds, err := cmd.Datastore()
if err != nil {
return err
}
b, err := ds.Browser(context.TODO())
if err != nil {
return err
}
args := f.Args()
if len(args) == 0 {
args = []string{""}
}
result := &listOutput{
rs: make([]types.HostDatastoreBrowserSearchResults, 0),
long: cmd.long,
}
for _, arg := range args {
spec := types.HostDatastoreBrowserSearchSpec{
MatchPattern: []string{"*"},
}
if cmd.long {
spec.Details = &types.FileQueryFlags{
FileType: true,
FileSize: true,
FileOwner: types.NewBool(true), // TODO: omitempty is generated, but seems to be required
Modification: true,
}
}
for i := 0; ; i++ {
r, err := cmd.ListPath(b, arg, spec)
if err != nil {
// Treat the argument as a match pattern if not found as directory
if i == 0 && types.IsFileNotFound(err) {
spec.MatchPattern[0] = path.Base(arg)
arg = path.Dir(arg)
continue
}
return err
}
// Treat an empty result against match pattern as file not found
if i == 1 && len(r.File) == 0 {
return fmt.Errorf("File %s/%s was not found", r.FolderPath, spec.MatchPattern[0])
}
result.add(r)
break
}
}
return cmd.WriteResult(result)
}
func (cmd *ls) ListPath(b *object.HostDatastoreBrowser, path string, spec types.HostDatastoreBrowserSearchSpec) (types.HostDatastoreBrowserSearchResults, error) {
var res types.HostDatastoreBrowserSearchResults
path, err := cmd.DatastorePath(path)
if err != nil {
return res, err
}
task, err := b.SearchDatastore(context.TODO(), path, &spec)
if err != nil {
return res, err
}
info, err := task.WaitForResult(context.TODO(), nil)
if err != nil {
return res, err
}
res = info.Result.(types.HostDatastoreBrowserSearchResults)
return res, nil
}
type listOutput struct {
rs []types.HostDatastoreBrowserSearchResults
long bool
}
func (o *listOutput) add(r types.HostDatastoreBrowserSearchResults) {
o.rs = append(o.rs, r)
}
// hasMultiplePaths returns whether or not the slice of search results contains
// results from more than one folder path.
func (o *listOutput) hasMultiplePaths() bool {
if len(o.rs) == 0 {
return false
}
p := o.rs[0].FolderPath
// Multiple paths if any entry is not equal to the first one.
for _, e := range o.rs {
if e.FolderPath != p {
return true
}
}
return false
}
func (o *listOutput) MarshalJSON() ([]byte, error) {
return json.Marshal(o.rs)
}
func (o *listOutput) Write(w io.Writer) error {
// Only include path header if we're dealing with more than one path.
includeHeader := false
if o.hasMultiplePaths() {
includeHeader = true
}
tw := tabwriter.NewWriter(w, 3, 0, 2, ' ', 0)
for i, r := range o.rs {
if includeHeader {
if i > 0 {
fmt.Fprintf(tw, "\n")
}
fmt.Fprintf(tw, "%s:\n", r.FolderPath)
}
for _, file := range r.File {
info := file.GetFileInfo()
if o.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)
}
}
}
tw.Flush()
return nil
}

View File

@ -0,0 +1,87 @@
/*
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 datastore
import (
"errors"
"flag"
"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 mkdir struct {
*flags.DatastoreFlag
createParents bool
}
func init() {
cli.Register("datastore.mkdir", &mkdir{})
}
func (cmd *mkdir) Register(f *flag.FlagSet) {
f.BoolVar(&cmd.createParents, "p", false, "Create intermediate directories as needed")
}
func (cmd *mkdir) Process() error { return nil }
func (cmd *mkdir) Usage() string {
return "DIRECTORY"
}
func (cmd *mkdir) Run(f *flag.FlagSet) error {
args := f.Args()
if len(args) == 0 {
return errors.New("missing operand")
}
c, err := cmd.Client()
if err != nil {
return err
}
dc, err := cmd.Datacenter()
if err != nil {
return err
}
// TODO(PN): Accept multiple args
path, err := cmd.DatastorePath(args[0])
if err != nil {
return err
}
m := object.NewFileManager(c)
err = m.MakeDirectory(context.TODO(), path, dc, cmd.createParents)
// ignore EEXIST if -p flag is given
if err != nil && cmd.createParents {
if soap.IsSoapFault(err) {
soapFault := soap.ToSoapFault(err)
if _, ok := soapFault.VimFault().(types.FileAlreadyExists); ok {
return nil
}
}
}
return err
}

84
vendor/github.com/vmware/govmomi/govc/datastore/mv.go generated vendored Normal file
View File

@ -0,0 +1,84 @@
/*
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 datastore
import (
"errors"
"flag"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/object"
"golang.org/x/net/context"
)
type mv struct {
*flags.DatastoreFlag
force bool
}
func init() {
cli.Register("datastore.mv", &mv{})
}
func (cmd *mv) Register(f *flag.FlagSet) {
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) Usage() string {
return "SRC DST"
}
func (cmd *mv) Run(f *flag.FlagSet) error {
args := f.Args()
if len(args) != 2 {
return errors.New("SRC and DST arguments are required")
}
c, err := cmd.Client()
if err != nil {
return err
}
dc, err := cmd.Datacenter()
if err != nil {
return err
}
// TODO: support cross-datacenter move
src, err := cmd.DatastorePath(args[0])
if err != nil {
return err
}
dst, err := cmd.DatastorePath(args[1])
if err != nil {
return err
}
m := object.NewFileManager(c)
task, err := m.MoveDatastoreFile(context.TODO(), src, dc, dst, dc, cmd.force)
if err != nil {
return err
}
return task.Wait(context.TODO())
}

88
vendor/github.com/vmware/govmomi/govc/datastore/rm.go generated vendored Normal file
View File

@ -0,0 +1,88 @@
/*
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 datastore
import (
"errors"
"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 rm struct {
*flags.DatastoreFlag
force bool
}
func init() {
cli.Register("datastore.rm", &rm{})
cli.Alias("datastore.rm", "datastore.delete")
}
func (cmd *rm) Register(f *flag.FlagSet) {
f.BoolVar(&cmd.force, "f", false, "Force; ignore nonexistent files and arguments")
}
func (cmd *rm) Process() error { return nil }
func (cmd *rm) Usage() string {
return "FILE"
}
func (cmd *rm) Run(f *flag.FlagSet) error {
args := f.Args()
if len(args) == 0 {
return errors.New("missing operand")
}
c, err := cmd.Client()
if err != nil {
return err
}
dc, err := cmd.Datacenter()
if err != nil {
return err
}
// TODO(PN): Accept multiple args
path, err := cmd.DatastorePath(args[0])
if err != nil {
return err
}
m := object.NewFileManager(c)
task, err := m.DeleteDatastoreFile(context.TODO(), path, dc)
if err != nil {
return err
}
err = task.Wait(context.TODO())
if err != nil {
if types.IsFileNotFound(err) && cmd.force {
// Ignore error
return nil
}
}
return err
}

View File

@ -0,0 +1,69 @@
/*
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 datastore
import (
"errors"
"flag"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/vim25/soap"
)
type upload struct {
*flags.OutputFlag
*flags.DatastoreFlag
}
func init() {
cli.Register("datastore.upload", &upload{})
}
func (cmd *upload) Register(f *flag.FlagSet) {}
func (cmd *upload) Process() error { return nil }
func (cmd *upload) Usage() string {
return "LOCAL REMOTE"
}
func (cmd *upload) Run(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])
if err != nil {
return err
}
p := soap.DefaultUpload
if cmd.OutputFlag.TTY {
logger := cmd.ProgressLogger("Uploading... ")
p.Progress = logger
defer logger.Wait()
}
return c.Client.UploadFile(args[0], u, &p)
}

75
vendor/github.com/vmware/govmomi/govc/device/boot.go generated vendored Normal file
View File

@ -0,0 +1,75 @@
/*
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 device
import (
"flag"
"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 boot struct {
*flags.VirtualMachineFlag
order string
types.VirtualMachineBootOptions
}
func init() {
cli.Register("device.boot", &boot{})
}
func (cmd *boot) Register(f *flag.FlagSet) {
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")
cmd.BootRetryEnabled = types.NewBool(false)
f.BoolVar(cmd.BootRetryEnabled, "retry", false, "If true, retry boot after retry-delay")
cmd.EnterBIOSSetup = types.NewBool(false)
f.BoolVar(cmd.EnterBIOSSetup, "setup", false, "If true, enter BIOS setup on next boot")
}
func (cmd *boot) Process() error { return nil }
func (cmd *boot) Run(f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err
}
if vm == nil {
return flag.ErrHelp
}
devices, err := vm.Device(context.TODO())
if err != nil {
return err
}
if cmd.order != "" {
o := strings.Split(cmd.order, ",")
cmd.BootOrder = devices.BootOrder(o)
}
return vm.SetBootOptions(context.TODO(), &cmd.VirtualMachineBootOptions)
}

View File

@ -0,0 +1,87 @@
/*
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 cdrom
import (
"flag"
"fmt"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"golang.org/x/net/context"
)
type add struct {
*flags.VirtualMachineFlag
controller string
}
func init() {
cli.Register("device.cdrom.add", &add{})
}
func (cmd *add) Register(f *flag.FlagSet) {
f.StringVar(&cmd.controller, "controller", "", "IDE controller name")
}
func (cmd *add) Process() error { return nil }
func (cmd *add) Run(f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err
}
if vm == nil {
return flag.ErrHelp
}
devices, err := vm.Device(context.TODO())
if err != nil {
return err
}
c, err := devices.FindIDEController(cmd.controller)
if err != nil {
return err
}
d, err := devices.CreateCdrom(c)
if err != nil {
return err
}
err = vm.AddDevice(context.TODO(), d)
if err != nil {
return err
}
// output name of device we just created
devices, err = vm.Device(context.TODO())
if err != nil {
return err
}
devices = devices.SelectByType(d)
name := devices.Name(devices[len(devices)-1])
fmt.Println(name)
return nil
}

View File

@ -0,0 +1,70 @@
/*
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 cdrom
import (
"flag"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"golang.org/x/net/context"
)
type eject struct {
*flags.VirtualMachineFlag
device string
}
func init() {
cli.Register("device.cdrom.eject", &eject{})
}
func (cmd *eject) Register(f *flag.FlagSet) {
f.StringVar(&cmd.device, "device", "", "CD-ROM device name")
}
func (cmd *eject) Process() error { return nil }
func (cmd *eject) Description() string {
return `Eject media from CD-ROM device.
If device is not specified, the first CD-ROM device is used.`
}
func (cmd *eject) Run(f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err
}
if vm == nil {
return flag.ErrHelp
}
devices, err := vm.Device(context.TODO())
if err != nil {
return err
}
c, err := devices.FindCdrom(cmd.device)
if err != nil {
return err
}
return vm.EditDevice(context.TODO(), devices.EjectIso(c))
}

View File

@ -0,0 +1,80 @@
/*
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 cdrom
import (
"flag"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"golang.org/x/net/context"
)
type insert struct {
*flags.DatastoreFlag
*flags.VirtualMachineFlag
device string
}
func init() {
cli.Register("device.cdrom.insert", &insert{})
}
func (cmd *insert) Register(f *flag.FlagSet) {
f.StringVar(&cmd.device, "device", "", "CD-ROM device name")
}
func (cmd *insert) Process() error { return nil }
func (cmd *insert) Usage() string {
return "ISO"
}
func (cmd *insert) Description() string {
return `Insert media on datastore into CD-ROM device.
If device is not specified, the first CD-ROM device is used.`
}
func (cmd *insert) Run(f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err
}
if vm == nil || f.NArg() != 1 {
return flag.ErrHelp
}
devices, err := vm.Device(context.TODO())
if err != nil {
return err
}
c, err := devices.FindCdrom(cmd.device)
if err != nil {
return err
}
iso, err := cmd.DatastorePath(f.Arg(0))
if err != nil {
return nil
}
return vm.EditDevice(context.TODO(), devices.InsertIso(c, iso))
}

View File

@ -0,0 +1,75 @@
/*
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 device
import (
"flag"
"fmt"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"golang.org/x/net/context"
)
type connect struct {
*flags.VirtualMachineFlag
}
func init() {
cli.Register("device.connect", &connect{})
}
func (cmd *connect) Register(f *flag.FlagSet) {}
func (cmd *connect) Process() error { return nil }
func (cmd *connect) Usage() string {
return "DEVICE..."
}
func (cmd *connect) Run(f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err
}
if vm == nil {
return flag.ErrHelp
}
devices, err := vm.Device(context.TODO())
if err != nil {
return err
}
for _, name := range f.Args() {
device := devices.Find(name)
if device == nil {
return fmt.Errorf("device '%s' not found", name)
}
if err = devices.Connect(device); err != nil {
return err
}
if err = vm.EditDevice(context.TODO(), device); err != nil {
return err
}
}
return nil
}

View File

@ -0,0 +1,75 @@
/*
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 device
import (
"flag"
"fmt"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"golang.org/x/net/context"
)
type disconnect struct {
*flags.VirtualMachineFlag
}
func init() {
cli.Register("device.disconnect", &disconnect{})
}
func (cmd *disconnect) Register(f *flag.FlagSet) {}
func (cmd *disconnect) Process() error { return nil }
func (cmd *disconnect) Usage() string {
return "DEVICE..."
}
func (cmd *disconnect) Run(f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err
}
if vm == nil {
return flag.ErrHelp
}
devices, err := vm.Device(context.TODO())
if err != nil {
return err
}
for _, name := range f.Args() {
device := devices.Find(name)
if device == nil {
return fmt.Errorf("device '%s' not found", name)
}
if err = devices.Disconnect(device); err != nil {
return err
}
if err = vm.EditDevice(context.TODO(), device); err != nil {
return err
}
}
return nil
}

View File

@ -0,0 +1,78 @@
/*
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 floppy
import (
"flag"
"fmt"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"golang.org/x/net/context"
)
type add struct {
*flags.VirtualMachineFlag
}
func init() {
cli.Register("device.floppy.add", &add{})
}
func (cmd *add) Register(f *flag.FlagSet) {}
func (cmd *add) Process() error { return nil }
func (cmd *add) Run(f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err
}
if vm == nil {
return flag.ErrHelp
}
devices, err := vm.Device(context.TODO())
if err != nil {
return err
}
d, err := devices.CreateFloppy()
if err != nil {
return err
}
err = vm.AddDevice(context.TODO(), d)
if err != nil {
return err
}
// output name of device we just created
devices, err = vm.Device(context.TODO())
if err != nil {
return err
}
devices = devices.SelectByType(d)
name := devices.Name(devices[len(devices)-1])
fmt.Println(name)
return nil
}

View File

@ -0,0 +1,70 @@
/*
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 floppy
import (
"flag"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"golang.org/x/net/context"
)
type eject struct {
*flags.VirtualMachineFlag
device string
}
func init() {
cli.Register("device.floppy.eject", &eject{})
}
func (cmd *eject) Register(f *flag.FlagSet) {
f.StringVar(&cmd.device, "device", "", "Floppy device name")
}
func (cmd *eject) Process() error { return nil }
func (cmd *eject) Description() string {
return `Eject image from floppy device.
If device is not specified, the first floppy device is used.`
}
func (cmd *eject) Run(f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err
}
if vm == nil {
return flag.ErrHelp
}
devices, err := vm.Device(context.TODO())
if err != nil {
return err
}
c, err := devices.FindFloppy(cmd.device)
if err != nil {
return err
}
return vm.EditDevice(context.TODO(), devices.EjectImg(c))
}

View File

@ -0,0 +1,80 @@
/*
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 floppy
import (
"flag"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"golang.org/x/net/context"
)
type insert struct {
*flags.DatastoreFlag
*flags.VirtualMachineFlag
device string
}
func init() {
cli.Register("device.floppy.insert", &insert{})
}
func (cmd *insert) Register(f *flag.FlagSet) {
f.StringVar(&cmd.device, "device", "", "Floppy device name")
}
func (cmd *insert) Process() error { return nil }
func (cmd *insert) Usage() string {
return "IMG"
}
func (cmd *insert) Description() string {
return `Insert image on datastore into floppy device.
If device is not specified, the first floppy device is used.`
}
func (cmd *insert) Run(f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err
}
if vm == nil || f.NArg() != 1 {
return flag.ErrHelp
}
devices, err := vm.Device(context.TODO())
if err != nil {
return err
}
c, err := devices.FindFloppy(cmd.device)
if err != nil {
return err
}
img, err := cmd.DatastorePath(f.Arg(0))
if err != nil {
return nil
}
return vm.EditDevice(context.TODO(), devices.InsertImg(c, img))
}

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

@ -0,0 +1,115 @@
/*
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 device
import (
"flag"
"fmt"
"os"
"strings"
"text/tabwriter"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type info struct {
*flags.VirtualMachineFlag
}
func init() {
cli.Register("device.info", &info{})
}
func (cmd *info) Register(f *flag.FlagSet) {}
func (cmd *info) Process() error { return nil }
func (cmd *info) Usage() string {
return "DEVICE..."
}
func (cmd *info) Run(f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err
}
if vm == nil {
return flag.ErrHelp
}
devices, err := vm.Device(context.TODO())
if err != nil {
return err
}
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)
}
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, " Label:\t%s\n", info.Label)
fmt.Fprintf(tw, " Summary:\t%s\n", info.Summary)
fmt.Fprintf(tw, " Key:\t%d\n", d.Key)
if c, ok := device.(types.BaseVirtualController); ok {
var attached []string
for _, key := range c.GetVirtualController().Device {
attached = append(attached, devices.Name(devices.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))
fmt.Fprintf(tw, " Unit number:\t%d\n", d.UnitNumber)
}
}
if ca := d.Connectable; ca != nil {
fmt.Fprintf(tw, " Connected:\t%t\n", ca.Connected)
fmt.Fprintf(tw, " Start connected:\t%t\n", ca.StartConnected)
fmt.Fprintf(tw, " Guest control:\t%t\n", ca.AllowGuestControl)
fmt.Fprintf(tw, " Status:\t%s\n", ca.Status)
}
switch md := device.(type) {
case types.BaseVirtualEthernetCard:
fmt.Fprintf(tw, " MAC Address:\t%s\n", md.GetVirtualEthernetCard().MacAddress)
fmt.Fprintf(tw, " Address type:\t%s\n", md.GetVirtualEthernetCard().AddressType)
case *types.VirtualDisk:
if b, ok := md.Backing.(types.BaseVirtualDeviceFileBackingInfo); ok {
fmt.Fprintf(tw, " File:\t%s\n", b.GetVirtualDeviceFileBackingInfo().FileName)
}
if b, ok := md.Backing.(*types.VirtualDiskFlatVer2BackingInfo); ok && b.Parent != nil {
fmt.Fprintf(tw, " Parent:\t%s\n", b.Parent.GetVirtualDeviceFileBackingInfo().FileName)
}
}
}
return tw.Flush()
}

78
vendor/github.com/vmware/govmomi/govc/device/ls.go generated vendored Normal file
View File

@ -0,0 +1,78 @@
/*
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 device
import (
"flag"
"fmt"
"os"
"text/tabwriter"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"golang.org/x/net/context"
)
type ls struct {
*flags.VirtualMachineFlag
boot bool
}
func init() {
cli.Register("device.ls", &ls{})
}
func (cmd *ls) Register(f *flag.FlagSet) {
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) Run(f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err
}
if vm == nil {
return flag.ErrHelp
}
devices, err := vm.Device(context.TODO())
if err != nil {
return err
}
if cmd.boot {
options, err := vm.BootOptions(context.TODO())
if err != nil {
return err
}
devices = devices.SelectBootOrder(options.BootOrder)
}
tw := tabwriter.NewWriter(os.Stdout, 3, 0, 2, ' ', 0)
for _, device := range devices {
fmt.Fprintf(tw, "%s\t%s\t%s\n", devices.Name(device), devices.TypeName(device),
device.GetVirtualDevice().DeviceInfo.GetDescription().Summary)
}
return tw.Flush()
}

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

@ -0,0 +1,71 @@
/*
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 device
import (
"flag"
"fmt"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"golang.org/x/net/context"
)
type remove struct {
*flags.VirtualMachineFlag
}
func init() {
cli.Register("device.remove", &remove{})
}
func (cmd *remove) Register(f *flag.FlagSet) {}
func (cmd *remove) Process() error { return nil }
func (cmd *remove) Usage() string {
return "DEVICE..."
}
func (cmd *remove) Run(f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err
}
if vm == nil {
return flag.ErrHelp
}
devices, err := vm.Device(context.TODO())
if err != nil {
return err
}
for _, name := range f.Args() {
device := devices.Find(name)
if device == nil {
return fmt.Errorf("device '%s' not found", name)
}
if err = vm.RemoveDevice(context.TODO(), device); err != nil {
return err
}
}
return nil
}

View File

@ -0,0 +1,99 @@
/*
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 scsi
import (
"flag"
"fmt"
"strings"
"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 add struct {
*flags.VirtualMachineFlag
controller string
sharedBus string
hotAddRemove bool
}
func init() {
cli.Register("device.scsi.add", &add{})
}
func (cmd *add) Register(f *flag.FlagSet) {
var ctypes []string
ct := object.SCSIControllerTypes()
for _, t := range ct {
ctypes = append(ctypes, ct.Type(t))
}
f.StringVar(&cmd.controller, "type", ct.Type(ct[0]),
fmt.Sprintf("SCSI controller type (%s)", strings.Join(ctypes, "|")))
f.StringVar(&cmd.sharedBus, "sharing", string(types.VirtualSCSISharingNoSharing), "SCSI sharing")
f.BoolVar(&cmd.hotAddRemove, "hot", false, "Enable hot-add/remove")
}
func (cmd *add) Process() error { return nil }
func (cmd *add) Run(f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err
}
if vm == nil {
return flag.ErrHelp
}
devices, err := vm.Device(context.TODO())
if err != nil {
return err
}
d, err := devices.CreateSCSIController(cmd.controller)
if err != nil {
return err
}
c := d.(types.BaseVirtualSCSIController).GetVirtualSCSIController()
c.HotAddRemove = &cmd.hotAddRemove
c.SharedBus = types.VirtualSCSISharing(cmd.sharedBus)
err = vm.AddDevice(context.TODO(), d)
if err != nil {
return err
}
// output name of device we just created
devices, err = vm.Device(context.TODO())
if err != nil {
return err
}
devices = devices.SelectByType(d)
name := devices.Name(devices[len(devices)-1])
fmt.Println(name)
return nil
}

View File

@ -0,0 +1,78 @@
/*
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 serial
import (
"flag"
"fmt"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"golang.org/x/net/context"
)
type add struct {
*flags.VirtualMachineFlag
}
func init() {
cli.Register("device.serial.add", &add{})
}
func (cmd *add) Register(f *flag.FlagSet) {}
func (cmd *add) Process() error { return nil }
func (cmd *add) Run(f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err
}
if vm == nil {
return flag.ErrHelp
}
devices, err := vm.Device(context.TODO())
if err != nil {
return err
}
d, err := devices.CreateSerialPort()
if err != nil {
return err
}
err = vm.AddDevice(context.TODO(), d)
if err != nil {
return err
}
// output name of device we just created
devices, err = vm.Device(context.TODO())
if err != nil {
return err
}
devices = devices.SelectByType(d)
name := devices.Name(devices[len(devices)-1])
fmt.Println(name)
return nil
}

View File

@ -0,0 +1,66 @@
/*
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 serial
import (
"flag"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"golang.org/x/net/context"
)
type connect struct {
*flags.VirtualMachineFlag
device string
client bool
}
func init() {
cli.Register("device.serial.connect", &connect{})
}
func (cmd *connect) Register(f *flag.FlagSet) {
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) Run(f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err
}
if vm == nil {
return flag.ErrHelp
}
devices, err := vm.Device(context.TODO())
if err != nil {
return err
}
d, err := devices.FindSerialPort(cmd.device)
if err != nil {
return err
}
return vm.EditDevice(context.TODO(), devices.ConnectSerialPort(d, f.Arg(0), cmd.client))
}

View File

@ -0,0 +1,64 @@
/*
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 serial
import (
"flag"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"golang.org/x/net/context"
)
type disconnect struct {
*flags.VirtualMachineFlag
device string
}
func init() {
cli.Register("device.serial.disconnect", &disconnect{})
}
func (cmd *disconnect) Register(f *flag.FlagSet) {
f.StringVar(&cmd.device, "device", "", "serial port device name")
}
func (cmd *disconnect) Process() error { return nil }
func (cmd *disconnect) Run(f *flag.FlagSet) error {
vm, err := cmd.VirtualMachine()
if err != nil {
return err
}
if vm == nil {
return flag.ErrHelp
}
devices, err := vm.Device(context.TODO())
if err != nil {
return err
}
d, err := devices.FindSerialPort(cmd.device)
if err != nil {
return err
}
return vm.EditDevice(context.TODO(), devices.DisconnectSerialPort(d))
}

138
vendor/github.com/vmware/govmomi/govc/events/command.go generated vendored Normal file
View File

@ -0,0 +1,138 @@
/*
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 events
import (
"flag"
"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"
)
type events struct {
*flags.DatacenterFlag
Max int
}
func init() {
cli.Register("events", &events{})
}
func (cmd *events) Register(f *flag.FlagSet) {
f.IntVar(&cmd.Max, "n", 25, "Output the last N events")
}
func (cmd *events) Process() error { 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
}
c, err := cmd.Client()
if err != nil {
return err
}
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...)
}
var events []types.BaseEvent
for _, o := range objs {
filter := types.EventFilterSpec{
Entity: &types.EventFilterSpecByEntity{
Entity: o.Object.Reference(),
Recursion: types.EventFilterSpecRecursionOptionAll,
},
}
collector, err := m.CreateCollectorForEvents(ctx, filter)
if err != nil {
return fmt.Errorf("[%s] %s", o.Path, err)
}
defer collector.Destroy(ctx)
err = collector.SetPageSize(ctx, cmd.Max)
if err != nil {
return err
}
page, err := collector.LatestPage(ctx)
if err != nil {
return err
}
events = append(events, page...)
}
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 {
return err
}
event := e.GetEvent()
msg := strings.TrimSpace(event.FullFormattedMessage)
if t, ok := e.(*types.TaskEvent); ok {
msg = fmt.Sprintf("%s (target=%s %s)", msg, t.Info.Entity.Type, t.Info.EntityName)
}
fmt.Fprintf(tw, "[%s]\t[%s]\t%s\n",
event.CreatedTime.Local().Format(time.ANSIC),
cat, msg)
}
return tw.Flush()
}

View File

@ -0,0 +1,44 @@
function public-key {
local dir=${HOME}/.ssh
for f in $HOME/.ssh/{id_{rsa,dsa},*}.pub; do
if [ -r $f ]; then
echo $f
return
fi
done
echo "Can't find public key file..."
exit 1
}
PUBLIC_KEY_FILE=${PUBLIC_KEY_FILE-$(public-key)}
SSH_OPTS="-oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -oLogLevel=quiet"
function upload-public-key {
local vm_name=$1
local dir=$2
if [ -z "$dir" ]
then
uid=$(echo $GOVC_GUEST_LOGIN | awk -F: '{print $1}')
dir=$(govc guest.getenv -vm ${vm_name} HOME | awk -F= '{print $2}')
if [ -z "$dir" ]
then
echo "Can't find ${uid}'s HOME dir..."
exit 1
fi
fi
govc guest.mkdir \
-vm ${vm_name} \
-p \
${dir}/.ssh
govc guest.upload \
-vm ${vm_name} \
-f \
${PUBLIC_KEY_FILE} \
${dir}/.ssh/authorized_keys
}

57
vendor/github.com/vmware/govmomi/govc/examples/vcsa.sh generated vendored Normal file
View File

@ -0,0 +1,57 @@
#!/bin/bash -e
lib=$(readlink -nf $(dirname $0))/lib
. $lib/ssh.sh
ova=$1
if [ -z "$ova" ]
then
ova=./VMware-vCenter-Server-Appliance-5.5.0.10300-2000350_OVF10.ova
fi
# default to local Vagrant esxbox for testing
export GOVC_URL=${GOVC_URL-"https://root:vagrant@localhost:8443/sdk"}
# default VCSA credentials
export GOVC_GUEST_LOGIN=root:vmware
# VM name as defined in the VCSA .ovf
vm_name=VMware_vCenter_Server_Appliance
echo "Importing $ova..."
govc import.ova $ova
echo "Powering on $vm_name..."
govc vm.power -on $vm_name
echo "Waiting for $vm_name's IP address..."
vc=$(govc vm.ip $vm_name)
govc vm.info $vm_name
echo "Uploading ssh public key to $vm_name..."
upload-public-key $vm_name
echo "Configuring vCenter Server Appliance..."
# http://www.virtuallyghetto.com/2012/02/automating-vcenter-server-appliance.html
ssh ${SSH_OPTS} root@$vc <<EOF
echo "Accepting EULA ..."
/usr/sbin/vpxd_servicecfg eula accept
echo "Configuring Embedded DB ..."
/usr/sbin/vpxd_servicecfg db write embedded
echo "Configuring SSO..."
/usr/sbin/vpxd_servicecfg sso write embedded
echo "Starting VCSA ..."
/usr/sbin/vpxd_servicecfg service start
EOF
vc_url=https://${GOVC_GUEST_LOGIN}@${vc}/sdk
echo "VCSA configured and ready..."
govc about -u $vc_url

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

@ -0,0 +1,72 @@
/*
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 fields
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.ClientFlag
}
func init() {
cli.Register("fields.add", &add{})
}
func (cmd *add) Register(f *flag.FlagSet) {}
func (cmd *add) Process() error { return nil }
func (cmd *add) Usage() string {
return "NAME"
}
func (cmd *add) Run(f *flag.FlagSet) error {
if f.NArg() != 1 {
return flag.ErrHelp
}
ctx := context.TODO()
c, err := cmd.Client()
if err != nil {
return err
}
m, err := object.GetCustomFieldsManager(c)
if err != nil {
return err
}
name := f.Arg(0)
def, err := m.Add(ctx, name, "", nil, nil)
if err != nil {
return err
}
fmt.Printf("%d\n", def.Key)
return nil
}

68
vendor/github.com/vmware/govmomi/govc/fields/ls.go generated vendored Normal file
View File

@ -0,0 +1,68 @@
/*
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 fields
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.ClientFlag
}
func init() {
cli.Register("fields.ls", &ls{})
}
func (cmd *ls) Register(f *flag.FlagSet) {}
func (cmd *ls) Process() error { return nil }
func (cmd *ls) Run(f *flag.FlagSet) error {
ctx := context.TODO()
c, err := cmd.Client()
if err != nil {
return err
}
m, err := object.GetCustomFieldsManager(c)
if err != nil {
return err
}
field, err := m.Field(ctx)
if err != nil {
return err
}
tw := tabwriter.NewWriter(os.Stdout, 2, 0, 2, ' ', 0)
for _, def := range field {
fmt.Fprintf(tw, "%d\t%s\n", def.Key, def.Name)
}
return tw.Flush()
}

69
vendor/github.com/vmware/govmomi/govc/fields/rename.go generated vendored Normal file
View File

@ -0,0 +1,69 @@
/*
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 fields
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 rename struct {
*flags.ClientFlag
}
func init() {
cli.Register("fields.rename", &rename{})
}
func (cmd *rename) Register(f *flag.FlagSet) {}
func (cmd *rename) Process() error { return nil }
func (cmd *rename) Usage() string {
return "KEY NAME"
}
func (cmd *rename) Run(f *flag.FlagSet) error {
if f.NArg() != 2 {
return flag.ErrHelp
}
ctx := context.TODO()
c, err := cmd.Client()
if err != nil {
return err
}
m, err := object.GetCustomFieldsManager(c)
if err != nil {
return err
}
key, err := m.FindKey(ctx, f.Arg(0))
if err != nil {
return err
}
name := f.Arg(1)
return m.Rename(ctx, key, name)
}

69
vendor/github.com/vmware/govmomi/govc/fields/rm.go generated vendored Normal file
View File

@ -0,0 +1,69 @@
/*
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 fields
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 rm struct {
*flags.ClientFlag
}
func init() {
cli.Register("fields.rm", &rm{})
}
func (cmd *rm) Register(f *flag.FlagSet) {}
func (cmd *rm) Process() error { return nil }
func (cmd *rm) Usage() string {
return "KEY..."
}
func (cmd *rm) Run(f *flag.FlagSet) error {
ctx := context.TODO()
c, err := cmd.Client()
if err != nil {
return err
}
m, err := object.GetCustomFieldsManager(c)
if err != nil {
return err
}
for _, name := range f.Args() {
key, err := m.FindKey(ctx, name)
if err != nil {
return err
}
if err := m.Remove(ctx, key); err != nil {
return err
}
}
return nil
}

95
vendor/github.com/vmware/govmomi/govc/fields/set.go generated vendored Normal file
View File

@ -0,0 +1,95 @@
/*
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 fields
import (
"flag"
"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"
)
type set struct {
*flags.DatacenterFlag
}
func init() {
cli.Register("fields.set", &set{})
}
func (cmd *set) Register(f *flag.FlagSet) {}
func (cmd *set) Process() error { return nil }
func (cmd *set) Usage() string {
return "KEY VALUE PATH..."
}
func (cmd *set) Run(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
}
m, err := object.GetCustomFieldsManager(c)
if err != nil {
return err
}
var objs []list.Element
args := f.Args()
key, err := m.FindKey(ctx, args[0])
if err != nil {
return err
}
val := args[1]
for _, arg := range args[2:] {
es, err := finder.ManagedObjectList(ctx, arg)
if err != nil {
return err
}
objs = append(objs, es...)
}
for _, ref := range objs {
err := m.Set(ctx, ref.Object.Reference(), key, val)
if err != nil {
return err
}
}
return nil
}

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

@ -0,0 +1,366 @@
/*
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 flags
import (
"crypto/sha1"
"encoding/json"
"errors"
"flag"
"fmt"
"net/url"
"os"
"path/filepath"
"regexp"
"strings"
"sync"
"github.com/vmware/govmomi/session"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/soap"
"golang.org/x/net/context"
)
const (
envURL = "GOVC_URL"
envUsername = "GOVC_USERNAME"
envPassword = "GOVC_PASSWORD"
envInsecure = "GOVC_INSECURE"
envPersist = "GOVC_PERSIST_SESSION"
envMinAPIVersion = "GOVC_MIN_API_VERSION"
)
const cDescr = "ESX or vCenter URL"
type ClientFlag struct {
*DebugFlag
register sync.Once
url *url.URL
username string
password string
insecure bool
persist bool
minAPIVersion string
client *vim25.Client
}
func (flag *ClientFlag) URLWithoutPassword() *url.URL {
if flag.url == nil {
return nil
}
withoutCredentials := *flag.url
withoutCredentials.User = url.User(flag.url.User.Username())
return &withoutCredentials
}
func (flag *ClientFlag) String() string {
url := flag.URLWithoutPassword()
if url == nil {
return ""
}
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 = 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
}
func (flag *ClientFlag) Register(f *flag.FlagSet) {
flag.register.Do(func() {
{
flag.Set(os.Getenv(envURL))
usage := fmt.Sprintf("%s [%s]", cDescr, envURL)
f.Var(flag, "u", usage)
}
{
flag.username = os.Getenv(envUsername)
flag.password = os.Getenv(envPassword)
}
{
insecure := false
switch env := strings.ToLower(os.Getenv(envInsecure)); env {
case "1", "true":
insecure = true
}
usage := fmt.Sprintf("Skip verification of server certificate [%s]", envInsecure)
f.BoolVar(&flag.insecure, "k", insecure, usage)
}
{
persist := true
switch env := strings.ToLower(os.Getenv(envPersist)); env {
case "0", "false":
persist = false
}
usage := fmt.Sprintf("Persist session to disk [%s]", envPersist)
f.BoolVar(&flag.persist, "persist-session", persist, usage)
}
{
env := os.Getenv(envMinAPIVersion)
if env == "" {
env = "5.5"
}
flag.minAPIVersion = env
}
})
}
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()
}
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.
// This means a maximum of 3 attempts.
func attachRetries(rt soap.RoundTripper) soap.RoundTripper {
return vim25.Retry(rt, vim25.TemporaryNetworkError(3))
}
func (flag *ClientFlag) sessionFile() string {
url := flag.URLWithoutPassword()
// Key session file off of full URI and insecure setting.
// Hash key to get a predictable, canonical format.
key := fmt.Sprintf("%s#insecure=%t", url.String(), flag.insecure)
name := fmt.Sprintf("%040x", sha1.Sum([]byte(key)))
return filepath.Join(os.Getenv("HOME"), ".govmomi", "sessions", name)
}
func (flag *ClientFlag) saveClient(c *vim25.Client) error {
if !flag.persist {
return nil
}
p := flag.sessionFile()
err := os.MkdirAll(filepath.Dir(p), 0700)
if err != nil {
return err
}
f, err := os.OpenFile(p, os.O_CREATE|os.O_WRONLY, 0600)
if err != nil {
return err
}
defer f.Close()
enc := json.NewEncoder(f)
err = enc.Encode(c)
if err != nil {
return err
}
return nil
}
func (flag *ClientFlag) restoreClient(c *vim25.Client) (bool, error) {
if !flag.persist {
return false, nil
}
f, err := os.Open(flag.sessionFile())
if err != nil {
if os.IsNotExist(err) {
return false, nil
}
return false, err
}
defer f.Close()
dec := json.NewDecoder(f)
err = dec.Decode(c)
if err != nil {
return false, err
}
return true, nil
}
func (flag *ClientFlag) loadClient() (*vim25.Client, error) {
c := new(vim25.Client)
ok, err := flag.restoreClient(c)
if err != nil {
return nil, err
}
if !ok || !c.Valid() {
return nil, nil
}
// Add retry functionality before making any calls
c.RoundTripper = attachRetries(c.RoundTripper)
m := session.NewManager(c)
u, err := m.UserSession(context.TODO())
if err != nil {
return nil, err
}
// If the session is nil, the client is not authenticated
if u == nil {
return nil, nil
}
return c, nil
}
func (flag *ClientFlag) newClient() (*vim25.Client, error) {
sc := soap.NewClient(flag.url, flag.insecure)
// Add retry functionality before making any calls
rt := attachRetries(sc)
c, err := vim25.NewClient(context.TODO(), rt)
if err != nil {
return nil, err
}
// Set client, since we didn't pass it in the constructor
c.Client = sc
m := session.NewManager(c)
err = m.Login(context.TODO(), flag.url.User)
if err != nil {
return nil, err
}
err = flag.saveClient(c)
if err != nil {
return nil, err
}
return c, nil
}
// 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 err != nil {
return err
}
minVersion, err := ParseVersion(minVersionString)
if err != nil {
return err
}
if !minVersion.Lte(realVersion) {
err = fmt.Errorf("Require API version %s, connected to API version %s (set %s to override)",
minVersionString,
c.ServiceContent.About.ApiVersion,
envMinAPIVersion)
return err
}
return nil
}
func (flag *ClientFlag) Client() (*vim25.Client, error) {
if flag.client != nil {
return flag.client, nil
}
c, err := flag.loadClient()
if err != nil {
return nil, err
}
// loadClient returns nil if it was unable to load a session from disk
if c == nil {
c, err = flag.newClient()
if err != nil {
return nil, err
}
}
// Check that the endpoint has the right API version
err = apiVersionValid(c, flag.minAPIVersion)
if err != nil {
return nil, err
}
flag.client = c
return flag.client, nil
}

View File

@ -0,0 +1,98 @@
/*
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 flags
import (
"flag"
"fmt"
"os"
"sync"
"github.com/vmware/govmomi/find"
"github.com/vmware/govmomi/object"
"golang.org/x/net/context"
)
type DatacenterFlag struct {
*ClientFlag
*OutputFlag
register sync.Once
path string
dc *object.Datacenter
finder *find.Finder
err error
}
func (flag *DatacenterFlag) Register(f *flag.FlagSet) {
flag.register.Do(func() {
env := "GOVC_DATACENTER"
value := os.Getenv(env)
usage := fmt.Sprintf("Datacenter [%s]", env)
f.StringVar(&flag.path, "dc", value, usage)
})
}
func (flag *DatacenterFlag) Process() error { return nil }
func (flag *DatacenterFlag) Finder() (*find.Finder, error) {
if flag.finder != nil {
return flag.finder, nil
}
c, err := flag.Client()
if err != nil {
return nil, err
}
finder := find.NewFinder(c, flag.JSON)
// 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
}
}
finder.SetDatacenter(flag.dc)
flag.finder = finder
return flag.finder, nil
}
func (flag *DatacenterFlag) Datacenter() (*object.Datacenter, error) {
if flag.dc != nil {
return flag.dc, nil
}
_, err := flag.Finder()
if err != nil {
return nil, err
}
if flag.err != nil {
// Should only happen if no dc is specified and len(dcs) > 1
return nil, flag.err
}
return flag.dc, err
}

View File

@ -0,0 +1,149 @@
/*
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 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 {
*DatacenterFlag
register sync.Once
name string
ds *object.Datastore
}
func (flag *DatastoreFlag) Register(f *flag.FlagSet) {
flag.register.Do(func() {
env := "GOVC_DATASTORE"
value := os.Getenv(env)
usage := fmt.Sprintf("Datastore [%s]", env)
f.StringVar(&flag.name, "ds", value, usage)
})
}
func (flag *DatastoreFlag) Process() error { return nil }
func (flag *DatastoreFlag) Datastore() (*object.Datastore, error) {
if flag.ds != nil {
return flag.ds, nil
}
finder, err := flag.Finder()
if err != nil {
return nil, err
}
if flag.name == "" {
flag.ds, err = finder.DefaultDatastore(context.TODO())
} else {
flag.ds, err = finder.Datastore(context.TODO(), flag.name)
}
return flag.ds, err
}
func (flag *DatastoreFlag) DatastorePath(name string) (string, error) {
ds, err := flag.Datastore()
if err != nil {
return "", err
}
return ds.Path(name), nil
}
func (flag *DatastoreFlag) DatastoreURL(path string) (*url.URL, error) {
dc, err := flag.Datacenter()
if err != nil {
return nil, err
}
ds, err := flag.Datastore()
if err != nil {
return nil, err
}
u, err := ds.URL(context.TODO(), dc, path)
if err != nil {
return nil, err
}
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
}

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

@ -0,0 +1,72 @@
/*
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 flags
import (
"flag"
"fmt"
"os"
"path/filepath"
"strings"
"time"
"github.com/vmware/govmomi/vim25/debug"
)
type DebugFlag struct {
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
}
usage := fmt.Sprintf("Store debug logs [%s]", env)
f.BoolVar(&flag.enable, "debug", enable, usage)
}
func (flag *DebugFlag) Process() error {
if flag.enable {
// Base path for storing debug logs.
r := os.Getenv("GOVC_DEBUG_PATH")
if r == "" {
r = filepath.Join(os.Getenv("HOME"), ".govmomi")
}
r = filepath.Join(r, "debug")
// Path for this particular run.
now := time.Now().Format("2006-01-02T15-04-05.999999999")
r = filepath.Join(r, now)
err := os.MkdirAll(r, 0700)
if err != nil {
return err
}
p := debug.FileProvider{
Path: r,
}
debug.SetProvider(&p)
}
return nil
}

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

@ -0,0 +1,25 @@
/*
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 flags
import "flag"
type EmptyFlag struct{}
func (flag *EmptyFlag) Register(f *flag.FlagSet) {}
func (flag *EmptyFlag) Process() error { return nil }

View File

@ -0,0 +1,111 @@
/*
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 flags
import (
"flag"
"fmt"
"os"
"sync"
"github.com/vmware/govmomi/object"
"golang.org/x/net/context"
)
type HostSystemFlag struct {
*ClientFlag
*DatacenterFlag
*SearchFlag
register sync.Once
name string
host *object.HostSystem
pool *object.ResourcePool
}
func (flag *HostSystemFlag) Register(f *flag.FlagSet) {
flag.SearchFlag = NewSearchFlag(SearchHosts)
flag.register.Do(func() {
env := "GOVC_HOST"
value := os.Getenv(env)
usage := fmt.Sprintf("Host system [%s]", env)
f.StringVar(&flag.name, "host", value, usage)
})
}
func (flag *HostSystemFlag) Process() error { return nil }
func (flag *HostSystemFlag) HostSystemIfSpecified() (*object.HostSystem, error) {
if flag.host != nil {
return flag.host, nil
}
// Use search flags if specified.
if flag.SearchFlag.IsSet() {
host, err := flag.SearchFlag.HostSystem()
if err != nil {
return nil, err
}
flag.host = host
return flag.host, nil
}
// Never look for a default host system.
// A host system parameter is optional for vm creation. It uses a mandatory
// resource pool parameter to determine where the vm should be placed.
if flag.name == "" {
return nil, nil
}
finder, err := flag.Finder()
if err != nil {
return nil, err
}
flag.host, err = finder.HostSystem(context.TODO(), flag.name)
return flag.host, err
}
func (flag *HostSystemFlag) HostSystem() (*object.HostSystem, error) {
host, err := flag.HostSystemIfSpecified()
if err != nil {
return nil, err
}
if host != nil {
return host, nil
}
finder, err := flag.Finder()
if err != nil {
return nil, err
}
flag.host, err = finder.DefaultHostSystem(context.TODO())
return flag.host, err
}
func (flag *HostSystemFlag) HostNetworkSystem() (*object.HostNetworkSystem, error) {
host, err := flag.HostSystem()
if err != nil {
return nil, err
}
return host.ConfigManager().NetworkSystem(context.TODO())
}

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

@ -0,0 +1,109 @@
/*
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 flags
import (
"flag"
"fmt"
"os"
"sync"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type NetworkFlag struct {
*DatacenterFlag
register sync.Once
name string
net object.NetworkReference
adapter string
address string
}
func NewNetworkFlag() *NetworkFlag {
return &NetworkFlag{}
}
func (flag *NetworkFlag) Register(f *flag.FlagSet) {
flag.register.Do(func() {
env := "GOVC_NETWORK"
value := os.Getenv(env)
flag.Set(value)
usage := fmt.Sprintf("Network [%s]", env)
f.Var(flag, "net", usage)
f.StringVar(&flag.adapter, "net.adapter", "e1000", "Network adapter type")
f.StringVar(&flag.address, "net.address", "", "Network hardware address")
})
}
func (flag *NetworkFlag) Process() error { return nil }
func (flag *NetworkFlag) String() string {
return flag.name
}
func (flag *NetworkFlag) Set(name string) error {
flag.name = name
return nil
}
func (flag *NetworkFlag) Network() (object.NetworkReference, error) {
if flag.net != nil {
return flag.net, nil
}
finder, err := flag.Finder()
if err != nil {
return nil, err
}
if flag.name == "" {
flag.net, err = finder.DefaultNetwork(context.TODO())
} else {
flag.net, err = finder.Network(context.TODO(), flag.name)
}
return flag.net, err
}
func (flag *NetworkFlag) Device() (types.BaseVirtualDevice, error) {
net, err := flag.Network()
if err != nil {
return nil, err
}
backing, err := net.EthernetCardBackingInfo(context.TODO())
if err != nil {
return nil, err
}
device, err := object.EthernetCardTypes().CreateEthernetCard(flag.adapter, backing)
if err != nil {
return nil, err
}
if flag.address != "" {
card := device.(types.BaseVirtualEthernetCard).GetVirtualEthernetCard()
card.AddressType = string(types.VirtualEthernetCardMacTypeManual)
card.MacAddress = flag.address
}
return device, nil
}

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

@ -0,0 +1,191 @@
/*
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 flags
import (
"encoding/json"
"flag"
"fmt"
"io"
"os"
"sync"
"time"
"github.com/vmware/govmomi/vim25/progress"
)
type OutputWriter interface {
Write(io.Writer) error
}
type OutputFlag struct {
JSON bool
TTY bool
}
func (flag *OutputFlag) Register(f *flag.FlagSet) {
f.BoolVar(&flag.JSON, "json", false, "Enable JSON output")
}
func (flag *OutputFlag) Process() 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.
// A newline is not automatically added. If the specified string
// starts with a '\r', the current line is cleared first.
func (flag *OutputFlag) Log(s string) (int, error) {
if len(s) > 0 && s[0] == '\r' {
flag.Write([]byte{'\r', 033, '[', 'K'})
s = s[1:]
}
return flag.WriteString(time.Now().Format("[02-01-06 15:04:05] ") + s)
}
func (flag *OutputFlag) Write(b []byte) (int, error) {
if !flag.TTY {
return 0, nil
}
n, err := os.Stdout.Write(b)
os.Stdout.Sync()
return n, err
}
func (flag *OutputFlag) WriteString(s string) (int, error) {
return flag.Write([]byte(s))
}
func (flag *OutputFlag) WriteResult(result OutputWriter) error {
var err error
var out = os.Stdout
if flag.JSON {
enc := json.NewEncoder(out)
err = enc.Encode(result)
} else {
err = result.Write(out)
}
return err
}
type progressLogger struct {
flag *OutputFlag
prefix string
wg sync.WaitGroup
sink chan chan progress.Report
done chan struct{}
}
func newProgressLogger(flag *OutputFlag, prefix string) *progressLogger {
p := &progressLogger{
flag: flag,
prefix: prefix,
sink: make(chan chan progress.Report),
done: make(chan struct{}),
}
p.wg.Add(1)
go p.loopA()
return p
}
// loopA runs before Sink() has been called.
func (p *progressLogger) loopA() {
var err error
defer p.wg.Done()
tick := time.NewTicker(100 * time.Millisecond)
defer tick.Stop()
for stop := false; !stop; {
select {
case ch := <-p.sink:
err = p.loopB(tick, ch)
stop = true
case <-p.done:
stop = true
case <-tick.C:
line := fmt.Sprintf("\r%s", p.prefix)
p.flag.Log(line)
}
}
if err != nil && err != io.EOF {
p.flag.Log(fmt.Sprintf("\r%sError: %s\n", p.prefix, err))
} else {
p.flag.Log(fmt.Sprintf("\r%sOK\n", p.prefix))
}
}
// loopA runs after Sink() has been called.
func (p *progressLogger) loopB(tick *time.Ticker, ch <-chan progress.Report) error {
var r progress.Report
var ok bool
var err error
for ok = true; ok; {
select {
case r, ok = <-ch:
if !ok {
break
}
err = r.Error()
case <-tick.C:
line := fmt.Sprintf("\r%s", p.prefix)
if r != nil {
line += fmt.Sprintf("(%.0f%%", r.Percentage())
detail := r.Detail()
if detail != "" {
line += fmt.Sprintf(", %s", detail)
}
line += ")"
}
p.flag.Log(line)
}
}
return err
}
func (p *progressLogger) Sink() chan<- progress.Report {
ch := make(chan progress.Report)
p.sink <- ch
return ch
}
func (p *progressLogger) Wait() {
close(p.done)
p.wg.Wait()
}
func (flag *OutputFlag) ProgressLogger(prefix string) *progressLogger {
return newProgressLogger(flag, prefix)
}

View File

@ -0,0 +1,65 @@
/*
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 flags
import (
"flag"
"fmt"
"os"
"sync"
"github.com/vmware/govmomi/object"
"golang.org/x/net/context"
)
type ResourcePoolFlag struct {
*DatacenterFlag
register sync.Once
name string
pool *object.ResourcePool
}
func (flag *ResourcePoolFlag) Register(f *flag.FlagSet) {
flag.register.Do(func() {
env := "GOVC_RESOURCE_POOL"
value := os.Getenv(env)
usage := fmt.Sprintf("Resource pool [%s]", env)
f.StringVar(&flag.name, "pool", value, usage)
})
}
func (flag *ResourcePoolFlag) Process() error { return nil }
func (flag *ResourcePoolFlag) ResourcePool() (*object.ResourcePool, error) {
if flag.pool != nil {
return flag.pool, nil
}
finder, err := flag.Finder()
if err != nil {
return nil, err
}
if flag.name == "" {
flag.pool, err = finder.DefaultResourcePool(context.TODO())
} else {
flag.pool, err = finder.ResourcePool(context.TODO(), flag.name)
}
return flag.pool, err
}

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

@ -0,0 +1,305 @@
/*
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 flags
import (
"errors"
"flag"
"fmt"
"strings"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25"
"golang.org/x/net/context"
)
const (
SearchVirtualMachines = iota + 1
SearchHosts
)
type SearchFlag struct {
*ClientFlag
*DatacenterFlag
t int
entity string
byDatastorePath string
byDNSName string
byInventoryPath string
byIP string
byUUID string
isset bool
}
func NewSearchFlag(t int) *SearchFlag {
s := SearchFlag{
t: t,
}
switch t {
case SearchVirtualMachines:
s.entity = "VM"
case SearchHosts:
s.entity = "host"
default:
panic("invalid search type")
}
return &s
}
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)
}
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
}
}
return nil
}
func (flag *SearchFlag) IsSet() bool {
return flag.isset
}
func (flag *SearchFlag) searchIndex(c *vim25.Client) *object.SearchIndex {
return object.NewSearchIndex(c)
}
func (flag *SearchFlag) searchByDatastorePath(c *vim25.Client, dc *object.Datacenter) (object.Reference, error) {
switch flag.t {
case SearchVirtualMachines:
return flag.searchIndex(c).FindByDatastorePath(context.TODO(), dc, flag.byDatastorePath)
default:
panic("unsupported type")
}
}
func (flag *SearchFlag) searchByDNSName(c *vim25.Client, dc *object.Datacenter) (object.Reference, error) {
switch flag.t {
case SearchVirtualMachines:
return flag.searchIndex(c).FindByDnsName(context.TODO(), dc, flag.byDNSName, true)
case SearchHosts:
return flag.searchIndex(c).FindByDnsName(context.TODO(), dc, flag.byDNSName, false)
default:
panic("unsupported type")
}
}
func (flag *SearchFlag) searchByInventoryPath(c *vim25.Client, dc *object.Datacenter) (object.Reference, error) {
// TODO(PN): The datacenter flag should not be set because it is ignored.
return flag.searchIndex(c).FindByInventoryPath(context.TODO(), flag.byInventoryPath)
}
func (flag *SearchFlag) searchByIP(c *vim25.Client, dc *object.Datacenter) (object.Reference, error) {
switch flag.t {
case SearchVirtualMachines:
return flag.searchIndex(c).FindByIp(context.TODO(), dc, flag.byIP, true)
case SearchHosts:
return flag.searchIndex(c).FindByIp(context.TODO(), dc, flag.byIP, false)
default:
panic("unsupported type")
}
}
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)
case SearchHosts:
return flag.searchIndex(c).FindByUuid(context.TODO(), dc, flag.byUUID, false)
default:
panic("unsupported type")
}
}
func (flag *SearchFlag) search() (object.Reference, error) {
var ref object.Reference
var err error
c, err := flag.Client()
if err != nil {
return nil, err
}
dc, err := flag.Datacenter()
if err != nil {
return nil, err
}
switch {
case flag.byDatastorePath != "":
ref, err = flag.searchByDatastorePath(c, dc)
case flag.byDNSName != "":
ref, err = flag.searchByDNSName(c, dc)
case flag.byInventoryPath != "":
ref, err = flag.searchByInventoryPath(c, dc)
case flag.byIP != "":
ref, err = flag.searchByIP(c, dc)
case flag.byUUID != "":
ref, err = flag.searchByUUID(c, dc)
default:
err = errors.New("no search flag specified")
}
if err != nil {
return nil, err
}
if ref == nil {
return nil, fmt.Errorf("no such %s", flag.entity)
}
return ref, nil
}
func (flag *SearchFlag) VirtualMachine() (*object.VirtualMachine, error) {
ref, err := flag.search()
if err != nil {
return nil, err
}
vm, ok := ref.(*object.VirtualMachine)
if !ok {
return nil, fmt.Errorf("expected VirtualMachine entity, got %s", ref.Reference().Type)
}
return vm, nil
}
func (flag *SearchFlag) VirtualMachines(args []string) ([]*object.VirtualMachine, error) {
var out []*object.VirtualMachine
if flag.IsSet() {
vm, err := flag.VirtualMachine()
if err != nil {
return nil, err
}
out = append(out, vm)
return out, nil
}
// List virtual machines
if len(args) == 0 {
return nil, errors.New("no argument")
}
finder, err := flag.Finder()
if err != nil {
return nil, err
}
// List virtual machines for every argument
for _, arg := range args {
vms, err := finder.VirtualMachineList(context.TODO(), arg)
if err != nil {
return nil, err
}
out = append(out, vms...)
}
return out, nil
}
func (flag *SearchFlag) HostSystem() (*object.HostSystem, error) {
ref, err := flag.search()
if err != nil {
return nil, err
}
host, ok := ref.(*object.HostSystem)
if !ok {
return nil, fmt.Errorf("expected HostSystem entity, got %s", ref.Reference().Type)
}
return host, nil
}
func (flag *SearchFlag) HostSystems(args []string) ([]*object.HostSystem, error) {
var out []*object.HostSystem
if flag.IsSet() {
host, err := flag.HostSystem()
if err != nil {
return nil, err
}
out = append(out, host)
return out, nil
}
// List host system
if len(args) == 0 {
return nil, errors.New("no argument")
}
finder, err := flag.Finder()
if err != nil {
return nil, err
}
// List host systems for every argument
for _, arg := range args {
vms, err := finder.HostSystemList(context.TODO(), arg)
if err != nil {
return nil, err
}
out = append(out, vms...)
}
return out, nil
}

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

@ -0,0 +1,61 @@
/*
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 flags
import (
"strconv"
"strings"
)
type version []int
func ParseVersion(s string) (version, error) {
v := make(version, 0)
ps := strings.Split(s, ".")
for _, p := range ps {
i, err := strconv.Atoi(p)
if err != nil {
return nil, err
}
v = append(v, i)
}
return v, nil
}
func (v version) Lte(u version) bool {
lv := len(v)
lu := len(u)
for i := 0; i < lv; i++ {
// Everything up to here has been equal and v has more elements than u.
if i >= lu {
return false
}
// Move to next digit if equal.
if v[i] == u[i] {
continue
}
return v[i] < u[i]
}
// Equal.
return true
}

View File

@ -0,0 +1,80 @@
/*
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 flags
import (
"flag"
"fmt"
"os"
"sync"
"github.com/vmware/govmomi/object"
"golang.org/x/net/context"
)
type VirtualMachineFlag struct {
*ClientFlag
*DatacenterFlag
*SearchFlag
register sync.Once
name string
vm *object.VirtualMachine
}
func (flag *VirtualMachineFlag) Register(f *flag.FlagSet) {
flag.SearchFlag = NewSearchFlag(SearchVirtualMachines)
flag.register.Do(func() {
env := "GOVC_VM"
value := os.Getenv(env)
usage := fmt.Sprintf("Virtual machine [%s]", env)
f.StringVar(&flag.name, "vm", value, usage)
})
}
func (flag *VirtualMachineFlag) Process() error { return nil }
func (flag *VirtualMachineFlag) VirtualMachine() (*object.VirtualMachine, error) {
if flag.vm != nil {
return flag.vm, nil
}
// Use search flags if specified.
if flag.SearchFlag.IsSet() {
vm, err := flag.SearchFlag.VirtualMachine()
if err != nil {
return nil, err
}
flag.vm = vm
return flag.vm, nil
}
// Never look for a default virtual machine.
if flag.name == "" {
return nil, nil
}
finder, err := flag.Finder()
if err != nil {
return nil, err
}
flag.vm, err = finder.VirtualMachine(context.TODO(), flag.name)
return flag.vm, err
}

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

@ -0,0 +1,165 @@
/*
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 (
"errors"
"flag"
"fmt"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type add struct {
*flags.ClientFlag
*flags.DatacenterFlag
parent string
host string
username string
password string
connect bool
fingerprint string
}
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")
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")
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 == "" {
return flag.ErrHelp
}
if cmd.username == "" {
return flag.ErrHelp
}
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.
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
client, err := cmd.Client()
if err != nil {
return err
}
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
}
mo, err := finder.ManagedObjectList(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,
}
res, err := methods.AddStandaloneHost_Task(ctx, client, &req)
if 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
}

View File

@ -0,0 +1,53 @@
/*
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 autostart
import (
"flag"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/vim25/types"
)
type add struct {
*AutostartFlag
}
func init() {
cli.Register("host.autostart.add", &add{})
}
func (cmd *add) Register(f *flag.FlagSet) {}
func (cmd *add) Process() error { return nil }
func (cmd *add) Usage() string {
return "VM..."
}
func (cmd *add) Run(f *flag.FlagSet) error {
var powerInfo = types.AutoStartPowerInfo{
StartAction: "powerOn",
StartDelay: -1,
StartOrder: -1,
StopAction: "systemDefault",
StopDelay: -1,
WaitForHeartbeat: types.AutoStartWaitHeartbeatSettingSystemDefault,
}
return cmd.ReconfigureVMs(f.Args(), powerInfo)
}

View File

@ -0,0 +1,150 @@
/*
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 autostart
import (
"errors"
"flag"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type AutostartFlag struct {
*flags.ClientFlag
*flags.DatacenterFlag
*flags.HostSystemFlag
}
func (f *AutostartFlag) Register(fs *flag.FlagSet) {}
func (f *AutostartFlag) Process() error { return nil }
// VirtualMachines returns list of virtual machine objects based on the
// arguments specified on the command line. This helper is defined in
// flags.SearchFlag as well, but that pulls in other virtual machine flags that
// are not relevant here.
func (f *AutostartFlag) VirtualMachines(args []string) ([]*object.VirtualMachine, error) {
if len(args) == 0 {
return nil, errors.New("no argument")
}
finder, err := f.Finder()
if err != nil {
return nil, err
}
var out []*object.VirtualMachine
for _, arg := range args {
vms, err := finder.VirtualMachineList(context.TODO(), arg)
if err != nil {
return nil, err
}
out = append(out, vms...)
}
return out, nil
}
func (f *AutostartFlag) HostAutoStartManager() (*mo.HostAutoStartManager, error) {
h, err := f.HostSystem()
if err != nil {
return nil, err
}
var mhs mo.HostSystem
err = h.Properties(context.TODO(), h.Reference(), []string{"configManager.autoStartManager"}, &mhs)
if err != nil {
return nil, err
}
var mhas mo.HostAutoStartManager
err = h.Properties(context.TODO(), *mhs.ConfigManager.AutoStartManager, nil, &mhas)
if err != nil {
return nil, err
}
return &mhas, nil
}
func (f *AutostartFlag) ReconfigureDefaults(template types.AutoStartDefaults) error {
c, err := f.Client()
if err != nil {
return err
}
mhas, err := f.HostAutoStartManager()
if err != nil {
return err
}
req := types.ReconfigureAutostart{
This: mhas.Reference(),
Spec: types.HostAutoStartManagerConfig{
Defaults: &template,
},
}
_, err = methods.ReconfigureAutostart(context.TODO(), c, &req)
if err != nil {
return err
}
return nil
}
func (f *AutostartFlag) ReconfigureVMs(args []string, template types.AutoStartPowerInfo) error {
c, err := f.Client()
if err != nil {
return err
}
mhas, err := f.HostAutoStartManager()
if err != nil {
return err
}
req := types.ReconfigureAutostart{
This: mhas.Reference(),
Spec: types.HostAutoStartManagerConfig{
PowerInfo: make([]types.AutoStartPowerInfo, 0),
},
}
vms, err := f.VirtualMachines(args)
if err != nil {
return err
}
for _, vm := range vms {
pi := template
pi.Key = vm.Reference()
req.Spec.PowerInfo = append(req.Spec.PowerInfo, pi)
}
_, err = methods.ReconfigureAutostart(context.TODO(), c, &req)
if err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,59 @@
/*
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 autostart
import (
"flag"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/vim25/types"
)
type configure struct {
*AutostartFlag
defaults 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, "")
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, "")
}
func (cmd *configure) Process() error { 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)
}

View File

@ -0,0 +1,129 @@
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package autostart
import (
"encoding/json"
"flag"
"fmt"
"io"
"os"
"text/tabwriter"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/mo"
"golang.org/x/net/context"
)
type info struct {
*AutostartFlag
*flags.OutputFlag
}
func init() {
cli.Register("host.autostart.info", &info{})
}
func (cmd *info) Register(f *flag.FlagSet) {}
func (cmd *info) Process() error { return nil }
func (cmd *info) Usage() string {
return ""
}
func (cmd *info) Run(f *flag.FlagSet) error {
client, err := cmd.Client()
if err != nil {
return err
}
mhas, err := cmd.HostAutoStartManager()
if err != nil {
return err
}
return cmd.WriteResult(&infoResult{client, mhas})
}
type infoResult struct {
client *vim25.Client
mhas *mo.HostAutoStartManager
}
func (r *infoResult) MarshalJSON() ([]byte, error) {
return json.Marshal(r.mhas)
}
// vmPaths resolves the paths for the VMs in the result.
func (r *infoResult) vmPaths() (map[string]string, error) {
paths := make(map[string]string)
for _, info := range r.mhas.Config.PowerInfo {
mes, err := mo.Ancestors(context.TODO(), r.client, r.client.ServiceContent.PropertyCollector, info.Key)
if err != nil {
return nil, err
}
path := ""
for _, me := range mes {
// Skip root entity in building inventory path.
if me.Parent == nil {
continue
}
path += "/" + me.Name
}
paths[info.Key.Value] = path
}
return paths, nil
}
func (r *infoResult) Write(w io.Writer) error {
paths, err := r.vmPaths()
if err != nil {
return err
}
tw := tabwriter.NewWriter(os.Stdout, 2, 0, 2, ' ', 0)
fmt.Fprintf(tw, "VM")
fmt.Fprintf(tw, "\tStartAction")
fmt.Fprintf(tw, "\tStartDelay")
fmt.Fprintf(tw, "\tStartOrder")
fmt.Fprintf(tw, "\tStopAction")
fmt.Fprintf(tw, "\tStopDelay")
fmt.Fprintf(tw, "\tWaitForHeartbeat")
fmt.Fprintf(tw, "\n")
for _, info := range r.mhas.Config.PowerInfo {
fmt.Fprintf(tw, "%s", paths[info.Key.Value])
fmt.Fprintf(tw, "\t%s", info.StartAction)
fmt.Fprintf(tw, "\t%d", info.StartDelay)
fmt.Fprintf(tw, "\t%d", info.StartOrder)
fmt.Fprintf(tw, "\t%s", info.StopAction)
fmt.Fprintf(tw, "\t%d", info.StopDelay)
fmt.Fprintf(tw, "\t%s", info.WaitForHeartbeat)
fmt.Fprintf(tw, "\n")
}
_ = tw.Flush()
return nil
}

View File

@ -0,0 +1,53 @@
/*
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 autostart
import (
"flag"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/vim25/types"
)
type remove struct {
*AutostartFlag
}
func init() {
cli.Register("host.autostart.remove", &remove{})
}
func (cmd *remove) Register(f *flag.FlagSet) {}
func (cmd *remove) Process() error { return nil }
func (cmd *remove) Usage() string {
return "VM..."
}
func (cmd *remove) Run(f *flag.FlagSet) error {
var powerInfo = types.AutoStartPowerInfo{
StartAction: "none",
StartDelay: -1,
StartOrder: -1,
StopAction: "none",
StopDelay: -1,
WaitForHeartbeat: types.AutoStartWaitHeartbeatSettingSystemDefault,
}
return cmd.ReconfigureVMs(f.Args(), powerInfo)
}

View File

@ -0,0 +1,149 @@
/*
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 esxcli
import (
"flag"
"fmt"
"strings"
"github.com/vmware/govmomi/vim25/types"
)
type Command struct {
name []string
args []string
}
type CommandInfoItem struct {
Name string `xml:"name"`
DisplayName string `xml:"displayName"`
Help string `xml:"help"`
}
type CommandInfoParam struct {
CommandInfoItem
Aliases []string `xml:"aliases"`
Flag bool `xml:"flag"`
}
type CommandInfoHint struct {
Key string `xml:"key"`
Value string `xml:"value"`
}
type CommandInfoHints []CommandInfoHint
type CommandInfoMethod struct {
CommandInfoItem
Param []CommandInfoParam `xml:"param"`
Hints CommandInfoHints `xml:"hints"`
}
type CommandInfo struct {
CommandInfoItem
Method []*CommandInfoMethod `xml:"method"`
}
func NewCommand(args []string) *Command {
c := &Command{}
for i, arg := range args {
if strings.HasPrefix(arg, "-") {
c.args = args[i:]
break
} else {
c.name = append(c.name, arg)
}
}
return c
}
func (c *Command) Namespace() string {
return strings.Join(c.name[:len(c.name)-1], ".")
}
func (c *Command) Name() string {
return c.name[len(c.name)-1]
}
func (c *Command) Method() string {
return "vim.EsxCLI." + strings.Join(c.name, ".")
}
func (c *Command) Moid() string {
return "ha-cli-handler-" + strings.Join(c.name[:len(c.name)-1], "-")
}
// Parse generates a flag.FlagSet based on the given []CommandInfoParam and
// returns arguments for use with methods.ExecuteSoap
func (c *Command) Parse(params []CommandInfoParam) ([]types.ReflectManagedMethodExecuterSoapArgument, error) {
flags := flag.NewFlagSet(strings.Join(c.name, " "), flag.ExitOnError)
vals := make([]string, len(params))
for i, p := range params {
v := &vals[i]
for _, a := range p.Aliases {
a = strings.TrimPrefix(a[1:], "-")
flags.StringVar(v, a, "", p.Help)
}
}
err := flags.Parse(c.args)
if err != nil {
return nil, err
}
args := []types.ReflectManagedMethodExecuterSoapArgument{}
for i, p := range params {
if vals[i] == "" {
continue
}
args = append(args, c.Argument(p.Name, vals[i]))
}
return args, nil
}
func (c *Command) Argument(name string, val string) types.ReflectManagedMethodExecuterSoapArgument {
return types.ReflectManagedMethodExecuterSoapArgument{
Name: name,
Val: fmt.Sprintf("<%s>%s</%s>", name, val, name),
}
}
func (h CommandInfoHints) Formatter() string {
for _, hint := range h {
if hint.Key == "formatter" {
return hint.Value
}
}
return "simple"
}
func (h CommandInfoHints) Fields() []string {
for _, hint := range h {
if strings.HasPrefix(hint.Key, "fields:") {
return strings.Split(hint.Value, ",")
}
}
return nil
}

View File

@ -0,0 +1,143 @@
/*
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 esxcli
import (
"flag"
"fmt"
"os"
"sort"
"strings"
"text/tabwriter"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
)
type esxcli struct {
*flags.HostSystemFlag
hints bool
}
func init() {
cli.Register("host.esxcli", &esxcli{})
}
func (cmd *esxcli) Usage() string {
return "COMMAND [ARG]..."
}
func (cmd *esxcli) Register(f *flag.FlagSet) {
f.BoolVar(&cmd.hints, "hints", true, "Use command info hints when formatting output")
}
func (cmd *esxcli) Process() error { return nil }
func (cmd *esxcli) Run(f *flag.FlagSet) error {
c, err := cmd.Client()
if err != nil {
return nil
}
host, err := cmd.HostSystem()
if err != nil {
return err
}
e, err := NewExecutor(c, host)
if err != nil {
return err
}
res, err := e.Run(f.Args())
if err != nil {
return err
}
if len(res.Values) == 0 {
return nil
}
var formatType string
if cmd.hints {
formatType = res.Info.Hints.Formatter()
}
// TODO: OutputFlag / format options
switch formatType {
case "table":
cmd.formatTable(res)
default:
cmd.formatSimple(res)
}
return nil
}
func (cmd *esxcli) formatSimple(res *Response) {
var keys []string
for key := range res.Values[0] {
keys = append(keys, key)
}
sort.Strings(keys)
tw := tabwriter.NewWriter(os.Stdout, 2, 0, 2, ' ', 0)
for i, rv := range res.Values {
if i > 0 {
fmt.Fprintln(tw)
_ = tw.Flush()
}
for _, key := range keys {
fmt.Fprintf(tw, "%s:\t%s\n", key, strings.Join(rv[key], ", "))
}
}
_ = tw.Flush()
}
func (cmd *esxcli) formatTable(res *Response) {
fields := res.Info.Hints.Fields()
tw := tabwriter.NewWriter(os.Stdout, len(fields), 0, 2, ' ', 0)
var hr []string
for _, name := range fields {
hr = append(hr, strings.Repeat("-", len(name)))
}
fmt.Fprintln(tw, strings.Join(fields, "\t"))
fmt.Fprintln(tw, strings.Join(hr, "\t"))
for _, vals := range res.Values {
var row []string
for _, name := range fields {
key := strings.Replace(name, " ", "", -1)
if val, ok := vals[key]; ok {
row = append(row, strings.Join(val, ", "))
} else {
row = append(row, "")
}
}
fmt.Fprintln(tw, strings.Join(row, "\t"))
}
_ = tw.Flush()
}

View File

@ -0,0 +1,166 @@
/*
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 esxcli
import (
"errors"
"fmt"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/types"
"github.com/vmware/govmomi/vim25/xml"
"golang.org/x/net/context"
)
type Executor struct {
c *vim25.Client
host *object.HostSystem
mme *types.ReflectManagedMethodExecuter
dtm *types.InternalDynamicTypeManager
info map[string]*CommandInfo
}
func NewExecutor(c *vim25.Client, host *object.HostSystem) (*Executor, error) {
e := &Executor{
c: c,
host: host,
info: make(map[string]*CommandInfo),
}
{
req := types.RetrieveManagedMethodExecuter{
This: host.Reference(),
}
res, err := methods.RetrieveManagedMethodExecuter(context.TODO(), c, &req)
if err != nil {
return nil, err
}
e.mme = res.Returnval
}
{
req := types.RetrieveDynamicTypeManager{
This: host.Reference(),
}
res, err := methods.RetrieveDynamicTypeManager(context.TODO(), c, &req)
if err != nil {
return nil, err
}
e.dtm = res.Returnval
}
return e, nil
}
func (e *Executor) CommandInfo(c *Command) (*CommandInfoMethod, error) {
ns := c.Namespace()
var info *CommandInfo
var ok bool
if info, ok = e.info[ns]; !ok {
req := types.ExecuteSoap{
Moid: "ha-dynamic-type-manager-local-cli-cliinfo",
Method: "vim.CLIInfo.FetchCLIInfo",
Argument: []types.ReflectManagedMethodExecuterSoapArgument{
c.Argument("typeName", "vim.EsxCLI."+ns),
},
}
info = new(CommandInfo)
if err := e.Execute(&req, info); err != nil {
return nil, err
}
e.info[ns] = info
}
name := c.Name()
for _, method := range info.Method {
if method.Name == name {
return method, nil
}
}
return nil, fmt.Errorf("method '%s' not found in name space '%s'", name, c.Namespace())
}
func (e *Executor) NewRequest(args []string) (*types.ExecuteSoap, *CommandInfoMethod, error) {
c := NewCommand(args)
info, err := e.CommandInfo(c)
if err != nil {
return nil, nil, err
}
sargs, err := c.Parse(info.Param)
if err != nil {
return nil, nil, err
}
sreq := types.ExecuteSoap{
Moid: c.Moid(),
Method: c.Method(),
Argument: sargs,
}
return &sreq, info, nil
}
func (e *Executor) Execute(req *types.ExecuteSoap, res interface{}) error {
req.This = e.mme.ManagedObjectReference
req.Version = "urn:vim25/5.0"
x, err := methods.ExecuteSoap(context.TODO(), e.c, req)
if err != nil {
return err
}
if x.Returnval != nil {
if x.Returnval.Fault != nil {
return errors.New(x.Returnval.Fault.FaultMsg)
}
if err := xml.Unmarshal([]byte(x.Returnval.Response), res); err != nil {
return err
}
}
return nil
}
func (e *Executor) Run(args []string) (*Response, error) {
req, info, err := e.NewRequest(args)
if err != nil {
return nil, err
}
res := &Response{
Info: info,
}
if err := e.Execute(req, res); err != nil {
return nil, err
}
return res, nil
}

View File

@ -0,0 +1,15 @@
<obj xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:vim25" versionId="5.0" xsi:type="ArrayOfDataObject">
<DataObject xsi:type="VimEsxCLInetworkvmlistVM">
<Name>foo</Name>
<Networks>VM Network</Networks>
<Networks>dougm</Networks>
<NumPorts>2</NumPorts>
<WorldID>98842</WorldID>
</DataObject>
<DataObject xsi:type="VimEsxCLInetworkvmlistVM">
<Name>bar</Name>
<Networks>VM Network</Networks>
<NumPorts>1</NumPorts>
<WorldID>236235</WorldID>
</DataObject>
</obj>

View File

@ -0,0 +1,12 @@
<obj xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:vim25" versionId="5.0" xsi:type="ArrayOfDataObject">
<DataObject xsi:type="VimEsxCLInetworkvmportlistPort">
<DVPortID></DVPortID>
<IPAddress>192.168.247.149</IPAddress>
<MACAddress>00:0c:29:12:b2:cf</MACAddress>
<PortID>33554438</PortID>
<Portgroup>VM Network</Portgroup>
<TeamUplink>vmnic0</TeamUplink>
<UplinkPortID>33554434</UplinkPortID>
<vSwitch>vSwitch0</vSwitch>
</DataObject>
</obj>

View File

@ -0,0 +1,5 @@
<obj xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:vim25" versionId="5.0" xsi:type="VimEsxCLIsystemhostnamegetFullyQualifiedHostName">
<DomainName>localdomain</DomainName>
<FullyQualifiedDomainName>esxbox.localdomain</FullyQualifiedDomainName>
<HostName>esxbox</HostName>
</obj>

View File

@ -0,0 +1,116 @@
/*
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 esxcli
import (
"strings"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type hostInfo struct {
*Executor
wids map[string]string
}
type GuestInfo struct {
c *vim25.Client
hosts map[string]*hostInfo
}
func NewGuestInfo(c *vim25.Client) *GuestInfo {
return &GuestInfo{
c: c,
hosts: make(map[string]*hostInfo),
}
}
func (g *GuestInfo) hostInfo(ref *types.ManagedObjectReference) (*hostInfo, error) {
// cache exectuor and uuid -> worldid map
if h, ok := g.hosts[ref.Value]; ok {
return h, nil
}
host := object.NewHostSystem(g.c, *ref)
e, err := NewExecutor(g.c, host)
if err != nil {
return nil, err
}
res, err := e.Run([]string{"vm", "process", "list"})
if err != nil {
return nil, err
}
ids := make(map[string]string, len(res.Values))
for _, process := range res.Values {
// Normalize uuid, esxcli and mo.VirtualMachine have different formats
uuid := strings.Replace(process["UUID"][0], " ", "", -1)
uuid = strings.Replace(uuid, "-", "", -1)
ids[uuid] = process["WorldID"][0]
}
h := &hostInfo{e, ids}
g.hosts[ref.Value] = h
return h, nil
}
// IpAddress attempts to find the guest IP address using esxcli.
// ESX hosts must be configured with the /Net/GuestIPHack enabled.
// For example:
// $ govc host.esxcli -- system settings advanced set -o /Net/GuestIPHack -i 1
func (g *GuestInfo) IpAddress(vm *object.VirtualMachine) (string, error) {
var mvm mo.VirtualMachine
pc := property.DefaultCollector(g.c)
err := pc.RetrieveOne(context.TODO(), vm.Reference(), []string{"runtime.host", "config.uuid"}, &mvm)
if err != nil {
return "", err
}
h, err := g.hostInfo(mvm.Runtime.Host)
if err != nil {
return "", err
}
// Normalize uuid, esxcli and mo.VirtualMachine have different formats
uuid := strings.Replace(mvm.Config.Uuid, "-", "", -1)
if wid, ok := h.wids[uuid]; ok {
res, err := h.Run([]string{"network", "vm", "port", "list", "--world-id", wid})
if err != nil {
return "", err
}
if len(res.Values) == 1 {
if ip, ok := res.Values[0]["IPAddress"]; ok {
return ip[0], nil
}
}
}
return "", nil
}

View File

@ -0,0 +1,82 @@
package esxcli
import (
"io"
"github.com/vmware/govmomi/vim25/xml"
)
type Values map[string][]string
type Response struct {
Info *CommandInfoMethod
Values []Values
}
func (v Values) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
for {
t, err := d.Token()
if err != nil {
if err == io.EOF {
return nil
}
return err
}
if s, ok := t.(xml.StartElement); ok {
t, err = d.Token()
if err != nil {
return err
}
key := s.Name.Local
var val string
if c, ok := t.(xml.CharData); ok {
val = string(c)
}
v[key] = append(v[key], val)
}
}
}
func (r *Response) Type(start xml.StartElement) string {
for _, a := range start.Attr {
if a.Name.Local == "type" {
return a.Value
}
}
return ""
}
func (r *Response) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
stype := r.Type(start)
if stype != "ArrayOfDataObject" {
v := Values{}
if err := d.DecodeElement(&v, &start); err != nil {
return err
}
r.Values = append(r.Values, v)
return nil
}
for {
t, err := d.Token()
if err != nil {
if err == io.EOF {
return nil
}
return err
}
if s, ok := t.(xml.StartElement); ok {
if s.Name.Local == "DataObject" {
v := Values{}
if err := d.DecodeElement(&v, &s); err != nil {
return err
}
r.Values = append(r.Values, v)
}
}
}
}

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

@ -0,0 +1,129 @@
/*
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 host
import (
"flag"
"fmt"
"io"
"os"
"text/tabwriter"
"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"
)
type info struct {
*flags.ClientFlag
*flags.OutputFlag
*flags.HostSystemFlag
}
func init() {
cli.Register("host.info", &info{})
}
func (c *info) Register(f *flag.FlagSet) {}
func (c *info) Process() error { return nil }
func (c *info) Run(f *flag.FlagSet) error {
client, err := c.Client()
if err != nil {
return err
}
var hosts []*object.HostSystem
// We could do without the -host flag, leaving it for compat
host, err := c.HostSystemIfSpecified()
if err != nil {
return err
}
// Default only if there is a single host
if host == nil && f.NArg() == 0 {
host, err = c.HostSystem()
if err != nil {
return err
}
}
if host != nil {
hosts = append(hosts, host)
} else {
hosts, err = c.HostSystems(f.Args())
if err != nil {
return err
}
}
var res infoResult
var props []string
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)
if err != nil {
return err
}
res.HostSystems = append(res.HostSystems, h)
}
return c.WriteResult(&res)
}
type infoResult struct {
HostSystems []mo.HostSystem
}
func (r *infoResult) Write(w io.Writer) error {
tw := tabwriter.NewWriter(os.Stdout, 2, 0, 2, ' ', 0)
for _, host := range r.HostSystems {
s := host.Summary
h := s.Hardware
z := s.QuickStats
ncpu := int(h.NumCpuPkgs * h.NumCpuCores)
cpuUsage := 100 * float64(z.OverallCpuUsage) / float64(ncpu*h.CpuMhz)
memUsage := 100 * float64(z.OverallMemoryUsage<<20) / float64(h.MemorySize)
fmt.Fprintf(tw, "Name:\t%s\n", s.Config.Name)
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)
fmt.Fprintf(tw, " CPU usage:\t%d MHz (%.1f%%)\n", z.OverallCpuUsage, cpuUsage)
fmt.Fprintf(tw, " Memory:\t%dMB\n", h.MemorySize/(1024*1024))
fmt.Fprintf(tw, " Memory usage:\t%d MB (%.1f%%)\n", z.OverallMemoryUsage, memUsage)
fmt.Fprintf(tw, " Boot time:\t%s\n", s.Runtime.BootTime)
}
return tw.Flush()
}

View File

@ -0,0 +1,58 @@
/*
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 portgroup
import (
"flag"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type add struct {
*flags.HostSystemFlag
spec types.HostPortGroupSpec
}
func init() {
cli.Register("host.portgroup.add", &add{})
}
func (cmd *add) Register(f *flag.FlagSet) {
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) Usage() string {
return "NAME"
}
func (cmd *add) Run(f *flag.FlagSet) error {
ns, err := cmd.HostNetworkSystem()
if err != nil {
return err
}
cmd.spec.Name = f.Arg(0)
return ns.AddPortGroup(context.TODO(), cmd.spec)
}

View File

@ -0,0 +1,50 @@
/*
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 portgroup
import (
"flag"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"golang.org/x/net/context"
)
type remove struct {
*flags.HostSystemFlag
}
func init() {
cli.Register("host.portgroup.remove", &remove{})
}
func (cmd *remove) Register(f *flag.FlagSet) {}
func (cmd *remove) Process() error { return nil }
func (cmd *remove) Usage() string {
return "NAME"
}
func (cmd *remove) Run(f *flag.FlagSet) error {
ns, err := cmd.HostNetworkSystem()
if err != nil {
return err
}
return ns.RemovePortGroup(context.TODO(), f.Arg(0))
}

View File

@ -0,0 +1,64 @@
/*
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 vswitch
import (
"flag"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context"
)
type add struct {
*flags.HostSystemFlag
nic string
spec types.HostVirtualSwitchSpec
}
func init() {
cli.Register("host.vswitch.add", &add{})
}
func (cmd *add) Register(f *flag.FlagSet) {
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) Usage() string {
return "NAME"
}
func (cmd *add) Run(f *flag.FlagSet) error {
ns, err := cmd.HostNetworkSystem()
if err != nil {
return err
}
if cmd.nic != "" {
cmd.spec.Bridge = &types.HostVirtualSwitchBondBridge{
NicDevice: []string{cmd.nic},
}
}
return ns.AddVirtualSwitch(context.TODO(), f.Arg(0), &cmd.spec)
}

View File

@ -0,0 +1,88 @@
/*
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 vswitch
import (
"flag"
"fmt"
"os"
"strings"
"text/tabwriter"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/vim25/mo"
"golang.org/x/net/context"
)
type info struct {
*flags.ClientFlag
*flags.OutputFlag
*flags.HostSystemFlag
}
func init() {
cli.Register("host.vswitch.info", &info{})
}
func (cmd *info) Register(f *flag.FlagSet) {}
func (cmd *info) Process() error { return nil }
func (cmd *info) Run(f *flag.FlagSet) error {
client, err := cmd.Client()
if err != nil {
return err
}
ns, err := cmd.HostNetworkSystem()
if err != nil {
return err
}
var mns mo.HostNetworkSystem
pc := property.DefaultCollector(client)
err = pc.RetrieveOne(context.TODO(), ns.Reference(), []string{"networkInfo.vswitch"}, &mns)
if err != nil {
return err
}
tw := tabwriter.NewWriter(os.Stdout, 2, 0, 2, ' ', 0)
for i, s := range mns.NetworkInfo.Vswitch {
if i > 0 {
fmt.Fprintln(tw)
}
fmt.Fprintf(tw, "Name:\t%s\n", s.Name)
fmt.Fprintf(tw, "Portgroup:\t%s\n", cmd.keys("key-vim.host.PortGroup-", s.Portgroup))
fmt.Fprintf(tw, "Pnic:\t%s\n", cmd.keys("key-vim.host.PhysicalNic-", s.Pnic))
fmt.Fprintf(tw, "MTU:\t%d\n", s.Mtu)
fmt.Fprintf(tw, "Ports:\t%d\n", s.NumPorts)
fmt.Fprintf(tw, "Ports Available:\t%d\n", s.NumPortsAvailable)
}
return tw.Flush()
}
func (cmd *info) keys(key string, vals []string) string {
for i, val := range vals {
vals[i] = strings.TrimPrefix(val, key)
}
return strings.Join(vals, ", ")
}

View File

@ -0,0 +1,50 @@
/*
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 vswitch
import (
"flag"
"github.com/vmware/govmomi/govc/cli"
"github.com/vmware/govmomi/govc/flags"
"golang.org/x/net/context"
)
type remove struct {
*flags.HostSystemFlag
}
func init() {
cli.Register("host.vswitch.remove", &remove{})
}
func (cmd *remove) Register(f *flag.FlagSet) {}
func (cmd *remove) Process() error { return nil }
func (cmd *remove) Usage() string {
return "NAME"
}
func (cmd *remove) Run(f *flag.FlagSet) error {
ns, err := cmd.HostNetworkSystem()
if err != nil {
return err
}
return ns.RemoveVirtualSwitch(context.TODO(), f.Arg(0))
}

View File

@ -0,0 +1,97 @@
/*
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 importx
import (
"archive/tar"
"io"
"os"
"path"
"path/filepath"
)
type Archive interface {
Open(string) (io.ReadCloser, int64, error)
}
type TapeArchive struct {
path string
}
type TapeArchiveEntry struct {
io.Reader
f *os.File
}
func (t *TapeArchiveEntry) Close() error {
return t.f.Close()
}
func (t *TapeArchive) Open(name string) (io.ReadCloser, int64, error) {
f, err := os.Open(t.path)
if err != nil {
return nil, 0, err
}
r := tar.NewReader(f)
for {
h, err := r.Next()
if err == io.EOF {
break
}
if err != nil {
return nil, 0, err
}
matched, err := filepath.Match(name, path.Base(h.Name))
if err != nil {
return nil, 0, err
}
if matched {
return &TapeArchiveEntry{r, f}, h.Size, nil
}
}
_ = f.Close()
return nil, 0, os.ErrNotExist
}
type FileArchive struct {
path string
}
func (t *FileArchive) Open(name string) (io.ReadCloser, int64, error) {
fpath := name
if name != t.path {
fpath = filepath.Join(filepath.Dir(t.path), name)
}
s, err := os.Stat(fpath)
if err != nil {
return nil, 0, err
}
f, err := os.Open(fpath)
if err != nil {
return nil, 0, err
}
return f, s.Size(), nil
}

View File

@ -0,0 +1,59 @@
/*
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 importx
import (
"fmt"
"path"
)
type importable struct {
localPath string
remotePath string
}
func (i importable) Ext() string {
return path.Ext(i.localPath)
}
func (i importable) Base() string {
return path.Base(i.localPath)
}
func (i importable) BaseClean() string {
b := i.Base()
e := i.Ext()
return b[:len(b)-len(e)]
}
func (i importable) RemoteSrcVMDK() string {
file := fmt.Sprintf("%s-src.vmdk", i.BaseClean())
return i.toRemotePath(file)
}
func (i importable) RemoteDstVMDK() string {
file := fmt.Sprintf("%s.vmdk", i.BaseClean())
return i.toRemotePath(file)
}
func (i importable) toRemotePath(p string) string {
if i.remotePath == "" {
return p
}
return path.Join(i.remotePath, p)
}

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