Commit 09da53c8 authored by Doug MacEachern's avatar Doug MacEachern

Update vmware/govmomi godeps

parent 8a9954d4
...@@ -1713,6 +1713,11 @@ ...@@ -1713,6 +1713,11 @@
"Rev": "44d81051d367757e1c7c6a5a86423ece9afcf63c" "Rev": "44d81051d367757e1c7c6a5a86423ece9afcf63c"
}, },
{ {
"ImportPath": "github.com/google/uuid",
"Comment": "0.2-15-g8c31c18",
"Rev": "8c31c18f31ede9fc8eae72290a7e7a8064e9b3e3"
},
{
"ImportPath": "github.com/googleapis/gnostic/OpenAPIv2", "ImportPath": "github.com/googleapis/gnostic/OpenAPIv2",
"Rev": "0c5108395e2debce0d731cf0287ddf7242066aba" "Rev": "0c5108395e2debce0d731cf0287ddf7242066aba"
}, },
...@@ -2630,93 +2635,113 @@ ...@@ -2630,93 +2635,113 @@
}, },
{ {
"ImportPath": "github.com/vmware/govmomi", "ImportPath": "github.com/vmware/govmomi",
"Comment": "v0.14.0-11-gb8b228c", "Comment": "v0.16.0-5-g5f0f400",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1" "Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
}, },
{ {
"ImportPath": "github.com/vmware/govmomi/find", "ImportPath": "github.com/vmware/govmomi/find",
"Comment": "v0.14.0-11-gb8b228c", "Comment": "v0.16.0-5-g5f0f400",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1" "Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
}, },
{ {
"ImportPath": "github.com/vmware/govmomi/list", "ImportPath": "github.com/vmware/govmomi/list",
"Comment": "v0.14.0-11-gb8b228c", "Comment": "v0.16.0-5-g5f0f400",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1" "Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
},
{
"ImportPath": "github.com/vmware/govmomi/nfc",
"Comment": "v0.16.0-5-g5f0f400",
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
}, },
{ {
"ImportPath": "github.com/vmware/govmomi/object", "ImportPath": "github.com/vmware/govmomi/object",
"Comment": "v0.14.0-11-gb8b228c", "Comment": "v0.16.0-5-g5f0f400",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1" "Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
}, },
{ {
"ImportPath": "github.com/vmware/govmomi/pbm", "ImportPath": "github.com/vmware/govmomi/pbm",
"Comment": "v0.14.0-11-gb8b228c", "Comment": "v0.16.0-5-g5f0f400",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1" "Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
}, },
{ {
"ImportPath": "github.com/vmware/govmomi/pbm/methods", "ImportPath": "github.com/vmware/govmomi/pbm/methods",
"Comment": "v0.14.0-11-gb8b228c", "Comment": "v0.16.0-5-g5f0f400",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1" "Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
}, },
{ {
"ImportPath": "github.com/vmware/govmomi/pbm/types", "ImportPath": "github.com/vmware/govmomi/pbm/types",
"Comment": "v0.14.0-11-gb8b228c", "Comment": "v0.16.0-5-g5f0f400",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1" "Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
}, },
{ {
"ImportPath": "github.com/vmware/govmomi/property", "ImportPath": "github.com/vmware/govmomi/property",
"Comment": "v0.14.0-11-gb8b228c", "Comment": "v0.16.0-5-g5f0f400",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1" "Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
}, },
{ {
"ImportPath": "github.com/vmware/govmomi/session", "ImportPath": "github.com/vmware/govmomi/session",
"Comment": "v0.14.0-11-gb8b228c", "Comment": "v0.16.0-5-g5f0f400",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1" "Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
},
{
"ImportPath": "github.com/vmware/govmomi/simulator",
"Comment": "v0.16.0-5-g5f0f400",
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
},
{
"ImportPath": "github.com/vmware/govmomi/simulator/esx",
"Comment": "v0.16.0-5-g5f0f400",
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
},
{
"ImportPath": "github.com/vmware/govmomi/simulator/vpx",
"Comment": "v0.16.0-5-g5f0f400",
"Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
}, },
{ {
"ImportPath": "github.com/vmware/govmomi/task", "ImportPath": "github.com/vmware/govmomi/task",
"Comment": "v0.14.0-11-gb8b228c", "Comment": "v0.16.0-5-g5f0f400",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1" "Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
}, },
{ {
"ImportPath": "github.com/vmware/govmomi/vim25", "ImportPath": "github.com/vmware/govmomi/vim25",
"Comment": "v0.14.0-11-gb8b228c", "Comment": "v0.16.0-5-g5f0f400",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1" "Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
}, },
{ {
"ImportPath": "github.com/vmware/govmomi/vim25/debug", "ImportPath": "github.com/vmware/govmomi/vim25/debug",
"Comment": "v0.14.0-11-gb8b228c", "Comment": "v0.16.0-5-g5f0f400",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1" "Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
}, },
{ {
"ImportPath": "github.com/vmware/govmomi/vim25/methods", "ImportPath": "github.com/vmware/govmomi/vim25/methods",
"Comment": "v0.14.0-11-gb8b228c", "Comment": "v0.16.0-5-g5f0f400",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1" "Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
}, },
{ {
"ImportPath": "github.com/vmware/govmomi/vim25/mo", "ImportPath": "github.com/vmware/govmomi/vim25/mo",
"Comment": "v0.14.0-11-gb8b228c", "Comment": "v0.16.0-5-g5f0f400",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1" "Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
}, },
{ {
"ImportPath": "github.com/vmware/govmomi/vim25/progress", "ImportPath": "github.com/vmware/govmomi/vim25/progress",
"Comment": "v0.14.0-11-gb8b228c", "Comment": "v0.16.0-5-g5f0f400",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1" "Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
}, },
{ {
"ImportPath": "github.com/vmware/govmomi/vim25/soap", "ImportPath": "github.com/vmware/govmomi/vim25/soap",
"Comment": "v0.14.0-11-gb8b228c", "Comment": "v0.16.0-5-g5f0f400",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1" "Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
}, },
{ {
"ImportPath": "github.com/vmware/govmomi/vim25/types", "ImportPath": "github.com/vmware/govmomi/vim25/types",
"Comment": "v0.14.0-11-gb8b228c", "Comment": "v0.16.0-5-g5f0f400",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1" "Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
}, },
{ {
"ImportPath": "github.com/vmware/govmomi/vim25/xml", "ImportPath": "github.com/vmware/govmomi/vim25/xml",
"Comment": "v0.14.0-11-gb8b228c", "Comment": "v0.16.0-5-g5f0f400",
"Rev": "b8b228cfbad7f0a69ed90393ca9aee085d3c6ef1" "Rev": "5f0f4004a1f075f29e715f1b956ca0ab4b428f17"
}, },
{ {
"ImportPath": "github.com/vmware/photon-controller-go-sdk/SSPI", "ImportPath": "github.com/vmware/photon-controller-go-sdk/SSPI",
......
...@@ -3,6 +3,7 @@ package(default_visibility = ["//visibility:public"]) ...@@ -3,6 +3,7 @@ package(default_visibility = ["//visibility:public"])
load( load(
"@io_bazel_rules_go//go:def.bzl", "@io_bazel_rules_go//go:def.bzl",
"go_library", "go_library",
"go_test",
) )
go_library( go_library(
...@@ -55,3 +56,14 @@ filegroup( ...@@ -55,3 +56,14 @@ filegroup(
], ],
tags = ["automanaged"], tags = ["automanaged"],
) )
go_test(
name = "go_default_test",
srcs = ["datacenter_test.go"],
embed = [":go_default_library"],
importpath = "k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/vclib",
deps = [
"//vendor/github.com/vmware/govmomi:go_default_library",
"//vendor/github.com/vmware/govmomi/simulator:go_default_library",
],
)
...@@ -244,6 +244,7 @@ filegroup( ...@@ -244,6 +244,7 @@ filegroup(
"//vendor/github.com/google/cadvisor/zfs:all-srcs", "//vendor/github.com/google/cadvisor/zfs:all-srcs",
"//vendor/github.com/google/certificate-transparency/go:all-srcs", "//vendor/github.com/google/certificate-transparency/go:all-srcs",
"//vendor/github.com/google/gofuzz:all-srcs", "//vendor/github.com/google/gofuzz:all-srcs",
"//vendor/github.com/google/uuid:all-srcs",
"//vendor/github.com/googleapis/gnostic/OpenAPIv2:all-srcs", "//vendor/github.com/googleapis/gnostic/OpenAPIv2:all-srcs",
"//vendor/github.com/googleapis/gnostic/compiler:all-srcs", "//vendor/github.com/googleapis/gnostic/compiler:all-srcs",
"//vendor/github.com/googleapis/gnostic/extensions:all-srcs", "//vendor/github.com/googleapis/gnostic/extensions:all-srcs",
......
language: go
go:
- 1.4.3
- 1.5.3
- tip
script:
- go test -v ./...
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"dce.go",
"doc.go",
"hash.go",
"marshal.go",
"node.go",
"sql.go",
"time.go",
"util.go",
"uuid.go",
"version1.go",
"version4.go",
],
importpath = "github.com/google/uuid",
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
# How to contribute
We definitely welcome patches and contribution to this project!
### Legal requirements
In order to protect both you and ourselves, you will need to sign the
[Contributor License Agreement](https://cla.developers.google.com/clas).
You may have already signed it for other Google projects.
Paul Borman <borman@google.com>
bmatsuo
shawnps
theory
jboverfelt
dsymonds
cd1
wallclockbuilder
dansouza
Copyright (c) 2009,2014 Google Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**This package is currently in development and the API may not be stable.**
The API will become stable with v1.
# uuid ![build status](https://travis-ci.org/google/uuid.svg?branch=master)
The uuid package generates and inspects UUIDs based on
[RFC 4122](http://tools.ietf.org/html/rfc4122)
and DCE 1.1: Authentication and Security Services.
This package is based on the github.com/pborman/uuid package (previously named
code.google.com/p/go-uuid). It differs from these earlier packages in that
a UUID is a 16 byte array rather than a byte slice. One loss due to this
change is the ability to represent an invalid UUID (vs a NIL UUID).
###### Install
`go get github.com/google/uuid`
###### Documentation
[![GoDoc](https://godoc.org/github.com/google/uuid?status.svg)](http://godoc.org/github.com/google/uuid)
Full `go doc` style documentation for the package can be viewed online without
installing this package by using the GoDoc site here:
http://godoc.org/github.com/google/uuid
// Copyright 2016 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import (
"encoding/binary"
"fmt"
"os"
)
// A Domain represents a Version 2 domain
type Domain byte
// Domain constants for DCE Security (Version 2) UUIDs.
const (
Person = Domain(0)
Group = Domain(1)
Org = Domain(2)
)
// NewDCESecurity returns a DCE Security (Version 2) UUID.
//
// The domain should be one of Person, Group or Org.
// On a POSIX system the id should be the users UID for the Person
// domain and the users GID for the Group. The meaning of id for
// the domain Org or on non-POSIX systems is site defined.
//
// For a given domain/id pair the same token may be returned for up to
// 7 minutes and 10 seconds.
func NewDCESecurity(domain Domain, id uint32) (UUID, error) {
uuid, err := NewUUID()
if err == nil {
uuid[6] = (uuid[6] & 0x0f) | 0x20 // Version 2
uuid[9] = byte(domain)
binary.BigEndian.PutUint32(uuid[0:], id)
}
return uuid, err
}
// NewDCEPerson returns a DCE Security (Version 2) UUID in the person
// domain with the id returned by os.Getuid.
//
// NewDCESecurity(Person, uint32(os.Getuid()))
func NewDCEPerson() (UUID, error) {
return NewDCESecurity(Person, uint32(os.Getuid()))
}
// NewDCEGroup returns a DCE Security (Version 2) UUID in the group
// domain with the id returned by os.Getgid.
//
// NewDCESecurity(Group, uint32(os.Getgid()))
func NewDCEGroup() (UUID, error) {
return NewDCESecurity(Group, uint32(os.Getgid()))
}
// Domain returns the domain for a Version 2 UUID. Domains are only defined
// for Version 2 UUIDs.
func (uuid UUID) Domain() Domain {
return Domain(uuid[9])
}
// ID returns the id for a Version 2 UUID. IDs are only defined for Version 2
// UUIDs.
func (uuid UUID) ID() uint32 {
return binary.BigEndian.Uint32(uuid[0:4])
}
func (d Domain) String() string {
switch d {
case Person:
return "Person"
case Group:
return "Group"
case Org:
return "Org"
}
return fmt.Sprintf("Domain%d", int(d))
}
// Copyright 2016 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package uuid generates and inspects UUIDs.
//
// UUIDs are based on RFC 4122 and DCE 1.1: Authentication and Security
// Services.
//
// A UUID is a 16 byte (128 bit) array. UUIDs may be used as keys to
// maps or compared directly.
package uuid
// Copyright 2016 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import (
"crypto/md5"
"crypto/sha1"
"hash"
)
// Well known namespace IDs and UUIDs
var (
NameSpaceDNS = Must(Parse("6ba7b810-9dad-11d1-80b4-00c04fd430c8"))
NameSpaceURL = Must(Parse("6ba7b811-9dad-11d1-80b4-00c04fd430c8"))
NameSpaceOID = Must(Parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8"))
NameSpaceX500 = Must(Parse("6ba7b814-9dad-11d1-80b4-00c04fd430c8"))
Nil UUID // empty UUID, all zeros
)
// NewHash returns a new UUID derived from the hash of space concatenated with
// data generated by h. The hash should be at least 16 byte in length. The
// first 16 bytes of the hash are used to form the UUID. The version of the
// UUID will be the lower 4 bits of version. NewHash is used to implement
// NewMD5 and NewSHA1.
func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID {
h.Reset()
h.Write(space[:])
h.Write([]byte(data))
s := h.Sum(nil)
var uuid UUID
copy(uuid[:], s)
uuid[6] = (uuid[6] & 0x0f) | uint8((version&0xf)<<4)
uuid[8] = (uuid[8] & 0x3f) | 0x80 // RFC 4122 variant
return uuid
}
// NewMD5 returns a new MD5 (Version 3) UUID based on the
// supplied name space and data. It is the same as calling:
//
// NewHash(md5.New(), space, data, 3)
func NewMD5(space UUID, data []byte) UUID {
return NewHash(md5.New(), space, data, 3)
}
// NewSHA1 returns a new SHA1 (Version 5) UUID based on the
// supplied name space and data. It is the same as calling:
//
// NewHash(sha1.New(), space, data, 5)
func NewSHA1(space UUID, data []byte) UUID {
return NewHash(sha1.New(), space, data, 5)
}
// Copyright 2016 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import "fmt"
// MarshalText implements encoding.TextMarshaler.
func (uuid UUID) MarshalText() ([]byte, error) {
var js [36]byte
encodeHex(js[:], uuid)
return js[:], nil
}
// UnmarshalText implements encoding.TextUnmarshaler.
func (uuid *UUID) UnmarshalText(data []byte) error {
// See comment in ParseBytes why we do this.
// id, err := ParseBytes(data)
id, err := ParseBytes(data)
if err == nil {
*uuid = id
}
return err
}
// MarshalBinary implements encoding.BinaryMarshaler.
func (uuid UUID) MarshalBinary() ([]byte, error) {
return uuid[:], nil
}
// UnmarshalBinary implements encoding.BinaryUnmarshaler.
func (uuid *UUID) UnmarshalBinary(data []byte) error {
if len(data) != 16 {
return fmt.Errorf("invalid UUID (got %d bytes)", len(data))
}
copy(uuid[:], data)
return nil
}
// Copyright 2016 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import (
"net"
"sync"
)
var (
nodeMu sync.Mutex
interfaces []net.Interface // cached list of interfaces
ifname string // name of interface being used
nodeID [6]byte // hardware for version 1 UUIDs
zeroID [6]byte // nodeID with only 0's
)
// NodeInterface returns the name of the interface from which the NodeID was
// derived. The interface "user" is returned if the NodeID was set by
// SetNodeID.
func NodeInterface() string {
defer nodeMu.Unlock()
nodeMu.Lock()
return ifname
}
// SetNodeInterface selects the hardware address to be used for Version 1 UUIDs.
// If name is "" then the first usable interface found will be used or a random
// Node ID will be generated. If a named interface cannot be found then false
// is returned.
//
// SetNodeInterface never fails when name is "".
func SetNodeInterface(name string) bool {
defer nodeMu.Unlock()
nodeMu.Lock()
return setNodeInterface(name)
}
func setNodeInterface(name string) bool {
if interfaces == nil {
var err error
interfaces, err = net.Interfaces()
if err != nil && name != "" {
return false
}
}
for _, ifs := range interfaces {
if len(ifs.HardwareAddr) >= 6 && (name == "" || name == ifs.Name) {
copy(nodeID[:], ifs.HardwareAddr)
ifname = ifs.Name
return true
}
}
// We found no interfaces with a valid hardware address. If name
// does not specify a specific interface generate a random Node ID
// (section 4.1.6)
if name == "" {
randomBits(nodeID[:])
return true
}
return false
}
// NodeID returns a slice of a copy of the current Node ID, setting the Node ID
// if not already set.
func NodeID() []byte {
defer nodeMu.Unlock()
nodeMu.Lock()
if nodeID == zeroID {
setNodeInterface("")
}
nid := nodeID
return nid[:]
}
// SetNodeID sets the Node ID to be used for Version 1 UUIDs. The first 6 bytes
// of id are used. If id is less than 6 bytes then false is returned and the
// Node ID is not set.
func SetNodeID(id []byte) bool {
if len(id) < 6 {
return false
}
defer nodeMu.Unlock()
nodeMu.Lock()
copy(nodeID[:], id)
ifname = "user"
return true
}
// NodeID returns the 6 byte node id encoded in uuid. It returns nil if uuid is
// not valid. The NodeID is only well defined for version 1 and 2 UUIDs.
func (uuid UUID) NodeID() []byte {
var node [6]byte
copy(node[:], uuid[10:])
return node[:]
}
// Copyright 2016 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import (
"database/sql/driver"
"fmt"
)
// Scan implements sql.Scanner so UUIDs can be read from databases transparently
// Currently, database types that map to string and []byte are supported. Please
// consult database-specific driver documentation for matching types.
func (uuid *UUID) Scan(src interface{}) error {
switch src := src.(type) {
case nil:
return nil
case string:
// if an empty UUID comes from a table, we return a null UUID
if src == "" {
return nil
}
// see Parse for required string format
u, err := Parse(src)
if err != nil {
return fmt.Errorf("Scan: %v", err)
}
*uuid = u
case []byte:
// if an empty UUID comes from a table, we return a null UUID
if len(src) == 0 {
return nil
}
// assumes a simple slice of bytes if 16 bytes
// otherwise attempts to parse
if len(src) != 16 {
return uuid.Scan(string(src))
}
copy((*uuid)[:], src)
default:
return fmt.Errorf("Scan: unable to scan type %T into UUID", src)
}
return nil
}
// Value implements sql.Valuer so that UUIDs can be written to databases
// transparently. Currently, UUIDs map to strings. Please consult
// database-specific driver documentation for matching types.
func (uuid UUID) Value() (driver.Value, error) {
return uuid.String(), nil
}
// Copyright 2016 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import (
"encoding/binary"
"sync"
"time"
)
// A Time represents a time as the number of 100's of nanoseconds since 15 Oct
// 1582.
type Time int64
const (
lillian = 2299160 // Julian day of 15 Oct 1582
unix = 2440587 // Julian day of 1 Jan 1970
epoch = unix - lillian // Days between epochs
g1582 = epoch * 86400 // seconds between epochs
g1582ns100 = g1582 * 10000000 // 100s of a nanoseconds between epochs
)
var (
timeMu sync.Mutex
lasttime uint64 // last time we returned
clockSeq uint16 // clock sequence for this run
timeNow = time.Now // for testing
)
// UnixTime converts t the number of seconds and nanoseconds using the Unix
// epoch of 1 Jan 1970.
func (t Time) UnixTime() (sec, nsec int64) {
sec = int64(t - g1582ns100)
nsec = (sec % 10000000) * 100
sec /= 10000000
return sec, nsec
}
// GetTime returns the current Time (100s of nanoseconds since 15 Oct 1582) and
// clock sequence as well as adjusting the clock sequence as needed. An error
// is returned if the current time cannot be determined.
func GetTime() (Time, uint16, error) {
defer timeMu.Unlock()
timeMu.Lock()
return getTime()
}
func getTime() (Time, uint16, error) {
t := timeNow()
// If we don't have a clock sequence already, set one.
if clockSeq == 0 {
setClockSequence(-1)
}
now := uint64(t.UnixNano()/100) + g1582ns100
// If time has gone backwards with this clock sequence then we
// increment the clock sequence
if now <= lasttime {
clockSeq = ((clockSeq + 1) & 0x3fff) | 0x8000
}
lasttime = now
return Time(now), clockSeq, nil
}
// ClockSequence returns the current clock sequence, generating one if not
// already set. The clock sequence is only used for Version 1 UUIDs.
//
// The uuid package does not use global static storage for the clock sequence or
// the last time a UUID was generated. Unless SetClockSequence is used, a new
// random clock sequence is generated the first time a clock sequence is
// requested by ClockSequence, GetTime, or NewUUID. (section 4.2.1.1)
func ClockSequence() int {
defer timeMu.Unlock()
timeMu.Lock()
return clockSequence()
}
func clockSequence() int {
if clockSeq == 0 {
setClockSequence(-1)
}
return int(clockSeq & 0x3fff)
}
// SetClockSeq sets the clock sequence to the lower 14 bits of seq. Setting to
// -1 causes a new sequence to be generated.
func SetClockSequence(seq int) {
defer timeMu.Unlock()
timeMu.Lock()
setClockSequence(seq)
}
func setClockSequence(seq int) {
if seq == -1 {
var b [2]byte
randomBits(b[:]) // clock sequence
seq = int(b[0])<<8 | int(b[1])
}
old_seq := clockSeq
clockSeq = uint16(seq&0x3fff) | 0x8000 // Set our variant
if old_seq != clockSeq {
lasttime = 0
}
}
// Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in
// uuid. The time is only defined for version 1 and 2 UUIDs.
func (uuid UUID) Time() Time {
time := int64(binary.BigEndian.Uint32(uuid[0:4]))
time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32
time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48
return Time(time)
}
// ClockSequence returns the clock sequence encoded in uuid.
// The clock sequence is only well defined for version 1 and 2 UUIDs.
func (uuid UUID) ClockSequence() int {
return int(binary.BigEndian.Uint16(uuid[8:10])) & 0x3fff
}
// Copyright 2016 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import (
"io"
)
// randomBits completely fills slice b with random data.
func randomBits(b []byte) {
if _, err := io.ReadFull(rander, b); err != nil {
panic(err.Error()) // rand should never fail
}
}
// xvalues returns the value of a byte as a hexadecimal digit or 255.
var xvalues = [256]byte{
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255,
255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
}
// xtob converts hex characters x1 and x2 into a byte.
func xtob(x1, x2 byte) (byte, bool) {
b1 := xvalues[x1]
b2 := xvalues[x2]
return (b1 << 4) | b2, b1 != 255 && b2 != 255
}
// Copyright 2016 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import (
"bytes"
"crypto/rand"
"encoding/hex"
"errors"
"fmt"
"io"
"strings"
)
// A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC
// 4122.
type UUID [16]byte
// A Version represents a UUID's version.
type Version byte
// A Variant represents a UUID's variant.
type Variant byte
// Constants returned by Variant.
const (
Invalid = Variant(iota) // Invalid UUID
RFC4122 // The variant specified in RFC4122
Reserved // Reserved, NCS backward compatibility.
Microsoft // Reserved, Microsoft Corporation backward compatibility.
Future // Reserved for future definition.
)
var rander = rand.Reader // random function
// Parse decodes s into a UUID or returns an error. Both the UUID form of
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded.
func Parse(s string) (UUID, error) {
var uuid UUID
if len(s) != 36 {
if len(s) != 36+9 {
return uuid, fmt.Errorf("invalid UUID length: %d", len(s))
}
if strings.ToLower(s[:9]) != "urn:uuid:" {
return uuid, fmt.Errorf("invalid urn prefix: %q", s[:9])
}
s = s[9:]
}
if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' {
return uuid, errors.New("invalid UUID format")
}
for i, x := range [16]int{
0, 2, 4, 6,
9, 11,
14, 16,
19, 21,
24, 26, 28, 30, 32, 34} {
if v, ok := xtob(s[x], s[x+1]); !ok {
return uuid, errors.New("invalid UUID format")
} else {
uuid[i] = v
}
}
return uuid, nil
}
// ParseBytes is like Parse, except it parses a byte slice instead of a string.
func ParseBytes(b []byte) (UUID, error) {
var uuid UUID
if len(b) != 36 {
if len(b) != 36+9 {
return uuid, fmt.Errorf("invalid UUID length: %d", len(b))
}
if !bytes.Equal(bytes.ToLower(b[:9]), []byte("urn:uuid:")) {
return uuid, fmt.Errorf("invalid urn prefix: %q", b[:9])
}
b = b[9:]
}
if b[8] != '-' || b[13] != '-' || b[18] != '-' || b[23] != '-' {
return uuid, errors.New("invalid UUID format")
}
for i, x := range [16]int{
0, 2, 4, 6,
9, 11,
14, 16,
19, 21,
24, 26, 28, 30, 32, 34} {
if v, ok := xtob(b[x], b[x+1]); !ok {
return uuid, errors.New("invalid UUID format")
} else {
uuid[i] = v
}
}
return uuid, nil
}
// FromBytes creates a new UUID from a byte slice. Returns an error if the slice
// does not have a length of 16. The bytes are copied from the slice.
func FromBytes(b []byte) (uuid UUID, err error) {
err = uuid.UnmarshalBinary(b)
return uuid, err
}
// Must returns uuid if err is nil and panics otherwise.
func Must(uuid UUID, err error) UUID {
if err != nil {
panic(err)
}
return uuid
}
// String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
// , or "" if uuid is invalid.
func (uuid UUID) String() string {
var buf [36]byte
encodeHex(buf[:], uuid)
return string(buf[:])
}
// URN returns the RFC 2141 URN form of uuid,
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, or "" if uuid is invalid.
func (uuid UUID) URN() string {
var buf [36 + 9]byte
copy(buf[:], "urn:uuid:")
encodeHex(buf[9:], uuid)
return string(buf[:])
}
func encodeHex(dst []byte, uuid UUID) {
hex.Encode(dst[:], uuid[:4])
dst[8] = '-'
hex.Encode(dst[9:13], uuid[4:6])
dst[13] = '-'
hex.Encode(dst[14:18], uuid[6:8])
dst[18] = '-'
hex.Encode(dst[19:23], uuid[8:10])
dst[23] = '-'
hex.Encode(dst[24:], uuid[10:])
}
// Variant returns the variant encoded in uuid.
func (uuid UUID) Variant() Variant {
switch {
case (uuid[8] & 0xc0) == 0x80:
return RFC4122
case (uuid[8] & 0xe0) == 0xc0:
return Microsoft
case (uuid[8] & 0xe0) == 0xe0:
return Future
default:
return Reserved
}
}
// Version returns the version of uuid.
func (uuid UUID) Version() Version {
return Version(uuid[6] >> 4)
}
func (v Version) String() string {
if v > 15 {
return fmt.Sprintf("BAD_VERSION_%d", v)
}
return fmt.Sprintf("VERSION_%d", v)
}
func (v Variant) String() string {
switch v {
case RFC4122:
return "RFC4122"
case Reserved:
return "Reserved"
case Microsoft:
return "Microsoft"
case Future:
return "Future"
case Invalid:
return "Invalid"
}
return fmt.Sprintf("BadVariant%d", int(v))
}
// SetRand sets the random number generator to r, which implements io.Reader.
// If r.Read returns an error when the package requests random data then
// a panic will be issued.
//
// Calling SetRand with nil sets the random number generator to the default
// generator.
func SetRand(r io.Reader) {
if r == nil {
rander = rand.Reader
return
}
rander = r
}
// Copyright 2016 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import (
"encoding/binary"
)
// NewUUID returns a Version 1 UUID based on the current NodeID and clock
// sequence, and the current time. If the NodeID has not been set by SetNodeID
// or SetNodeInterface then it will be set automatically. If the NodeID cannot
// be set NewUUID returns nil. If clock sequence has not been set by
// SetClockSequence then it will be set automatically. If GetTime fails to
// return the current NewUUID returns nil and an error.
//
// In most cases, New should be used.
func NewUUID() (UUID, error) {
nodeMu.Lock()
if nodeID == zeroID {
setNodeInterface("")
}
nodeMu.Unlock()
var uuid UUID
now, seq, err := GetTime()
if err != nil {
return uuid, err
}
timeLow := uint32(now & 0xffffffff)
timeMid := uint16((now >> 32) & 0xffff)
timeHi := uint16((now >> 48) & 0x0fff)
timeHi |= 0x1000 // Version 1
binary.BigEndian.PutUint32(uuid[0:], timeLow)
binary.BigEndian.PutUint16(uuid[4:], timeMid)
binary.BigEndian.PutUint16(uuid[6:], timeHi)
binary.BigEndian.PutUint16(uuid[8:], seq)
copy(uuid[10:], nodeID[:])
return uuid, nil
}
// Copyright 2016 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package uuid
import "io"
// New creates a new random UUID or panics. New is equivalent to
// the expression
//
// uuid.Must(uuid.NewRandom())
func New() UUID {
return Must(NewRandom())
}
// NewRandom returns a Random (Version 4) UUID or panics.
//
// The strength of the UUIDs is based on the strength of the crypto/rand
// package.
//
// A note about uniqueness derived from the UUID Wikipedia entry:
//
// Randomly generated UUIDs have 122 random bits. One's annual risk of being
// hit by a meteorite is estimated to be one chance in 17 billion, that
// means the probability is about 0.00000000006 (6 × 10−11),
// equivalent to the odds of creating a few tens of trillions of UUIDs in a
// year and having one duplicate.
func NewRandom() (UUID, error) {
var uuid UUID
_, err := io.ReadFull(rander, uuid[:])
if err != nil {
return Nil, err
}
uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4
uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10
return uuid, nil
}
eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.kK6pryC8R-O1R0Gj9ydLvQuIZlcYLGze23WdW7xbpiEEKdz6nweJrMm7ysy8lgu1tM47JVo19p2_b26bNKSQshCUOETvd7Hb2UMZOjnyUnqdyAAyoi6UkIquXfUUbHTNS0iMxwSxxW9KMp2GXNq8-o6T8xQZTDirBJFKKd8ZNUasTaoa5j8U9IfdR1aCavTBuOhvk8IVs-jSbY5TVJMJiE0IOPXois7aRJ6uAiANQBk9VKLegEcZD_qAewecXHDsHi-u0jbmg3o3PPaJaK_Qv5dsPlR2M-E2kE3AGUn0-zn5zYRngoAZ8WZr2O4GvLdltJKq9i2z7jOrdOzzRcDRow.96qvwl_E1Hj15u7Q.hWs-jQ8FsqQFD7pE9N-UEP1BWQ9rsJIcCaPvQRIp8Fukm_vvlw9YEaEq0ERLrsUWsJWpd1ca8_h8x7xD6f_d5YppwRqRHIeGIsdBOTMhNs0lG8ikkQXLat-UroCpy8EC17nuUtDE2E2Kdxrk4Cdd6Bk-dKk0Ta4w3Ud0YBKa.P8zrO7xizgv0i98eVWWzEg
\ No newline at end of file
clone:
tags: true
path: github.com/vmware/govmomi
build:
image: golang:1.7
pull: true
environment:
- GOVC_TEST_URL=$$GOVC_TEST_URL
- GOVC_INSECURE=1
- VCA=1
commands:
- make all install
- git clone https://github.com/sstephenson/bats.git /tmp/bats
- /tmp/bats/install.sh /usr/local
- apt-get -qq update && apt-get install -yqq uuid-runtime bsdmainutils jq
- govc/test/images/update.sh
- bats govc/test
...@@ -13,4 +13,7 @@ Pieter Noordhuis <pnoordhuis@vmware.com> <pcnoordhuis@gmail.com> ...@@ -13,4 +13,7 @@ Pieter Noordhuis <pnoordhuis@vmware.com> <pcnoordhuis@gmail.com>
Takaaki Furukawa <takaaki.frkw@gmail.com> takaaki.furukawa <takaaki.furukawa@mail.rakuten.com> Takaaki Furukawa <takaaki.frkw@gmail.com> takaaki.furukawa <takaaki.furukawa@mail.rakuten.com>
Takaaki Furukawa <takaaki.frkw@gmail.com> tkak <takaaki.frkw@gmail.com> Takaaki Furukawa <takaaki.frkw@gmail.com> tkak <takaaki.frkw@gmail.com>
Vadim Egorov <vegorov@vmware.com> <egorovv@gmail.com> Vadim Egorov <vegorov@vmware.com> <egorovv@gmail.com>
Anfernee Yongkun Gui <agui@vmware.com> <anfernee.gui@gmail.com>
Anfernee Yongkun Gui <agui@vmware.com> Yongkun Anfernee Gui <agui@vmware.com>
Zach Tucker <ztucker@vmware.com> <jzt@users.noreply.github.com>
Zee Yang <zeey@vmware.com> <zee.yang@gmail.com> Zee Yang <zeey@vmware.com> <zee.yang@gmail.com>
...@@ -3,7 +3,7 @@ sudo: false ...@@ -3,7 +3,7 @@ sudo: false
language: go language: go
go: go:
- 1.7 - 1.8
before_install: before_install:
- make vendor - make vendor
......
...@@ -27,10 +27,12 @@ filegroup( ...@@ -27,10 +27,12 @@ filegroup(
":package-srcs", ":package-srcs",
"//vendor/github.com/vmware/govmomi/find:all-srcs", "//vendor/github.com/vmware/govmomi/find:all-srcs",
"//vendor/github.com/vmware/govmomi/list:all-srcs", "//vendor/github.com/vmware/govmomi/list:all-srcs",
"//vendor/github.com/vmware/govmomi/nfc:all-srcs",
"//vendor/github.com/vmware/govmomi/object:all-srcs", "//vendor/github.com/vmware/govmomi/object:all-srcs",
"//vendor/github.com/vmware/govmomi/pbm:all-srcs", "//vendor/github.com/vmware/govmomi/pbm:all-srcs",
"//vendor/github.com/vmware/govmomi/property:all-srcs", "//vendor/github.com/vmware/govmomi/property:all-srcs",
"//vendor/github.com/vmware/govmomi/session:all-srcs", "//vendor/github.com/vmware/govmomi/session:all-srcs",
"//vendor/github.com/vmware/govmomi/simulator:all-srcs",
"//vendor/github.com/vmware/govmomi/task:all-srcs", "//vendor/github.com/vmware/govmomi/task:all-srcs",
"//vendor/github.com/vmware/govmomi/vim25:all-srcs", "//vendor/github.com/vmware/govmomi/vim25:all-srcs",
], ],
......
# changelog # changelog
### 0.16.0 (2017-11-08)
* Add support for SOAP request operation ID header
* Moved ovf helpers from govc import.ovf command to ovf and nfc packages
* Added guest/toolbox (client) package
* Added toolbox package and toolbox command
* Added simulator package and vcsim command
### 0.15.0 (2017-06-19)
* WaitOptions.MaxWaitSeconds is now optional
* Support removal of ExtraConfig entries
* GuestPosixFileAttributes OwnerId and GroupId fields are now pointers,
rather than omitempty ints to allow chown with root uid:gid
* Updated examples/ using view package
* Add DatastoreFile.TailFunc method
* Export VirtualMachine.FindSnapshot method
* Add AuthorizationManager {Enable,Disable}Methods
* Add PBM client
### 0.14.0 (2017-04-08) ### 0.14.0 (2017-04-08)
* Add view.ContainerView type and methods * Add view.ContainerView type and methods
......
...@@ -17,6 +17,16 @@ git remote add $USER git@github.com:$USER/govmomi.git ...@@ -17,6 +17,16 @@ git remote add $USER git@github.com:$USER/govmomi.git
git fetch $USER git fetch $USER
``` ```
## Installing from source
Compile the govmomi libraries and install govc using:
``` shell
go install -v github.com/vmware/govmomi/govc
```
Note that **govc/build.sh** is only used for building release binaries.
## Contribution flow ## Contribution flow
This is a rough outline of what a contributor's workflow looks like: This is a rough outline of what a contributor's workflow looks like:
......
...@@ -3,12 +3,20 @@ ...@@ -3,12 +3,20 @@
# This script is generated by contributors.sh # This script is generated by contributors.sh
# #
Abhijeet Kasurde <akasurde@redhat.com>
abrarshivani <abrarshivani@users.noreply.github.com> abrarshivani <abrarshivani@users.noreply.github.com>
Adam Shannon <adamkshannon@gmail.com>
Alvaro Miranda <kikitux@gmail.com> Alvaro Miranda <kikitux@gmail.com>
amandahla <amanda.andrade@serpro.gov.br>
Amit Bathla <abathla@.vmware.com> Amit Bathla <abathla@.vmware.com>
amit bezalel <amit.bezalel@hpe.com>
Andrew Chin <andrew@andrewtchin.com> Andrew Chin <andrew@andrewtchin.com>
Anfernee Yongkun Gui <agui@vmware.com>
aniketGslab <aniket.shinde@gslab.com>
Arran Walker <arran.walker@zopa.com> Arran Walker <arran.walker@zopa.com>
Aryeh Weinreb <aryehweinreb@gmail.com>
Austin Parker <aparker@apprenda.com> Austin Parker <aparker@apprenda.com>
Balu Dontu <bdontu@vmware.com>
bastienbc <bastien.barbe.creuly@gmail.com> bastienbc <bastien.barbe.creuly@gmail.com>
Bob Killen <killen.bob@gmail.com> Bob Killen <killen.bob@gmail.com>
Brad Fitzpatrick <bradfitz@golang.org> Brad Fitzpatrick <bradfitz@golang.org>
...@@ -35,8 +43,10 @@ gthombare <gthombare@vmware.com> ...@@ -35,8 +43,10 @@ gthombare <gthombare@vmware.com>
Hasan Mahmood <mahmoodh@vmware.com> Hasan Mahmood <mahmoodh@vmware.com>
Henrik Hodne <henrik@travis-ci.com> Henrik Hodne <henrik@travis-ci.com>
Isaac Rodman <isaac@eyz.us> Isaac Rodman <isaac@eyz.us>
Ivan Porto Carrero <icarrero@vmware.com>
Jason Kincl <jkincl@gmail.com> Jason Kincl <jkincl@gmail.com>
Jeremy Canady <jcanady@jackhenry.com> Jeremy Canady <jcanady@jackhenry.com>
João Pereira <joaodrp@gmail.com>
Louie Jiang <jiangl@vmware.com> Louie Jiang <jiangl@vmware.com>
Marc Carmier <mcarmier@gmail.com> Marc Carmier <mcarmier@gmail.com>
Mevan Samaratunga <mevansam@gmail.com> Mevan Samaratunga <mevansam@gmail.com>
...@@ -47,7 +57,9 @@ S.Çağlar Onur <conur@vmware.com> ...@@ -47,7 +57,9 @@ S.Çağlar Onur <conur@vmware.com>
Sergey Ignatov <sergey.ignatov@jetbrains.com> Sergey Ignatov <sergey.ignatov@jetbrains.com>
Steve Purcell <steve@sanityinc.com> Steve Purcell <steve@sanityinc.com>
Takaaki Furukawa <takaaki.frkw@gmail.com> Takaaki Furukawa <takaaki.frkw@gmail.com>
tanishi <tanishi503@gmail.com>
Ted Zlatanov <tzz@lifelogs.com> Ted Zlatanov <tzz@lifelogs.com>
Thibaut Ackermann <thibaut.ackermann@alcatel-lucent.com>
Vadim Egorov <vegorov@vmware.com> Vadim Egorov <vegorov@vmware.com>
Yang Yang <yangy@vmware.com> Yang Yang <yangy@vmware.com>
Yuya Kusakabe <yuya.kusakabe@gmail.com> Yuya Kusakabe <yuya.kusakabe@gmail.com>
......
...@@ -11,13 +11,19 @@ goimports: ...@@ -11,13 +11,19 @@ goimports:
govet: govet:
@echo checking go vet... @echo checking go vet...
@go tool vet -structtags=false -methods=false . @go tool vet -structtags=false -methods=false $$(find . -mindepth 1 -maxdepth 1 -type d -not -name vendor)
test: install:
go install -v github.com/vmware/govmomi/govc
go install -v github.com/vmware/govmomi/vcsim
go-test:
go test -v $(TEST_OPTS) ./... go test -v $(TEST_OPTS) ./...
install: govc-test: install
go install github.com/vmware/govmomi/govc (cd govc/test && ./vendor/github.com/sstephenson/bats/libexec/bats -t .)
test: go-test govc-test
doc: install doc: install
./govc/usage.sh > ./govc/USAGE.md ./govc/usage.sh > ./govc/USAGE.md
...@@ -5,14 +5,19 @@ ...@@ -5,14 +5,19 @@
A Go library for interacting with VMware vSphere APIs (ESXi and/or vCenter). 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 and [USAGE](./govc/USAGE.md) document. In addition to the vSphere API client, this repository includes:
* [govc](./govc) - vSphere CLI
* [vcsim](./vcsim) - vSphere API mock framework
* [toolbox](./toolbox) - VM guest tools framework
## Compatibility ## Compatibility
This library is built for and tested against ESXi and vCenter 5.5, 6.0 and 6.5. This library is built for and tested against ESXi and vCenter 6.0 and 6.5.
If you're able to use it against older versions of ESXi and/or vCenter, please It should work with versions 5.5 and 5.1, but neither are officially supported.
leave a note and we'll include it in this compatibility list.
## Documentation ## Documentation
...@@ -23,19 +28,14 @@ The code in the `govmomi` package is a wrapper for the code that is generated fr ...@@ -23,19 +28,14 @@ The code in the `govmomi` package is a wrapper for the code that is generated fr
It primarily provides convenience functions for working with the vSphere API. It primarily provides convenience functions for working with the vSphere API.
See [godoc.org][godoc] for documentation. See [godoc.org][godoc] for documentation.
[apiref]:http://pubs.vmware.com/vsphere-60/index.jsp#com.vmware.wssdk.apiref.doc/right-pane.html [apiref]:http://pubs.vmware.com/vsphere-6-5/index.jsp#com.vmware.wssdk.apiref.doc/right-pane.html
[godoc]:http://godoc.org/github.com/vmware/govmomi [godoc]:http://godoc.org/github.com/vmware/govmomi
[drone]:https://drone.io
[dronesrc]:https://github.com/drone/drone
[dronecli]:http://readme.drone.io/devs/cli/
#### Building with CI ## Installation
Merges to this repository will trigger builds in both Travis and [Drone][drone].
To build locally with Drone: ```sh
- Ensure that you have Docker 1.6 or higher installed. go get -u github.com/vmware/govmomi
- Install the [Drone command line tools][dronecli]. ```
- Run `drone exec` from within the root directory of the govmomi repository.
## Discussion ## Discussion
...@@ -53,9 +53,17 @@ Refer to the [CHANGELOG](CHANGELOG.md) for version to version changes. ...@@ -53,9 +53,17 @@ Refer to the [CHANGELOG](CHANGELOG.md) for version to version changes.
* [Docker Machine](https://github.com/docker/machine/tree/master/drivers/vmwarevsphere) * [Docker Machine](https://github.com/docker/machine/tree/master/drivers/vmwarevsphere)
* [Docker InfraKit](https://github.com/docker/infrakit/tree/master/pkg/provider/vsphere)
* [Docker LinuxKit](https://github.com/linuxkit/linuxkit/tree/master/src/cmd/linuxkit)
* [Kubernetes](https://github.com/kubernetes/kubernetes/tree/master/pkg/cloudprovider/providers/vsphere) * [Kubernetes](https://github.com/kubernetes/kubernetes/tree/master/pkg/cloudprovider/providers/vsphere)
* [Terraform](https://github.com/hashicorp/terraform/tree/master/builtin/providers/vsphere) * [Kubernetes kops](https://github.com/kubernetes/kops/tree/master/upup/pkg/fi/cloudup/vsphere)
* [Terraform](https://github.com/terraform-providers/terraform-provider-vsphere)
* [Packer](https://github.com/jetbrains-infra/packer-builder-vsphere)
* [VMware VIC Engine](https://github.com/vmware/vic) * [VMware VIC Engine](https://github.com/vmware/vic)
......
...@@ -20,6 +20,7 @@ import ( ...@@ -20,6 +20,7 @@ import (
"context" "context"
"os" "os"
"path" "path"
"strings"
"github.com/vmware/govmomi/list" "github.com/vmware/govmomi/list"
"github.com/vmware/govmomi/object" "github.com/vmware/govmomi/object"
...@@ -177,6 +178,7 @@ func (r recurser) List(ctx context.Context, s *spec, root list.Element, parts [] ...@@ -177,6 +178,7 @@ func (r recurser) List(ctx context.Context, s *spec, root list.Element, parts []
return in, nil return in, nil
} }
all := parts
pattern := parts[0] pattern := parts[0]
parts = parts[1:] parts = parts[1:]
...@@ -188,6 +190,12 @@ func (r recurser) List(ctx context.Context, s *spec, root list.Element, parts [] ...@@ -188,6 +190,12 @@ func (r recurser) List(ctx context.Context, s *spec, root list.Element, parts []
} }
if !matched { if !matched {
matched = strings.HasSuffix(e.Path, "/"+path.Join(all...))
if matched {
// name contains a '/'
out = append(out, e)
}
continue continue
} }
......
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"lease.go",
"lease_updater.go",
],
importpath = "github.com/vmware/govmomi/nfc",
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/vmware/govmomi/property:go_default_library",
"//vendor/github.com/vmware/govmomi/vim25:go_default_library",
"//vendor/github.com/vmware/govmomi/vim25/methods:go_default_library",
"//vendor/github.com/vmware/govmomi/vim25/mo:go_default_library",
"//vendor/github.com/vmware/govmomi/vim25/progress:go_default_library",
"//vendor/github.com/vmware/govmomi/vim25/soap:go_default_library",
"//vendor/github.com/vmware/govmomi/vim25/types:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
/* /*
Copyright (c) 2015 VMware, Inc. All Rights Reserved. Copyright (c) 2015-2017 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
...@@ -14,38 +14,42 @@ See the License for the specific language governing permissions and ...@@ -14,38 +14,42 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package object package nfc
import ( import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"io"
"path"
"github.com/vmware/govmomi/property" "github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/vim25" "github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods" "github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo" "github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/progress"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types" "github.com/vmware/govmomi/vim25/types"
) )
type HttpNfcLease struct { type Lease struct {
Common types.ManagedObjectReference
c *vim25.Client
} }
func NewHttpNfcLease(c *vim25.Client, ref types.ManagedObjectReference) *HttpNfcLease { func NewLease(c *vim25.Client, ref types.ManagedObjectReference) *Lease {
return &HttpNfcLease{ return &Lease{ref, c}
Common: NewCommon(c, ref),
}
} }
// HttpNfcLeaseAbort wraps methods.HttpNfcLeaseAbort // Abort wraps methods.Abort
func (o HttpNfcLease) HttpNfcLeaseAbort(ctx context.Context, fault *types.LocalizedMethodFault) error { func (l *Lease) Abort(ctx context.Context, fault *types.LocalizedMethodFault) error {
req := types.HttpNfcLeaseAbort{ req := types.HttpNfcLeaseAbort{
This: o.Reference(), This: l.Reference(),
Fault: fault, Fault: fault,
} }
_, err := methods.HttpNfcLeaseAbort(ctx, o.c, &req) _, err := methods.HttpNfcLeaseAbort(ctx, l.c, &req)
if err != nil { if err != nil {
return err return err
} }
...@@ -53,13 +57,13 @@ func (o HttpNfcLease) HttpNfcLeaseAbort(ctx context.Context, fault *types.Locali ...@@ -53,13 +57,13 @@ func (o HttpNfcLease) HttpNfcLeaseAbort(ctx context.Context, fault *types.Locali
return nil return nil
} }
// HttpNfcLeaseComplete wraps methods.HttpNfcLeaseComplete // Complete wraps methods.Complete
func (o HttpNfcLease) HttpNfcLeaseComplete(ctx context.Context) error { func (l *Lease) Complete(ctx context.Context) error {
req := types.HttpNfcLeaseComplete{ req := types.HttpNfcLeaseComplete{
This: o.Reference(), This: l.Reference(),
} }
_, err := methods.HttpNfcLeaseComplete(ctx, o.c, &req) _, err := methods.HttpNfcLeaseComplete(ctx, l.c, &req)
if err != nil { if err != nil {
return err return err
} }
...@@ -67,13 +71,13 @@ func (o HttpNfcLease) HttpNfcLeaseComplete(ctx context.Context) error { ...@@ -67,13 +71,13 @@ func (o HttpNfcLease) HttpNfcLeaseComplete(ctx context.Context) error {
return nil return nil
} }
// HttpNfcLeaseGetManifest wraps methods.HttpNfcLeaseGetManifest // GetManifest wraps methods.GetManifest
func (o HttpNfcLease) HttpNfcLeaseGetManifest(ctx context.Context) error { func (l *Lease) GetManifest(ctx context.Context) error {
req := types.HttpNfcLeaseGetManifest{ req := types.HttpNfcLeaseGetManifest{
This: o.Reference(), This: l.Reference(),
} }
_, err := methods.HttpNfcLeaseGetManifest(ctx, o.c, &req) _, err := methods.HttpNfcLeaseGetManifest(ctx, l.c, &req)
if err != nil { if err != nil {
return err return err
} }
...@@ -81,14 +85,14 @@ func (o HttpNfcLease) HttpNfcLeaseGetManifest(ctx context.Context) error { ...@@ -81,14 +85,14 @@ func (o HttpNfcLease) HttpNfcLeaseGetManifest(ctx context.Context) error {
return nil return nil
} }
// HttpNfcLeaseProgress wraps methods.HttpNfcLeaseProgress // Progress wraps methods.Progress
func (o HttpNfcLease) HttpNfcLeaseProgress(ctx context.Context, percent int32) error { func (l *Lease) Progress(ctx context.Context, percent int32) error {
req := types.HttpNfcLeaseProgress{ req := types.HttpNfcLeaseProgress{
This: o.Reference(), This: l.Reference(),
Percent: percent, Percent: percent,
} }
_, err := methods.HttpNfcLeaseProgress(ctx, o.c, &req) _, err := methods.HttpNfcLeaseProgress(ctx, l.c, &req)
if err != nil { if err != nil {
return err return err
} }
...@@ -96,11 +100,66 @@ func (o HttpNfcLease) HttpNfcLeaseProgress(ctx context.Context, percent int32) e ...@@ -96,11 +100,66 @@ func (o HttpNfcLease) HttpNfcLeaseProgress(ctx context.Context, percent int32) e
return nil return nil
} }
func (o HttpNfcLease) Wait(ctx context.Context) (*types.HttpNfcLeaseInfo, error) { type LeaseInfo struct {
types.HttpNfcLeaseInfo
Items []FileItem
}
func (l *Lease) newLeaseInfo(li *types.HttpNfcLeaseInfo, items []types.OvfFileItem) (*LeaseInfo, error) {
info := &LeaseInfo{
HttpNfcLeaseInfo: *li,
}
for _, device := range li.DeviceUrl {
u, err := l.c.ParseURL(device.Url)
if err != nil {
return nil, err
}
if device.SslThumbprint != "" {
// TODO: prefer host management IP
l.c.SetThumbprint(u.Host, device.SslThumbprint)
}
if len(items) == 0 {
// this is an export
item := types.OvfFileItem{
DeviceId: device.Key,
Path: device.TargetId,
Size: device.FileSize,
}
if item.Size == 0 {
item.Size = li.TotalDiskCapacityInKB * 1024
}
if item.Path == "" {
item.Path = path.Base(device.Url)
}
info.Items = append(info.Items, NewFileItem(u, item))
continue
}
// this is an import
for _, item := range items {
if device.ImportKey == item.DeviceId {
info.Items = append(info.Items, NewFileItem(u, item))
break
}
}
}
return info, nil
}
func (l *Lease) Wait(ctx context.Context, items []types.OvfFileItem) (*LeaseInfo, error) {
var lease mo.HttpNfcLease var lease mo.HttpNfcLease
pc := property.DefaultCollector(o.c) pc := property.DefaultCollector(l.c)
err := property.Wait(ctx, pc, o.Reference(), []string{"state", "info", "error"}, func(pc []types.PropertyChange) bool { err := property.Wait(ctx, pc, l.Reference(), []string{"state", "info", "error"}, func(pc []types.PropertyChange) bool {
done := false done := false
for _, c := range pc { for _, c := range pc {
...@@ -132,7 +191,7 @@ func (o HttpNfcLease) Wait(ctx context.Context) (*types.HttpNfcLeaseInfo, error) ...@@ -132,7 +191,7 @@ func (o HttpNfcLease) Wait(ctx context.Context) (*types.HttpNfcLeaseInfo, error)
} }
if lease.State == types.HttpNfcLeaseStateReady { if lease.State == types.HttpNfcLeaseStateReady {
return lease.Info, nil return l.newLeaseInfo(lease.Info, items)
} }
if lease.Error != nil { if lease.Error != nil {
...@@ -141,3 +200,39 @@ func (o HttpNfcLease) Wait(ctx context.Context) (*types.HttpNfcLeaseInfo, error) ...@@ -141,3 +200,39 @@ func (o HttpNfcLease) Wait(ctx context.Context) (*types.HttpNfcLeaseInfo, error)
return nil, fmt.Errorf("unexpected nfc lease state: %s", lease.State) return nil, fmt.Errorf("unexpected nfc lease state: %s", lease.State)
} }
func (l *Lease) StartUpdater(ctx context.Context, info *LeaseInfo) *LeaseUpdater {
return newLeaseUpdater(ctx, l, info)
}
func (l *Lease) Upload(ctx context.Context, item FileItem, f io.Reader, opts soap.Upload) error {
if opts.Progress == nil {
opts.Progress = item
} else {
opts.Progress = progress.Tee(item, opts.Progress)
}
// Non-disk files (such as .iso) use the PUT method.
// Overwrite: t header is also required in this case (ovftool does the same)
if item.Create {
opts.Method = "PUT"
opts.Headers = map[string]string{
"Overwrite": "t",
}
} else {
opts.Method = "POST"
opts.Type = "application/x-vnd.vmware-streamVmdk"
}
return l.c.Upload(f, item.URL, &opts)
}
func (l *Lease) DownloadFile(ctx context.Context, file string, item FileItem, opts soap.Download) error {
if opts.Progress == nil {
opts.Progress = item
} else {
opts.Progress = progress.Tee(item, opts.Progress)
}
return l.c.DownloadFile(file, item.URL, &opts)
}
/*
Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package nfc
import (
"context"
"log"
"net/url"
"sync"
"sync/atomic"
"time"
"github.com/vmware/govmomi/vim25/progress"
"github.com/vmware/govmomi/vim25/types"
)
type FileItem struct {
types.OvfFileItem
URL *url.URL
ch chan progress.Report
}
func NewFileItem(u *url.URL, item types.OvfFileItem) FileItem {
return FileItem{
OvfFileItem: item,
URL: u,
ch: make(chan progress.Report),
}
}
func (o FileItem) Sink() chan<- progress.Report {
return o.ch
}
// File converts the FileItem.OvfFileItem to an OvfFile
func (o FileItem) File() types.OvfFile {
return types.OvfFile{
DeviceId: o.DeviceId,
Path: o.Path,
Size: o.Size,
}
}
type LeaseUpdater struct {
lease *Lease
pos int64 // Number of bytes
total int64 // Total number of bytes
done chan struct{} // When lease updater should stop
wg sync.WaitGroup // Track when update loop is done
}
func newLeaseUpdater(ctx context.Context, lease *Lease, info *LeaseInfo) *LeaseUpdater {
l := LeaseUpdater{
lease: lease,
done: make(chan struct{}),
}
for _, item := range info.Items {
l.total += item.Size
go l.waitForProgress(item)
}
// Kickstart update loop
l.wg.Add(1)
go l.run()
return &l
}
func (l *LeaseUpdater) waitForProgress(item FileItem) {
var pos, total int64
total = item.Size
for {
select {
case <-l.done:
return
case p, ok := <-item.ch:
// Return in case of error
if ok && p.Error() != nil {
return
}
if !ok {
// Last element on the channel, add to total
atomic.AddInt64(&l.pos, total-pos)
return
}
// Approximate progress in number of bytes
x := int64(float32(total) * (p.Percentage() / 100.0))
atomic.AddInt64(&l.pos, x-pos)
pos = x
}
}
}
func (l *LeaseUpdater) run() {
defer l.wg.Done()
tick := time.NewTicker(2 * time.Second)
defer tick.Stop()
for {
select {
case <-l.done:
return
case <-tick.C:
// From the vim api HttpNfcLeaseProgress(percent) doc, percent ==
// "Completion status represented as an integer in the 0-100 range."
// Always report the current value of percent, as it will renew the
// lease even if the value hasn't changed or is 0.
percent := int32(float32(100*atomic.LoadInt64(&l.pos)) / float32(l.total))
err := l.lease.Progress(context.TODO(), percent)
if err != nil {
log.Printf("NFC lease progress: %s", err)
return
}
}
}
}
func (l *LeaseUpdater) Done() {
close(l.done)
l.wg.Wait()
}
...@@ -38,13 +38,11 @@ go_library( ...@@ -38,13 +38,11 @@ go_library(
"host_virtual_nic_manager.go", "host_virtual_nic_manager.go",
"host_vsan_internal_system.go", "host_vsan_internal_system.go",
"host_vsan_system.go", "host_vsan_system.go",
"http_nfc_lease.go",
"namespace_manager.go", "namespace_manager.go",
"network.go", "network.go",
"network_reference.go", "network_reference.go",
"opaque_network.go", "opaque_network.go",
"option_manager.go", "option_manager.go",
"ovf_manager.go",
"resource_pool.go", "resource_pool.go",
"search_index.go", "search_index.go",
"storage_pod.go", "storage_pod.go",
...@@ -61,6 +59,7 @@ go_library( ...@@ -61,6 +59,7 @@ go_library(
importpath = "github.com/vmware/govmomi/object", importpath = "github.com/vmware/govmomi/object",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
"//vendor/github.com/vmware/govmomi/nfc:go_default_library",
"//vendor/github.com/vmware/govmomi/property:go_default_library", "//vendor/github.com/vmware/govmomi/property:go_default_library",
"//vendor/github.com/vmware/govmomi/session:go_default_library", "//vendor/github.com/vmware/govmomi/session:go_default_library",
"//vendor/github.com/vmware/govmomi/task:go_default_library", "//vendor/github.com/vmware/govmomi/task:go_default_library",
......
...@@ -80,17 +80,24 @@ func (c *Common) SetInventoryPath(p string) { ...@@ -80,17 +80,24 @@ func (c *Common) SetInventoryPath(p string) {
func (c Common) ObjectName(ctx context.Context) (string, error) { func (c Common) ObjectName(ctx context.Context) (string, error) {
var o mo.ManagedEntity var o mo.ManagedEntity
name := c.Name() err := c.Properties(ctx, c.Reference(), []string{"name"}, &o)
if name != "" { if err != nil {
return name, nil return "", err
} }
err := c.Properties(ctx, c.Reference(), []string{"name"}, &o) if o.Name != "" {
return o.Name, nil
}
// Network has its own "name" field...
var n mo.Network
err = c.Properties(ctx, c.Reference(), []string{"name"}, &n)
if err != nil { if err != nil {
return "", err return "", err
} }
return o.Name, nil return n.Name, nil
} }
func (c Common) Properties(ctx context.Context, r types.ManagedObjectReference, ps []string, dst interface{}) error { func (c Common) Properties(ctx context.Context, r types.ManagedObjectReference, ps []string, dst interface{}) error {
......
...@@ -102,7 +102,9 @@ func (m CustomFieldsManager) Set(ctx context.Context, entity types.ManagedObject ...@@ -102,7 +102,9 @@ func (m CustomFieldsManager) Set(ctx context.Context, entity types.ManagedObject
return err return err
} }
func (m CustomFieldsManager) Field(ctx context.Context) ([]types.CustomFieldDef, error) { type CustomFieldDefList []types.CustomFieldDef
func (m CustomFieldsManager) Field(ctx context.Context) (CustomFieldDefList, error) {
var fm mo.CustomFieldsManager var fm mo.CustomFieldsManager
err := m.Properties(ctx, m.Reference(), []string{"field"}, &fm) err := m.Properties(ctx, m.Reference(), []string{"field"}, &fm)
...@@ -113,19 +115,19 @@ func (m CustomFieldsManager) Field(ctx context.Context) ([]types.CustomFieldDef, ...@@ -113,19 +115,19 @@ func (m CustomFieldsManager) Field(ctx context.Context) ([]types.CustomFieldDef,
return fm.Field, nil return fm.Field, nil
} }
func (m CustomFieldsManager) FindKey(ctx context.Context, key string) (int32, error) { func (m CustomFieldsManager) FindKey(ctx context.Context, name string) (int32, error) {
field, err := m.Field(ctx) field, err := m.Field(ctx)
if err != nil { if err != nil {
return -1, err return -1, err
} }
for _, def := range field { for _, def := range field {
if def.Name == key { if def.Name == name {
return def.Key, nil return def.Key, nil
} }
} }
k, err := strconv.Atoi(key) k, err := strconv.Atoi(name)
if err == nil { if err == nil {
// assume literal int key // assume literal int key
return int32(k), nil return int32(k), nil
...@@ -133,3 +135,12 @@ func (m CustomFieldsManager) FindKey(ctx context.Context, key string) (int32, er ...@@ -133,3 +135,12 @@ func (m CustomFieldsManager) FindKey(ctx context.Context, key string) (int32, er
return -1, ErrKeyNameNotFound return -1, ErrKeyNameNotFound
} }
func (l CustomFieldDefList) ByKey(key int32) *types.CustomFieldDef {
for _, def := range l {
if def.Key == key {
return &def
}
}
return nil
}
/* /*
Copyright (c) 2016 VMware, Inc. All Rights Reserved. Copyright (c) 2016-2017 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
...@@ -25,6 +25,7 @@ import ( ...@@ -25,6 +25,7 @@ import (
"net/http" "net/http"
"os" "os"
"path" "path"
"sync"
"time" "time"
"github.com/vmware/govmomi/vim25/soap" "github.com/vmware/govmomi/vim25/soap"
...@@ -232,8 +233,9 @@ func (f *DatastoreFile) get() (io.Reader, error) { ...@@ -232,8 +233,9 @@ func (f *DatastoreFile) get() (io.Reader, error) {
return f.body, nil return f.body, nil
} }
func lastIndexLines(s []byte, n *int) int64 { func lastIndexLines(s []byte, line *int, include func(l int, m string) bool) (int64, bool) {
i := len(s) - 1 i := len(s) - 1
done := false
for i > 0 { for i > 0 {
o := bytes.LastIndexByte(s[:i], '\n') o := bytes.LastIndexByte(s[:i], '\n')
...@@ -241,18 +243,27 @@ func lastIndexLines(s []byte, n *int) int64 { ...@@ -241,18 +243,27 @@ func lastIndexLines(s []byte, n *int) int64 {
break break
} }
i = o msg := string(s[o+1 : i+1])
*n-- if !include(*line, msg) {
if *n == 0 { done = true
break break
} else {
i = o
*line++
} }
} }
return int64(i) return int64(i), done
} }
// Tail seeks to the position of the last N lines of the file. // Tail seeks to the position of the last N lines of the file.
func (f *DatastoreFile) Tail(n int) error { func (f *DatastoreFile) Tail(n int) error {
return f.TailFunc(n, func(line int, _ string) bool { return n > line })
}
// TailFunc will seek backwards in the datastore file until it hits a line that does
// not satisfy the supplied `include` function.
func (f *DatastoreFile) TailFunc(lines int, include func(line int, message string) bool) error {
// Read the file in reverse using bsize chunks // Read the file in reverse using bsize chunks
const bsize = int64(1024 * 16) const bsize = int64(1024 * 16)
...@@ -261,13 +272,14 @@ func (f *DatastoreFile) Tail(n int) error { ...@@ -261,13 +272,14 @@ func (f *DatastoreFile) Tail(n int) error {
return err return err
} }
if n == 0 { if lines == 0 {
return nil return nil
} }
chunk := int64(-1) chunk := int64(-1)
buf := bytes.NewBuffer(make([]byte, 0, bsize)) buf := bytes.NewBuffer(make([]byte, 0, bsize))
line := 0
for { for {
var eof bool var eof bool
...@@ -298,19 +310,19 @@ func (f *DatastoreFile) Tail(n int) error { ...@@ -298,19 +310,19 @@ func (f *DatastoreFile) Tail(n int) error {
} }
b := buf.Bytes() b := buf.Bytes()
idx := lastIndexLines(b, &n) + 1 idx, done := lastIndexLines(b, &line, include)
if n == 0 { if done {
if chunk == -1 { if chunk == -1 {
// We found all N lines in the last chunk of the file. // We found all N lines in the last chunk of the file.
// The seek offset is also now at the current end of file. // The seek offset is also now at the current end of file.
// Save this buffer to avoid another GET request when Read() is called. // Save this buffer to avoid another GET request when Read() is called.
buf.Next(int(idx)) buf.Next(int(idx + 1))
f.buf = buf f.buf = buf
return nil return nil
} }
if _, err = f.Seek(pos+idx, io.SeekStart); err != nil { if _, err = f.Seek(pos+idx+1, io.SeekStart); err != nil {
return err return err
} }
...@@ -336,6 +348,7 @@ type followDatastoreFile struct { ...@@ -336,6 +348,7 @@ type followDatastoreFile struct {
r *DatastoreFile r *DatastoreFile
c chan struct{} c chan struct{}
i time.Duration i time.Duration
o sync.Once
} }
// Read reads up to len(b) bytes from the DatastoreFile being followed. // Read reads up to len(b) bytes from the DatastoreFile being followed.
...@@ -387,11 +400,15 @@ func (f *followDatastoreFile) Read(p []byte) (int, error) { ...@@ -387,11 +400,15 @@ func (f *followDatastoreFile) Read(p []byte) (int, error) {
// Close will stop Follow polling and close the underlying DatastoreFile. // Close will stop Follow polling and close the underlying DatastoreFile.
func (f *followDatastoreFile) Close() error { func (f *followDatastoreFile) Close() error {
close(f.c) f.o.Do(func() { close(f.c) })
return nil return nil
} }
// Follow returns an io.ReadCloser to stream the file contents as data is appended. // Follow returns an io.ReadCloser to stream the file contents as data is appended.
func (f *DatastoreFile) Follow(interval time.Duration) io.ReadCloser { func (f *DatastoreFile) Follow(interval time.Duration) io.ReadCloser {
return &followDatastoreFile{f, make(chan struct{}), interval} return &followDatastoreFile{
r: f,
c: make(chan struct{}),
i: interval,
}
} }
...@@ -97,6 +97,25 @@ func (m *DatastoreFileManager) DeleteVirtualDisk(ctx context.Context, name strin ...@@ -97,6 +97,25 @@ func (m *DatastoreFileManager) DeleteVirtualDisk(ctx context.Context, name strin
return task.Wait(ctx) return task.Wait(ctx)
} }
// Move dispatches to the appropriate Move method based on file name extension
func (m *DatastoreFileManager) Move(ctx context.Context, src string, dst string) error {
srcp := m.Path(src)
dstp := m.Path(dst)
f := m.FileManager.MoveDatastoreFile
if srcp.IsVMDK() {
f = m.VirtualDiskManager.MoveVirtualDisk
}
task, err := f(ctx, srcp.String(), m.Datacenter, dstp.String(), m.Datacenter, m.Force)
if err != nil {
return err
}
return task.Wait(ctx)
}
// Path converts path name to a DatastorePath // Path converts path name to a DatastorePath
func (m *DatastoreFileManager) Path(name string) *DatastorePath { func (m *DatastoreFileManager) Path(name string) *DatastorePath {
var p DatastorePath var p DatastorePath
......
...@@ -18,6 +18,7 @@ package object ...@@ -18,6 +18,7 @@ package object
import ( import (
"fmt" "fmt"
"path"
"strings" "strings"
) )
...@@ -63,3 +64,8 @@ func (p *DatastorePath) String() string { ...@@ -63,3 +64,8 @@ func (p *DatastorePath) String() string {
return strings.Join([]string{s, p.Path}, " ") return strings.Join([]string{s, p.Path}, " ")
} }
// IsVMDK returns true if Path has a ".vmdk" extension
func (p *DatastorePath) IsVMDK() bool {
return path.Ext(p.Path) == ".vmdk"
}
...@@ -38,7 +38,7 @@ func NewDistributedVirtualPortgroup(c *vim25.Client, ref types.ManagedObjectRefe ...@@ -38,7 +38,7 @@ func NewDistributedVirtualPortgroup(c *vim25.Client, ref types.ManagedObjectRefe
// EthernetCardBackingInfo returns the VirtualDeviceBackingInfo for this DistributedVirtualPortgroup // EthernetCardBackingInfo returns the VirtualDeviceBackingInfo for this DistributedVirtualPortgroup
func (p DistributedVirtualPortgroup) EthernetCardBackingInfo(ctx context.Context) (types.BaseVirtualDeviceBackingInfo, error) { func (p DistributedVirtualPortgroup) EthernetCardBackingInfo(ctx context.Context) (types.BaseVirtualDeviceBackingInfo, error) {
var dvp mo.DistributedVirtualPortgroup var dvp mo.DistributedVirtualPortgroup
var dvs mo.VmwareDistributedVirtualSwitch // TODO: should be mo.BaseDistributedVirtualSwitch var dvs mo.DistributedVirtualSwitch
if err := p.Properties(ctx, p.Reference(), []string{"key", "config.distributedVirtualSwitch"}, &dvp); err != nil { if err := p.Properties(ctx, p.Reference(), []string{"key", "config.distributedVirtualSwitch"}, &dvp); err != nil {
return nil, err return nil, err
......
...@@ -65,3 +65,15 @@ func (s DistributedVirtualSwitch) AddPortgroup(ctx context.Context, spec []types ...@@ -65,3 +65,15 @@ func (s DistributedVirtualSwitch) AddPortgroup(ctx context.Context, spec []types
return NewTask(s.Client(), res.Returnval), nil return NewTask(s.Client(), res.Returnval), nil
} }
func (s DistributedVirtualSwitch) FetchDVPorts(ctx context.Context) ([]types.DistributedVirtualPort, error) {
req := &types.FetchDVPorts{
This: s.Reference(),
}
res, err := methods.FetchDVPorts(ctx, s.Client(), req)
if err != nil {
return nil, err
}
return res.Returnval, nil
}
...@@ -88,6 +88,15 @@ func (s HostStorageSystem) RescanAllHba(ctx context.Context) error { ...@@ -88,6 +88,15 @@ func (s HostStorageSystem) RescanAllHba(ctx context.Context) error {
return err return err
} }
func (s HostStorageSystem) Refresh(ctx context.Context) error {
req := types.RefreshStorageSystem{
This: s.Reference(),
}
_, err := methods.RefreshStorageSystem(ctx, s.c, &req)
return err
}
func (s HostStorageSystem) MarkAsSsd(ctx context.Context, uuid string) (*Task, error) { func (s HostStorageSystem) MarkAsSsd(ctx context.Context, uuid string) (*Task, error) {
req := types.MarkAsSsd_Task{ req := types.MarkAsSsd_Task{
This: s.Reference(), This: s.Reference(),
......
...@@ -42,7 +42,7 @@ func (m HostVsanInternalSystem) QueryVsanObjectUuidsByFilter(ctx context.Context ...@@ -42,7 +42,7 @@ func (m HostVsanInternalSystem) QueryVsanObjectUuidsByFilter(ctx context.Context
req := types.QueryVsanObjectUuidsByFilter{ req := types.QueryVsanObjectUuidsByFilter{
This: m.Reference(), This: m.Reference(),
Uuids: uuids, Uuids: uuids,
Limit: limit, Limit: &limit,
Version: version, Version: version,
} }
......
...@@ -20,6 +20,7 @@ import ( ...@@ -20,6 +20,7 @@ import (
"context" "context"
"github.com/vmware/govmomi/vim25" "github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types" "github.com/vmware/govmomi/vim25/types"
) )
...@@ -34,12 +35,20 @@ func NewNetwork(c *vim25.Client, ref types.ManagedObjectReference) *Network { ...@@ -34,12 +35,20 @@ func NewNetwork(c *vim25.Client, ref types.ManagedObjectReference) *Network {
} }
// EthernetCardBackingInfo returns the VirtualDeviceBackingInfo for this Network // EthernetCardBackingInfo returns the VirtualDeviceBackingInfo for this Network
func (n Network) EthernetCardBackingInfo(_ context.Context) (types.BaseVirtualDeviceBackingInfo, error) { func (n Network) EthernetCardBackingInfo(ctx context.Context) (types.BaseVirtualDeviceBackingInfo, error) {
name := n.Name() var e mo.Network
// Use Network.Name rather than Common.Name as the latter does not return the complete name if it contains a '/'
// We can't use Common.ObjectName here either as we need the ManagedEntity.Name field is not set since mo.Network
// has its own Name field.
err := n.Properties(ctx, n.Reference(), []string{"name"}, &e)
if err != nil {
return nil, err
}
backing := &types.VirtualEthernetCardNetworkBackingInfo{ backing := &types.VirtualEthernetCardNetworkBackingInfo{
VirtualDeviceDeviceBackingInfo: types.VirtualDeviceDeviceBackingInfo{ VirtualDeviceDeviceBackingInfo: types.VirtualDeviceDeviceBackingInfo{
DeviceName: name, DeviceName: e.Name,
}, },
} }
......
/*
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package object
import (
"context"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/types"
)
type OvfManager struct {
Common
}
func NewOvfManager(c *vim25.Client) *OvfManager {
o := OvfManager{
Common: NewCommon(c, *c.ServiceContent.OvfManager),
}
return &o
}
// CreateDescriptor wraps methods.CreateDescriptor
func (o OvfManager) CreateDescriptor(ctx context.Context, obj Reference, cdp types.OvfCreateDescriptorParams) (*types.OvfCreateDescriptorResult, error) {
req := types.CreateDescriptor{
This: o.Reference(),
Obj: obj.Reference(),
Cdp: cdp,
}
res, err := methods.CreateDescriptor(ctx, o.c, &req)
if err != nil {
return nil, err
}
return &res.Returnval, nil
}
// CreateImportSpec wraps methods.CreateImportSpec
func (o OvfManager) CreateImportSpec(ctx context.Context, ovfDescriptor string, resourcePool Reference, datastore Reference, cisp types.OvfCreateImportSpecParams) (*types.OvfCreateImportSpecResult, error) {
req := types.CreateImportSpec{
This: o.Reference(),
OvfDescriptor: ovfDescriptor,
ResourcePool: resourcePool.Reference(),
Datastore: datastore.Reference(),
Cisp: cisp,
}
res, err := methods.CreateImportSpec(ctx, o.c, &req)
if err != nil {
return nil, err
}
return &res.Returnval, nil
}
// ParseDescriptor wraps methods.ParseDescriptor
func (o OvfManager) ParseDescriptor(ctx context.Context, ovfDescriptor string, pdp types.OvfParseDescriptorParams) (*types.OvfParseDescriptorResult, error) {
req := types.ParseDescriptor{
This: o.Reference(),
OvfDescriptor: ovfDescriptor,
Pdp: pdp,
}
res, err := methods.ParseDescriptor(ctx, o.c, &req)
if err != nil {
return nil, err
}
return &res.Returnval, nil
}
// ValidateHost wraps methods.ValidateHost
func (o OvfManager) ValidateHost(ctx context.Context, ovfDescriptor string, host Reference, vhp types.OvfValidateHostParams) (*types.OvfValidateHostResult, error) {
req := types.ValidateHost{
This: o.Reference(),
OvfDescriptor: ovfDescriptor,
Host: host.Reference(),
Vhp: vhp,
}
res, err := methods.ValidateHost(ctx, o.c, &req)
if err != nil {
return nil, err
}
return &res.Returnval, nil
}
...@@ -19,6 +19,7 @@ package object ...@@ -19,6 +19,7 @@ package object
import ( import (
"context" "context"
"github.com/vmware/govmomi/nfc"
"github.com/vmware/govmomi/vim25" "github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods" "github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/types" "github.com/vmware/govmomi/vim25/types"
...@@ -34,7 +35,7 @@ func NewResourcePool(c *vim25.Client, ref types.ManagedObjectReference) *Resourc ...@@ -34,7 +35,7 @@ func NewResourcePool(c *vim25.Client, ref types.ManagedObjectReference) *Resourc
} }
} }
func (p ResourcePool) ImportVApp(ctx context.Context, spec types.BaseImportSpec, folder *Folder, host *HostSystem) (*HttpNfcLease, error) { func (p ResourcePool) ImportVApp(ctx context.Context, spec types.BaseImportSpec, folder *Folder, host *HostSystem) (*nfc.Lease, error) {
req := types.ImportVApp{ req := types.ImportVApp{
This: p.Reference(), This: p.Reference(),
Spec: spec, Spec: spec,
...@@ -55,7 +56,7 @@ func (p ResourcePool) ImportVApp(ctx context.Context, spec types.BaseImportSpec, ...@@ -55,7 +56,7 @@ func (p ResourcePool) ImportVApp(ctx context.Context, spec types.BaseImportSpec,
return nil, err return nil, err
} }
return NewHttpNfcLease(p.c, res.Returnval), nil return nfc.NewLease(p.c, res.Returnval), nil
} }
func (p ResourcePool) Create(ctx context.Context, name string, spec types.ResourceConfigSpec) (*ResourcePool, error) { func (p ResourcePool) Create(ctx context.Context, name string, spec types.ResourceConfigSpec) (*ResourcePool, error) {
......
...@@ -22,6 +22,7 @@ import ( ...@@ -22,6 +22,7 @@ import (
"github.com/vmware/govmomi/property" "github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/task" "github.com/vmware/govmomi/task"
"github.com/vmware/govmomi/vim25" "github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/progress" "github.com/vmware/govmomi/vim25/progress"
"github.com/vmware/govmomi/vim25/types" "github.com/vmware/govmomi/vim25/types"
) )
...@@ -51,3 +52,11 @@ func (t *Task) WaitForResult(ctx context.Context, s progress.Sinker) (*types.Tas ...@@ -51,3 +52,11 @@ func (t *Task) WaitForResult(ctx context.Context, s progress.Sinker) (*types.Tas
p := property.DefaultCollector(t.c) p := property.DefaultCollector(t.c)
return task.Wait(ctx, t.Reference(), p, s) return task.Wait(ctx, t.Reference(), p, s)
} }
func (t *Task) Cancel(ctx context.Context) error {
_, err := methods.CancelTask(ctx, t.Client(), &types.CancelTask{
This: t.Reference(),
})
return err
}
/* /*
Copyright (c) 2015 VMware, Inc. All Rights Reserved. Copyright (c) 2015-2017 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
...@@ -30,6 +30,7 @@ import ( ...@@ -30,6 +30,7 @@ import (
// Type values for use in BootOrder // Type values for use in BootOrder
const ( const (
DeviceTypeNone = "-"
DeviceTypeCdrom = "cdrom" DeviceTypeCdrom = "cdrom"
DeviceTypeDisk = "disk" DeviceTypeDisk = "disk"
DeviceTypeEthernet = "ethernet" DeviceTypeEthernet = "ethernet"
...@@ -754,6 +755,9 @@ func (l VirtualDeviceList) PrimaryMacAddress() string { ...@@ -754,6 +755,9 @@ func (l VirtualDeviceList) PrimaryMacAddress() string {
// convert a BaseVirtualDevice to a BaseVirtualMachineBootOptionsBootableDevice // convert a BaseVirtualDevice to a BaseVirtualMachineBootOptionsBootableDevice
var bootableDevices = map[string]func(device types.BaseVirtualDevice) types.BaseVirtualMachineBootOptionsBootableDevice{ var bootableDevices = map[string]func(device types.BaseVirtualDevice) types.BaseVirtualMachineBootOptionsBootableDevice{
DeviceTypeNone: func(types.BaseVirtualDevice) types.BaseVirtualMachineBootOptionsBootableDevice {
return &types.VirtualMachineBootOptionsBootableDevice{}
},
DeviceTypeCdrom: func(types.BaseVirtualDevice) types.BaseVirtualMachineBootOptionsBootableDevice { DeviceTypeCdrom: func(types.BaseVirtualDevice) types.BaseVirtualMachineBootOptionsBootableDevice {
return &types.VirtualMachineBootOptionsBootableCdromDevice{} return &types.VirtualMachineBootOptionsBootableCdromDevice{}
}, },
...@@ -773,17 +777,23 @@ var bootableDevices = map[string]func(device types.BaseVirtualDevice) types.Base ...@@ -773,17 +777,23 @@ var bootableDevices = map[string]func(device types.BaseVirtualDevice) types.Base
} }
// BootOrder returns a list of devices which can be used to set boot order via VirtualMachine.SetBootOptions. // BootOrder returns a list of devices which can be used to set boot order via VirtualMachine.SetBootOptions.
// The order can any of "ethernet", "cdrom", "floppy" or "disk" or by specific device name. // The order can be any of "ethernet", "cdrom", "floppy" or "disk" or by specific device name.
// A value of "-" will clear the existing boot order on the VC/ESX side.
func (l VirtualDeviceList) BootOrder(order []string) []types.BaseVirtualMachineBootOptionsBootableDevice { func (l VirtualDeviceList) BootOrder(order []string) []types.BaseVirtualMachineBootOptionsBootableDevice {
var devices []types.BaseVirtualMachineBootOptionsBootableDevice var devices []types.BaseVirtualMachineBootOptionsBootableDevice
for _, name := range order { for _, name := range order {
if kind, ok := bootableDevices[name]; ok { if kind, ok := bootableDevices[name]; ok {
if name == DeviceTypeNone {
// Not covered in the API docs, nor obvious, but this clears the boot order on the VC/ESX side.
devices = append(devices, new(types.VirtualMachineBootOptionsBootableDevice))
continue
}
for _, device := range l { for _, device := range l {
if l.Type(device) == name { if l.Type(device) == name {
devices = append(devices, kind(device)) devices = append(devices, kind(device))
} }
} }
continue continue
} }
......
/* /*
Copyright (c) 2015 VMware, Inc. All Rights Reserved. Copyright (c) 2015-2017 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
...@@ -23,6 +23,7 @@ import ( ...@@ -23,6 +23,7 @@ import (
"net" "net"
"path" "path"
"github.com/vmware/govmomi/nfc"
"github.com/vmware/govmomi/property" "github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/vim25" "github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods" "github.com/vmware/govmomi/vim25/methods"
...@@ -464,6 +465,20 @@ func (v VirtualMachine) Answer(ctx context.Context, id, answer string) error { ...@@ -464,6 +465,20 @@ func (v VirtualMachine) Answer(ctx context.Context, id, answer string) error {
return nil return nil
} }
func (v VirtualMachine) AcquireTicket(ctx context.Context, kind string) (*types.VirtualMachineTicket, error) {
req := types.AcquireTicket{
This: v.Reference(),
TicketType: kind,
}
res, err := methods.AcquireTicket(ctx, v.c, &req)
if err != nil {
return nil, err
}
return &res.Returnval, nil
}
// CreateSnapshot creates a new snapshot of a virtual machine. // CreateSnapshot creates a new snapshot of a virtual machine.
func (v VirtualMachine) CreateSnapshot(ctx context.Context, name string, description string, memory bool, quiesce bool) (*Task, error) { func (v VirtualMachine) CreateSnapshot(ctx context.Context, name string, description string, memory bool, quiesce bool) (*Task, error) {
req := types.CreateSnapshot_Task{ req := types.CreateSnapshot_Task{
...@@ -497,7 +512,7 @@ func (v VirtualMachine) RemoveAllSnapshot(ctx context.Context, consolidate *bool ...@@ -497,7 +512,7 @@ func (v VirtualMachine) RemoveAllSnapshot(ctx context.Context, consolidate *bool
return NewTask(v.c, res.Returnval), nil return NewTask(v.c, res.Returnval), nil
} }
type snapshotMap map[string][]Reference type snapshotMap map[string][]types.ManagedObjectReference
func (m snapshotMap) add(parent string, tree []types.VirtualMachineSnapshotTree) { func (m snapshotMap) add(parent string, tree []types.VirtualMachineSnapshotTree) {
for i, st := range tree { for i, st := range tree {
...@@ -511,18 +526,18 @@ func (m snapshotMap) add(parent string, tree []types.VirtualMachineSnapshotTree) ...@@ -511,18 +526,18 @@ func (m snapshotMap) add(parent string, tree []types.VirtualMachineSnapshotTree)
} }
for _, name := range names { for _, name := range names {
m[name] = append(m[name], &tree[i].Snapshot) m[name] = append(m[name], tree[i].Snapshot)
} }
m.add(sname, st.ChildSnapshotList) m.add(sname, st.ChildSnapshotList)
} }
} }
// findSnapshot supports snapshot lookup by name, where name can be: // FindSnapshot supports snapshot lookup by name, where name can be:
// 1) snapshot ManagedObjectReference.Value (unique) // 1) snapshot ManagedObjectReference.Value (unique)
// 2) snapshot name (may not be unique) // 2) snapshot name (may not be unique)
// 3) snapshot tree path (may not be unique) // 3) snapshot tree path (may not be unique)
func (v VirtualMachine) findSnapshot(ctx context.Context, name string) (Reference, error) { func (v VirtualMachine) FindSnapshot(ctx context.Context, name string) (*types.ManagedObjectReference, error) {
var o mo.VirtualMachine var o mo.VirtualMachine
err := v.Properties(ctx, v.Reference(), []string{"snapshot"}, &o) err := v.Properties(ctx, v.Reference(), []string{"snapshot"}, &o)
...@@ -542,7 +557,7 @@ func (v VirtualMachine) findSnapshot(ctx context.Context, name string) (Referenc ...@@ -542,7 +557,7 @@ func (v VirtualMachine) findSnapshot(ctx context.Context, name string) (Referenc
case 0: case 0:
return nil, fmt.Errorf("snapshot %q not found", name) return nil, fmt.Errorf("snapshot %q not found", name)
case 1: case 1:
return s[0], nil return &s[0], nil
default: default:
return nil, fmt.Errorf("%q resolves to %d snapshots", name, len(s)) return nil, fmt.Errorf("%q resolves to %d snapshots", name, len(s))
} }
...@@ -550,7 +565,7 @@ func (v VirtualMachine) findSnapshot(ctx context.Context, name string) (Referenc ...@@ -550,7 +565,7 @@ func (v VirtualMachine) findSnapshot(ctx context.Context, name string) (Referenc
// RemoveSnapshot removes a named snapshot // RemoveSnapshot removes a named snapshot
func (v VirtualMachine) RemoveSnapshot(ctx context.Context, name string, removeChildren bool, consolidate *bool) (*Task, error) { func (v VirtualMachine) RemoveSnapshot(ctx context.Context, name string, removeChildren bool, consolidate *bool) (*Task, error) {
snapshot, err := v.findSnapshot(ctx, name) snapshot, err := v.FindSnapshot(ctx, name)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -586,7 +601,7 @@ func (v VirtualMachine) RevertToCurrentSnapshot(ctx context.Context, suppressPow ...@@ -586,7 +601,7 @@ func (v VirtualMachine) RevertToCurrentSnapshot(ctx context.Context, suppressPow
// RevertToSnapshot reverts to a named snapshot // RevertToSnapshot reverts to a named snapshot
func (v VirtualMachine) RevertToSnapshot(ctx context.Context, name string, suppressPowerOn bool) (*Task, error) { func (v VirtualMachine) RevertToSnapshot(ctx context.Context, name string, suppressPowerOn bool) (*Task, error) {
snapshot, err := v.findSnapshot(ctx, name) snapshot, err := v.FindSnapshot(ctx, name)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -757,3 +772,30 @@ func (v VirtualMachine) UpgradeTools(ctx context.Context, options string) (*Task ...@@ -757,3 +772,30 @@ func (v VirtualMachine) UpgradeTools(ctx context.Context, options string) (*Task
return NewTask(v.c, res.Returnval), nil return NewTask(v.c, res.Returnval), nil
} }
func (v VirtualMachine) Export(ctx context.Context) (*nfc.Lease, error) {
req := types.ExportVm{
This: v.Reference(),
}
res, err := methods.ExportVm(ctx, v.Client(), &req)
if err != nil {
return nil, err
}
return nfc.NewLease(v.c, res.Returnval), nil
}
func (v VirtualMachine) UpgradeVM(ctx context.Context, version string) (*Task, error) {
req := types.UpgradeVM_Task{
This: v.Reference(),
Version: version,
}
res, err := methods.UpgradeVM_Task(ctx, v.Client(), &req)
if err != nil {
return nil, err
}
return NewTask(v.c, res.Returnval), nil
}
...@@ -30,7 +30,7 @@ import ( ...@@ -30,7 +30,7 @@ import (
// Collector models the PropertyCollector managed object. // Collector models the PropertyCollector managed object.
// //
// For more information, see: // For more information, see:
// http://pubs.vmware.com/vsphere-55/index.jsp#com.vmware.wssdk.apiref.doc/vmodl.query.PropertyCollector.html // http://pubs.vmware.com/vsphere-60/index.jsp?topic=%2Fcom.vmware.wssdk.apiref.doc%2Fvmodl.query.PropertyCollector.html
// //
type Collector struct { type Collector struct {
roundTripper soap.RoundTripper roundTripper soap.RoundTripper
......
...@@ -18,7 +18,7 @@ package property ...@@ -18,7 +18,7 @@ package property
import ( import (
"fmt" "fmt"
"path/filepath" "path"
"reflect" "reflect"
"strconv" "strconv"
"strings" "strings"
...@@ -103,7 +103,11 @@ func (f Filter) MatchProperty(prop types.DynamicProperty) bool { ...@@ -103,7 +103,11 @@ func (f Filter) MatchProperty(prop types.DynamicProperty) bool {
switch pval := prop.Val.(type) { switch pval := prop.Val.(type) {
case string: case string:
m, _ := filepath.Match(match.(string), pval) s := match.(string)
if s == "*" {
return true // TODO: path.Match fails if s contains a '/'
}
m, _ := path.Match(s, pval)
return m return m
default: default:
return reflect.DeepEqual(match, pval) return reflect.DeepEqual(match, pval)
......
/* /*
Copyright (c) 2015 VMware, Inc. All Rights Reserved. Copyright (c) 2015-2017 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
...@@ -22,73 +22,63 @@ import ( ...@@ -22,73 +22,63 @@ import (
"github.com/vmware/govmomi/vim25/types" "github.com/vmware/govmomi/vim25/types"
) )
// Wait waits for any of the specified properties of the specified managed // WaitFilter provides helpers to construct a types.CreateFilter for use with property.Wait
// object to change. It calls the specified function for every update it type WaitFilter struct {
// receives. If this function returns false, it continues waiting for types.CreateFilter
// subsequent updates. If this function returns true, it stops waiting and }
// returns.
//
// To only receive updates for the specified managed object, the function
// creates a new property collector and calls CreateFilter. A new property
// collector is required because filters can only be added, not removed.
//
// The newly created collector is destroyed before this function returns (both
// in case of success or error).
//
func Wait(ctx context.Context, c *Collector, obj types.ManagedObjectReference, ps []string, f func([]types.PropertyChange) bool) error {
p, err := c.Create(ctx)
if err != nil {
return err
}
// Attempt to destroy the collector using the background context, as the // Add a new ObjectSpec and PropertySpec to the WaitFilter
// specified context may have timed out or have been cancelled. func (f *WaitFilter) Add(obj types.ManagedObjectReference, kind string, ps []string, set ...types.BaseSelectionSpec) *WaitFilter {
defer p.Destroy(context.Background()) spec := types.ObjectSpec{
Obj: obj,
SelectSet: set,
}
req := types.CreateFilter{ pset := types.PropertySpec{
Spec: types.PropertyFilterSpec{ Type: kind,
ObjectSet: []types.ObjectSpec{ PathSet: ps,
{
Obj: obj,
},
},
PropSet: []types.PropertySpec{
{
PathSet: ps,
Type: obj.Type,
},
},
},
} }
if len(ps) == 0 { if len(ps) == 0 {
req.Spec.PropSet[0].All = types.NewBool(true) pset.All = types.NewBool(true)
} }
err = p.CreateFilter(ctx, req) f.Spec.ObjectSet = append(f.Spec.ObjectSet, spec)
if err != nil {
return err f.Spec.PropSet = append(f.Spec.PropSet, pset)
}
return waitLoop(ctx, p, func(_ types.ManagedObjectReference, pc []types.PropertyChange) bool { return f
return f(pc) }
// Wait creates a new WaitFilter and calls the specified function for each ObjectUpdate via WaitForUpdates
func Wait(ctx context.Context, c *Collector, obj types.ManagedObjectReference, ps []string, f func([]types.PropertyChange) bool) error {
filter := new(WaitFilter).Add(obj, obj.Type, ps)
return WaitForUpdates(ctx, c, filter, func(updates []types.ObjectUpdate) bool {
for _, update := range updates {
if f(update.ChangeSet) {
return true
}
}
return false
}) })
} }
// WaitForView waits for any of the specified properties of the managed // WaitForUpdates waits for any of the specified properties of the specified managed
// objects in the View to change. It calls the specified function for every update it // object to change. It calls the specified function for every update it
// receives. If this function returns false, it continues waiting for // receives. If this function returns false, it continues waiting for
// subsequent updates. If this function returns true, it stops waiting and // subsequent updates. If this function returns true, it stops waiting and
// returns. // returns.
// //
// To only receive updates for the View's specified managed objects, the function // To only receive updates for the specified managed object, the function
// creates a new property collector and calls CreateFilter. A new property // creates a new property collector and calls CreateFilter. A new property
// collector is required because filters can only be added, not removed. // collector is required because filters can only be added, not removed.
// //
// The newly created collector is destroyed before this function returns (both // The newly created collector is destroyed before this function returns (both
// in case of success or error). // in case of success or error).
// //
// The code assumes that all objects in the View are the same type func WaitForUpdates(ctx context.Context, c *Collector, filter *WaitFilter, f func([]types.ObjectUpdate) bool) error {
func WaitForView(ctx context.Context, c *Collector, view types.ManagedObjectReference, obj types.ManagedObjectReference, ps []string, f func(types.ManagedObjectReference, []types.PropertyChange) bool) error {
p, err := c.Create(ctx) p, err := c.Create(ctx)
if err != nil { if err != nil {
return err return err
...@@ -98,38 +88,13 @@ func WaitForView(ctx context.Context, c *Collector, view types.ManagedObjectRefe ...@@ -98,38 +88,13 @@ func WaitForView(ctx context.Context, c *Collector, view types.ManagedObjectRefe
// specified context may have timed out or have been cancelled. // specified context may have timed out or have been cancelled.
defer p.Destroy(context.Background()) defer p.Destroy(context.Background())
req := types.CreateFilter{ err = p.CreateFilter(ctx, filter.CreateFilter)
Spec: types.PropertyFilterSpec{
ObjectSet: []types.ObjectSpec{
{
Obj: view,
SelectSet: []types.BaseSelectionSpec{
&types.TraversalSpec{
SelectionSpec: types.SelectionSpec{
Name: "traverseEntities",
},
Path: "view",
Type: view.Type}},
},
},
PropSet: []types.PropertySpec{
{
Type: obj.Type,
PathSet: ps,
},
},
}}
err = p.CreateFilter(ctx, req)
if err != nil { if err != nil {
return err return err
} }
return waitLoop(ctx, p, f)
}
func waitLoop(ctx context.Context, c *Collector, f func(types.ManagedObjectReference, []types.PropertyChange) bool) error {
for version := ""; ; { for version := ""; ; {
res, err := c.WaitForUpdates(ctx, version) res, err := p.WaitForUpdates(ctx, version)
if err != nil { if err != nil {
return err return err
} }
...@@ -142,12 +107,9 @@ func waitLoop(ctx context.Context, c *Collector, f func(types.ManagedObjectRefer ...@@ -142,12 +107,9 @@ func waitLoop(ctx context.Context, c *Collector, f func(types.ManagedObjectRefer
version = res.Version version = res.Version
for _, fs := range res.FilterSet { for _, fs := range res.FilterSet {
for _, os := range fs.ObjectSet { if f(fs.ObjectSet) {
if f(os.Obj, os.ChangeSet) { return nil
return nil
}
} }
} }
} }
} }
...@@ -199,3 +199,31 @@ func (sm *Manager) AcquireLocalTicket(ctx context.Context, userName string) (*ty ...@@ -199,3 +199,31 @@ func (sm *Manager) AcquireLocalTicket(ctx context.Context, userName string) (*ty
return &res.Returnval, nil return &res.Returnval, nil
} }
func (sm *Manager) AcquireCloneTicket(ctx context.Context) (string, error) {
req := types.AcquireCloneTicket{
This: sm.Reference(),
}
res, err := methods.AcquireCloneTicket(ctx, sm.client, &req)
if err != nil {
return "", err
}
return res.Returnval, nil
}
func (sm *Manager) CloneSession(ctx context.Context, ticket string) error {
req := types.CloneSession{
This: sm.Reference(),
CloneTicket: ticket,
}
res, err := methods.CloneSession(ctx, sm.client, &req)
if err != nil {
return err
}
sm.userSession = &res.Returnval
return nil
}
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"authorization_manager.go",
"cluster_compute_resource.go",
"custom_fields_manager.go",
"datacenter.go",
"datastore.go",
"doc.go",
"dvs.go",
"entity.go",
"file_manager.go",
"folder.go",
"guest_id.go",
"host_datastore_browser.go",
"host_datastore_system.go",
"host_firewall_system.go",
"host_network_system.go",
"host_system.go",
"ip_pool_manager.go",
"license_manager.go",
"model.go",
"option_manager.go",
"os_unix.go",
"performance_manager.go",
"portgroup.go",
"property_collector.go",
"property_filter.go",
"registry.go",
"resource_pool.go",
"search_index.go",
"service_instance.go",
"session_manager.go",
"simulator.go",
"snapshot.go",
"task.go",
"task_manager.go",
"user_directory.go",
"view_manager.go",
"virtual_disk_manager.go",
"virtual_machine.go",
] + select({
"@io_bazel_rules_go//go/platform:windows": [
"os_windows.go",
],
"//conditions:default": [],
}),
importpath = "github.com/vmware/govmomi/simulator",
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/google/uuid:go_default_library",
"//vendor/github.com/vmware/govmomi/find:go_default_library",
"//vendor/github.com/vmware/govmomi/object:go_default_library",
"//vendor/github.com/vmware/govmomi/session:go_default_library",
"//vendor/github.com/vmware/govmomi/simulator/esx:go_default_library",
"//vendor/github.com/vmware/govmomi/simulator/vpx:go_default_library",
"//vendor/github.com/vmware/govmomi/vim25:go_default_library",
"//vendor/github.com/vmware/govmomi/vim25/methods:go_default_library",
"//vendor/github.com/vmware/govmomi/vim25/mo:go_default_library",
"//vendor/github.com/vmware/govmomi/vim25/soap:go_default_library",
"//vendor/github.com/vmware/govmomi/vim25/types:go_default_library",
"//vendor/github.com/vmware/govmomi/vim25/xml:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//vendor/github.com/vmware/govmomi/simulator/esx:all-srcs",
"//vendor/github.com/vmware/govmomi/simulator/vpx:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
/*
Copyright (c) 2017 VMware, Inc. All 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 simulator
import (
"strings"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/simulator/esx"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
type AuthorizationManager struct {
mo.AuthorizationManager
permissions map[types.ManagedObjectReference][]types.Permission
privileges map[string]struct{}
system []string
nextID int32
}
func NewAuthorizationManager(ref types.ManagedObjectReference) object.Reference {
m := &AuthorizationManager{}
m.Self = ref
m.RoleList = esx.RoleList
m.permissions = make(map[types.ManagedObjectReference][]types.Permission)
l := object.AuthorizationRoleList(m.RoleList)
m.system = l.ByName("ReadOnly").Privilege
admin := l.ByName("Admin")
m.privileges = make(map[string]struct{}, len(admin.Privilege))
for _, id := range admin.Privilege {
m.privileges[id] = struct{}{}
}
root := Map.content().RootFolder
for _, u := range DefaultUserGroup {
m.permissions[root] = append(m.permissions[root], types.Permission{
Entity: &root,
Principal: u.Principal,
Group: u.Group,
RoleId: admin.RoleId,
Propagate: true,
})
}
return m
}
func (m *AuthorizationManager) RetrieveEntityPermissions(req *types.RetrieveEntityPermissions) soap.HasFault {
e := Map.Get(req.Entity).(mo.Entity)
p := m.permissions[e.Reference()]
if req.Inherited {
for {
parent := e.Entity().Parent
if parent == nil {
break
}
e = Map.Get(parent.Reference()).(mo.Entity)
p = append(p, m.permissions[e.Reference()]...)
}
}
return &methods.RetrieveEntityPermissionsBody{
Res: &types.RetrieveEntityPermissionsResponse{
Returnval: p,
},
}
}
func (m *AuthorizationManager) RetrieveAllPermissions(req *types.RetrieveAllPermissions) soap.HasFault {
var p []types.Permission
for _, v := range m.permissions {
p = append(p, v...)
}
return &methods.RetrieveAllPermissionsBody{
Res: &types.RetrieveAllPermissionsResponse{
Returnval: p,
},
}
}
func (m *AuthorizationManager) RemoveEntityPermission(req *types.RemoveEntityPermission) soap.HasFault {
var p []types.Permission
for _, v := range m.permissions[req.Entity] {
if v.Group == req.IsGroup && v.Principal == req.User {
continue
}
p = append(p, v)
}
m.permissions[req.Entity] = p
return &methods.RemoveEntityPermissionBody{
Res: &types.RemoveEntityPermissionResponse{},
}
}
func (m *AuthorizationManager) SetEntityPermissions(req *types.SetEntityPermissions) soap.HasFault {
m.permissions[req.Entity] = req.Permission
return &methods.SetEntityPermissionsBody{
Res: &types.SetEntityPermissionsResponse{},
}
}
func (m *AuthorizationManager) RetrieveRolePermissions(req *types.RetrieveRolePermissions) soap.HasFault {
var p []types.Permission
for _, set := range m.permissions {
for _, v := range set {
if v.RoleId == req.RoleId {
p = append(p, v)
}
}
}
return &methods.RetrieveRolePermissionsBody{
Res: &types.RetrieveRolePermissionsResponse{
Returnval: p,
},
}
}
func (m *AuthorizationManager) AddAuthorizationRole(req *types.AddAuthorizationRole) soap.HasFault {
body := &methods.AddAuthorizationRoleBody{}
for _, role := range m.RoleList {
if role.Name == req.Name {
body.Fault_ = Fault("", &types.AlreadyExists{})
return body
}
}
ids, err := m.privIDs(req.PrivIds)
if err != nil {
body.Fault_ = err
return body
}
m.RoleList = append(m.RoleList, types.AuthorizationRole{
Info: &types.Description{
Label: req.Name,
Summary: req.Name,
},
RoleId: m.nextID,
Privilege: ids,
Name: req.Name,
System: false,
})
m.nextID++
body.Res = &types.AddAuthorizationRoleResponse{}
return body
}
func (m *AuthorizationManager) UpdateAuthorizationRole(req *types.UpdateAuthorizationRole) soap.HasFault {
body := &methods.UpdateAuthorizationRoleBody{}
for _, role := range m.RoleList {
if role.Name == req.NewName && role.RoleId != req.RoleId {
body.Fault_ = Fault("", &types.AlreadyExists{})
return body
}
}
for i, role := range m.RoleList {
if role.RoleId == req.RoleId {
if len(req.PrivIds) != 0 {
ids, err := m.privIDs(req.PrivIds)
if err != nil {
body.Fault_ = err
return body
}
m.RoleList[i].Privilege = ids
}
m.RoleList[i].Name = req.NewName
body.Res = &types.UpdateAuthorizationRoleResponse{}
return body
}
}
body.Fault_ = Fault("", &types.NotFound{})
return body
}
func (m *AuthorizationManager) RemoveAuthorizationRole(req *types.RemoveAuthorizationRole) soap.HasFault {
body := &methods.RemoveAuthorizationRoleBody{}
for i, role := range m.RoleList {
if role.RoleId == req.RoleId {
m.RoleList = append(m.RoleList[:i], m.RoleList[i+1:]...)
body.Res = &types.RemoveAuthorizationRoleResponse{}
return body
}
}
body.Fault_ = Fault("", &types.NotFound{})
return body
}
func (m *AuthorizationManager) privIDs(ids []string) ([]string, *soap.Fault) {
system := make(map[string]struct{}, len(m.system))
for _, id := range ids {
if _, ok := m.privileges[id]; !ok {
return nil, Fault("", &types.InvalidArgument{InvalidProperty: "privIds"})
}
if strings.HasPrefix(id, "System.") {
system[id] = struct{}{}
}
}
for _, id := range m.system {
if _, ok := system[id]; ok {
continue
}
ids = append(ids, id)
}
return ids, nil
}
/*
Copyright (c) 2017 VMware, Inc. All 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 simulator
import (
"github.com/vmware/govmomi/simulator/esx"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
type ClusterComputeResource struct {
mo.ClusterComputeResource
}
type addHost struct {
*ClusterComputeResource
req *types.AddHost_Task
}
func (add *addHost) Run(task *Task) (types.AnyType, types.BaseMethodFault) {
spec := add.req.Spec
if spec.HostName == "" {
return nil, &types.NoHost{}
}
host := NewHostSystem(esx.HostSystem)
host.Summary.Config.Name = spec.HostName
host.Name = host.Summary.Config.Name
host.Runtime.ConnectionState = types.HostSystemConnectionStateDisconnected
cr := add.ClusterComputeResource
Map.PutEntity(cr, Map.NewEntity(host))
cr.Host = append(cr.Host, host.Reference())
if add.req.AsConnected {
host.Runtime.ConnectionState = types.HostSystemConnectionStateConnected
}
addComputeResource(add.ClusterComputeResource.Summary.GetComputeResourceSummary(), host)
return host.Reference(), nil
}
func (c *ClusterComputeResource) AddHostTask(add *types.AddHost_Task) soap.HasFault {
return &methods.AddHost_TaskBody{
Res: &types.AddHost_TaskResponse{
Returnval: NewTask(&addHost{c, add}).Run(),
},
}
}
func CreateClusterComputeResource(f *Folder, name string, spec types.ClusterConfigSpecEx) (*ClusterComputeResource, types.BaseMethodFault) {
if e := Map.FindByName(name, f.ChildEntity); e != nil {
return nil, &types.DuplicateName{
Name: e.Entity().Name,
Object: e.Reference(),
}
}
cluster := &ClusterComputeResource{}
cluster.Name = name
cluster.Summary = &types.ClusterComputeResourceSummary{
UsageSummary: new(types.ClusterUsageSummary),
}
config := &types.ClusterConfigInfoEx{}
cluster.ConfigurationEx = config
config.DrsConfig.Enabled = types.NewBool(true)
pool := NewResourcePool()
Map.PutEntity(cluster, Map.NewEntity(pool))
cluster.ResourcePool = &pool.Self
f.putChild(cluster)
pool.Owner = cluster.Self
return cluster, nil
}
/*
Copyright (c) 2017 VMware, Inc. All 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 simulator
import (
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
type CustomFieldsManager struct {
mo.CustomFieldsManager
nextKey int32
}
func NewCustomFieldsManager(ref types.ManagedObjectReference) object.Reference {
m := &CustomFieldsManager{}
m.Self = ref
return m
}
func (c *CustomFieldsManager) find(key int32) (int, *types.CustomFieldDef) {
for i, field := range c.Field {
if field.Key == key {
return i, &c.Field[i]
}
}
return -1, nil
}
func (c *CustomFieldsManager) AddCustomFieldDef(req *types.AddCustomFieldDef) soap.HasFault {
body := &methods.AddCustomFieldDefBody{}
def := types.CustomFieldDef{
Key: c.nextKey,
Name: req.Name,
ManagedObjectType: req.MoType,
Type: req.MoType,
FieldDefPrivileges: req.FieldDefPolicy,
FieldInstancePrivileges: req.FieldPolicy,
}
c.Field = append(c.Field, def)
c.nextKey++
body.Res = &types.AddCustomFieldDefResponse{
Returnval: def,
}
return body
}
func (c *CustomFieldsManager) RemoveCustomFieldDef(req *types.RemoveCustomFieldDef) soap.HasFault {
body := &methods.RemoveCustomFieldDefBody{}
i, field := c.find(req.Key)
if field == nil {
body.Fault_ = Fault("", &types.NotFound{})
return body
}
c.Field = append(c.Field[:i], c.Field[i+1:]...)
body.Res = &types.RemoveCustomFieldDefResponse{}
return body
}
func (c *CustomFieldsManager) RenameCustomFieldDef(req *types.RenameCustomFieldDef) soap.HasFault {
body := &methods.RenameCustomFieldDefBody{}
_, field := c.find(req.Key)
if field == nil {
body.Fault_ = Fault("", &types.NotFound{})
return body
}
field.Name = req.Name
body.Res = &types.RenameCustomFieldDefResponse{}
return body
}
func (c *CustomFieldsManager) SetField(req *types.SetField) soap.HasFault {
body := &methods.SetFieldBody{}
entity := Map.Get(req.Entity).(mo.Entity).Entity()
entity.CustomValue = append(entity.CustomValue, &types.CustomFieldStringValue{
CustomFieldValue: types.CustomFieldValue{Key: req.Key},
Value: req.Value,
})
body.Res = &types.SetFieldResponse{}
return body
}
/*
Copyright (c) 2017 VMware, Inc. All 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 simulator
import (
"strings"
"github.com/vmware/govmomi/simulator/esx"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
)
// Create Datacenter Folders.
// Every Datacenter has 4 inventory Folders: Vm, Host, Datastore and Network.
// The ESX folder child types are limited to 1 type.
// The VC folders have additional child types, including nested folders.
func createDatacenterFolders(dc *mo.Datacenter, isVC bool) {
folders := []struct {
ref *types.ManagedObjectReference
name string
types []string
}{
{&dc.VmFolder, "vm", []string{"VirtualMachine", "VirtualApp", "Folder"}},
{&dc.HostFolder, "host", []string{"ComputeResource", "Folder"}},
{&dc.DatastoreFolder, "datastore", []string{"Datastore", "StoragePod", "Folder"}},
{&dc.NetworkFolder, "network", []string{"Network", "DistributedVirtualSwitch", "Folder"}},
}
for _, f := range folders {
folder := &Folder{}
folder.Name = f.name
if isVC {
folder.ChildType = f.types
e := Map.PutEntity(dc, folder)
// propagate the generated morefs to Datacenter
ref := e.Reference()
f.ref.Type = ref.Type
f.ref.Value = ref.Value
} else {
folder.ChildType = f.types[:1]
folder.Self = *f.ref
Map.PutEntity(dc, folder)
}
}
net := Map.Get(dc.NetworkFolder).(*Folder)
for _, ref := range esx.Datacenter.Network {
// Add VM Network by default to each Datacenter
network := &mo.Network{}
network.Self = ref
network.Name = strings.Split(ref.Value, "-")[1]
network.Entity().Name = network.Name
if isVC {
network.Self.Value = "" // we want a different moid per-DC
}
net.putChild(network)
}
}
/*
Copyright (c) 2017 VMware, Inc. All 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 simulator
import (
"time"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
type Datastore struct {
mo.Datastore
}
func parseDatastorePath(dsPath string) (*object.DatastorePath, types.BaseMethodFault) {
var p object.DatastorePath
if p.FromString(dsPath) {
return &p, nil
}
return nil, &types.InvalidDatastorePath{DatastorePath: dsPath}
}
func (ds *Datastore) RefreshDatastore(*types.RefreshDatastore) soap.HasFault {
r := &methods.RefreshDatastoreBody{}
err := ds.stat()
if err != nil {
r.Fault_ = Fault(err.Error(), &types.HostConfigFault{})
return r
}
info := ds.Info.GetDatastoreInfo()
now := time.Now()
info.Timestamp = &now
return r
}
/*
Copyright (c) 2017 VMware, Inc. All 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 simulator is a mock framework for the vSphere API.
See also: https://github.com/vmware/govmomi/blob/master/vcsim/README.md
*/
package simulator
/*
Copyright (c) 2017 VMware, Inc. All 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 simulator
import (
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
type DistributedVirtualSwitch struct {
mo.DistributedVirtualSwitch
}
func (s *DistributedVirtualSwitch) AddDVPortgroupTask(c *types.AddDVPortgroup_Task) soap.HasFault {
task := CreateTask(s, "addDVPortgroup", func(t *Task) (types.AnyType, types.BaseMethodFault) {
f := Map.getEntityParent(s, "Folder").(*Folder)
for _, spec := range c.Spec {
pg := &DistributedVirtualPortgroup{}
pg.Name = spec.Name
pg.Entity().Name = pg.Name
if obj := Map.FindByName(pg.Name, f.ChildEntity); obj != nil {
return nil, &types.DuplicateName{
Name: pg.Name,
Object: obj.Reference(),
}
}
f.putChild(pg)
pg.Key = pg.Self.Value
pg.Config = types.DVPortgroupConfigInfo{
Key: pg.Key,
Name: pg.Name,
NumPorts: spec.NumPorts,
DistributedVirtualSwitch: &s.Self,
DefaultPortConfig: spec.DefaultPortConfig,
Description: spec.Description,
Type: spec.Type,
Policy: spec.Policy,
PortNameFormat: spec.PortNameFormat,
Scope: spec.Scope,
VendorSpecificConfig: spec.VendorSpecificConfig,
ConfigVersion: spec.ConfigVersion,
AutoExpand: spec.AutoExpand,
VmVnicNetworkResourcePoolKey: spec.VmVnicNetworkResourcePoolKey,
}
s.Portgroup = append(s.Portgroup, pg.Self)
s.Summary.PortgroupName = append(s.Summary.PortgroupName, pg.Name)
for _, h := range s.Summary.HostMember {
pg.Host = AddReference(h, pg.Host)
host := Map.Get(h).(*HostSystem)
host.Network = append(host.Network, pg.Reference())
}
}
return nil, nil
})
return &methods.AddDVPortgroup_TaskBody{
Res: &types.AddDVPortgroup_TaskResponse{
Returnval: task.Run(),
},
}
}
func (s *DistributedVirtualSwitch) ReconfigureDvsTask(req *types.ReconfigureDvs_Task) soap.HasFault {
task := CreateTask(s, "reconfigureDvs", func(t *Task) (types.AnyType, types.BaseMethodFault) {
spec := req.Spec.GetDVSConfigSpec()
for _, member := range spec.Host {
h := Map.Get(member.Host)
if h == nil {
return nil, &types.ManagedObjectNotFound{Obj: member.Host}
}
host := h.(*HostSystem)
switch types.ConfigSpecOperation(member.Operation) {
case types.ConfigSpecOperationAdd:
if FindReference(host.Network, s.Self) != nil {
return nil, &types.AlreadyExists{Name: host.Name}
}
host.Network = append(host.Network, s.Self)
host.Network = append(host.Network, s.Portgroup...)
s.Summary.HostMember = append(s.Summary.HostMember, member.Host)
for _, ref := range s.Portgroup {
pg := Map.Get(ref).(*DistributedVirtualPortgroup)
pg.Host = AddReference(member.Host, pg.Host)
}
case types.ConfigSpecOperationRemove:
if pg := FindReference(host.Network, s.Portgroup...); pg != nil {
return nil, &types.ResourceInUse{
Type: pg.Type,
Name: pg.Value,
}
}
host.Network = RemoveReference(s.Self, host.Network)
s.Summary.HostMember = RemoveReference(s.Self, s.Summary.HostMember)
case types.ConfigSpecOperationEdit:
return nil, &types.NotSupported{}
}
}
return nil, nil
})
return &methods.ReconfigureDvs_TaskBody{
Res: &types.ReconfigureDvs_TaskResponse{
Returnval: task.Run(),
},
}
}
func (s *DistributedVirtualSwitch) FetchDVPorts(req *types.FetchDVPorts) soap.HasFault {
body := &methods.FetchDVPortsBody{}
body.Res = &types.FetchDVPortsResponse{
Returnval: s.dvPortgroups(req.Criteria),
}
return body
}
func (s *DistributedVirtualSwitch) DestroyTask(req *types.Destroy_Task) soap.HasFault {
task := CreateTask(s, "destroy", func(t *Task) (types.AnyType, types.BaseMethodFault) {
f := Map.getEntityParent(s, "Folder").(*Folder)
f.removeChild(s.Reference())
return nil, nil
})
return &methods.Destroy_TaskBody{
Res: &types.Destroy_TaskResponse{
Returnval: task.Run(),
},
}
}
func (s *DistributedVirtualSwitch) dvPortgroups(_ *types.DistributedVirtualSwitchPortCriteria) []types.DistributedVirtualPort {
// TODO(agui): Filter is not implemented yet
var res []types.DistributedVirtualPort
for _, ref := range s.Portgroup {
pg := Map.Get(ref).(*DistributedVirtualPortgroup)
res = append(res, types.DistributedVirtualPort{
DvsUuid: s.Uuid,
Key: pg.Key,
Config: types.DVPortConfigInfo{
Setting: pg.Config.DefaultPortConfig,
},
})
if pg.PortKeys == nil {
continue
}
for _, key := range pg.PortKeys {
res = append(res, types.DistributedVirtualPort{
DvsUuid: s.Uuid,
Key: key,
Config: types.DVPortConfigInfo{
Setting: pg.Config.DefaultPortConfig,
},
})
}
}
return res
}
/*
Copyright (c) 2017 VMware, Inc. All 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 simulator
import (
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
func RenameTask(e mo.Entity, r *types.Rename_Task) soap.HasFault {
task := CreateTask(e, "rename", func(t *Task) (types.AnyType, types.BaseMethodFault) {
obj := Map.Get(r.This).(mo.Entity).Entity()
if parent, ok := Map.Get(*obj.Parent).(*Folder); ok {
if Map.FindByName(r.NewName, parent.ChildEntity) != nil {
return nil, &types.InvalidArgument{InvalidProperty: "name"}
}
}
obj.Name = r.NewName
return nil, nil
})
return &methods.Rename_TaskBody{
Res: &types.Rename_TaskResponse{
Returnval: task.Run(),
},
}
}
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"authorization_manager.go",
"datacenter.go",
"doc.go",
"host_config_info.go",
"host_firewall_system.go",
"host_hardware_info.go",
"host_storage_device_info.go",
"host_system.go",
"performance_manager.go",
"resource_pool.go",
"root_folder.go",
"service_content.go",
"setting.go",
"virtual_device.go",
],
importpath = "github.com/vmware/govmomi/simulator/esx",
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/vmware/govmomi/vim25/mo:go_default_library",
"//vendor/github.com/vmware/govmomi/vim25/types:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
/*
Copyright (c) 2017 VMware, Inc. All 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 esx
import (
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
)
// Datacenter is the default template for Datacenter properties.
// Capture method:
// govc datacenter.info -dump
var Datacenter = mo.Datacenter{
ManagedEntity: mo.ManagedEntity{
ExtensibleManagedObject: mo.ExtensibleManagedObject{
Self: types.ManagedObjectReference{Type: "Datacenter", Value: "ha-datacenter"},
Value: nil,
AvailableField: nil,
},
Parent: (*types.ManagedObjectReference)(nil),
CustomValue: nil,
OverallStatus: "",
ConfigStatus: "",
ConfigIssue: nil,
EffectiveRole: nil,
Permission: nil,
Name: "ha-datacenter",
DisabledMethod: nil,
RecentTask: nil,
DeclaredAlarmState: nil,
TriggeredAlarmState: nil,
AlarmActionsEnabled: (*bool)(nil),
Tag: nil,
},
VmFolder: types.ManagedObjectReference{Type: "Folder", Value: "ha-folder-vm"},
HostFolder: types.ManagedObjectReference{Type: "Folder", Value: "ha-folder-host"},
DatastoreFolder: types.ManagedObjectReference{Type: "Folder", Value: "ha-folder-datastore"},
NetworkFolder: types.ManagedObjectReference{Type: "Folder", Value: "ha-folder-network"},
Datastore: []types.ManagedObjectReference{
{Type: "Datastore", Value: "57089c25-85e3ccd4-17b6-000c29d0beb3"},
},
Network: []types.ManagedObjectReference{
{Type: "Network", Value: "HaNetwork-VM Network"},
},
Configuration: types.DatacenterConfigInfo{},
}
/*
Copyright (c) 2017 VMware, Inc. All 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 esx contains SOAP responses from an ESX server, captured using `govc ... -dump`.
*/
package esx
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
Copyright (c) 2017 VMware, Inc. All 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 esx
import (
"time"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
)
// ResourcePool is the default template for ResourcePool properties.
// Capture method:
// govc pool.info "*" -dump
var ResourcePool = mo.ResourcePool{
ManagedEntity: mo.ManagedEntity{
ExtensibleManagedObject: mo.ExtensibleManagedObject{
Self: types.ManagedObjectReference{Type: "ResourcePool", Value: "ha-root-pool"},
Value: nil,
AvailableField: nil,
},
Parent: &types.ManagedObjectReference{Type: "ComputeResource", Value: "ha-compute-res"},
CustomValue: nil,
OverallStatus: "green",
ConfigStatus: "green",
ConfigIssue: nil,
EffectiveRole: []int32{-1},
Permission: nil,
Name: "Resources",
DisabledMethod: []string{"CreateVApp", "CreateChildVM_Task"},
RecentTask: nil,
DeclaredAlarmState: nil,
TriggeredAlarmState: nil,
AlarmActionsEnabled: (*bool)(nil),
Tag: nil,
},
Summary: &types.ResourcePoolSummary{
DynamicData: types.DynamicData{},
Name: "Resources",
Config: types.ResourceConfigSpec{
DynamicData: types.DynamicData{},
Entity: &types.ManagedObjectReference{Type: "ResourcePool", Value: "ha-root-pool"},
ChangeVersion: "",
LastModified: (*time.Time)(nil),
CpuAllocation: types.ResourceAllocationInfo{
DynamicData: types.DynamicData{},
Reservation: types.NewInt64(4121),
ExpandableReservation: types.NewBool(false),
Limit: types.NewInt64(4121),
Shares: &types.SharesInfo{
DynamicData: types.DynamicData{},
Shares: 9000,
Level: "custom",
},
OverheadLimit: nil,
},
MemoryAllocation: types.ResourceAllocationInfo{
DynamicData: types.DynamicData{},
Reservation: types.NewInt64(961),
ExpandableReservation: types.NewBool(false),
Limit: types.NewInt64(961),
Shares: &types.SharesInfo{
DynamicData: types.DynamicData{},
Shares: 9000,
Level: "custom",
},
OverheadLimit: nil,
},
},
Runtime: types.ResourcePoolRuntimeInfo{
DynamicData: types.DynamicData{},
Memory: types.ResourcePoolResourceUsage{
DynamicData: types.DynamicData{},
ReservationUsed: 0,
ReservationUsedForVm: 0,
UnreservedForPool: 1007681536,
UnreservedForVm: 1007681536,
OverallUsage: 0,
MaxUsage: 1007681536,
},
Cpu: types.ResourcePoolResourceUsage{
DynamicData: types.DynamicData{},
ReservationUsed: 0,
ReservationUsedForVm: 0,
UnreservedForPool: 4121,
UnreservedForVm: 4121,
OverallUsage: 0,
MaxUsage: 4121,
},
OverallStatus: "green",
},
QuickStats: (*types.ResourcePoolQuickStats)(nil),
ConfiguredMemoryMB: 0,
},
Runtime: types.ResourcePoolRuntimeInfo{
DynamicData: types.DynamicData{},
Memory: types.ResourcePoolResourceUsage{
DynamicData: types.DynamicData{},
ReservationUsed: 0,
ReservationUsedForVm: 0,
UnreservedForPool: 1007681536,
UnreservedForVm: 1007681536,
OverallUsage: 0,
MaxUsage: 1007681536,
},
Cpu: types.ResourcePoolResourceUsage{
DynamicData: types.DynamicData{},
ReservationUsed: 0,
ReservationUsedForVm: 0,
UnreservedForPool: 4121,
UnreservedForVm: 4121,
OverallUsage: 0,
MaxUsage: 4121,
},
OverallStatus: "green",
},
Owner: types.ManagedObjectReference{Type: "ComputeResource", Value: "ha-compute-res"},
ResourcePool: nil,
Vm: nil,
Config: types.ResourceConfigSpec{
DynamicData: types.DynamicData{},
Entity: &types.ManagedObjectReference{Type: "ResourcePool", Value: "ha-root-pool"},
ChangeVersion: "",
LastModified: (*time.Time)(nil),
CpuAllocation: types.ResourceAllocationInfo{
DynamicData: types.DynamicData{},
Reservation: types.NewInt64(4121),
ExpandableReservation: types.NewBool(false),
Limit: types.NewInt64(4121),
Shares: &types.SharesInfo{
DynamicData: types.DynamicData{},
Shares: 9000,
Level: "custom",
},
OverheadLimit: nil,
},
MemoryAllocation: types.ResourceAllocationInfo{
DynamicData: types.DynamicData{},
Reservation: types.NewInt64(961),
ExpandableReservation: types.NewBool(false),
Limit: types.NewInt64(961),
Shares: &types.SharesInfo{
DynamicData: types.DynamicData{},
Shares: 9000,
Level: "custom",
},
OverheadLimit: nil,
},
},
ChildConfiguration: nil,
}
/*
Copyright (c) 2017 VMware, Inc. All 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 esx
import (
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
)
// RootFolder is the default template for the ServiceContent rootFolder property.
// Capture method:
// govc folder.info -dump /
var RootFolder = mo.Folder{
ManagedEntity: mo.ManagedEntity{
ExtensibleManagedObject: mo.ExtensibleManagedObject{
Self: types.ManagedObjectReference{Type: "Folder", Value: "ha-folder-root"},
Value: nil,
AvailableField: nil,
},
Parent: (*types.ManagedObjectReference)(nil),
CustomValue: nil,
OverallStatus: "green",
ConfigStatus: "green",
ConfigIssue: nil,
EffectiveRole: []int32{-1},
Permission: []types.Permission{
{
DynamicData: types.DynamicData{},
Entity: &types.ManagedObjectReference{Type: "Folder", Value: "ha-folder-root"},
Principal: "vpxuser",
Group: false,
RoleId: -1,
Propagate: true,
},
{
DynamicData: types.DynamicData{},
Entity: &types.ManagedObjectReference{Type: "Folder", Value: "ha-folder-root"},
Principal: "dcui",
Group: false,
RoleId: -1,
Propagate: true,
},
{
DynamicData: types.DynamicData{},
Entity: &types.ManagedObjectReference{Type: "Folder", Value: "ha-folder-root"},
Principal: "root",
Group: false,
RoleId: -1,
Propagate: true,
},
},
Name: "ha-folder-root",
DisabledMethod: nil,
RecentTask: nil,
DeclaredAlarmState: nil,
TriggeredAlarmState: nil,
AlarmActionsEnabled: (*bool)(nil),
Tag: nil,
},
ChildType: []string{"Datacenter"},
ChildEntity: nil,
}
/*
Copyright (c) 2017 VMware, Inc. All 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 esx
import "github.com/vmware/govmomi/vim25/types"
// ServiceContent is the default template for the ServiceInstance content property.
// Capture method:
// govc object.collect -s -dump - content
var ServiceContent = types.ServiceContent{
RootFolder: types.ManagedObjectReference{Type: "Folder", Value: "ha-folder-root"},
PropertyCollector: types.ManagedObjectReference{Type: "PropertyCollector", Value: "ha-property-collector"},
ViewManager: &types.ManagedObjectReference{Type: "ViewManager", Value: "ViewManager"},
About: types.AboutInfo{
Name: "VMware ESXi",
FullName: "VMware ESXi 6.5.0 build-5969303",
Vendor: "VMware, Inc.",
Version: "6.5.0",
Build: "5969303",
LocaleVersion: "INTL",
LocaleBuild: "000",
OsType: "vmnix-x86",
ProductLineId: "embeddedEsx",
ApiType: "HostAgent",
ApiVersion: "6.5",
InstanceUuid: "",
LicenseProductName: "VMware ESX Server",
LicenseProductVersion: "6.0",
},
Setting: &types.ManagedObjectReference{Type: "OptionManager", Value: "HostAgentSettings"},
UserDirectory: &types.ManagedObjectReference{Type: "UserDirectory", Value: "ha-user-directory"},
SessionManager: &types.ManagedObjectReference{Type: "SessionManager", Value: "ha-sessionmgr"},
AuthorizationManager: &types.ManagedObjectReference{Type: "AuthorizationManager", Value: "ha-authmgr"},
ServiceManager: &types.ManagedObjectReference{Type: "ServiceManager", Value: "ha-servicemanager"},
PerfManager: &types.ManagedObjectReference{Type: "PerformanceManager", Value: "ha-perfmgr"},
ScheduledTaskManager: (*types.ManagedObjectReference)(nil),
AlarmManager: (*types.ManagedObjectReference)(nil),
EventManager: &types.ManagedObjectReference{Type: "EventManager", Value: "ha-eventmgr"},
TaskManager: &types.ManagedObjectReference{Type: "TaskManager", Value: "ha-taskmgr"},
ExtensionManager: (*types.ManagedObjectReference)(nil),
CustomizationSpecManager: (*types.ManagedObjectReference)(nil),
CustomFieldsManager: (*types.ManagedObjectReference)(nil),
AccountManager: &types.ManagedObjectReference{Type: "HostLocalAccountManager", Value: "ha-localacctmgr"},
DiagnosticManager: &types.ManagedObjectReference{Type: "DiagnosticManager", Value: "ha-diagnosticmgr"},
LicenseManager: &types.ManagedObjectReference{Type: "LicenseManager", Value: "ha-license-manager"},
SearchIndex: &types.ManagedObjectReference{Type: "SearchIndex", Value: "ha-searchindex"},
FileManager: &types.ManagedObjectReference{Type: "FileManager", Value: "ha-nfc-file-manager"},
DatastoreNamespaceManager: &types.ManagedObjectReference{Type: "DatastoreNamespaceManager", Value: "ha-datastore-namespace-manager"},
VirtualDiskManager: &types.ManagedObjectReference{Type: "VirtualDiskManager", Value: "ha-vdiskmanager"},
VirtualizationManager: (*types.ManagedObjectReference)(nil),
SnmpSystem: (*types.ManagedObjectReference)(nil),
VmProvisioningChecker: (*types.ManagedObjectReference)(nil),
VmCompatibilityChecker: (*types.ManagedObjectReference)(nil),
OvfManager: &types.ManagedObjectReference{Type: "OvfManager", Value: "ha-ovf-manager"},
IpPoolManager: (*types.ManagedObjectReference)(nil),
DvSwitchManager: &types.ManagedObjectReference{Type: "DistributedVirtualSwitchManager", Value: "ha-dvsmanager"},
HostProfileManager: (*types.ManagedObjectReference)(nil),
ClusterProfileManager: (*types.ManagedObjectReference)(nil),
ComplianceManager: (*types.ManagedObjectReference)(nil),
LocalizationManager: &types.ManagedObjectReference{Type: "LocalizationManager", Value: "ha-l10n-manager"},
StorageResourceManager: &types.ManagedObjectReference{Type: "StorageResourceManager", Value: "ha-storage-resource-manager"},
GuestOperationsManager: &types.ManagedObjectReference{Type: "GuestOperationsManager", Value: "ha-guest-operations-manager"},
OverheadMemoryManager: (*types.ManagedObjectReference)(nil),
CertificateManager: (*types.ManagedObjectReference)(nil),
IoFilterManager: (*types.ManagedObjectReference)(nil),
VStorageObjectManager: &types.ManagedObjectReference{Type: "HostVStorageObjectManager", Value: "ha-vstorage-object-manager"},
HostSpecManager: (*types.ManagedObjectReference)(nil),
CryptoManager: &types.ManagedObjectReference{Type: "CryptoManager", Value: "ha-crypto-manager"},
HealthUpdateManager: (*types.ManagedObjectReference)(nil),
FailoverClusterConfigurator: (*types.ManagedObjectReference)(nil),
FailoverClusterManager: (*types.ManagedObjectReference)(nil),
}
/*
Copyright (c) 2017 VMware, Inc. All 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 esx
import "github.com/vmware/govmomi/vim25/types"
// Setting is captured from ESX's HostSystem.configManager.advancedOption
// Capture method:
// govc object.collect -s -dump $(govc object.collect -s HostSystem:ha-host configManager.advancedOption) setting
var Setting = []types.BaseOptionValue{
// This list is currently pruned to include a single option for testing
&types.OptionValue{
Key: "Config.HostAgent.log.level",
Value: "info",
},
}
/*
Copyright (c) 2017 VMware, Inc. All 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 esx
import "github.com/vmware/govmomi/vim25/types"
// VirtualDevice is the default set of VirtualDevice types created for a VirtualMachine
// Capture method:
// govc vm.create foo
// govc object.collect -s -dump vm/foo config.hardware.device
var VirtualDevice = []types.BaseVirtualDevice{
&types.VirtualIDEController{
VirtualController: types.VirtualController{
VirtualDevice: types.VirtualDevice{
DynamicData: types.DynamicData{},
Key: 200,
DeviceInfo: &types.Description{
DynamicData: types.DynamicData{},
Label: "IDE 0",
Summary: "IDE 0",
},
Backing: nil,
Connectable: (*types.VirtualDeviceConnectInfo)(nil),
SlotInfo: nil,
ControllerKey: 0,
UnitNumber: (*int32)(nil),
},
BusNumber: 0,
Device: nil,
},
},
&types.VirtualIDEController{
VirtualController: types.VirtualController{
VirtualDevice: types.VirtualDevice{
DynamicData: types.DynamicData{},
Key: 201,
DeviceInfo: &types.Description{
DynamicData: types.DynamicData{},
Label: "IDE 1",
Summary: "IDE 1",
},
Backing: nil,
Connectable: (*types.VirtualDeviceConnectInfo)(nil),
SlotInfo: nil,
ControllerKey: 0,
UnitNumber: (*int32)(nil),
},
BusNumber: 1,
Device: nil,
},
},
&types.VirtualPS2Controller{
VirtualController: types.VirtualController{
VirtualDevice: types.VirtualDevice{
DynamicData: types.DynamicData{},
Key: 300,
DeviceInfo: &types.Description{
DynamicData: types.DynamicData{},
Label: "PS2 controller 0",
Summary: "PS2 controller 0",
},
Backing: nil,
Connectable: (*types.VirtualDeviceConnectInfo)(nil),
SlotInfo: nil,
ControllerKey: 0,
UnitNumber: (*int32)(nil),
},
BusNumber: 0,
Device: []int32{600, 700},
},
},
&types.VirtualPCIController{
VirtualController: types.VirtualController{
VirtualDevice: types.VirtualDevice{
DynamicData: types.DynamicData{},
Key: 100,
DeviceInfo: &types.Description{
DynamicData: types.DynamicData{},
Label: "PCI controller 0",
Summary: "PCI controller 0",
},
Backing: nil,
Connectable: (*types.VirtualDeviceConnectInfo)(nil),
SlotInfo: nil,
ControllerKey: 0,
UnitNumber: (*int32)(nil),
},
BusNumber: 0,
Device: []int32{500, 12000},
},
},
&types.VirtualSIOController{
VirtualController: types.VirtualController{
VirtualDevice: types.VirtualDevice{
DynamicData: types.DynamicData{},
Key: 400,
DeviceInfo: &types.Description{
DynamicData: types.DynamicData{},
Label: "SIO controller 0",
Summary: "SIO controller 0",
},
Backing: nil,
Connectable: (*types.VirtualDeviceConnectInfo)(nil),
SlotInfo: nil,
ControllerKey: 0,
UnitNumber: (*int32)(nil),
},
BusNumber: 0,
Device: nil,
},
},
&types.VirtualKeyboard{
VirtualDevice: types.VirtualDevice{
DynamicData: types.DynamicData{},
Key: 600,
DeviceInfo: &types.Description{
DynamicData: types.DynamicData{},
Label: "Keyboard ",
Summary: "Keyboard",
},
Backing: nil,
Connectable: (*types.VirtualDeviceConnectInfo)(nil),
SlotInfo: nil,
ControllerKey: 300,
UnitNumber: types.NewInt32(0),
},
},
&types.VirtualPointingDevice{
VirtualDevice: types.VirtualDevice{
DynamicData: types.DynamicData{},
Key: 700,
DeviceInfo: &types.Description{
DynamicData: types.DynamicData{},
Label: "Pointing device",
Summary: "Pointing device; Device",
},
Backing: &types.VirtualPointingDeviceDeviceBackingInfo{
VirtualDeviceDeviceBackingInfo: types.VirtualDeviceDeviceBackingInfo{
VirtualDeviceBackingInfo: types.VirtualDeviceBackingInfo{},
DeviceName: "",
UseAutoDetect: types.NewBool(false),
},
HostPointingDevice: "autodetect",
},
Connectable: (*types.VirtualDeviceConnectInfo)(nil),
SlotInfo: nil,
ControllerKey: 300,
UnitNumber: types.NewInt32(1),
},
},
&types.VirtualMachineVideoCard{
VirtualDevice: types.VirtualDevice{
DynamicData: types.DynamicData{},
Key: 500,
DeviceInfo: &types.Description{
DynamicData: types.DynamicData{},
Label: "Video card ",
Summary: "Video card",
},
Backing: nil,
Connectable: (*types.VirtualDeviceConnectInfo)(nil),
SlotInfo: nil,
ControllerKey: 100,
UnitNumber: types.NewInt32(0),
},
VideoRamSizeInKB: 4096,
NumDisplays: 1,
UseAutoDetect: types.NewBool(false),
Enable3DSupport: types.NewBool(false),
Use3dRenderer: "automatic",
GraphicsMemorySizeInKB: 262144,
},
&types.VirtualMachineVMCIDevice{
VirtualDevice: types.VirtualDevice{
DynamicData: types.DynamicData{},
Key: 12000,
DeviceInfo: &types.Description{
DynamicData: types.DynamicData{},
Label: "VMCI device",
Summary: "Device on the virtual machine PCI bus that provides support for the virtual machine communication interface",
},
Backing: nil,
Connectable: (*types.VirtualDeviceConnectInfo)(nil),
SlotInfo: nil,
ControllerKey: 100,
UnitNumber: types.NewInt32(17),
},
Id: -1,
AllowUnrestrictedCommunication: types.NewBool(false),
FilterEnable: types.NewBool(true),
FilterInfo: (*types.VirtualMachineVMCIDeviceFilterInfo)(nil),
},
}
// EthernetCard template for types.VirtualEthernetCard
var EthernetCard = types.VirtualE1000{
VirtualEthernetCard: types.VirtualEthernetCard{
VirtualDevice: types.VirtualDevice{
DynamicData: types.DynamicData{},
Key: 4000,
Backing: &types.VirtualEthernetCardNetworkBackingInfo{
VirtualDeviceDeviceBackingInfo: types.VirtualDeviceDeviceBackingInfo{
VirtualDeviceBackingInfo: types.VirtualDeviceBackingInfo{},
DeviceName: "VM Network",
UseAutoDetect: types.NewBool(false),
},
Network: (*types.ManagedObjectReference)(nil),
InPassthroughMode: types.NewBool(false),
},
Connectable: &types.VirtualDeviceConnectInfo{
DynamicData: types.DynamicData{},
StartConnected: true,
AllowGuestControl: true,
Connected: false,
Status: "untried",
},
SlotInfo: &types.VirtualDevicePciBusSlotInfo{
VirtualDeviceBusSlotInfo: types.VirtualDeviceBusSlotInfo{},
PciSlotNumber: 32,
},
ControllerKey: 100,
UnitNumber: types.NewInt32(7),
},
AddressType: "generated",
MacAddress: "",
WakeOnLanEnabled: types.NewBool(true),
},
}
/*
Copyright (c) 2017 VMware, Inc. All 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 simulator
import (
"io"
"os"
"path"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/simulator/esx"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
type FileManager struct {
mo.FileManager
}
func NewFileManager(ref types.ManagedObjectReference) object.Reference {
m := &FileManager{}
m.Self = ref
return m
}
func (f *FileManager) findDatastore(ref mo.Reference, name string) (*Datastore, types.BaseMethodFault) {
var refs []types.ManagedObjectReference
switch obj := ref.(type) {
case *Folder:
refs = obj.ChildEntity
case *StoragePod:
refs = obj.ChildEntity
}
for _, ref := range refs {
switch obj := Map.Get(ref).(type) {
case *Datastore:
if obj.Name == name {
return obj, nil
}
case *Folder, *StoragePod:
ds, _ := f.findDatastore(obj, name)
if ds != nil {
return ds, nil
}
}
}
return nil, &types.InvalidDatastore{Name: name}
}
func (f *FileManager) resolve(dc *types.ManagedObjectReference, name string) (string, types.BaseMethodFault) {
p, fault := parseDatastorePath(name)
if fault != nil {
return "", fault
}
if dc == nil {
if Map.IsESX() {
dc = &esx.Datacenter.Self
} else {
return "", &types.InvalidArgument{InvalidProperty: "dc"}
}
}
folder := Map.Get(*dc).(*mo.Datacenter).DatastoreFolder
ds, fault := f.findDatastore(Map.Get(folder), p.Datastore)
if fault != nil {
return "", fault
}
dir := ds.Info.GetDatastoreInfo().Url
return path.Join(dir, p.Path), nil
}
func (f *FileManager) fault(name string, err error, fault types.BaseFileFault) types.BaseMethodFault {
switch {
case os.IsNotExist(err):
fault = new(types.FileNotFound)
case os.IsExist(err):
fault = new(types.FileAlreadyExists)
}
fault.GetFileFault().File = name
return fault.(types.BaseMethodFault)
}
func (f *FileManager) deleteDatastoreFile(req *types.DeleteDatastoreFile_Task) types.BaseMethodFault {
file, fault := f.resolve(req.Datacenter, req.Name)
if fault != nil {
return fault
}
_, err := os.Stat(file)
if err != nil {
if os.IsNotExist(err) {
return f.fault(file, err, new(types.CannotDeleteFile))
}
}
err = os.RemoveAll(file)
if err != nil {
return f.fault(file, err, new(types.CannotDeleteFile))
}
return nil
}
func (f *FileManager) DeleteDatastoreFileTask(req *types.DeleteDatastoreFile_Task) soap.HasFault {
task := CreateTask(f, "deleteDatastoreFile", func(*Task) (types.AnyType, types.BaseMethodFault) {
return nil, f.deleteDatastoreFile(req)
})
return &methods.DeleteDatastoreFile_TaskBody{
Res: &types.DeleteDatastoreFile_TaskResponse{
Returnval: task.Run(),
},
}
}
func (f *FileManager) MakeDirectory(req *types.MakeDirectory) soap.HasFault {
body := &methods.MakeDirectoryBody{}
name, fault := f.resolve(req.Datacenter, req.Name)
if fault != nil {
body.Fault_ = Fault("", fault)
return body
}
mkdir := os.Mkdir
if isTrue(req.CreateParentDirectories) {
mkdir = os.MkdirAll
}
err := mkdir(name, 0700)
if err != nil {
fault = f.fault(req.Name, err, new(types.CannotCreateFile))
body.Fault_ = Fault(err.Error(), fault)
return body
}
return body
}
func (f *FileManager) moveDatastoreFile(req *types.MoveDatastoreFile_Task) types.BaseMethodFault {
src, fault := f.resolve(req.SourceDatacenter, req.SourceName)
if fault != nil {
return fault
}
dst, fault := f.resolve(req.DestinationDatacenter, req.DestinationName)
if fault != nil {
return fault
}
if !isTrue(req.Force) {
_, err := os.Stat(dst)
if err == nil {
return f.fault(dst, nil, new(types.FileAlreadyExistsFault))
}
}
err := os.Rename(src, dst)
if err != nil {
return f.fault(src, err, new(types.CannotAccessFile))
}
return nil
}
func (f *FileManager) MoveDatastoreFileTask(req *types.MoveDatastoreFile_Task) soap.HasFault {
task := CreateTask(f, "moveDatastoreFile", func(*Task) (types.AnyType, types.BaseMethodFault) {
return nil, f.moveDatastoreFile(req)
})
return &methods.MoveDatastoreFile_TaskBody{
Res: &types.MoveDatastoreFile_TaskResponse{
Returnval: task.Run(),
},
}
}
func (f *FileManager) copyDatastoreFile(req *types.CopyDatastoreFile_Task) types.BaseMethodFault {
src, fault := f.resolve(req.SourceDatacenter, req.SourceName)
if fault != nil {
return fault
}
dst, fault := f.resolve(req.DestinationDatacenter, req.DestinationName)
if fault != nil {
return fault
}
if !isTrue(req.Force) {
_, err := os.Stat(dst)
if err == nil {
return f.fault(dst, nil, new(types.FileAlreadyExistsFault))
}
}
r, err := os.Open(src)
if err != nil {
return f.fault(dst, err, new(types.CannotAccessFile))
}
defer r.Close()
w, err := os.Create(dst)
if err != nil {
return f.fault(dst, err, new(types.CannotCreateFile))
}
defer w.Close()
if _, err = io.Copy(w, r); err != nil {
return f.fault(dst, err, new(types.CannotCreateFile))
}
return nil
}
func (f *FileManager) CopyDatastoreFileTask(req *types.CopyDatastoreFile_Task) soap.HasFault {
task := CreateTask(f, "copyDatastoreFile", func(*Task) (types.AnyType, types.BaseMethodFault) {
return nil, f.copyDatastoreFile(req)
})
return &methods.CopyDatastoreFile_TaskBody{
Res: &types.CopyDatastoreFile_TaskResponse{
Returnval: task.Run(),
},
}
}
/*
Copyright (c) 2017 VMware, Inc. All 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 simulator
import "github.com/vmware/govmomi/vim25/types"
// GuestID is the list of valid types.VirtualMachineGuestOsIdentifier
var GuestID = []types.VirtualMachineGuestOsIdentifier{
types.VirtualMachineGuestOsIdentifierDosGuest,
types.VirtualMachineGuestOsIdentifierWin31Guest,
types.VirtualMachineGuestOsIdentifierWin95Guest,
types.VirtualMachineGuestOsIdentifierWin98Guest,
types.VirtualMachineGuestOsIdentifierWinMeGuest,
types.VirtualMachineGuestOsIdentifierWinNTGuest,
types.VirtualMachineGuestOsIdentifierWin2000ProGuest,
types.VirtualMachineGuestOsIdentifierWin2000ServGuest,
types.VirtualMachineGuestOsIdentifierWin2000AdvServGuest,
types.VirtualMachineGuestOsIdentifierWinXPHomeGuest,
types.VirtualMachineGuestOsIdentifierWinXPProGuest,
types.VirtualMachineGuestOsIdentifierWinXPPro64Guest,
types.VirtualMachineGuestOsIdentifierWinNetWebGuest,
types.VirtualMachineGuestOsIdentifierWinNetStandardGuest,
types.VirtualMachineGuestOsIdentifierWinNetEnterpriseGuest,
types.VirtualMachineGuestOsIdentifierWinNetDatacenterGuest,
types.VirtualMachineGuestOsIdentifierWinNetBusinessGuest,
types.VirtualMachineGuestOsIdentifierWinNetStandard64Guest,
types.VirtualMachineGuestOsIdentifierWinNetEnterprise64Guest,
types.VirtualMachineGuestOsIdentifierWinLonghornGuest,
types.VirtualMachineGuestOsIdentifierWinLonghorn64Guest,
types.VirtualMachineGuestOsIdentifierWinNetDatacenter64Guest,
types.VirtualMachineGuestOsIdentifierWinVistaGuest,
types.VirtualMachineGuestOsIdentifierWinVista64Guest,
types.VirtualMachineGuestOsIdentifierWindows7Guest,
types.VirtualMachineGuestOsIdentifierWindows7_64Guest,
types.VirtualMachineGuestOsIdentifierWindows7Server64Guest,
types.VirtualMachineGuestOsIdentifierWindows8Guest,
types.VirtualMachineGuestOsIdentifierWindows8_64Guest,
types.VirtualMachineGuestOsIdentifierWindows8Server64Guest,
types.VirtualMachineGuestOsIdentifierWindows9Guest,
types.VirtualMachineGuestOsIdentifierWindows9_64Guest,
types.VirtualMachineGuestOsIdentifierWindows9Server64Guest,
types.VirtualMachineGuestOsIdentifierWindowsHyperVGuest,
types.VirtualMachineGuestOsIdentifierFreebsdGuest,
types.VirtualMachineGuestOsIdentifierFreebsd64Guest,
types.VirtualMachineGuestOsIdentifierRedhatGuest,
types.VirtualMachineGuestOsIdentifierRhel2Guest,
types.VirtualMachineGuestOsIdentifierRhel3Guest,
types.VirtualMachineGuestOsIdentifierRhel3_64Guest,
types.VirtualMachineGuestOsIdentifierRhel4Guest,
types.VirtualMachineGuestOsIdentifierRhel4_64Guest,
types.VirtualMachineGuestOsIdentifierRhel5Guest,
types.VirtualMachineGuestOsIdentifierRhel5_64Guest,
types.VirtualMachineGuestOsIdentifierRhel6Guest,
types.VirtualMachineGuestOsIdentifierRhel6_64Guest,
types.VirtualMachineGuestOsIdentifierRhel7Guest,
types.VirtualMachineGuestOsIdentifierRhel7_64Guest,
types.VirtualMachineGuestOsIdentifierCentosGuest,
types.VirtualMachineGuestOsIdentifierCentos64Guest,
types.VirtualMachineGuestOsIdentifierCentos6Guest,
types.VirtualMachineGuestOsIdentifierCentos6_64Guest,
types.VirtualMachineGuestOsIdentifierCentos7Guest,
types.VirtualMachineGuestOsIdentifierCentos7_64Guest,
types.VirtualMachineGuestOsIdentifierOracleLinuxGuest,
types.VirtualMachineGuestOsIdentifierOracleLinux64Guest,
types.VirtualMachineGuestOsIdentifierOracleLinux6Guest,
types.VirtualMachineGuestOsIdentifierOracleLinux6_64Guest,
types.VirtualMachineGuestOsIdentifierOracleLinux7Guest,
types.VirtualMachineGuestOsIdentifierOracleLinux7_64Guest,
types.VirtualMachineGuestOsIdentifierSuseGuest,
types.VirtualMachineGuestOsIdentifierSuse64Guest,
types.VirtualMachineGuestOsIdentifierSlesGuest,
types.VirtualMachineGuestOsIdentifierSles64Guest,
types.VirtualMachineGuestOsIdentifierSles10Guest,
types.VirtualMachineGuestOsIdentifierSles10_64Guest,
types.VirtualMachineGuestOsIdentifierSles11Guest,
types.VirtualMachineGuestOsIdentifierSles11_64Guest,
types.VirtualMachineGuestOsIdentifierSles12Guest,
types.VirtualMachineGuestOsIdentifierSles12_64Guest,
types.VirtualMachineGuestOsIdentifierNld9Guest,
types.VirtualMachineGuestOsIdentifierOesGuest,
types.VirtualMachineGuestOsIdentifierSjdsGuest,
types.VirtualMachineGuestOsIdentifierMandrakeGuest,
types.VirtualMachineGuestOsIdentifierMandrivaGuest,
types.VirtualMachineGuestOsIdentifierMandriva64Guest,
types.VirtualMachineGuestOsIdentifierTurboLinuxGuest,
types.VirtualMachineGuestOsIdentifierTurboLinux64Guest,
types.VirtualMachineGuestOsIdentifierUbuntuGuest,
types.VirtualMachineGuestOsIdentifierUbuntu64Guest,
types.VirtualMachineGuestOsIdentifierDebian4Guest,
types.VirtualMachineGuestOsIdentifierDebian4_64Guest,
types.VirtualMachineGuestOsIdentifierDebian5Guest,
types.VirtualMachineGuestOsIdentifierDebian5_64Guest,
types.VirtualMachineGuestOsIdentifierDebian6Guest,
types.VirtualMachineGuestOsIdentifierDebian6_64Guest,
types.VirtualMachineGuestOsIdentifierDebian7Guest,
types.VirtualMachineGuestOsIdentifierDebian7_64Guest,
types.VirtualMachineGuestOsIdentifierDebian8Guest,
types.VirtualMachineGuestOsIdentifierDebian8_64Guest,
types.VirtualMachineGuestOsIdentifierDebian9Guest,
types.VirtualMachineGuestOsIdentifierDebian9_64Guest,
types.VirtualMachineGuestOsIdentifierDebian10Guest,
types.VirtualMachineGuestOsIdentifierDebian10_64Guest,
types.VirtualMachineGuestOsIdentifierAsianux3Guest,
types.VirtualMachineGuestOsIdentifierAsianux3_64Guest,
types.VirtualMachineGuestOsIdentifierAsianux4Guest,
types.VirtualMachineGuestOsIdentifierAsianux4_64Guest,
types.VirtualMachineGuestOsIdentifierAsianux5_64Guest,
types.VirtualMachineGuestOsIdentifierAsianux7_64Guest,
types.VirtualMachineGuestOsIdentifierOpensuseGuest,
types.VirtualMachineGuestOsIdentifierOpensuse64Guest,
types.VirtualMachineGuestOsIdentifierFedoraGuest,
types.VirtualMachineGuestOsIdentifierFedora64Guest,
types.VirtualMachineGuestOsIdentifierCoreos64Guest,
types.VirtualMachineGuestOsIdentifierVmwarePhoton64Guest,
types.VirtualMachineGuestOsIdentifierOther24xLinuxGuest,
types.VirtualMachineGuestOsIdentifierOther26xLinuxGuest,
types.VirtualMachineGuestOsIdentifierOtherLinuxGuest,
types.VirtualMachineGuestOsIdentifierOther3xLinuxGuest,
types.VirtualMachineGuestOsIdentifierGenericLinuxGuest,
types.VirtualMachineGuestOsIdentifierOther24xLinux64Guest,
types.VirtualMachineGuestOsIdentifierOther26xLinux64Guest,
types.VirtualMachineGuestOsIdentifierOther3xLinux64Guest,
types.VirtualMachineGuestOsIdentifierOtherLinux64Guest,
types.VirtualMachineGuestOsIdentifierSolaris6Guest,
types.VirtualMachineGuestOsIdentifierSolaris7Guest,
types.VirtualMachineGuestOsIdentifierSolaris8Guest,
types.VirtualMachineGuestOsIdentifierSolaris9Guest,
types.VirtualMachineGuestOsIdentifierSolaris10Guest,
types.VirtualMachineGuestOsIdentifierSolaris10_64Guest,
types.VirtualMachineGuestOsIdentifierSolaris11_64Guest,
types.VirtualMachineGuestOsIdentifierOs2Guest,
types.VirtualMachineGuestOsIdentifierEComStationGuest,
types.VirtualMachineGuestOsIdentifierEComStation2Guest,
types.VirtualMachineGuestOsIdentifierNetware4Guest,
types.VirtualMachineGuestOsIdentifierNetware5Guest,
types.VirtualMachineGuestOsIdentifierNetware6Guest,
types.VirtualMachineGuestOsIdentifierOpenServer5Guest,
types.VirtualMachineGuestOsIdentifierOpenServer6Guest,
types.VirtualMachineGuestOsIdentifierUnixWare7Guest,
types.VirtualMachineGuestOsIdentifierDarwinGuest,
types.VirtualMachineGuestOsIdentifierDarwin64Guest,
types.VirtualMachineGuestOsIdentifierDarwin10Guest,
types.VirtualMachineGuestOsIdentifierDarwin10_64Guest,
types.VirtualMachineGuestOsIdentifierDarwin11Guest,
types.VirtualMachineGuestOsIdentifierDarwin11_64Guest,
types.VirtualMachineGuestOsIdentifierDarwin12_64Guest,
types.VirtualMachineGuestOsIdentifierDarwin13_64Guest,
types.VirtualMachineGuestOsIdentifierDarwin14_64Guest,
types.VirtualMachineGuestOsIdentifierDarwin15_64Guest,
types.VirtualMachineGuestOsIdentifierDarwin16_64Guest,
types.VirtualMachineGuestOsIdentifierVmkernelGuest,
types.VirtualMachineGuestOsIdentifierVmkernel5Guest,
types.VirtualMachineGuestOsIdentifierVmkernel6Guest,
types.VirtualMachineGuestOsIdentifierVmkernel65Guest,
types.VirtualMachineGuestOsIdentifierOtherGuest,
types.VirtualMachineGuestOsIdentifierOtherGuest64,
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment