*: Bump version of vmware/govmomi
Bumping version to include changes that better handle TLS errors. Bump nescessary to prepare for when the version of Go is bumped to 1.20 Signed-off-by: Madhav Jivrajani <madhav.jiv@gmail.com>
This commit is contained in:
4
vendor/github.com/google/uuid/hash.go
generated
vendored
4
vendor/github.com/google/uuid/hash.go
generated
vendored
@@ -26,8 +26,8 @@ var (
|
||||
// NewMD5 and NewSHA1.
|
||||
func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID {
|
||||
h.Reset()
|
||||
h.Write(space[:])
|
||||
h.Write(data)
|
||||
h.Write(space[:]) //nolint:errcheck
|
||||
h.Write(data) //nolint:errcheck
|
||||
s := h.Sum(nil)
|
||||
var uuid UUID
|
||||
copy(uuid[:], s)
|
||||
|
118
vendor/github.com/google/uuid/null.go
generated
vendored
Normal file
118
vendor/github.com/google/uuid/null.go
generated
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
// Copyright 2021 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"
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var jsonNull = []byte("null")
|
||||
|
||||
// NullUUID represents a UUID that may be null.
|
||||
// NullUUID implements the SQL driver.Scanner interface so
|
||||
// it can be used as a scan destination:
|
||||
//
|
||||
// var u uuid.NullUUID
|
||||
// err := db.QueryRow("SELECT name FROM foo WHERE id=?", id).Scan(&u)
|
||||
// ...
|
||||
// if u.Valid {
|
||||
// // use u.UUID
|
||||
// } else {
|
||||
// // NULL value
|
||||
// }
|
||||
//
|
||||
type NullUUID struct {
|
||||
UUID UUID
|
||||
Valid bool // Valid is true if UUID is not NULL
|
||||
}
|
||||
|
||||
// Scan implements the SQL driver.Scanner interface.
|
||||
func (nu *NullUUID) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
nu.UUID, nu.Valid = Nil, false
|
||||
return nil
|
||||
}
|
||||
|
||||
err := nu.UUID.Scan(value)
|
||||
if err != nil {
|
||||
nu.Valid = false
|
||||
return err
|
||||
}
|
||||
|
||||
nu.Valid = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (nu NullUUID) Value() (driver.Value, error) {
|
||||
if !nu.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
// Delegate to UUID Value function
|
||||
return nu.UUID.Value()
|
||||
}
|
||||
|
||||
// MarshalBinary implements encoding.BinaryMarshaler.
|
||||
func (nu NullUUID) MarshalBinary() ([]byte, error) {
|
||||
if nu.Valid {
|
||||
return nu.UUID[:], nil
|
||||
}
|
||||
|
||||
return []byte(nil), nil
|
||||
}
|
||||
|
||||
// UnmarshalBinary implements encoding.BinaryUnmarshaler.
|
||||
func (nu *NullUUID) UnmarshalBinary(data []byte) error {
|
||||
if len(data) != 16 {
|
||||
return fmt.Errorf("invalid UUID (got %d bytes)", len(data))
|
||||
}
|
||||
copy(nu.UUID[:], data)
|
||||
nu.Valid = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalText implements encoding.TextMarshaler.
|
||||
func (nu NullUUID) MarshalText() ([]byte, error) {
|
||||
if nu.Valid {
|
||||
return nu.UUID.MarshalText()
|
||||
}
|
||||
|
||||
return jsonNull, nil
|
||||
}
|
||||
|
||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||
func (nu *NullUUID) UnmarshalText(data []byte) error {
|
||||
id, err := ParseBytes(data)
|
||||
if err != nil {
|
||||
nu.Valid = false
|
||||
return err
|
||||
}
|
||||
nu.UUID = id
|
||||
nu.Valid = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler.
|
||||
func (nu NullUUID) MarshalJSON() ([]byte, error) {
|
||||
if nu.Valid {
|
||||
return json.Marshal(nu.UUID)
|
||||
}
|
||||
|
||||
return jsonNull, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler.
|
||||
func (nu *NullUUID) UnmarshalJSON(data []byte) error {
|
||||
if bytes.Equal(data, jsonNull) {
|
||||
*nu = NullUUID{}
|
||||
return nil // valid null UUID
|
||||
}
|
||||
err := json.Unmarshal(data, &nu.UUID)
|
||||
nu.Valid = err == nil
|
||||
return err
|
||||
}
|
2
vendor/github.com/google/uuid/sql.go
generated
vendored
2
vendor/github.com/google/uuid/sql.go
generated
vendored
@@ -9,7 +9,7 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Scan implements sql.Scanner so UUIDs can be read from databases transparently
|
||||
// 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 {
|
||||
|
55
vendor/github.com/google/uuid/uuid.go
generated
vendored
55
vendor/github.com/google/uuid/uuid.go
generated
vendored
@@ -12,6 +12,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC
|
||||
@@ -33,7 +34,27 @@ const (
|
||||
Future // Reserved for future definition.
|
||||
)
|
||||
|
||||
var rander = rand.Reader // random function
|
||||
const randPoolSize = 16 * 16
|
||||
|
||||
var (
|
||||
rander = rand.Reader // random function
|
||||
poolEnabled = false
|
||||
poolMu sync.Mutex
|
||||
poolPos = randPoolSize // protected with poolMu
|
||||
pool [randPoolSize]byte // protected with poolMu
|
||||
)
|
||||
|
||||
type invalidLengthError struct{ len int }
|
||||
|
||||
func (err invalidLengthError) Error() string {
|
||||
return fmt.Sprintf("invalid UUID length: %d", err.len)
|
||||
}
|
||||
|
||||
// IsInvalidLengthError is matcher function for custom error invalidLengthError
|
||||
func IsInvalidLengthError(err error) bool {
|
||||
_, ok := err.(invalidLengthError)
|
||||
return ok
|
||||
}
|
||||
|
||||
// Parse decodes s into a UUID or returns an error. Both the standard UUID
|
||||
// forms of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and
|
||||
@@ -68,7 +89,7 @@ func Parse(s string) (UUID, error) {
|
||||
}
|
||||
return uuid, nil
|
||||
default:
|
||||
return uuid, fmt.Errorf("invalid UUID length: %d", len(s))
|
||||
return uuid, invalidLengthError{len(s)}
|
||||
}
|
||||
// s is now at least 36 bytes long
|
||||
// it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
@@ -112,7 +133,7 @@ func ParseBytes(b []byte) (UUID, error) {
|
||||
}
|
||||
return uuid, nil
|
||||
default:
|
||||
return uuid, fmt.Errorf("invalid UUID length: %d", len(b))
|
||||
return uuid, invalidLengthError{len(b)}
|
||||
}
|
||||
// s is now at least 36 bytes long
|
||||
// it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
@@ -243,3 +264,31 @@ func SetRand(r io.Reader) {
|
||||
}
|
||||
rander = r
|
||||
}
|
||||
|
||||
// EnableRandPool enables internal randomness pool used for Random
|
||||
// (Version 4) UUID generation. The pool contains random bytes read from
|
||||
// the random number generator on demand in batches. Enabling the pool
|
||||
// may improve the UUID generation throughput significantly.
|
||||
//
|
||||
// Since the pool is stored on the Go heap, this feature may be a bad fit
|
||||
// for security sensitive applications.
|
||||
//
|
||||
// Both EnableRandPool and DisableRandPool are not thread-safe and should
|
||||
// only be called when there is no possibility that New or any other
|
||||
// UUID Version 4 generation function will be called concurrently.
|
||||
func EnableRandPool() {
|
||||
poolEnabled = true
|
||||
}
|
||||
|
||||
// DisableRandPool disables the randomness pool if it was previously
|
||||
// enabled with EnableRandPool.
|
||||
//
|
||||
// Both EnableRandPool and DisableRandPool are not thread-safe and should
|
||||
// only be called when there is no possibility that New or any other
|
||||
// UUID Version 4 generation function will be called concurrently.
|
||||
func DisableRandPool() {
|
||||
poolEnabled = false
|
||||
defer poolMu.Unlock()
|
||||
poolMu.Lock()
|
||||
poolPos = randPoolSize
|
||||
}
|
||||
|
35
vendor/github.com/google/uuid/version4.go
generated
vendored
35
vendor/github.com/google/uuid/version4.go
generated
vendored
@@ -14,11 +14,21 @@ func New() UUID {
|
||||
return Must(NewRandom())
|
||||
}
|
||||
|
||||
// NewString creates a new random UUID and returns it as a string or panics.
|
||||
// NewString is equivalent to the expression
|
||||
//
|
||||
// uuid.New().String()
|
||||
func NewString() string {
|
||||
return Must(NewRandom()).String()
|
||||
}
|
||||
|
||||
// NewRandom returns a Random (Version 4) UUID.
|
||||
//
|
||||
// The strength of the UUIDs is based on the strength of the crypto/rand
|
||||
// package.
|
||||
//
|
||||
// Uses the randomness pool if it was enabled with EnableRandPool.
|
||||
//
|
||||
// A note about uniqueness derived from the UUID Wikipedia entry:
|
||||
//
|
||||
// Randomly generated UUIDs have 122 random bits. One's annual risk of being
|
||||
@@ -27,7 +37,10 @@ func New() UUID {
|
||||
// equivalent to the odds of creating a few tens of trillions of UUIDs in a
|
||||
// year and having one duplicate.
|
||||
func NewRandom() (UUID, error) {
|
||||
return NewRandomFromReader(rander)
|
||||
if !poolEnabled {
|
||||
return NewRandomFromReader(rander)
|
||||
}
|
||||
return newRandomFromPool()
|
||||
}
|
||||
|
||||
// NewRandomFromReader returns a UUID based on bytes read from a given io.Reader.
|
||||
@@ -41,3 +54,23 @@ func NewRandomFromReader(r io.Reader) (UUID, error) {
|
||||
uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10
|
||||
return uuid, nil
|
||||
}
|
||||
|
||||
func newRandomFromPool() (UUID, error) {
|
||||
var uuid UUID
|
||||
poolMu.Lock()
|
||||
if poolPos == randPoolSize {
|
||||
_, err := io.ReadFull(rander, pool[:])
|
||||
if err != nil {
|
||||
poolMu.Unlock()
|
||||
return Nil, err
|
||||
}
|
||||
poolPos = 0
|
||||
}
|
||||
copy(uuid[:], pool[poolPos:(poolPos+16)])
|
||||
poolPos += 16
|
||||
poolMu.Unlock()
|
||||
|
||||
uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4
|
||||
uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10
|
||||
return uuid, nil
|
||||
}
|
||||
|
2
vendor/github.com/vmware/govmomi/.dockerignore
generated
vendored
Normal file
2
vendor/github.com/vmware/govmomi/.dockerignore
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
Dockerfile*
|
||||
.*ignore
|
10
vendor/github.com/vmware/govmomi/.gitignore
generated
vendored
10
vendor/github.com/vmware/govmomi/.gitignore
generated
vendored
@@ -1,3 +1,13 @@
|
||||
secrets.yml
|
||||
dist/
|
||||
.idea/
|
||||
|
||||
# ignore tools binaries
|
||||
/git-chglog
|
||||
|
||||
# ignore RELEASE-specific CHANGELOG
|
||||
/RELEASE_CHANGELOG.md
|
||||
|
||||
# Ignore editor temp files
|
||||
*~
|
||||
.vscode/
|
||||
|
18
vendor/github.com/vmware/govmomi/.golangci.yml
generated
vendored
Normal file
18
vendor/github.com/vmware/govmomi/.golangci.yml
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
linters:
|
||||
disable-all: true
|
||||
enable:
|
||||
- goimports
|
||||
- govet
|
||||
# Run with --fast=false for more extensive checks
|
||||
fast: true
|
||||
# override defaults
|
||||
linters-settings:
|
||||
goimports:
|
||||
# put imports beginning with prefix after 3rd-party packages;
|
||||
# it's a comma-separated list of prefixes
|
||||
local-prefixes: github.com/vmware/govmomi
|
||||
run:
|
||||
timeout: 6m
|
||||
skip-dirs:
|
||||
- vim25/xml
|
||||
- cns/types
|
185
vendor/github.com/vmware/govmomi/.goreleaser.yml
generated
vendored
185
vendor/github.com/vmware/govmomi/.goreleaser.yml
generated
vendored
@@ -1,57 +1,148 @@
|
||||
---
|
||||
project_name: govc
|
||||
project_name: govmomi
|
||||
|
||||
builds:
|
||||
- goos:
|
||||
- linux
|
||||
- darwin
|
||||
- windows
|
||||
- freebsd
|
||||
goarch:
|
||||
- amd64
|
||||
- 386
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
main: ./govc/main.go
|
||||
binary: govc
|
||||
flags: -compiler gc
|
||||
ldflags: -X github.com/vmware/govmomi/govc/flags.GitVersion={{.Version}}
|
||||
archive:
|
||||
name_template: '{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}'
|
||||
format: tar.gz
|
||||
format_overrides:
|
||||
- goos: windows
|
||||
format: zip
|
||||
files:
|
||||
- none*
|
||||
- id: govc
|
||||
goos: &goos-defs
|
||||
- linux
|
||||
- darwin
|
||||
- windows
|
||||
- freebsd
|
||||
goarch: &goarch-defs
|
||||
- amd64
|
||||
- arm
|
||||
- arm64
|
||||
- mips64le
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
- PKGPATH=github.com/vmware/govmomi/govc/flags
|
||||
main: ./govc/main.go
|
||||
binary: govc
|
||||
ldflags:
|
||||
- "-X {{.Env.PKGPATH}}.BuildVersion={{.Version}} -X {{.Env.PKGPATH}}.BuildCommit={{.ShortCommit}} -X {{.Env.PKGPATH}}.BuildDate={{.Date}}"
|
||||
- id: vcsim
|
||||
goos: *goos-defs
|
||||
goarch: *goarch-defs
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
main: ./vcsim/main.go
|
||||
binary: vcsim
|
||||
ldflags:
|
||||
- "-X main.buildVersion={{.Version}} -X main.buildCommit={{.ShortCommit}} -X main.buildDate={{.Date}}"
|
||||
|
||||
archives:
|
||||
- id: govcbuild
|
||||
builds:
|
||||
- govc
|
||||
name_template: "govc_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
|
||||
replacements: &replacements
|
||||
darwin: Darwin
|
||||
linux: Linux
|
||||
windows: Windows
|
||||
freebsd: FreeBSD
|
||||
amd64: x86_64
|
||||
format_overrides: &overrides
|
||||
- goos: windows
|
||||
format: zip
|
||||
files: &extrafiles
|
||||
- CHANGELOG.md
|
||||
- LICENSE.txt
|
||||
- README.md
|
||||
|
||||
- id: vcsimbuild
|
||||
builds:
|
||||
- vcsim
|
||||
name_template: "vcsim_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
|
||||
replacements: *replacements
|
||||
format_overrides: *overrides
|
||||
files: *extrafiles
|
||||
|
||||
snapshot:
|
||||
name_template: "{{ .Tag }}-next"
|
||||
|
||||
checksum:
|
||||
name_template: '{{ .ProjectName }}_{{ .Version }}_checksums.txt'
|
||||
name_template: "checksums.txt"
|
||||
|
||||
changelog:
|
||||
sort: asc
|
||||
filters:
|
||||
exclude:
|
||||
- '^docs:'
|
||||
- '^test:'
|
||||
- "^docs:"
|
||||
- "^test:"
|
||||
- Merge pull request
|
||||
- Merge branch
|
||||
brew:
|
||||
github:
|
||||
owner: govmomi
|
||||
name: homebrew-tap
|
||||
commit_author:
|
||||
name: Alfred the Narwhal
|
||||
email: cna-alfred@vmware.com
|
||||
folder: Formula
|
||||
homepage: "https://github.com/vmware/govmomi/blob/master/govc/README.md"
|
||||
description: "govc is a vSphere CLI built on top of govmomi."
|
||||
test: |
|
||||
system "#{bin}/govc version"
|
||||
|
||||
# upload disabled since it is maintained in homebrew-core
|
||||
brews:
|
||||
- name: govc
|
||||
ids:
|
||||
- govcbuild
|
||||
tap:
|
||||
owner: govmomi
|
||||
name: homebrew-tap
|
||||
# TODO: create token in specified tap repo, add as secret to govmomi repo and reference in release workflow
|
||||
# token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}"
|
||||
# enable once we do fully automated releases
|
||||
skip_upload: true
|
||||
commit_author:
|
||||
name: Alfred the Narwhal
|
||||
email: cna-alfred@vmware.com
|
||||
folder: Formula
|
||||
homepage: "https://github.com/vmware/govmomi/blob/master/govc/README.md"
|
||||
description: "govc is a vSphere CLI built on top of govmomi."
|
||||
test: |
|
||||
system "#{bin}/govc version"
|
||||
install: |
|
||||
bin.install "govc"
|
||||
- name: vcsim
|
||||
ids:
|
||||
- vcsimbuild
|
||||
tap:
|
||||
owner: govmomi
|
||||
name: homebrew-tap
|
||||
# TODO: create token in specified tap repo, add as secret to govmomi repo and reference in release workflow
|
||||
# token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}"
|
||||
# enable once we do fully automated releases
|
||||
skip_upload: true
|
||||
commit_author:
|
||||
name: Alfred the Narwhal
|
||||
email: cna-alfred@vmware.com
|
||||
folder: Formula
|
||||
homepage: "https://github.com/vmware/govmomi/blob/master/vcsim/README.md"
|
||||
description: "vcsim is a vSphere API simulator built on top of govmomi."
|
||||
test: |
|
||||
system "#{bin}/vcsim -h"
|
||||
install: |
|
||||
bin.install "vcsim"
|
||||
|
||||
dockers:
|
||||
- image: vmware/govc
|
||||
goos: linux
|
||||
goarch: amd64
|
||||
binary: govc
|
||||
tag_templates:
|
||||
- "{{ .Tag }}"
|
||||
- "v{{ .Major }}"
|
||||
- "v{{ .Major }}.{{ .Minor }}"
|
||||
- latest
|
||||
- image_templates:
|
||||
- "vmware/govc:{{ .Tag }}"
|
||||
- "vmware/govc:{{ .ShortCommit }}"
|
||||
- "vmware/govc:latest"
|
||||
dockerfile: Dockerfile.govc
|
||||
ids:
|
||||
- govc
|
||||
build_flag_templates:
|
||||
- "--pull"
|
||||
- "--label=org.opencontainers.image.created={{.Date}}"
|
||||
- "--label=org.opencontainers.image.title={{.ProjectName}}"
|
||||
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
|
||||
- "--label=org.opencontainers.image.version={{.Version}}"
|
||||
- "--label=org.opencontainers.image.url=https://github.com/vmware/govmomi"
|
||||
- "--platform=linux/amd64"
|
||||
- image_templates:
|
||||
- "vmware/vcsim:{{ .Tag }}"
|
||||
- "vmware/vcsim:{{ .ShortCommit }}"
|
||||
- "vmware/vcsim:latest"
|
||||
dockerfile: Dockerfile.vcsim
|
||||
ids:
|
||||
- vcsim
|
||||
build_flag_templates:
|
||||
- "--pull"
|
||||
- "--label=org.opencontainers.image.created={{.Date}}"
|
||||
- "--label=org.opencontainers.image.title={{.ProjectName}}"
|
||||
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
|
||||
- "--label=org.opencontainers.image.version={{.Version}}"
|
||||
- "--label=org.opencontainers.image.url=https://github.com/vmware/govmomi"
|
||||
- "--platform=linux/amd64"
|
||||
|
33
vendor/github.com/vmware/govmomi/.mailmap
generated
vendored
33
vendor/github.com/vmware/govmomi/.mailmap
generated
vendored
@@ -1,28 +1,45 @@
|
||||
amanpaha <amanpahariya@microsoft.com> amanpaha <84718160+amanpaha@users.noreply.github.com>
|
||||
Amanda H. L. de Andrade <amanda.andrade@serpro.gov.br> Amanda Hager Lopes de Andrade Katz <amanda.katz@serpro.gov.br>
|
||||
Amanda H. L. de Andrade <amanda.andrade@serpro.gov.br> amandahla <amanda.andrade@serpro.gov.br>
|
||||
Amit Bathla <abathla@.vmware.com> <abathla@promb-1s-dhcp216.eng.vmware.com>
|
||||
Andrew Kutz <akutz@vmware.com> akutz <akutz@vmware.com>
|
||||
Andrew Kutz <akutz@vmware.com> <sakutz@gmail.com>
|
||||
Andrew Kutz <akutz@vmware.com> akutz <akutz@vmware.com>
|
||||
Andrew Kutz <akutz@vmware.com> Andrew Kutz <101085+akutz@users.noreply.github.com>
|
||||
Anfernee Yongkun Gui <agui@vmware.com> <anfernee.gui@gmail.com>
|
||||
Anfernee Yongkun Gui <agui@vmware.com> Yongkun Anfernee Gui <agui@vmware.com>
|
||||
Anna Carrigan <anna.carrigan@hpe.com> Anna <anna.carrigan@outlook.com>
|
||||
Balu Dontu <bdontu@vmware.com> BaluDontu <bdontu@vmware.com>
|
||||
Bruce Downs <bruceadowns@gmail.com> <bdowns@vmware.com>
|
||||
Bruce Downs <bruceadowns@gmail.com> <bruce.downs@jivesoftware.com>
|
||||
Bruce Downs <bruceadowns@gmail.com> <bruce.downs@autodesk.com>
|
||||
Bruce Downs <bruceadowns@gmail.com> <bruce.downs@jivesoftware.com>
|
||||
Clint Greenwood <cgreenwood@vmware.com> <clint.greenwood@gmail.com>
|
||||
Cédric Blomart <cblomart@gmail.com> <cedric.blomart@minfin.fed.be>
|
||||
Cédric Blomart <cblomart@gmail.com> cedric <cblomart@gmail.com>
|
||||
David Stark <dave@davidstark.name> <david.stark@bskyb.com>
|
||||
Doug MacEachern <dougm@vmware.com> dougm <dougm@users.noreply.github.com>
|
||||
Eric Gray <egray@vmware.com> <ericgray@users.noreply.github.com>
|
||||
Eric Yutao <eric.yutao@gmail.com> eric <eric.yutao@gmail.com>
|
||||
Fabio Rapposelli <fabio@vmware.com> <fabio@rapposelli.org>
|
||||
Faiyaz Ahmed <faiyaza@vmware.com> Faiyaz Ahmed <ahmedf@vmware.com>
|
||||
Faiyaz Ahmed <faiyaza@vmware.com> Faiyaz Ahmed <faiyaza@gmail.com>
|
||||
Faiyaz Ahmed <faiyaza@vmware.com> Faiyaz Ahmed <fdawg4l@users.noreply.github.com>
|
||||
Henrik Hodne <henrik@travis-ci.com> <henrik@hodne.io>
|
||||
Ian Eyberg <ian@deferpanic.com> <ian@opuler.com>
|
||||
Jeremy Canady <jcanady@jackhenry.com> <jcanady@gmail.com>
|
||||
Jiatong Wang <wjiatong@vmware.com> jiatongw <wjiatong@vmware.com>
|
||||
Lintong Jiang <lintongj@vmware.com> lintongj <55512168+lintongj@users.noreply.github.com>
|
||||
Michael Gasch <mgasch@vmware.com> Michael Gasch <embano1@live.com>
|
||||
Mincho Tonev <mtonev@vmware.com> matonev <31008054+matonev@users.noreply.github.com>
|
||||
Parveen Chahal <parkuma@microsoft.com> <mail.chahal@gmail.com>
|
||||
Pieter Noordhuis <pnoordhuis@vmware.com> <pcnoordhuis@gmail.com>
|
||||
Saad Malik <saad@spectrocloud.com> <simfox3@gmail.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>
|
||||
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>
|
||||
Jiatong Wang <wjiatong@vmware.com> jiatongw <wjiatong@vmware.com>
|
||||
Uwe Bessle <Uwe.Bessle@iteratec.de> Uwe Bessle <u.bessle.extern@eos-ts.com>
|
||||
Uwe Bessle <Uwe.Bessle@iteratec.de> Uwe Bessle <uwe.bessle@web.de>
|
||||
Vadim Egorov <vegorov@vmware.com> <egorovv@gmail.com>
|
||||
William Lam <wlam@vmware.com> <info.virtuallyghetto@gmail.com>
|
||||
Yun Zhou <yunz@vmware.com> <41678287+gh05tn0va@users.noreply.github.com>
|
||||
Zach G <zguan@vmware.com> zach96guan <zach96guan@users.noreply.github.com>
|
||||
Zach Tucker <ztucker@vmware.com> <jzt@users.noreply.github.com>
|
||||
Zee Yang <zeey@vmware.com> <zee.yang@gmail.com>
|
||||
|
95
vendor/github.com/vmware/govmomi/.travis.yml
generated
vendored
95
vendor/github.com/vmware/govmomi/.travis.yml
generated
vendored
@@ -1,95 +0,0 @@
|
||||
# Use the newer Travis-CI build templates based on the
|
||||
# Debian Linux distribution "Trusty" release.
|
||||
os: linux
|
||||
dist: trusty
|
||||
|
||||
# Disable sudo for all builds by default. This ensures all jobs use
|
||||
# Travis-CI's containerized build environment unless specified otherwise.
|
||||
# The container builds have *much* shorter queue times than the VM-based
|
||||
# build environment on which the sudo builds depend.
|
||||
sudo: false
|
||||
services: false
|
||||
|
||||
# Set the version of Go.
|
||||
language: go
|
||||
go: 1.11
|
||||
|
||||
# Always set the project's Go import path to ensure that forked
|
||||
# builds get cloned to the correct location.
|
||||
go_import_path: github.com/vmware/govmomi
|
||||
|
||||
# Ensure all the jobs know where the temp directory is.
|
||||
env:
|
||||
global: TMPDIR=/tmp
|
||||
|
||||
jobs:
|
||||
include:
|
||||
|
||||
# The "lint" stage runs the various linters against the project.
|
||||
- &lint-stage
|
||||
stage: lint
|
||||
env: LINTER=govet
|
||||
install: true
|
||||
script: make "${LINTER}"
|
||||
|
||||
- <<: *lint-stage
|
||||
env: LINTER=goimports
|
||||
|
||||
# The "build" stage verifies the program can be built against the
|
||||
# various GOOS and GOARCH combinations found in the Go releaser
|
||||
# config file, ".goreleaser.yml".
|
||||
- &build-stage
|
||||
stage: build
|
||||
env: GOOS=linux GOARCH=amd64
|
||||
install: true
|
||||
script: make install
|
||||
|
||||
- <<: *build-stage
|
||||
env: GOOS=linux GOARCH=386
|
||||
|
||||
- <<: *build-stage
|
||||
env: GOOS=darwin GOARCH=amd64
|
||||
- <<: *build-stage
|
||||
env: GOOS=darwin GOARCH=386
|
||||
|
||||
- <<: *build-stage
|
||||
env: GOOS=freebsd GOARCH=amd64
|
||||
- <<: *build-stage
|
||||
env: GOOS=freebsd GOARCH=386
|
||||
|
||||
- <<: *build-stage
|
||||
env: GOOS=windows GOARCH=amd64
|
||||
- <<: *build-stage
|
||||
env: GOOS=windows GOARCH=386
|
||||
|
||||
# The test stage executes the test target.
|
||||
- stage: test
|
||||
install: true
|
||||
script: make test
|
||||
|
||||
# The deploy stage deploys the build artifacts using goreleaser.
|
||||
#
|
||||
# This stage will only be activated when there is an annotated tag present
|
||||
# or when the text "/ci-deploy" is present in the commit message. However,
|
||||
# the "deploy" phase of the build will still only be executed on non-PR
|
||||
# builds as that restriction is baked into Travis-CI.
|
||||
#
|
||||
# Finally, this stage requires the Travis-CI VM infrastructure in order to
|
||||
# leverage Docker. This will increase the amount of time the jobs sit
|
||||
# in the queue, waiting to be built. However, it's a necessity as Travis-CI
|
||||
# only allows the use of Docker with VM builds.
|
||||
- stage: deploy
|
||||
if: tag IS present OR commit_message =~ /\/ci-deploy/
|
||||
sudo: required
|
||||
services: docker
|
||||
install: true
|
||||
script: make install
|
||||
after_success: docker login -u="${DOCKER_USERNAME}" -p="${DOCKER_PASSWORD}"
|
||||
deploy:
|
||||
- provider: script
|
||||
skip_cleanup: true
|
||||
script: curl -sL http://git.io/goreleaser | bash
|
||||
addons:
|
||||
apt:
|
||||
update: true
|
||||
packages: xmlstarlet
|
3700
vendor/github.com/vmware/govmomi/CHANGELOG.md
generated
vendored
3700
vendor/github.com/vmware/govmomi/CHANGELOG.md
generated
vendored
File diff suppressed because it is too large
Load Diff
206
vendor/github.com/vmware/govmomi/CONTRIBUTING.md
generated
vendored
206
vendor/github.com/vmware/govmomi/CONTRIBUTING.md
generated
vendored
@@ -1,101 +1,197 @@
|
||||
# Contributing to govmomi
|
||||
# Contributing to `govmomi`
|
||||
|
||||
## Getting started
|
||||
|
||||
First, fork the repository on GitHub to your personal account.
|
||||
|
||||
Note that _GOPATH_ can be any directory, the example below uses _$HOME/govmomi_.
|
||||
Change _$USER_ below to your github username if they are not the same.
|
||||
Change `$USER` in the examples below to your Github username if they are not the
|
||||
same.
|
||||
|
||||
``` shell
|
||||
export GOPATH=$HOME/govmomi
|
||||
go get github.com/vmware/govmomi
|
||||
cd $GOPATH/src/github.com/vmware/govmomi
|
||||
git config push.default nothing # anything to avoid pushing to vmware/govmomi by default
|
||||
```bash
|
||||
git clone https://github.com/vmware/govmomi.git && cd govmomi
|
||||
|
||||
# prevent accidentally pushing to vmware/govmomi
|
||||
git config push.default nothing
|
||||
git remote rename origin vmware
|
||||
|
||||
# add your fork
|
||||
git remote add $USER git@github.com:$USER/govmomi.git
|
||||
git fetch $USER
|
||||
|
||||
git fetch -av
|
||||
```
|
||||
|
||||
## 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:
|
||||
|
||||
- Create an issue describing the feature/fix
|
||||
- Create a topic branch from where you want to base your work.
|
||||
- Make commits of logical units.
|
||||
- Make sure your commit messages are in the proper format (see below).
|
||||
- Update CHANGELOG.md and/or govc/CHANGELOG.md when appropriate.
|
||||
- Push your changes to a topic branch in your fork of the repository.
|
||||
- Submit a pull request to vmware/govmomi.
|
||||
- Submit a pull request to `vmware/govmomi`.
|
||||
|
||||
Example:
|
||||
See [below](#format-of-the-commit-message) for details on commit best practices
|
||||
and **supported prefixes**, e.g. `govc: <message>`.
|
||||
|
||||
``` shell
|
||||
git checkout -b my-new-feature vmware/master
|
||||
git commit -a
|
||||
git push $USER my-new-feature
|
||||
> **Note:** If you are new to Git(hub) check out [Git rebase, squash...oh
|
||||
> my!](https://www.mgasch.com/2021/05/git-basics/) for more details on how to
|
||||
> successfully contribute to an open source project.
|
||||
|
||||
### Example 1 - Fix a Bug in `govmomi`
|
||||
|
||||
```bash
|
||||
git checkout -b issue-<number> vmware/master
|
||||
git add <files>
|
||||
git commit -m "fix: ..." -m "Closes: #<issue-number>"
|
||||
git push $USER issue-<number>
|
||||
```
|
||||
|
||||
### Stay in sync with upstream
|
||||
### Example 2 - Add a new (non-breaking) API to `govmomi`
|
||||
|
||||
When your branch gets out of sync with the vmware/master branch, use the following to update:
|
||||
```bash
|
||||
git checkout -b issue-<number> vmware/master
|
||||
git add <files>
|
||||
git commit -m "Add API ..." -m "Closes: #<issue-number>"
|
||||
git push $USER issue-<number>
|
||||
```
|
||||
|
||||
``` shell
|
||||
git checkout my-new-feature
|
||||
### Example 3 - Add a Feature to `govc`
|
||||
|
||||
```bash
|
||||
git checkout -b issue-<number> vmware/master
|
||||
git add <files>
|
||||
git commit -m "govc: Add feature ..." -m "Closes: #<issue-number>"
|
||||
git push $USER issue-<number>
|
||||
```
|
||||
**Note**:
|
||||
To register the new `govc` command package, add a blank `_` import to `govmomi/govc/main.go`.
|
||||
|
||||
### Example 4 - Fix a Bug in `vcsim`
|
||||
|
||||
```bash
|
||||
git checkout -b issue-<number> vmware/master
|
||||
git add <files>
|
||||
git commit -m "vcsim: Fix ..." -m "Closes: #<issue-number>"
|
||||
git push $USER issue-<number>
|
||||
```
|
||||
|
||||
### Example 5 - Document Breaking (API) Changes
|
||||
|
||||
Breaking changes, e.g. to the `govmomi` APIs, are highlighted in the `CHANGELOG`
|
||||
and release notes when the keyword `BREAKING:` is used in the commit message
|
||||
body.
|
||||
|
||||
The text after `BREAKING:` is used in the corresponding highlighted section.
|
||||
Thus these details should be stated at the body of the commit message.
|
||||
Multi-line strings are supported.
|
||||
|
||||
```bash
|
||||
git checkout -b issue-<number> vmware/master
|
||||
git add <files>
|
||||
cat << EOF | git commit -F -
|
||||
Add ctx to funcXYZ
|
||||
|
||||
This commit introduces context.Context to function XYZ
|
||||
Closes: #1234
|
||||
|
||||
BREAKING: Add ctx to funcXYZ()
|
||||
EOF
|
||||
|
||||
git push $USER issue-<number>
|
||||
```
|
||||
|
||||
### Stay in sync with Upstream
|
||||
|
||||
When your branch gets out of sync with the vmware/master branch, use the
|
||||
following to update (rebase):
|
||||
|
||||
```bash
|
||||
git checkout issue-<number>
|
||||
git fetch -a
|
||||
git rebase vmware/master
|
||||
git push --force-with-lease $USER my-new-feature
|
||||
git push --force-with-lease $USER issue-<number>
|
||||
```
|
||||
|
||||
### Updating pull requests
|
||||
### Updating Pull Requests
|
||||
|
||||
If your PR fails to pass CI or needs changes based on code review, you'll most likely want to squash these changes into
|
||||
existing commits.
|
||||
If your PR fails to pass CI or needs changes based on code review, it's ok to
|
||||
add more commits stating the changes made, e.g. "Address review comments". This
|
||||
is to assist the reviewer(s) to easily detect and review the recent changes.
|
||||
|
||||
If your pull request contains a single commit or your changes are related to the most recent commit, you can simply
|
||||
amend the commit.
|
||||
In case of small PRs, it's ok to squash and force-push (see further below)
|
||||
directly instead.
|
||||
|
||||
``` shell
|
||||
```bash
|
||||
# incorporate review feedback
|
||||
git add .
|
||||
git commit --amend
|
||||
git push --force-with-lease $USER my-new-feature
|
||||
```
|
||||
|
||||
If you need to squash changes into an earlier commit, you can use:
|
||||
|
||||
``` shell
|
||||
git add .
|
||||
# create a fixup commit which will be merged into your (original) <commit>
|
||||
git commit --fixup <commit>
|
||||
git rebase -i --autosquash vmware/master
|
||||
git push --force-with-lease $USER my-new-feature
|
||||
git push $USER issue-<number>
|
||||
```
|
||||
|
||||
Be sure to add a comment to the PR indicating your new changes are ready to review, as github does not generate a
|
||||
notification when you git push.
|
||||
Be sure to add a comment to the PR indicating your new changes are ready to
|
||||
review, as Github does not generate a notification when you git push.
|
||||
|
||||
### Code style
|
||||
Once the review is complete, squash and push your final commit(s):
|
||||
|
||||
The coding style suggested by the Golang community is used in govmomi. See the
|
||||
```bash
|
||||
# squash all commits into one
|
||||
# --autosquash will automatically detect and merge fixup commits
|
||||
git rebase -i --autosquash vmware/master
|
||||
git push --force-with-lease $USER issue-<number>
|
||||
```
|
||||
|
||||
### Code Style
|
||||
|
||||
The coding style suggested by the Go community is used in `govmomi`. See the
|
||||
[style doc](https://github.com/golang/go/wiki/CodeReviewComments) for details.
|
||||
|
||||
Try to limit column width to 120 characters for both code and markdown documents such as this one.
|
||||
Try to limit column width to 120 characters for both code and markdown documents
|
||||
such as this one.
|
||||
|
||||
### Format of the Commit Message
|
||||
|
||||
We follow the conventions on [How to Write a Git Commit Message](http://chris.beams.io/posts/git-commit/).
|
||||
We follow the conventions described in [How to Write a Git Commit
|
||||
Message](http://chris.beams.io/posts/git-commit/).
|
||||
|
||||
Be sure to include any related GitHub issue references in the commit message.
|
||||
Be sure to include any related GitHub issue references in the commit message,
|
||||
e.g. `Closes: #<number>`.
|
||||
|
||||
The [`CHANGELOG.md`](./CHANGELOG.md) and release page uses **commit message
|
||||
prefixes** for grouping and highlighting. A commit message that
|
||||
starts with `[prefix:] ` will place this commit under the respective
|
||||
section in the `CHANGELOG`.
|
||||
|
||||
The following example creates a commit referencing the `issue: 1234` and puts
|
||||
the commit message in the `govc` `CHANGELOG` section:
|
||||
|
||||
```bash
|
||||
git commit -s -m "govc: Add CLI command X" -m "Closes: #1234"
|
||||
```
|
||||
|
||||
Currently the following prefixes are used:
|
||||
|
||||
- `api:` - Use for API-related changes
|
||||
- `govc:` - Use for changes to `govc` CLI
|
||||
- `vcsim:` - Use for changes to vCenter Simulator
|
||||
- `chore:` - Use for repository related activities
|
||||
- `fix:` - Use for bug fixes
|
||||
- `docs:` - Use for changes to the documentation
|
||||
- `examples:` - Use for changes to examples
|
||||
|
||||
If your contribution falls into multiple categories, e.g. `api` and `vcsim` it
|
||||
is recommended to break up your commits using distinct prefixes.
|
||||
|
||||
### Running CI Checks and Tests
|
||||
You can run both `make check` and `make test` from the top level of the
|
||||
repository.
|
||||
|
||||
While `make check` will catch formatting and import errors, it will not apply
|
||||
any fixes. The developer is expected to do that.
|
||||
|
||||
## Reporting Bugs and Creating Issues
|
||||
|
||||
When opening a new issue, try to roughly follow the commit message format conventions above.
|
||||
When opening a new issue, try to roughly follow the commit message format
|
||||
conventions above.
|
||||
|
156
vendor/github.com/vmware/govmomi/CONTRIBUTORS
generated
vendored
156
vendor/github.com/vmware/govmomi/CONTRIBUTORS
generated
vendored
@@ -5,104 +5,252 @@
|
||||
|
||||
Abhijeet Kasurde <akasurde@redhat.com>
|
||||
abrarshivani <abrarshivani@users.noreply.github.com>
|
||||
Adam Chalkley <atc0005@users.noreply.github.com>
|
||||
Adam Fowler <adam@adamfowler.org>
|
||||
Adam Shannon <adamkshannon@gmail.com>
|
||||
Akanksha Panse <pansea@vmware.com>
|
||||
Al Biheiri <abiheiri@apple.com>
|
||||
Alessandro Cortiana <alessandro.cortiana@gmail.com>
|
||||
Alex <puzo2002@gmail.com>
|
||||
Alex Bozhenko <alexbozhenko@fb.com>
|
||||
Alex Ellis (VMware) <alexellis2@gmail.com>
|
||||
Aligator <8278538+yet-another-aligator@users.noreply.github.com>
|
||||
Alvaro Miranda <kikitux@gmail.com>
|
||||
Amanda H. L. de Andrade <amanda.andrade@serpro.gov.br>
|
||||
amanpaha <amanpahariya@microsoft.com>
|
||||
Amit Bathla <abathla@.vmware.com>
|
||||
amit bezalel <amit.bezalel@hpe.com>
|
||||
Andrew <AndrewDi@users.noreply.github.com>
|
||||
Andrew Chin <andrew@andrewtchin.com>
|
||||
Andrew Kutz <akutz@vmware.com>
|
||||
Andrey Klimentyev <andrey.klimentyev@flant.com>
|
||||
Anfernee Yongkun Gui <agui@vmware.com>
|
||||
angystardust <angystardust@users.noreply.github.com>
|
||||
aniketGslab <aniket.shinde@gslab.com>
|
||||
Ankit Vaidya <vaidyaa@vmware.com>
|
||||
Ankur Huralikoppi <huralikoppia@vmware.com>
|
||||
Anna Carrigan <anna.carrigan@hpe.com>
|
||||
Antony Saba <awsaba@gmail.com>
|
||||
Ariel Chinn <arielchinn@gmail.com>
|
||||
Arran Walker <arran.walker@zopa.com>
|
||||
Artem Anisimov <aanisimov@inbox.ru>
|
||||
Arunesh Pandey <parunesh@vmware.com>
|
||||
Aryeh Weinreb <aryehweinreb@gmail.com>
|
||||
Augy StClair <augy@google.com>
|
||||
Austin Parker <aparker@apprenda.com>
|
||||
Balu Dontu <bdontu@vmware.com>
|
||||
bastienbc <bastien.barbe.creuly@gmail.com>
|
||||
Ben Corrie <bcorrie@vmware.com>
|
||||
Ben Vickers <bvickers@pivotal.io>
|
||||
Benjamin Davini <davinib@vmware.com>
|
||||
Benjamin Peterson <benjamin@python.org>
|
||||
Benjamin Vickers <bvickers@vmware.com>
|
||||
Bhavya Choudhary <bhavyac@vmware.com>
|
||||
Bob Killen <killen.bob@gmail.com>
|
||||
Brad Fitzpatrick <bradfitz@golang.org>
|
||||
Brian Rak <brak@vmware.com>
|
||||
brian57860 <brian57860@users.noreply.github.com>
|
||||
Bruce Downs <bruceadowns@gmail.com>
|
||||
Bryan Venteicher <bryanventeicher@gmail.com>
|
||||
Cédric Blomart <cblomart@gmail.com>
|
||||
Cheng Cheng <chengch@vmware.com>
|
||||
Chethan Venkatesh <chethanv@vmware.com>
|
||||
Choudhury Sarada Prasanna Nanda <cspn@google.com>
|
||||
Chris Marchesi <chrism@vancluevertech.com>
|
||||
Christian Höltje <docwhat@gerf.org>
|
||||
Clint Greenwood <cgreenwood@vmware.com>
|
||||
cpiment <pimentel.carlos@gmail.com>
|
||||
CuiHaozhi <cuihaozhi@chinacloud.com.cn>
|
||||
Dan Ilan <danilan@google.com>
|
||||
Dan Norris <protochron@users.noreply.github.com>
|
||||
Daniel Frederick Crisman <daniel@crisman.org>
|
||||
Daniel Mueller <deso@posteo.net>
|
||||
Danny Lockard <danny.lockard@banno.com>
|
||||
Dave Gress <gressd@vmware.com>
|
||||
Dave Smith-Uchida <dsmithuchida@vmware.com>
|
||||
Dave Tucker <dave@dtucker.co.uk>
|
||||
Davide Agnello <dagnello@hp.com>
|
||||
David Gress <gressd@vmware.com>
|
||||
David Stark <dave@davidstark.name>
|
||||
Davide Agnello <dagnello@hp.com>
|
||||
Davinder Kumar <davinderk@vmware.com>
|
||||
Defa <zhoudefa666@163.com>
|
||||
demarey <christophe.demarey@inria.fr>
|
||||
dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
|
||||
Deric Crago <deric.crago@gmail.com>
|
||||
ditsuke <ditsuke@protonmail.com>
|
||||
Divyen Patel <divyenp@vmware.com>
|
||||
Dnyanesh Gate <dnyanesh.gate@druva.com>
|
||||
Doug MacEachern <dougm@vmware.com>
|
||||
East <60801291+houfangdong@users.noreply.github.com>
|
||||
Eloy Coto <eloy.coto@gmail.com>
|
||||
embano1 <embano1@users.noreply.github.com>
|
||||
Eng Zer Jun <engzerjun@gmail.com>
|
||||
Eric Edens <ericedens@google.com>
|
||||
Eric Graham <16710890+Pheric@users.noreply.github.com>
|
||||
Eric Gray <egray@vmware.com>
|
||||
Eric Yutao <eric.yutao@gmail.com>
|
||||
Erik Hollensbe <github@hollensbe.org>
|
||||
Essodjolo KAHANAM <essodjolo@kahanam.com>
|
||||
Ethan Kaley <ethan.kaley@emc.com>
|
||||
Evan Chu <echu@vmware.com>
|
||||
Fabio Rapposelli <fabio@vmware.com>
|
||||
Faiyaz Ahmed <ahmedf@vmware.com>
|
||||
Faiyaz Ahmed <faiyaza@vmware.com>
|
||||
Federico Pellegatta <12744504+federico-pellegatta@users.noreply.github.com>
|
||||
forkbomber <forkbomber@users.noreply.github.com>
|
||||
François Rigault <rigault.francois@gmail.com>
|
||||
freebsdly <qinhuajun@outlook.com>
|
||||
Gavin Gray <gavin@infinio.com>
|
||||
Gavrie Philipson <gavrie.philipson@elastifile.com>
|
||||
George Hicken <ghicken@vmware.com>
|
||||
Gerrit Renker <Gerrit.Renker@ctl.io>
|
||||
gthombare <gthombare@vmware.com>
|
||||
HakanSunay <hakansunay@abv.bg>
|
||||
Hasan Mahmood <mahmoodh@vmware.com>
|
||||
Haydon Ryan <haydon.ryan@gmail.com>
|
||||
Heiko Reese <hreese@users.noreply.github.com>
|
||||
Henrik Hodne <henrik@travis-ci.com>
|
||||
hkumar <hkumar@vmware.com>
|
||||
Hrabur Stoyanov <hstoyanov@vmware.com>
|
||||
hui luo <luoh@vmware.com>
|
||||
Ian Eyberg <ian@deferpanic.com>
|
||||
Isaac Rodman <isaac@eyz.us>
|
||||
Ivan Mikushin <imikushin@vmware.com>
|
||||
Ivan Porto Carrero <icarrero@vmware.com>
|
||||
James King <james.king@emc.com>
|
||||
James Peach <jpeach@vmware.com>
|
||||
Jason Kincl <jkincl@gmail.com>
|
||||
Jeremy Canady <jcanady@jackhenry.com>
|
||||
jeremy-clerc <jeremy@clerc.io>
|
||||
Jiatong Wang <wjiatong@vmware.com>
|
||||
jingyizPensando <jingyiz@pensando.io>
|
||||
João Pereira <joaodrp@gmail.com>
|
||||
Jonas Ausevicius <jonas.ausevicius@virtustream.com>
|
||||
Jorge Sevilla <jorge.sevilla@rstor.io>
|
||||
Julien PILLON <jpillon@lesalternatives.org>
|
||||
Justin J. Novack <jnovack@users.noreply.github.com>
|
||||
kayrus <kay.diam@gmail.com>
|
||||
Keenan Brock <keenan@thebrocks.net>
|
||||
Kevin George <georgek@vmware.com>
|
||||
Knappek <andy.knapp.ak@gmail.com>
|
||||
Leslie Wang <qiwa@pensando.io>
|
||||
leslie-qiwa <leslie.qiwa@gmail.com>
|
||||
Lintong Jiang <lintongj@vmware.com>
|
||||
Liping Xue <lipingx@vmware.com>
|
||||
Louie Jiang <jiangl@vmware.com>
|
||||
Luther Monson <luther.monson@gmail.com>
|
||||
Madanagopal Arunachalam <marunachalam@vmware.com>
|
||||
makelarisjr <8687447+makelarisjr@users.noreply.github.com>
|
||||
maplain <fangyuanl@vmware.com>
|
||||
Marc Carmier <mcarmier@gmail.com>
|
||||
Marcus Tan <marcus.tan@rubrik.com>
|
||||
Maria Ntalla <maria.ntalla@gmail.com>
|
||||
Marin Atanasov Nikolov <mnikolov@vmware.com>
|
||||
Mario Trangoni <mjtrangoni@gmail.com>
|
||||
Mark Dechiaro <mdechiaro@users.noreply.github.com>
|
||||
Mark Peek <markpeek@vmware.com>
|
||||
Mark Rexwinkel <Mark.Rexwinkel@elekta.com>
|
||||
martin <martin@catai.org>
|
||||
Matt Clay <matt@mystile.com>
|
||||
Matthew Cosgrove <matthew.cosgrove@dell.com>
|
||||
Matt Moore <mattmoor@vmware.com>
|
||||
Matt Moriarity <matt@mattmoriarity.com>
|
||||
Matthew Cosgrove <matthew.cosgrove@dell.com>
|
||||
mbhadale <mbhadale@vmware.com>
|
||||
Merlijn Sebrechts <merlijn.sebrechts@gmail.com>
|
||||
Mevan Samaratunga <mevansam@gmail.com>
|
||||
Michael Gasch <15986659+embano1@users.noreply.github.com>
|
||||
Michael Gasch <mgasch@vmware.com>
|
||||
Michal Jankowski <mjankowski@vmware.com>
|
||||
Mike Schinkel <mike@newclarity.net>
|
||||
Mincho Tonev <mtonev@vmware.com>
|
||||
mingwei <mingwei@smartx.com>
|
||||
Nicolas Lamirault <nicolas.lamirault@gmail.com>
|
||||
Nikhil Kathare <nikhil.kathare@netapp.com>
|
||||
Nikhil R Deshpande <ndeshpande@vmware.com>
|
||||
Nikolas Grottendieck <git@nikolasgrottendieck.com>
|
||||
Nils Elde <nils.elde@sscinc.com>
|
||||
nirbhay <nirbhay.bagmar@nutanix.com>
|
||||
Nobuhiro MIKI <nmiki@yahoo-corp.jp>
|
||||
Om Kumar <om.kumar@hpe.com>
|
||||
Omar Kohl <omarkohl@gmail.com>
|
||||
Parham Alvani <parham.alvani@gmail.com>
|
||||
Parveen Chahal <parkuma@microsoft.com>
|
||||
Paul Martin <25058109+rawstorage@users.noreply.github.com>
|
||||
Pierre Gronlier <pierre.gronlier@corp.ovh.com>
|
||||
Pieter Noordhuis <pnoordhuis@vmware.com>
|
||||
pradeepj <50135054+pradeep288@users.noreply.github.com>
|
||||
Pranshu Jain <jpranshu@vmware.com>
|
||||
prydin <prydin@vmware.com>
|
||||
rconde01 <rconde01@hotmail.com>
|
||||
rHermes <teodor_spaeren@riseup.net>
|
||||
Rianto Wahyudi <rwahyudi@gmail.com>
|
||||
Ricardo Katz <rkatz@vmware.com>
|
||||
Robin Watkins <robwatkins@gmail.com>
|
||||
Rowan Jacobs <rojacobs@pivotal.io>
|
||||
Roy Ling <royling0024@gmail.com>
|
||||
rsikdar <rsikdar@berkeley.edu>
|
||||
runner.mei <runner.mei@gmail.com>
|
||||
Ryan Johnson <johnsonryan@vmware.com>
|
||||
S R Ashrith <sashrith@vmware.com>
|
||||
S.Çağlar Onur <conur@vmware.com>
|
||||
Saad Malik <saad@spectrocloud.com>
|
||||
Sam Zhu <zhusa@zhusa-a02.vmware.com>
|
||||
samzhu333 <45263849+samzhu333@users.noreply.github.com>
|
||||
Sandeep Pissay Srinivasa Rao <ssrinivas@vmware.com>
|
||||
Scott Holden <scott@nullops.io>
|
||||
Sergey Ignatov <sergey.ignatov@jetbrains.com>
|
||||
serokles <timbo.alexander@gmail.com>
|
||||
shahra <shahra@vmware.com>
|
||||
Shalini Bhaskara <sbhaskara@vmware.com>
|
||||
Shaozhen Ding <dsz0111@gmail.com>
|
||||
Shawn Neal <sneal@sneal.net>
|
||||
shylasrinivas <sshyla@vmware.com>
|
||||
sky-joker <sky.jokerxx@gmail.com>
|
||||
smaftoul <samuel.maftoul@gmail.com>
|
||||
smahadik <smahadik@vmware.com>
|
||||
Sten Feldman <exile@chamber.ee>
|
||||
Stepan Mazurov <smazurov@gmail.com>
|
||||
Steve Purcell <steve@sanityinc.com>
|
||||
Sudhindra Aithal <sudhiaithal@pensando.io>
|
||||
SUMIT AGRAWAL <asumit@vmware.com>
|
||||
Sunny Carter <sunny.carter@metaswitch.com>
|
||||
syuparn <s.hello.spagetti@gmail.com>
|
||||
Takaaki Furukawa <takaaki.frkw@gmail.com>
|
||||
Tamas Eger <tamas.eger@bitrise.io>
|
||||
Tanay Kothari <tkothari@vmware.com>
|
||||
tanishi <tanishi503@gmail.com>
|
||||
Ted Zlatanov <tzz@lifelogs.com>
|
||||
Thad Craft <tcraft@pivotal.io>
|
||||
Thibaut Ackermann <thibaut.ackermann@alcatel-lucent.com>
|
||||
Tim McNamara <tim.mcnamara@canonical.com>
|
||||
Tjeu Kayim <15987676+TjeuKayim@users.noreply.github.com>
|
||||
Toomas Pelberg <toomas.pelberg@playtech.com>
|
||||
Trevor Dawe <trevor.dawe@gmail.com>
|
||||
tshihad <tshihad9@gmail.com>
|
||||
Uwe Bessle <Uwe.Bessle@iteratec.de>
|
||||
Vadim Egorov <vegorov@vmware.com>
|
||||
Vikram Krishnamurthy <vikramkrishnamu@vmware.com>
|
||||
volanja <volaaanja@gmail.com>
|
||||
Volodymyr Bobyr <pupsua@gmail.com>
|
||||
Waldek Maleska <w.maleska@gmail.com>
|
||||
William Lam <wlam@vmware.com>
|
||||
Witold Krecicki <wpk@culm.net>
|
||||
xing-yang <xingyang105@gmail.com>
|
||||
xinyanw409 <wxinyan@vmware.com>
|
||||
Yang Yang <yangy@vmware.com>
|
||||
yangxi <yangxi@vmware.com>
|
||||
Yann Hodique <yhodique@google.com>
|
||||
Yash Nitin Desai <desaiy@vmware.com>
|
||||
Yassine TIJANI <ytijani@vmware.com>
|
||||
Yi Jiang <yijiang@vmware.com>
|
||||
yiyingy <yiyingy@vmware.com>
|
||||
ykakarap <yuva2811@gmail.com>
|
||||
Yogesh Sobale <6104071+ysobale@users.noreply.github.com>
|
||||
Yue Yin <yueyin@yuyin-a01.vmware.com>
|
||||
Yun Zhou <yunz@vmware.com>
|
||||
Yuya Kusakabe <yuya.kusakabe@gmail.com>
|
||||
Zacharias Taubert <zacharias.taubert@gmail.com>
|
||||
Zach G <zguan@vmware.com>
|
||||
Zach Tucker <ztucker@vmware.com>
|
||||
Zacharias Taubert <zacharias.taubert@gmail.com>
|
||||
Zee Yang <zeey@vmware.com>
|
||||
zyuxin <zyuxin@vmware.com>
|
||||
Кузаков Евгений <kuzakov@satel.org>
|
||||
|
4
vendor/github.com/vmware/govmomi/Dockerfile
generated
vendored
4
vendor/github.com/vmware/govmomi/Dockerfile
generated
vendored
@@ -1,4 +0,0 @@
|
||||
FROM scratch
|
||||
LABEL maintainer="fabio@vmware.com"
|
||||
COPY govc /
|
||||
ENTRYPOINT [ "/govc" ]
|
45
vendor/github.com/vmware/govmomi/Dockerfile.govc
generated
vendored
Normal file
45
vendor/github.com/vmware/govmomi/Dockerfile.govc
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
# Create a builder container
|
||||
# golang:1.18.0-buster amd64
|
||||
FROM golang@sha256:7d39537344486528f8cdb3bd8adb98ab7f0f4236044b6944fed8631da35a4ce5 AS build
|
||||
WORKDIR /go/src/app
|
||||
|
||||
# Create appuser to isolate potential vulnerabilities
|
||||
# See https://stackoverflow.com/a/55757473/12429735
|
||||
ENV USER=appuser
|
||||
ENV UID=10001
|
||||
RUN adduser \
|
||||
--disabled-password \
|
||||
--gecos "" \
|
||||
--shell "/sbin/nologin" \
|
||||
--no-create-home \
|
||||
--uid "${UID}" \
|
||||
"${USER}"
|
||||
|
||||
# Create a new tmp directory so no bad actors can manipulate it
|
||||
RUN mkdir /temporary-tmp-directory && chmod 777 /temporary-tmp-directory
|
||||
|
||||
###############################################################################
|
||||
# Final stage
|
||||
FROM scratch
|
||||
|
||||
# Allow container to use latest TLS certificates
|
||||
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
|
||||
|
||||
# Copy over appuser to run as non-root
|
||||
COPY --from=build /etc/passwd /etc/passwd
|
||||
COPY --from=build /etc/group /etc/group
|
||||
|
||||
# Copy over the /tmp directory for golang/os.TmpDir
|
||||
COPY --chown=appuser --from=build /temporary-tmp-directory /tmp
|
||||
|
||||
# Copy application from external build
|
||||
COPY govc /govc
|
||||
|
||||
# Run all commands as non-root
|
||||
USER appuser:appuser
|
||||
|
||||
# session cache, etc
|
||||
ENV GOVMOMI_HOME=/tmp
|
||||
|
||||
# Set CMD to application with container defaults
|
||||
CMD ["/govc"]
|
47
vendor/github.com/vmware/govmomi/Dockerfile.vcsim
generated
vendored
Normal file
47
vendor/github.com/vmware/govmomi/Dockerfile.vcsim
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
# Create a builder container
|
||||
# golang:1.18.0-buster amd64
|
||||
FROM golang@sha256:7d39537344486528f8cdb3bd8adb98ab7f0f4236044b6944fed8631da35a4ce5 AS build
|
||||
WORKDIR /go/src/app
|
||||
|
||||
# Create appuser to isolate potential vulnerabilities
|
||||
# See https://stackoverflow.com/a/55757473/12429735
|
||||
ENV USER=appuser
|
||||
ENV UID=10001
|
||||
RUN adduser \
|
||||
--disabled-password \
|
||||
--gecos "" \
|
||||
--home "/nonexistent" \
|
||||
--shell "/sbin/nologin" \
|
||||
--no-create-home \
|
||||
--uid "${UID}" \
|
||||
"${USER}"
|
||||
|
||||
# Create a new tmp directory so no bad actors can manipulate it
|
||||
RUN mkdir /temporary-tmp-directory && chmod 777 /temporary-tmp-directory
|
||||
|
||||
###############################################################################
|
||||
# Final stage
|
||||
FROM scratch
|
||||
|
||||
# Run all commands as non-root
|
||||
USER appuser:appuser
|
||||
|
||||
# Allow container to use latest TLS certificates
|
||||
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
|
||||
|
||||
# Copy over appuser to run as non-root
|
||||
COPY --from=build /etc/passwd /etc/passwd
|
||||
COPY --from=build /etc/group /etc/group
|
||||
|
||||
# Copy over the /tmp directory for golang/os.TmpDir
|
||||
COPY --chown=appuser --from=build /temporary-tmp-directory /tmp
|
||||
|
||||
# Expose application port
|
||||
EXPOSE 8989
|
||||
|
||||
# Copy application from external build
|
||||
COPY vcsim /vcsim
|
||||
|
||||
# Set entrypoint to application with container defaults
|
||||
ENTRYPOINT [ "/vcsim" ]
|
||||
CMD ["-l", "0.0.0.0:8989"]
|
60
vendor/github.com/vmware/govmomi/Gopkg.lock
generated
vendored
60
vendor/github.com/vmware/govmomi/Gopkg.lock
generated
vendored
@@ -1,60 +0,0 @@
|
||||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
branch = "improvements"
|
||||
digest = "1:b183578c34fabccaf65f1a57d2efeec2086abdce1446978d69ab3a0016cb750c"
|
||||
name = "github.com/davecgh/go-xdr"
|
||||
packages = ["xdr2"]
|
||||
pruneopts = "NUT"
|
||||
revision = "4930550ba2e22f87187498acfd78348b15f4e7a8"
|
||||
source = "https://github.com/rasky/go-xdr"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:1ab18cf8c2084968d6dca0dd46fbda9efba08664ecd7957b63c7ca57bb2455df"
|
||||
name = "github.com/google/uuid"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "6a5e28554805e78ea6141142aba763936c4761c0"
|
||||
|
||||
[[projects]]
|
||||
branch = "govmomi"
|
||||
digest = "1:f49ed6cb2129e9a3ce9dde5037cb243b5849c0ec0c7973b9d1e987872d8b8cc6"
|
||||
name = "github.com/kr/pretty"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "2ee9d7453c02ef7fa518a83ae23644eb8872186a"
|
||||
source = "https://github.com/dougm/pretty"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:c3a7836b5904db0f8b609595b619916a6831cb35b8b714aec39f96d00c6155d8"
|
||||
name = "github.com/kr/text"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "7cafcd837844e784b526369c9bce262804aebc60"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:4bea31865971675c482ed875caeabe7d2182dcb47d52900b7da5236d66dc9970"
|
||||
name = "github.com/vmware/vmw-guestinfo"
|
||||
packages = [
|
||||
"bdoor",
|
||||
"message",
|
||||
"vmcheck",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "25eff159a728be87e103a0b8045e08273f4dbec4"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
input-imports = [
|
||||
"github.com/davecgh/go-xdr/xdr2",
|
||||
"github.com/google/uuid",
|
||||
"github.com/kr/pretty",
|
||||
"github.com/vmware/vmw-guestinfo/message",
|
||||
"github.com/vmware/vmw-guestinfo/vmcheck",
|
||||
]
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
19
vendor/github.com/vmware/govmomi/Gopkg.toml
generated
vendored
19
vendor/github.com/vmware/govmomi/Gopkg.toml
generated
vendored
@@ -1,19 +0,0 @@
|
||||
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
|
||||
# for detailed Gopkg.toml documentation.
|
||||
#
|
||||
# Refer to https://github.com/toml-lang/toml for detailed TOML docs.
|
||||
|
||||
[prune]
|
||||
non-go = true
|
||||
go-tests = true
|
||||
unused-packages = true
|
||||
|
||||
[[constraint]]
|
||||
branch = "improvements"
|
||||
name = "github.com/davecgh/go-xdr"
|
||||
source = "https://github.com/rasky/go-xdr"
|
||||
|
||||
[[constraint]]
|
||||
branch = "govmomi"
|
||||
name = "github.com/kr/pretty"
|
||||
source = "https://github.com/dougm/pretty"
|
161
vendor/github.com/vmware/govmomi/Makefile
generated
vendored
161
vendor/github.com/vmware/govmomi/Makefile
generated
vendored
@@ -1,29 +1,158 @@
|
||||
.PHONY: test
|
||||
# Copyright (c) 2021 VMware, Inc. All Rights Reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
all: check test
|
||||
# If you update this file, please follow
|
||||
# https://www.thapaliya.com/en/writings/well-documented-makefiles/
|
||||
|
||||
check: goimports govet
|
||||
# Ensure Make is run with bash shell as some syntax below is bash-specific
|
||||
SHELL := /usr/bin/env bash
|
||||
|
||||
goimports:
|
||||
@echo checking go imports...
|
||||
@command -v goimports >/dev/null 2>&1 || go get golang.org/x/tools/cmd/goimports
|
||||
@! goimports -d . 2>&1 | egrep -v '^$$'
|
||||
# Print the help/usage when make is executed without any other arguments
|
||||
.DEFAULT_GOAL := help
|
||||
|
||||
govet:
|
||||
@echo checking go vet...
|
||||
@go tool vet -structtags=false -methods=false $$(find . -mindepth 1 -maxdepth 1 -type d -not -name vendor)
|
||||
|
||||
install:
|
||||
## --------------------------------------
|
||||
## Help
|
||||
## --------------------------------------
|
||||
|
||||
.PHONY: help
|
||||
help: ## Display usage
|
||||
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make [target] \033[36m\033[0m\n\nTargets:\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-20s\033[0m %s\n", $$1, $$2 }' $(MAKEFILE_LIST)
|
||||
|
||||
|
||||
## --------------------------------------
|
||||
## Locations and programs
|
||||
## --------------------------------------
|
||||
|
||||
# Directories
|
||||
BIN_DIR := bin
|
||||
TOOLS_DIR := hack/tools
|
||||
TOOLS_BIN_DIR := $(TOOLS_DIR)/bin
|
||||
|
||||
# Tooling binaries
|
||||
GO ?= $(shell command -v go 2>/dev/null)
|
||||
GOLANGCI_LINT := $(TOOLS_BIN_DIR)/golangci-lint
|
||||
|
||||
|
||||
## --------------------------------------
|
||||
## Prerequisites
|
||||
## --------------------------------------
|
||||
|
||||
# Do not proceed unless the go binary is present.
|
||||
ifeq (,$(strip $(GO)))
|
||||
$(error The "go" program cannot be found)
|
||||
endif
|
||||
|
||||
|
||||
## --------------------------------------
|
||||
## Linting and fixing linter errors
|
||||
## --------------------------------------
|
||||
|
||||
.PHONY: lint
|
||||
lint: ## Run all the lint targets
|
||||
$(MAKE) lint-go-full
|
||||
|
||||
GOLANGCI_LINT_FLAGS ?= --fast=true
|
||||
.PHONY: lint-go
|
||||
lint-go: $(GOLANGCI_LINT) ## Lint codebase
|
||||
$(GOLANGCI_LINT) run -v $(GOLANGCI_LINT_FLAGS)
|
||||
|
||||
.PHONY: lint-go-full
|
||||
lint-go-full: GOLANGCI_LINT_FLAGS = --fast=false
|
||||
lint-go-full: lint-go ## Run slower linters to detect possible issues
|
||||
|
||||
.PHONY: fix
|
||||
fix: GOLANGCI_LINT_FLAGS = --fast=false --fix
|
||||
fix: lint-go ## Tries to fix errors reported by lint-go-full target
|
||||
|
||||
.PHONY: check
|
||||
check: lint-go-full
|
||||
check: ## Run linters
|
||||
|
||||
|
||||
## --------------------------------------
|
||||
## Tooling Binaries
|
||||
## --------------------------------------
|
||||
|
||||
TOOLING_BINARIES := $(GOLANGCI_LINT)
|
||||
tools: $(TOOLING_BINARIES) ## Build tooling binaries
|
||||
.PHONY: $(TOOLING_BINARIES)
|
||||
$(TOOLING_BINARIES):
|
||||
cd $(TOOLS_DIR); make $(@F)
|
||||
|
||||
|
||||
## --------------------------------------
|
||||
## Build / Install
|
||||
## --------------------------------------
|
||||
.PHONY: install
|
||||
install: ## Install govc and vcsim
|
||||
$(MAKE) -C govc install
|
||||
$(MAKE) -C vcsim install
|
||||
|
||||
go-test:
|
||||
GORACE=history_size=5 go test -timeout 5m -count 1 -race -v $(TEST_OPTS) ./...
|
||||
|
||||
## --------------------------------------
|
||||
## Generate
|
||||
## --------------------------------------
|
||||
|
||||
.PHONY: mod
|
||||
mod: ## Runs go mod tidy to validate modules
|
||||
go mod tidy -v
|
||||
|
||||
.PHONY: mod-get
|
||||
mod-get: ## Downloads and caches the modules
|
||||
go mod download
|
||||
|
||||
.PHONY: doc
|
||||
doc: install
|
||||
doc: ## Generates govc USAGE.md
|
||||
./govc/usage.sh > ./govc/USAGE.md
|
||||
|
||||
|
||||
## --------------------------------------
|
||||
## Tests
|
||||
## --------------------------------------
|
||||
|
||||
# Test options
|
||||
TEST_COUNT ?= 1
|
||||
TEST_TIMEOUT ?= 5m
|
||||
TEST_RACE_HISTORY_SIZE ?= 5
|
||||
GORACE ?= history_size=$(TEST_RACE_HISTORY_SIZE)
|
||||
|
||||
ifeq (-count,$(findstring -count,$(TEST_OPTS)))
|
||||
$(error Use TEST_COUNT to override this option)
|
||||
endif
|
||||
|
||||
ifeq (-race,$(findstring -race,$(TEST_OPTS)))
|
||||
$(error The -race flag is enabled by default & cannot be specified in TEST_OPTS)
|
||||
endif
|
||||
|
||||
ifeq (-timeout,$(findstring -timeout,$(TEST_OPTS)))
|
||||
$(error Use TEST_TIMEOUT to override this option)
|
||||
endif
|
||||
|
||||
.PHONY: go-test
|
||||
go-test: ## Runs go unit tests with race detector enabled
|
||||
GORACE=$(GORACE) $(GO) test \
|
||||
-count $(TEST_COUNT) \
|
||||
-race \
|
||||
-timeout $(TEST_TIMEOUT) \
|
||||
-v $(TEST_OPTS) \
|
||||
./...
|
||||
|
||||
.PHONY: govc-test
|
||||
govc-test: install
|
||||
govc-test: ## Runs govc bats tests
|
||||
./govc/test/images/update.sh
|
||||
(cd govc/test && ./vendor/github.com/sstephenson/bats/libexec/bats -t .)
|
||||
|
||||
test: go-test govc-test
|
||||
.PHONY: govc-test-sso
|
||||
govc-test-sso: install
|
||||
./govc/test/images/update.sh
|
||||
(cd govc/test && SSO_BATS=1 ./vendor/github.com/sstephenson/bats/libexec/bats -t sso.bats)
|
||||
|
||||
doc: install
|
||||
./govc/usage.sh > ./govc/USAGE.md
|
||||
.PHONY: govc-test-sso-assert-cert
|
||||
govc-test-sso-assert-cert:
|
||||
SSO_BATS_ASSERT_CERT=1 $(MAKE) govc-test-sso
|
||||
|
||||
.PHONY: test
|
||||
test: go-test govc-test ## Runs go-test and govc-test
|
||||
|
159
vendor/github.com/vmware/govmomi/README.md
generated
vendored
159
vendor/github.com/vmware/govmomi/README.md
generated
vendored
@@ -1,94 +1,131 @@
|
||||
[](https://travis-ci.org/vmware/govmomi)
|
||||
[](https://goreportcard.com/report/github.com/vmware/govmomi)
|
||||
<!-- markdownlint-disable first-line-h1 no-inline-html -->
|
||||
|
||||
[][ci-build]
|
||||
[][ci-tests]
|
||||
[][go-report-card]
|
||||
[][latest-release]
|
||||
[][go-reference]
|
||||
[][go-version]
|
||||
|
||||
# govmomi
|
||||
|
||||
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 Server).
|
||||
|
||||
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
|
||||
* [govc][govc] - vSphere CLI
|
||||
* [vcsim][vcsim] - vSphere API mock framework
|
||||
* [toolbox][toolbox] - VM guest tools framework
|
||||
|
||||
## Compatibility
|
||||
|
||||
This library is built for and tested against ESXi and vCenter 6.0, 6.5 and 6.7.
|
||||
This library supports vCenter Server and ESXi versions following the [VMware Product Lifecycle Matrix][reference-lifecycle].
|
||||
|
||||
It may work with versions 5.5 and 5.1, but neither are officially supported.
|
||||
Product versions that are end of support may work, but are not officially supported.
|
||||
|
||||
## Documentation
|
||||
|
||||
The APIs exposed by this library very closely follow the API described in the [VMware vSphere API Reference Documentation][apiref].
|
||||
Refer to this document to become familiar with the upstream API.
|
||||
The APIs exposed by this library closely follow the API described in the [VMware vSphere API Reference Documentation][reference-api]. Refer to the documentation to become familiar with the upstream API.
|
||||
|
||||
The code in the `govmomi` package is a wrapper for the code that is generated from the vSphere API description.
|
||||
It primarily provides convenience functions for working with the vSphere API.
|
||||
See [godoc.org][godoc] for documentation.
|
||||
|
||||
[apiref]:http://pubs.vmware.com/vsphere-6-5/index.jsp#com.vmware.wssdk.apiref.doc/right-pane.html
|
||||
[godoc]:http://godoc.org/github.com/vmware/govmomi
|
||||
The code in the `govmomi` package is a wrapper for the code that is generated from the vSphere API description. It primarily provides convenience functions for working with the vSphere API. See [godoc.org][reference-godoc] for documentation.
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
### govmomi (Package)
|
||||
|
||||
```bash
|
||||
go get -u github.com/vmware/govmomi
|
||||
```
|
||||
|
||||
### Binaries and Docker Images for `govc` and `vcsim`
|
||||
|
||||
Installation instructions, released binaries, and Docker images are documented in the respective README files of [`govc`][govc] and [`vcsim`][vcsim].
|
||||
|
||||
## Discussion
|
||||
|
||||
Contributors and users are encouraged to collaborate using GitHub issues and/or
|
||||
[Slack](https://vmwarecode.slack.com/messages/govmomi).
|
||||
Access to Slack requires a [VMware {code} membership](https://code.vmware.com/join/).
|
||||
The project encourages the community to collaborate using GitHub [issues][govmomi-github-issues], GitHub [discussions][govmomi-github-discussions], and [Slack][slack-channel].
|
||||
|
||||
> **Note**
|
||||
> Access to Slack requires a free [VMware {code}][slack-join] developer program membership.
|
||||
|
||||
## Status
|
||||
|
||||
Changes to the API are subject to [semantic versioning](http://semver.org).
|
||||
Changes to the API are subject to [semantic versioning][reference-semver].
|
||||
|
||||
Refer to the [CHANGELOG](CHANGELOG.md) for version to version changes.
|
||||
Refer to the [CHANGELOG][govmomi-changelog] for version to version changes.
|
||||
|
||||
## Projects using govmomi
|
||||
## Notable Projects Using govmomi
|
||||
|
||||
* [Docker Machine](https://github.com/docker/machine/tree/master/drivers/vmwarevsphere)
|
||||
* [collectd-vsphere][project-travisci-collectd-vsphere]
|
||||
* [Docker LinuxKit][project-docker-linuxKit]
|
||||
* [Elastic Agent VMware vSphere integration][project-elastic-agent]
|
||||
* [Gru][project-gru]
|
||||
* [Juju][project-juju]
|
||||
* [Jupiter Brain][project-travisci-jupiter-brain]
|
||||
* [Kubernetes vSphere Cloud Provider][project-k8s-cloud-provider]
|
||||
* [Kubernetes Cluster API][project-k8s-cluster-api]
|
||||
* [OPS][project-nanovms-ops]
|
||||
* [Packer Plugin for VMware vSphere][project-hashicorp-packer-plugin-vsphere]
|
||||
* [Rancher][project-rancher]
|
||||
* [Terraform Provider for VMware vSphere][project-hashicorp-terraform-provider-vsphere]
|
||||
* [Telegraf][project-influxdata-telegraf]
|
||||
* [VMware Event Broker Appliance][project-vmware-veba]
|
||||
* [VMware vSphere Integrated Containers Engine][project-vmware-vic]
|
||||
* [VMware vSphere 7.0][project-vmware-vsphere]
|
||||
|
||||
* [Docker InfraKit](https://github.com/docker/infrakit/tree/master/pkg/provider/vsphere)
|
||||
## Related Projects
|
||||
|
||||
* [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 Cloud Provider](https://github.com/kubernetes/cloud-provider-vsphere)
|
||||
|
||||
* [Kubernetes Cluster API](https://github.com/kubernetes-sigs/cluster-api-provider-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)
|
||||
|
||||
* [Travis CI](https://github.com/travis-ci/jupiter-brain)
|
||||
|
||||
* [collectd-vsphere](https://github.com/travis-ci/collectd-vsphere)
|
||||
|
||||
* [Gru](https://github.com/dnaeon/gru)
|
||||
|
||||
* [Libretto](https://github.com/apcera/libretto/tree/master/virtualmachine/vsphere)
|
||||
|
||||
* [Telegraf](https://github.com/influxdata/telegraf/tree/master/plugins/inputs/vsphere)
|
||||
|
||||
* [Open Storage](https://github.com/libopenstorage/openstorage/tree/master/pkg/storageops/vsphere)
|
||||
|
||||
## Related projects
|
||||
|
||||
* [rbvmomi](https://github.com/vmware/rbvmomi)
|
||||
|
||||
* [pyvmomi](https://github.com/vmware/pyvmomi)
|
||||
* [go-vmware-nsxt][reference-go-vmware-nsxt]
|
||||
* [pyvmomi][reference-pyvmomi]
|
||||
* [rbvmomi][reference-rbvmomi]
|
||||
|
||||
## License
|
||||
|
||||
govmomi is available under the [Apache 2 license](LICENSE.txt).
|
||||
govmomi is available under the [Apache 2 License][govmomi-license].
|
||||
|
||||
## Name
|
||||
|
||||
Pronounced: _go·v·mom·ie_
|
||||
|
||||
Follows pyvmomi and rbvmomi: language prefix + the vSphere acronym "VM Object Management Infrastructure".
|
||||
|
||||
[//]: Links
|
||||
|
||||
[ci-build]: https://github.com/vmware/govmomi/actions/workflows/govmomi-build.yaml
|
||||
[ci-tests]: https://github.com/vmware/govmomi/actions/workflows/govmomi-go-tests.yaml
|
||||
[latest-release]: https://github.com/vmware/govmomi/releases/latest
|
||||
[govc]: govc/README.md
|
||||
[govmomi-github-issues]: https://github.com/vmware/govmomi/issues
|
||||
[govmomi-github-discussions]: https://github.com/vmware/govmomi/discussions
|
||||
[govmomi-changelog]: CHANGELOG.md
|
||||
[govmomi-license]: LICENSE.txt
|
||||
[go-reference]: https://pkg.go.dev/github.com/vmware/govmomi
|
||||
[go-report-card]: https://goreportcard.com/report/github.com/vmware/govmomi
|
||||
[go-version]: https://github.com/vmware/govmomi
|
||||
[project-docker-linuxKit]: https://github.com/linuxkit/linuxkit/tree/master/src/cmd/linuxkit
|
||||
[project-elastic-agent]: https://github.com/elastic/integrations/tree/main/packages/vsphere
|
||||
[project-gru]: https://github.com/dnaeon/gru
|
||||
[project-hashicorp-packer-plugin-vsphere]: https://github.com/hashicorp/packer-plugin-vsphere
|
||||
[project-hashicorp-terraform-provider-vsphere]: https://github.com/hashicorp/terraform-provider-vsphere
|
||||
[project-influxdata-telegraf]: https://github.com/influxdata/telegraf/tree/master/plugins/inputs/vsphere
|
||||
[project-juju]: https://github.com/juju/juju
|
||||
[project-k8s-cloud-provider]: https://github.com/kubernetes/cloud-provider-vsphere
|
||||
[project-k8s-cluster-api]: https://github.com/kubernetes-sigs/cluster-api-provider-vsphere
|
||||
[project-nanovms-ops]: https://github.com/nanovms/ops
|
||||
[project-rancher]: https://github.com/rancher/rancher/blob/master/pkg/api/norman/customization/vsphere/listers.go
|
||||
[project-travisci-collectd-vsphere]: https://github.com/travis-ci/collectd-vsphere
|
||||
[project-travisci-jupiter-brain]: https://github.com/travis-ci/jupiter-brain
|
||||
[project-vmware-veba]: https://github.com/vmware-samples/vcenter-event-broker-appliance/tree/development/vmware-event-router
|
||||
[project-vmware-vic]: https://github.com/vmware/vic
|
||||
[project-vmware-vsphere]: https://docs.vmware.com/en/VMware-vSphere/7.0/rn/vsphere-esxi-vcenter-server-7-vsphere-with-kubernetes-release-notes.html
|
||||
[reference-api]: https://developer.vmware.com/apis/968/vsphere
|
||||
[reference-godoc]: http://godoc.org/github.com/vmware/govmomi
|
||||
[reference-go-vmware-nsxt]: https://github.com/vmware/go-vmware-nsxt
|
||||
[reference-lifecycle]: https://lifecycle.vmware.com
|
||||
[reference-pyvmomi]: https://github.com/vmware/pyvmomi
|
||||
[reference-rbvmomi]: https://github.com/vmware/rbvmomi
|
||||
[reference-semver]: http://semver.org
|
||||
[slack-join]: https://developer.vmware.com/join/
|
||||
[slack-channel]: https://vmwarecode.slack.com/messages/govmomi
|
||||
[toolbox]: toolbox/README.md
|
||||
[vcsim]: vcsim/README.md
|
||||
|
225
vendor/github.com/vmware/govmomi/RELEASE.md
generated
vendored
Normal file
225
vendor/github.com/vmware/govmomi/RELEASE.md
generated
vendored
Normal file
@@ -0,0 +1,225 @@
|
||||
# How to create a `govmomi` Release on Github
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> The steps outlined in this document can only be performed by maintainers or
|
||||
> administrators of this project.
|
||||
|
||||
The release automation is based on Github
|
||||
[Actions](https://github.com/features/actions) and has been improved over time
|
||||
to simplify the experience for creating `govmomi` releases.
|
||||
|
||||
The Github Actions release [workflow](.github/workflows/govmomi-release.yaml)
|
||||
uses [`goreleaser`](http://goreleaser.com/) and automatically creates/pushes:
|
||||
|
||||
- Release artifacts for `govc` and `vcsim` to the
|
||||
[release](https://github.com/vmware/govmomi/releases) page, including
|
||||
`LICENSE.txt`, `README` and `CHANGELOG`
|
||||
- Docker images for `vmware/govc` and `vmware/vcsim` to Docker Hub
|
||||
- Source code
|
||||
|
||||
Starting with release tag `v0.29.0`, releases are not tagged on the `master`
|
||||
branch anymore but a dedicated release branch, for example `release-0.29`. This
|
||||
process has already been followed for patch releases and back-ports.
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> If you create a release after the `v0.29.0` tag, start
|
||||
> [here](#creating-a-release-after-v0290). To create a release with an older
|
||||
> tag, e.g. cherrypick or back-port, continue
|
||||
> [here](#creating-a-release-before-v0290).
|
||||
|
||||
## Creating a release after Version `v0.29.0`
|
||||
|
||||
The release process from `v0.29.0` has been further simplified and is done
|
||||
through the Github UI. The only pre-requirement is creating a release branch,
|
||||
which can be done through the Github UI or `git` CLI.
|
||||
|
||||
This guide describes the CLI process.
|
||||
|
||||
### Verify `master` branch is up to date with the remote
|
||||
|
||||
```console
|
||||
git checkout master
|
||||
git fetch -avp
|
||||
git diff master origin/master
|
||||
|
||||
# if your local and remote branches diverge run
|
||||
git pull origin/master
|
||||
```
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> These steps assume `origin` to point to the remote
|
||||
> `https://github.com/vmware/govmomi`, respectively
|
||||
> `git@github.com:vmware/govmomi`.
|
||||
|
||||
### Create a release branch
|
||||
|
||||
For new releases, create a release branch from the most recent commit in
|
||||
`master`, e.g. `release-0.30`.
|
||||
|
||||
```console
|
||||
export RELEASE_BRANCH=release-0.30
|
||||
git checkout -b ${RELEASE_BRANCH}
|
||||
```
|
||||
|
||||
For maintenance/patch releases on **existing** release branches **after** tag
|
||||
`v0.29.0` simply checkout the existing release branch and add commits to the
|
||||
existing release branch.
|
||||
|
||||
### Verify `make docs` and `CONTRIBUTORS` are up to date
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> Run the following commands and commit any changes to the release branch before
|
||||
> proceeding with the release.
|
||||
|
||||
```console
|
||||
make doc
|
||||
./scripts/contributors.sh
|
||||
if [ -z "$(git status --porcelain)" ]; then
|
||||
echo "working directory clean: proceed with release"
|
||||
else
|
||||
echo "working directory dirty: please commit changes"
|
||||
fi
|
||||
|
||||
# perform git add && git commit ... in case there were changes
|
||||
```
|
||||
|
||||
### Push the release branch
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> Do not create a tag as this will be done by the release automation.
|
||||
|
||||
The final step is pushing the new/updated release branch.
|
||||
|
||||
```console
|
||||
git push origin ${RELEASE_BRANCH}
|
||||
```
|
||||
|
||||
### Create a release in the Github UI
|
||||
|
||||
Open the `govmomi` Github [repository](https://github.com/vmware/govmomi) and
|
||||
navigate to `Actions -> Workflows -> Release`.
|
||||
|
||||
Click `Run Workflow` which opens a dropdown list.
|
||||
|
||||
Select the new/updated branch, e.g. `release-0.30`, i.e. **not** the `master`
|
||||
branch.
|
||||
|
||||
Specify a semantic `tag` to associate with the release, e.g. `v0.30.0`.
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> This tag **must not** exist or the release will fail during the validation
|
||||
> phase.
|
||||
|
||||
By default, a dry-run is performed to rule out most (but not all) errors during
|
||||
a release. If you do not want to perform a dry-run, e.g. to finally create a
|
||||
release, deselect the `Verify release workflow ...` checkbox.
|
||||
|
||||
Click `Run Workflow` to kick off the workflow.
|
||||
|
||||
After successful completion and if the newly created `tag` is the **latest**
|
||||
(semantic version sorted) tag in the repository, a PR is automatically opened
|
||||
against the `master` branch to update the `CHANGELOG`. Please review and merge
|
||||
accordingly.
|
||||
|
||||
## Creating a release before Version `v0.29.0`
|
||||
|
||||
The release process before `v0.29.0` differs since it's based on manually
|
||||
creating and pushing tags. Here, on every new tag matching `v*` pushed to the
|
||||
repository a Github Action Release Workflow is executed.
|
||||
|
||||
### Verify `master` branch is up to date with the remote
|
||||
|
||||
```console
|
||||
git checkout master
|
||||
git fetch -avp
|
||||
git diff master origin/master
|
||||
|
||||
# if your local and remote branches diverge run
|
||||
git pull origin/master
|
||||
```
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> These steps assume `origin` to point to the remote
|
||||
> `https://github.com/vmware/govmomi`, respectively
|
||||
> `git@github.com:vmware/govmomi`.
|
||||
|
||||
### Create a release branch
|
||||
|
||||
Pick a reference (commit, branch or tag) **before** the `v0.29.0` tag and create
|
||||
a release branch from there.
|
||||
|
||||
The following example creates a cherrypick release (`v0.28.1`) based on the
|
||||
`v0.28.0` tag.
|
||||
|
||||
```console
|
||||
export RELEASE_BRANCH=release-0.28
|
||||
git checkout -b ${RELEASE_BRANCH} v0.28.0
|
||||
```
|
||||
|
||||
Optionally, incorporate (cherry-pick) commits into the branch.
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> Make sure that these commits/ranges do not contain commits after the `v0.29.0`
|
||||
> tag which include release automation changes, i.e. files in `.github/workflows/`!
|
||||
|
||||
### Verify `make docs` and `CONTRIBUTORS` are up to date
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> Run the following commands and commit any changes to the release branch before
|
||||
> proceeding with the release.
|
||||
|
||||
```console
|
||||
make doc
|
||||
./scripts/contributors.sh
|
||||
if [ -z "$(git status --porcelain)" ]; then
|
||||
echo "working directory clean: proceed with release"
|
||||
else
|
||||
echo "working directory dirty: please commit changes"
|
||||
fi
|
||||
|
||||
# perform git add && git commit ... in case there were changes
|
||||
```
|
||||
|
||||
### Set `RELEASE_VERSION` variable
|
||||
|
||||
This variable is used and referenced in the subsequent commands. Set it to the
|
||||
**upcoming** release version, adhering to the [semantic
|
||||
versioning](https://semver.org/) scheme:
|
||||
|
||||
```console
|
||||
export RELEASE_VERSION=v0.28.1
|
||||
```
|
||||
|
||||
### Create the Git Tag
|
||||
|
||||
```console
|
||||
git tag -a ${RELEASE_VERSION} -m "Release ${RELEASE_VERSION}"
|
||||
```
|
||||
|
||||
### Push the new Tag
|
||||
|
||||
```console
|
||||
# Will trigger Github Actions Release Workflow
|
||||
git push --atomic origin ${RELEASE_BRANCH} refs/tags/${RELEASE_VERSION}
|
||||
```
|
||||
|
||||
### Verify Github Action Release Workflow
|
||||
|
||||
After pushing a new release tag, the status of the workflow can be inspected
|
||||
[here](https://github.com/vmware/govmomi/actions/workflows/govmomi-release.yaml).
|
||||
|
||||

|
||||
|
||||
After a successful release, a pull request is automatically created by the
|
||||
Github Actions bot to update the [CHANGELOG](CHANGELOG.md). This `CHANGELOG.md`
|
||||
is also generated with `git-chglog` but uses a slightly different template
|
||||
(`.chglog/CHANGELOG.tpl.md`) for rendering (issue/PR refs are excluded).
|
104
vendor/github.com/vmware/govmomi/find/finder.go
generated
vendored
104
vendor/github.com/vmware/govmomi/find/finder.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2014-2017 VMware, Inc. All Rights Reserved.
|
||||
Copyright (c) 2014-2020 VMware, Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -22,9 +22,11 @@ import (
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/vmware/govmomi/internal"
|
||||
"github.com/vmware/govmomi/list"
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/property"
|
||||
"github.com/vmware/govmomi/view"
|
||||
"github.com/vmware/govmomi/vim25"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
@@ -38,16 +40,26 @@ type Finder struct {
|
||||
folders *object.DatacenterFolders
|
||||
}
|
||||
|
||||
func NewFinder(client *vim25.Client, all bool) *Finder {
|
||||
func NewFinder(client *vim25.Client, all ...bool) *Finder {
|
||||
props := false
|
||||
if len(all) == 1 {
|
||||
props = all[0]
|
||||
}
|
||||
|
||||
f := &Finder{
|
||||
client: client,
|
||||
si: object.NewSearchIndex(client),
|
||||
r: recurser{
|
||||
Collector: property.DefaultCollector(client),
|
||||
All: all,
|
||||
All: props,
|
||||
},
|
||||
}
|
||||
|
||||
if len(all) == 0 {
|
||||
// attempt to avoid SetDatacenter() requirement
|
||||
f.dc, _ = f.DefaultDatacenter(context.Background())
|
||||
}
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
@@ -57,6 +69,18 @@ func (f *Finder) SetDatacenter(dc *object.Datacenter) *Finder {
|
||||
return f
|
||||
}
|
||||
|
||||
// InventoryPath composes the given object's inventory path.
|
||||
// There is no vSphere property or method that provides an inventory path directly.
|
||||
// This method uses the ManagedEntity.Parent field to determine the ancestry tree of the object and
|
||||
// the ManagedEntity.Name field for each ancestor to compose the path.
|
||||
func InventoryPath(ctx context.Context, client *vim25.Client, obj types.ManagedObjectReference) (string, error) {
|
||||
entities, err := mo.Ancestors(ctx, client, client.ServiceContent.PropertyCollector, obj)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return internal.InventoryPath(entities), nil
|
||||
}
|
||||
|
||||
// findRoot makes it possible to use "find" mode with a different root path.
|
||||
// Example: ResourcePoolList("/dc1/host/cluster1/...")
|
||||
func (f *Finder) findRoot(ctx context.Context, root *list.Element, parts []string) bool {
|
||||
@@ -93,8 +117,8 @@ func (f *Finder) find(ctx context.Context, arg string, s *spec) ([]list.Element,
|
||||
isPath := strings.Contains(arg, "/")
|
||||
|
||||
root := list.Element{
|
||||
Path: "/",
|
||||
Object: object.NewRootFolder(f.client),
|
||||
Path: "/",
|
||||
}
|
||||
|
||||
parts := list.ToParts(arg)
|
||||
@@ -109,19 +133,10 @@ func (f *Finder) find(ctx context.Context, arg string, s *spec) ([]list.Element,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mes, err := mo.Ancestors(ctx, f.client, f.client.ServiceContent.PropertyCollector, pivot.Reference())
|
||||
root.Path, err = InventoryPath(ctx, f.client, pivot.Reference())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, me := range mes {
|
||||
// Skip root entity in building inventory path.
|
||||
if me.Parent == nil {
|
||||
continue
|
||||
}
|
||||
root.Path = path.Join(root.Path, me.Name)
|
||||
}
|
||||
|
||||
root.Object = pivot
|
||||
parts = parts[1:]
|
||||
}
|
||||
@@ -253,7 +268,7 @@ func (f *Finder) managedObjectList(ctx context.Context, path string, tl bool, in
|
||||
fn = f.dcReference
|
||||
}
|
||||
|
||||
if len(path) == 0 {
|
||||
if path == "" {
|
||||
path = "."
|
||||
}
|
||||
|
||||
@@ -271,8 +286,7 @@ func (f *Finder) managedObjectList(ctx context.Context, path string, tl bool, in
|
||||
return f.find(ctx, path, s)
|
||||
}
|
||||
|
||||
// Element returns an Element for the given ManagedObjectReference
|
||||
// This method is only useful for looking up the InventoryPath of a ManagedObjectReference.
|
||||
// Element is deprecated, use InventoryPath() instead.
|
||||
func (f *Finder) Element(ctx context.Context, ref types.ManagedObjectReference) (*list.Element, error) {
|
||||
rl := func(_ context.Context) (object.Reference, error) {
|
||||
return ref, nil
|
||||
@@ -301,7 +315,7 @@ func (f *Finder) Element(ctx context.Context, ref types.ManagedObjectReference)
|
||||
// ObjectReference converts the given ManagedObjectReference to a type from the object package via object.NewReference
|
||||
// with the object.Common.InventoryPath field set.
|
||||
func (f *Finder) ObjectReference(ctx context.Context, ref types.ManagedObjectReference) (object.Reference, error) {
|
||||
e, err := f.Element(ctx, ref)
|
||||
path, err := InventoryPath(ctx, f.client, ref)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -312,7 +326,7 @@ func (f *Finder) ObjectReference(ctx context.Context, ref types.ManagedObjectRef
|
||||
SetInventoryPath(string)
|
||||
}
|
||||
|
||||
r.(common).SetInventoryPath(e.Path)
|
||||
r.(common).SetInventoryPath(path)
|
||||
|
||||
if f.dc != nil {
|
||||
if ds, ok := r.(*object.Datastore); ok {
|
||||
@@ -776,9 +790,26 @@ func (f *Finder) NetworkList(ctx context.Context, path string) ([]object.Network
|
||||
return ns, nil
|
||||
}
|
||||
|
||||
// Network finds a NetworkReference using a Name, Inventory Path, ManagedObject ID, Logical Switch UUID or Segment ID.
|
||||
// With standard vSphere networking, Portgroups cannot have the same name within the same network folder.
|
||||
// With NSX, Portgroups can have the same name, even within the same Switch. In this case, using an inventory path
|
||||
// results in a MultipleFoundError. A MOID, switch UUID or segment ID can be used instead, as both are unique.
|
||||
// See also: https://kb.vmware.com/s/article/79872#Duplicate_names
|
||||
// Examples:
|
||||
// - Name: "dvpg-1"
|
||||
// - Inventory Path: "vds-1/dvpg-1"
|
||||
// - ManagedObject ID: "DistributedVirtualPortgroup:dvportgroup-53"
|
||||
// - Logical Switch UUID: "da2a59b8-2450-4cb2-b5cc-79c4c1d2144c"
|
||||
// - Segment ID: "/infra/segments/vnet_ce50e69b-1784-4a14-9206-ffd7f1f146f7"
|
||||
func (f *Finder) Network(ctx context.Context, path string) (object.NetworkReference, error) {
|
||||
networks, err := f.NetworkList(ctx, path)
|
||||
if err != nil {
|
||||
if _, ok := err.(*NotFoundError); ok {
|
||||
net, nerr := f.networkByID(ctx, path)
|
||||
if nerr == nil {
|
||||
return net, nil
|
||||
}
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -789,6 +820,41 @@ func (f *Finder) Network(ctx context.Context, path string) (object.NetworkRefere
|
||||
return networks[0], nil
|
||||
}
|
||||
|
||||
func (f *Finder) networkByID(ctx context.Context, path string) (object.NetworkReference, error) {
|
||||
if ref := object.ReferenceFromString(path); ref != nil {
|
||||
// This is a MOID
|
||||
return object.NewReference(f.client, *ref).(object.NetworkReference), nil
|
||||
}
|
||||
|
||||
kind := []string{"DistributedVirtualPortgroup"}
|
||||
|
||||
m := view.NewManager(f.client)
|
||||
v, err := m.CreateContainerView(ctx, f.client.ServiceContent.RootFolder, kind, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer v.Destroy(ctx)
|
||||
|
||||
filter := property.Filter{
|
||||
"config.logicalSwitchUuid": path,
|
||||
"config.segmentId": path,
|
||||
}
|
||||
|
||||
refs, err := v.FindAny(ctx, kind, filter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(refs) == 0 {
|
||||
return nil, &NotFoundError{"network", path}
|
||||
}
|
||||
if len(refs) > 1 {
|
||||
return nil, &MultipleFoundError{"network", path}
|
||||
}
|
||||
|
||||
return object.NewReference(f.client, refs[0]).(object.NetworkReference), nil
|
||||
}
|
||||
|
||||
func (f *Finder) DefaultNetwork(ctx context.Context) (object.NetworkReference, error) {
|
||||
network, err := f.Network(ctx, "*")
|
||||
if err != nil {
|
||||
|
91
vendor/github.com/vmware/govmomi/history/collector.go
generated
vendored
Normal file
91
vendor/github.com/vmware/govmomi/history/collector.go
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package history
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/vmware/govmomi/property"
|
||||
"github.com/vmware/govmomi/vim25"
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
type Collector struct {
|
||||
r types.ManagedObjectReference
|
||||
c *vim25.Client
|
||||
}
|
||||
|
||||
func NewCollector(c *vim25.Client, ref types.ManagedObjectReference) *Collector {
|
||||
return &Collector{
|
||||
r: ref,
|
||||
c: c,
|
||||
}
|
||||
}
|
||||
|
||||
// Reference returns the managed object reference of this collector
|
||||
func (c Collector) Reference() types.ManagedObjectReference {
|
||||
return c.r
|
||||
}
|
||||
|
||||
// Client returns the vim25 client used by this collector
|
||||
func (c Collector) Client() *vim25.Client {
|
||||
return c.c
|
||||
}
|
||||
|
||||
// Properties wraps property.DefaultCollector().RetrieveOne() and returns
|
||||
// properties for the specified managed object reference
|
||||
func (c Collector) Properties(ctx context.Context, r types.ManagedObjectReference, ps []string, dst interface{}) error {
|
||||
return property.DefaultCollector(c.c).RetrieveOne(ctx, r, ps, dst)
|
||||
}
|
||||
|
||||
func (c Collector) Destroy(ctx context.Context) error {
|
||||
req := types.DestroyCollector{
|
||||
This: c.r,
|
||||
}
|
||||
|
||||
_, err := methods.DestroyCollector(ctx, c.c, &req)
|
||||
return err
|
||||
}
|
||||
|
||||
func (c Collector) Reset(ctx context.Context) error {
|
||||
req := types.ResetCollector{
|
||||
This: c.r,
|
||||
}
|
||||
|
||||
_, err := methods.ResetCollector(ctx, c.c, &req)
|
||||
return err
|
||||
}
|
||||
|
||||
func (c Collector) Rewind(ctx context.Context) error {
|
||||
req := types.RewindCollector{
|
||||
This: c.r,
|
||||
}
|
||||
|
||||
_, err := methods.RewindCollector(ctx, c.c, &req)
|
||||
return err
|
||||
}
|
||||
|
||||
func (c Collector) SetPageSize(ctx context.Context, maxCount int32) error {
|
||||
req := types.SetCollectorPageSize{
|
||||
This: c.r,
|
||||
MaxCount: maxCount,
|
||||
}
|
||||
|
||||
_, err := methods.SetCollectorPageSize(ctx, c.c, &req)
|
||||
return err
|
||||
}
|
63
vendor/github.com/vmware/govmomi/internal/helpers.go
generated
vendored
Normal file
63
vendor/github.com/vmware/govmomi/internal/helpers.go
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
Copyright (c) 2020 VMware, Inc. All 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 internal
|
||||
|
||||
import (
|
||||
"net"
|
||||
"path"
|
||||
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
// InventoryPath composed of entities by Name
|
||||
func InventoryPath(entities []mo.ManagedEntity) string {
|
||||
val := "/"
|
||||
|
||||
for _, entity := range entities {
|
||||
// Skip root folder in building inventory path.
|
||||
if entity.Parent == nil {
|
||||
continue
|
||||
}
|
||||
val = path.Join(val, entity.Name)
|
||||
}
|
||||
|
||||
return val
|
||||
}
|
||||
|
||||
func HostSystemManagementIPs(config []types.VirtualNicManagerNetConfig) []net.IP {
|
||||
var ips []net.IP
|
||||
|
||||
for _, nc := range config {
|
||||
if nc.NicType != string(types.HostVirtualNicManagerNicTypeManagement) {
|
||||
continue
|
||||
}
|
||||
for ix := range nc.CandidateVnic {
|
||||
for _, selectedVnicKey := range nc.SelectedVnic {
|
||||
if nc.CandidateVnic[ix].Key != selectedVnicKey {
|
||||
continue
|
||||
}
|
||||
ip := net.ParseIP(nc.CandidateVnic[ix].Spec.Ip.IpAddress)
|
||||
if ip != nil {
|
||||
ips = append(ips, ip)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ips
|
||||
}
|
123
vendor/github.com/vmware/govmomi/internal/methods.go
generated
vendored
Normal file
123
vendor/github.com/vmware/govmomi/internal/methods.go
generated
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
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 internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/vmware/govmomi/vim25/soap"
|
||||
)
|
||||
|
||||
type RetrieveDynamicTypeManagerBody struct {
|
||||
Req *RetrieveDynamicTypeManagerRequest `xml:"urn:vim25 RetrieveDynamicTypeManager"`
|
||||
Res *RetrieveDynamicTypeManagerResponse `xml:"urn:vim25 RetrieveDynamicTypeManagerResponse"`
|
||||
Fault_ *soap.Fault
|
||||
}
|
||||
|
||||
func (b *RetrieveDynamicTypeManagerBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func RetrieveDynamicTypeManager(ctx context.Context, r soap.RoundTripper, req *RetrieveDynamicTypeManagerRequest) (*RetrieveDynamicTypeManagerResponse, error) {
|
||||
var reqBody, resBody RetrieveDynamicTypeManagerBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type RetrieveManagedMethodExecuterBody struct {
|
||||
Req *RetrieveManagedMethodExecuterRequest `xml:"urn:vim25 RetrieveManagedMethodExecuter"`
|
||||
Res *RetrieveManagedMethodExecuterResponse `xml:"urn:vim25 RetrieveManagedMethodExecuterResponse"`
|
||||
Fault_ *soap.Fault
|
||||
}
|
||||
|
||||
func (b *RetrieveManagedMethodExecuterBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func RetrieveManagedMethodExecuter(ctx context.Context, r soap.RoundTripper, req *RetrieveManagedMethodExecuterRequest) (*RetrieveManagedMethodExecuterResponse, error) {
|
||||
var reqBody, resBody RetrieveManagedMethodExecuterBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type DynamicTypeMgrQueryMoInstancesBody struct {
|
||||
Req *DynamicTypeMgrQueryMoInstancesRequest `xml:"urn:vim25 DynamicTypeMgrQueryMoInstances"`
|
||||
Res *DynamicTypeMgrQueryMoInstancesResponse `xml:"urn:vim25 DynamicTypeMgrQueryMoInstancesResponse"`
|
||||
Fault_ *soap.Fault
|
||||
}
|
||||
|
||||
func (b *DynamicTypeMgrQueryMoInstancesBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func DynamicTypeMgrQueryMoInstances(ctx context.Context, r soap.RoundTripper, req *DynamicTypeMgrQueryMoInstancesRequest) (*DynamicTypeMgrQueryMoInstancesResponse, error) {
|
||||
var reqBody, resBody DynamicTypeMgrQueryMoInstancesBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type DynamicTypeMgrQueryTypeInfoBody struct {
|
||||
Req *DynamicTypeMgrQueryTypeInfoRequest `xml:"urn:vim25 DynamicTypeMgrQueryTypeInfo"`
|
||||
Res *DynamicTypeMgrQueryTypeInfoResponse `xml:"urn:vim25 DynamicTypeMgrQueryTypeInfoResponse"`
|
||||
Fault_ *soap.Fault
|
||||
}
|
||||
|
||||
func (b *DynamicTypeMgrQueryTypeInfoBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func DynamicTypeMgrQueryTypeInfo(ctx context.Context, r soap.RoundTripper, req *DynamicTypeMgrQueryTypeInfoRequest) (*DynamicTypeMgrQueryTypeInfoResponse, error) {
|
||||
var reqBody, resBody DynamicTypeMgrQueryTypeInfoBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type ExecuteSoapBody struct {
|
||||
Req *ExecuteSoapRequest `xml:"urn:vim25 ExecuteSoap"`
|
||||
Res *ExecuteSoapResponse `xml:"urn:vim25 ExecuteSoapResponse"`
|
||||
Fault_ *soap.Fault
|
||||
}
|
||||
|
||||
func (b *ExecuteSoapBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func ExecuteSoap(ctx context.Context, r soap.RoundTripper, req *ExecuteSoapRequest) (*ExecuteSoapResponse, error) {
|
||||
var reqBody, resBody ExecuteSoapBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
270
vendor/github.com/vmware/govmomi/internal/types.go
generated
vendored
Normal file
270
vendor/github.com/vmware/govmomi/internal/types.go
generated
vendored
Normal file
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
type DynamicTypeMgrQueryMoInstancesRequest struct {
|
||||
This types.ManagedObjectReference `xml:"_this"`
|
||||
FilterSpec BaseDynamicTypeMgrFilterSpec `xml:"filterSpec,omitempty,typeattr"`
|
||||
}
|
||||
|
||||
type DynamicTypeMgrQueryMoInstancesResponse struct {
|
||||
Returnval []DynamicTypeMgrMoInstance `xml:"urn:vim25 returnval"`
|
||||
}
|
||||
|
||||
type DynamicTypeEnumTypeInfo struct {
|
||||
types.DynamicData
|
||||
|
||||
Name string `xml:"name"`
|
||||
WsdlName string `xml:"wsdlName"`
|
||||
Version string `xml:"version"`
|
||||
Value []string `xml:"value,omitempty"`
|
||||
Annotation []DynamicTypeMgrAnnotation `xml:"annotation,omitempty"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
types.Add("DynamicTypeEnumTypeInfo", reflect.TypeOf((*DynamicTypeEnumTypeInfo)(nil)).Elem())
|
||||
}
|
||||
|
||||
type DynamicTypeMgrAllTypeInfoRequest struct {
|
||||
types.DynamicData
|
||||
|
||||
ManagedTypeInfo []DynamicTypeMgrManagedTypeInfo `xml:"managedTypeInfo,omitempty"`
|
||||
EnumTypeInfo []DynamicTypeEnumTypeInfo `xml:"enumTypeInfo,omitempty"`
|
||||
DataTypeInfo []DynamicTypeMgrDataTypeInfo `xml:"dataTypeInfo,omitempty"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
types.Add("DynamicTypeMgrAllTypeInfo", reflect.TypeOf((*DynamicTypeMgrAllTypeInfoRequest)(nil)).Elem())
|
||||
}
|
||||
|
||||
type DynamicTypeMgrAnnotation struct {
|
||||
types.DynamicData
|
||||
|
||||
Name string `xml:"name"`
|
||||
Parameter []string `xml:"parameter,omitempty"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
types.Add("DynamicTypeMgrAnnotation", reflect.TypeOf((*DynamicTypeMgrAnnotation)(nil)).Elem())
|
||||
}
|
||||
|
||||
type DynamicTypeMgrDataTypeInfo struct {
|
||||
types.DynamicData
|
||||
|
||||
Name string `xml:"name"`
|
||||
WsdlName string `xml:"wsdlName"`
|
||||
Version string `xml:"version"`
|
||||
Base []string `xml:"base,omitempty"`
|
||||
Property []DynamicTypeMgrPropertyTypeInfo `xml:"property,omitempty"`
|
||||
Annotation []DynamicTypeMgrAnnotation `xml:"annotation,omitempty"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
types.Add("DynamicTypeMgrDataTypeInfo", reflect.TypeOf((*DynamicTypeMgrDataTypeInfo)(nil)).Elem())
|
||||
}
|
||||
|
||||
func (b *DynamicTypeMgrFilterSpec) GetDynamicTypeMgrFilterSpec() *DynamicTypeMgrFilterSpec { return b }
|
||||
|
||||
type BaseDynamicTypeMgrFilterSpec interface {
|
||||
GetDynamicTypeMgrFilterSpec() *DynamicTypeMgrFilterSpec
|
||||
}
|
||||
|
||||
type DynamicTypeMgrFilterSpec struct {
|
||||
types.DynamicData
|
||||
}
|
||||
|
||||
func init() {
|
||||
types.Add("DynamicTypeMgrFilterSpec", reflect.TypeOf((*DynamicTypeMgrFilterSpec)(nil)).Elem())
|
||||
}
|
||||
|
||||
type DynamicTypeMgrManagedTypeInfo struct {
|
||||
types.DynamicData
|
||||
|
||||
Name string `xml:"name"`
|
||||
WsdlName string `xml:"wsdlName"`
|
||||
Version string `xml:"version"`
|
||||
Base []string `xml:"base,omitempty"`
|
||||
Property []DynamicTypeMgrPropertyTypeInfo `xml:"property,omitempty"`
|
||||
Method []DynamicTypeMgrMethodTypeInfo `xml:"method,omitempty"`
|
||||
Annotation []DynamicTypeMgrAnnotation `xml:"annotation,omitempty"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
types.Add("DynamicTypeMgrManagedTypeInfo", reflect.TypeOf((*DynamicTypeMgrManagedTypeInfo)(nil)).Elem())
|
||||
}
|
||||
|
||||
type DynamicTypeMgrMethodTypeInfo struct {
|
||||
types.DynamicData
|
||||
|
||||
Name string `xml:"name"`
|
||||
WsdlName string `xml:"wsdlName"`
|
||||
Version string `xml:"version"`
|
||||
ParamTypeInfo []DynamicTypeMgrParamTypeInfo `xml:"paramTypeInfo,omitempty"`
|
||||
ReturnTypeInfo *DynamicTypeMgrParamTypeInfo `xml:"returnTypeInfo,omitempty"`
|
||||
Fault []string `xml:"fault,omitempty"`
|
||||
PrivId string `xml:"privId,omitempty"`
|
||||
Annotation []DynamicTypeMgrAnnotation `xml:"annotation,omitempty"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
types.Add("DynamicTypeMgrMethodTypeInfo", reflect.TypeOf((*DynamicTypeMgrMethodTypeInfo)(nil)).Elem())
|
||||
}
|
||||
|
||||
type DynamicTypeMgrMoFilterSpec struct {
|
||||
DynamicTypeMgrFilterSpec
|
||||
|
||||
Id string `xml:"id,omitempty"`
|
||||
TypeSubstr string `xml:"typeSubstr,omitempty"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
types.Add("DynamicTypeMgrMoFilterSpec", reflect.TypeOf((*DynamicTypeMgrMoFilterSpec)(nil)).Elem())
|
||||
}
|
||||
|
||||
type DynamicTypeMgrMoInstance struct {
|
||||
types.DynamicData
|
||||
|
||||
Id string `xml:"id"`
|
||||
MoType string `xml:"moType"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
types.Add("DynamicTypeMgrMoInstance", reflect.TypeOf((*DynamicTypeMgrMoInstance)(nil)).Elem())
|
||||
}
|
||||
|
||||
type DynamicTypeMgrParamTypeInfo struct {
|
||||
types.DynamicData
|
||||
|
||||
Name string `xml:"name"`
|
||||
Version string `xml:"version"`
|
||||
Type string `xml:"type"`
|
||||
PrivId string `xml:"privId,omitempty"`
|
||||
Annotation []DynamicTypeMgrAnnotation `xml:"annotation,omitempty"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
types.Add("DynamicTypeMgrParamTypeInfo", reflect.TypeOf((*DynamicTypeMgrParamTypeInfo)(nil)).Elem())
|
||||
}
|
||||
|
||||
type DynamicTypeMgrPropertyTypeInfo struct {
|
||||
types.DynamicData
|
||||
|
||||
Name string `xml:"name"`
|
||||
Version string `xml:"version"`
|
||||
Type string `xml:"type"`
|
||||
PrivId string `xml:"privId,omitempty"`
|
||||
MsgIdFormat string `xml:"msgIdFormat,omitempty"`
|
||||
Annotation []DynamicTypeMgrAnnotation `xml:"annotation,omitempty"`
|
||||
}
|
||||
|
||||
type DynamicTypeMgrQueryTypeInfoRequest struct {
|
||||
This types.ManagedObjectReference `xml:"_this"`
|
||||
FilterSpec BaseDynamicTypeMgrFilterSpec `xml:"filterSpec,omitempty,typeattr"`
|
||||
}
|
||||
|
||||
type DynamicTypeMgrQueryTypeInfoResponse struct {
|
||||
Returnval DynamicTypeMgrAllTypeInfoRequest `xml:"urn:vim25 returnval"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
types.Add("DynamicTypeMgrPropertyTypeInfo", reflect.TypeOf((*DynamicTypeMgrPropertyTypeInfo)(nil)).Elem())
|
||||
}
|
||||
|
||||
type DynamicTypeMgrTypeFilterSpec struct {
|
||||
DynamicTypeMgrFilterSpec
|
||||
|
||||
TypeSubstr string `xml:"typeSubstr,omitempty"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
types.Add("DynamicTypeMgrTypeFilterSpec", reflect.TypeOf((*DynamicTypeMgrTypeFilterSpec)(nil)).Elem())
|
||||
}
|
||||
|
||||
type ReflectManagedMethodExecuterSoapArgument struct {
|
||||
types.DynamicData
|
||||
|
||||
Name string `xml:"name"`
|
||||
Val string `xml:"val"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
types.Add("ReflectManagedMethodExecuterSoapArgument", reflect.TypeOf((*ReflectManagedMethodExecuterSoapArgument)(nil)).Elem())
|
||||
}
|
||||
|
||||
type ReflectManagedMethodExecuterSoapFault struct {
|
||||
types.DynamicData
|
||||
|
||||
FaultMsg string `xml:"faultMsg"`
|
||||
FaultDetail string `xml:"faultDetail,omitempty"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
types.Add("ReflectManagedMethodExecuterSoapFault", reflect.TypeOf((*ReflectManagedMethodExecuterSoapFault)(nil)).Elem())
|
||||
}
|
||||
|
||||
type ReflectManagedMethodExecuterSoapResult struct {
|
||||
types.DynamicData
|
||||
|
||||
Response string `xml:"response,omitempty"`
|
||||
Fault *ReflectManagedMethodExecuterSoapFault `xml:"fault,omitempty"`
|
||||
}
|
||||
|
||||
type RetrieveDynamicTypeManagerRequest struct {
|
||||
This types.ManagedObjectReference `xml:"_this"`
|
||||
}
|
||||
|
||||
type RetrieveDynamicTypeManagerResponse struct {
|
||||
Returnval *InternalDynamicTypeManager `xml:"urn:vim25 returnval"`
|
||||
}
|
||||
|
||||
type RetrieveManagedMethodExecuterRequest struct {
|
||||
This types.ManagedObjectReference `xml:"_this"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
types.Add("RetrieveManagedMethodExecuter", reflect.TypeOf((*RetrieveManagedMethodExecuterRequest)(nil)).Elem())
|
||||
}
|
||||
|
||||
type RetrieveManagedMethodExecuterResponse struct {
|
||||
Returnval *ReflectManagedMethodExecuter `xml:"urn:vim25 returnval"`
|
||||
}
|
||||
|
||||
type InternalDynamicTypeManager struct {
|
||||
types.ManagedObjectReference
|
||||
}
|
||||
|
||||
type ReflectManagedMethodExecuter struct {
|
||||
types.ManagedObjectReference
|
||||
}
|
||||
|
||||
type ExecuteSoapRequest struct {
|
||||
This types.ManagedObjectReference `xml:"_this"`
|
||||
Moid string `xml:"moid"`
|
||||
Version string `xml:"version"`
|
||||
Method string `xml:"method"`
|
||||
Argument []ReflectManagedMethodExecuterSoapArgument `xml:"argument,omitempty"`
|
||||
}
|
||||
|
||||
type ExecuteSoapResponse struct {
|
||||
Returnval *ReflectManagedMethodExecuterSoapResult `xml:"urn:vim25 returnval"`
|
||||
}
|
25
vendor/github.com/vmware/govmomi/internal/version/version.go
generated
vendored
Normal file
25
vendor/github.com/vmware/govmomi/internal/version/version.go
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
Copyright (c) 2014-2022 VMware, Inc. All 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 version
|
||||
|
||||
const (
|
||||
// ClientName is the name of this SDK
|
||||
ClientName = "govmomi"
|
||||
|
||||
// ClientVersion is the version of this SDK
|
||||
ClientVersion = "0.30.0"
|
||||
)
|
65
vendor/github.com/vmware/govmomi/list/lister.go
generated
vendored
65
vendor/github.com/vmware/govmomi/list/lister.go
generated
vendored
@@ -165,6 +165,8 @@ func (l Lister) List(ctx context.Context) ([]Element, error) {
|
||||
return l.ListHostSystem(ctx)
|
||||
case "VirtualApp":
|
||||
return l.ListVirtualApp(ctx)
|
||||
case "VmwareDistributedVirtualSwitch", "DistributedVirtualSwitch":
|
||||
return l.ListDistributedVirtualSwitch(ctx)
|
||||
default:
|
||||
return nil, fmt.Errorf("cannot traverse type " + l.Reference.Type)
|
||||
}
|
||||
@@ -497,6 +499,69 @@ func (l Lister) ListHostSystem(ctx context.Context) ([]Element, error) {
|
||||
return es, nil
|
||||
}
|
||||
|
||||
func (l Lister) ListDistributedVirtualSwitch(ctx context.Context) ([]Element, error) {
|
||||
ospec := types.ObjectSpec{
|
||||
Obj: l.Reference,
|
||||
Skip: types.NewBool(true),
|
||||
}
|
||||
|
||||
fields := []string{
|
||||
"portgroup",
|
||||
}
|
||||
|
||||
for _, f := range fields {
|
||||
tspec := types.TraversalSpec{
|
||||
Path: f,
|
||||
Skip: types.NewBool(false),
|
||||
Type: "DistributedVirtualSwitch",
|
||||
}
|
||||
|
||||
ospec.SelectSet = append(ospec.SelectSet, &tspec)
|
||||
}
|
||||
|
||||
childTypes := []string{
|
||||
"DistributedVirtualPortgroup",
|
||||
}
|
||||
|
||||
var pspecs []types.PropertySpec
|
||||
for _, t := range childTypes {
|
||||
pspec := types.PropertySpec{
|
||||
Type: t,
|
||||
}
|
||||
|
||||
if l.All {
|
||||
pspec.All = types.NewBool(true)
|
||||
} else {
|
||||
pspec.PathSet = []string{"name"}
|
||||
}
|
||||
|
||||
pspecs = append(pspecs, pspec)
|
||||
}
|
||||
|
||||
req := types.RetrieveProperties{
|
||||
SpecSet: []types.PropertyFilterSpec{
|
||||
{
|
||||
ObjectSet: []types.ObjectSpec{ospec},
|
||||
PropSet: pspecs,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var dst []interface{}
|
||||
|
||||
err := l.retrieveProperties(ctx, req, &dst)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
es := []Element{}
|
||||
for _, v := range dst {
|
||||
es = append(es, ToElement(v.(mo.Reference), l.Prefix))
|
||||
}
|
||||
|
||||
return es, nil
|
||||
}
|
||||
|
||||
func (l Lister) ListVirtualApp(ctx context.Context) ([]Element, error) {
|
||||
ospec := types.ObjectSpec{
|
||||
Obj: l.Reference,
|
||||
|
26
vendor/github.com/vmware/govmomi/lookup/client.go
generated
vendored
26
vendor/github.com/vmware/govmomi/lookup/client.go
generated
vendored
@@ -25,6 +25,7 @@ import (
|
||||
|
||||
"github.com/vmware/govmomi/lookup/methods"
|
||||
"github.com/vmware/govmomi/lookup/types"
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/vim25"
|
||||
"github.com/vmware/govmomi/vim25/soap"
|
||||
vim "github.com/vmware/govmomi/vim25/types"
|
||||
@@ -47,12 +48,28 @@ var (
|
||||
type Client struct {
|
||||
*soap.Client
|
||||
|
||||
RoundTripper soap.RoundTripper
|
||||
|
||||
ServiceContent types.LookupServiceContent
|
||||
}
|
||||
|
||||
// NewClient returns a client targeting the SSO Lookup Service API endpoint.
|
||||
func NewClient(ctx context.Context, c *vim25.Client) (*Client, error) {
|
||||
sc := c.Client.NewServiceClient(Path, Namespace)
|
||||
// PSC may be external, attempt to derive from sts.uri
|
||||
path := &url.URL{Path: Path}
|
||||
if c.ServiceContent.Setting != nil {
|
||||
m := object.NewOptionManager(c, *c.ServiceContent.Setting)
|
||||
opts, err := m.Query(ctx, "config.vpxd.sso.sts.uri")
|
||||
if err == nil && len(opts) == 1 {
|
||||
u, err := url.Parse(opts[0].GetOptionValue().Value.(string))
|
||||
if err == nil {
|
||||
path.Scheme = u.Scheme
|
||||
path.Host = u.Host
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sc := c.Client.NewServiceClient(path.String(), Namespace)
|
||||
sc.Version = Version
|
||||
|
||||
req := types.RetrieveServiceContent{
|
||||
@@ -64,7 +81,12 @@ func NewClient(ctx context.Context, c *vim25.Client) (*Client, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Client{sc, res.Returnval}, nil
|
||||
return &Client{sc, sc, res.Returnval}, nil
|
||||
}
|
||||
|
||||
// RoundTrip dispatches to the RoundTripper field.
|
||||
func (c *Client) RoundTrip(ctx context.Context, req, res soap.HasFault) error {
|
||||
return c.RoundTripper.RoundTrip(ctx, req, res)
|
||||
}
|
||||
|
||||
func (c *Client) List(ctx context.Context, filter *types.LookupServiceRegistrationFilter) ([]types.LookupServiceRegistrationInfo, error) {
|
||||
|
16
vendor/github.com/vmware/govmomi/lookup/simulator/registration_info.go
generated
vendored
16
vendor/github.com/vmware/govmomi/lookup/simulator/registration_info.go
generated
vendored
@@ -18,6 +18,7 @@ package simulator
|
||||
|
||||
import (
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/vmware/govmomi/lookup"
|
||||
"github.com/vmware/govmomi/lookup/types"
|
||||
"github.com/vmware/govmomi/simulator"
|
||||
@@ -33,6 +34,7 @@ var (
|
||||
func registrationInfo() []types.LookupServiceRegistrationInfo {
|
||||
vc := simulator.Map.Get(vim25.ServiceInstance).(*simulator.ServiceInstance)
|
||||
setting := simulator.Map.OptionManager().Setting
|
||||
sm := simulator.Map.SessionManager()
|
||||
opts := make(map[string]string, len(setting))
|
||||
|
||||
for _, o := range setting {
|
||||
@@ -42,14 +44,17 @@ func registrationInfo() []types.LookupServiceRegistrationInfo {
|
||||
}
|
||||
}
|
||||
|
||||
trust := []string{opts["vcsim.server.cert"]}
|
||||
trust := []string{""}
|
||||
if sm.TLSCert != nil {
|
||||
trust[0] = sm.TLSCert()
|
||||
}
|
||||
sdk := opts["vcsim.server.url"] + vim25.Path
|
||||
admin := opts["config.vpxd.sso.default.admin"]
|
||||
owner := opts["config.vpxd.sso.solutionUser.name"]
|
||||
instance := opts["VirtualCenter.InstanceName"]
|
||||
|
||||
// Real PSC has 30+ services by default, we just provide a few that are useful for vmomi interaction..
|
||||
return []types.LookupServiceRegistrationInfo{
|
||||
info := []types.LookupServiceRegistrationInfo{
|
||||
{
|
||||
LookupServiceRegistrationCommonServiceInfo: types.LookupServiceRegistrationCommonServiceInfo{
|
||||
LookupServiceRegistrationMutableServiceInfo: types.LookupServiceRegistrationMutableServiceInfo{
|
||||
@@ -68,7 +73,7 @@ func registrationInfo() []types.LookupServiceRegistrationInfo {
|
||||
OwnerId: admin,
|
||||
ServiceType: types.LookupServiceRegistrationServiceType{
|
||||
Product: "com.vmware.cis",
|
||||
Type: "sso:sts",
|
||||
Type: "cs.identity",
|
||||
},
|
||||
},
|
||||
ServiceId: siteID + ":" + uuid.New().String(),
|
||||
@@ -126,4 +131,9 @@ func registrationInfo() []types.LookupServiceRegistrationInfo {
|
||||
SiteId: siteID,
|
||||
},
|
||||
}
|
||||
|
||||
sts := info[0]
|
||||
sts.ServiceType.Type = "sso:sts" // obsolete service type, but still used by PowerCLI
|
||||
|
||||
return append(info, sts)
|
||||
}
|
||||
|
27
vendor/github.com/vmware/govmomi/lookup/simulator/simulator.go
generated
vendored
27
vendor/github.com/vmware/govmomi/lookup/simulator/simulator.go
generated
vendored
@@ -17,6 +17,8 @@ limitations under the License.
|
||||
package simulator
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/vmware/govmomi/lookup"
|
||||
"github.com/vmware/govmomi/lookup/methods"
|
||||
"github.com/vmware/govmomi/lookup/types"
|
||||
@@ -32,6 +34,14 @@ var content = types.LookupServiceContent{
|
||||
L10n: vim.ManagedObjectReference{Type: "LookupL10n", Value: "l10n"},
|
||||
}
|
||||
|
||||
func init() {
|
||||
simulator.RegisterEndpoint(func(s *simulator.Service, r *simulator.Registry) {
|
||||
if r.IsVPX() {
|
||||
s.RegisterSDK(New())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func New() *simulator.Registry {
|
||||
r := simulator.NewRegistry()
|
||||
r.Namespace = lookup.Namespace
|
||||
@@ -40,10 +50,12 @@ func New() *simulator.Registry {
|
||||
r.Put(&ServiceInstance{
|
||||
ManagedObjectReference: lookup.ServiceInstance,
|
||||
Content: content,
|
||||
})
|
||||
r.Put(&ServiceRegistration{
|
||||
ManagedObjectReference: *content.ServiceRegistration,
|
||||
Info: registrationInfo(),
|
||||
register: func() {
|
||||
r.Put(&ServiceRegistration{
|
||||
ManagedObjectReference: *content.ServiceRegistration,
|
||||
Info: registrationInfo(),
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
return r
|
||||
@@ -53,9 +65,16 @@ type ServiceInstance struct {
|
||||
vim.ManagedObjectReference
|
||||
|
||||
Content types.LookupServiceContent
|
||||
|
||||
instance sync.Once
|
||||
register func()
|
||||
}
|
||||
|
||||
func (s *ServiceInstance) RetrieveServiceContent(_ *types.RetrieveServiceContent) soap.HasFault {
|
||||
// defer register to this point to ensure we can include vcsim's cert in ServiceEndpoints.SslTrust
|
||||
// TODO: we should be able to register within New(), but this is the only place that currently depends on vcsim's cert.
|
||||
s.instance.Do(s.register)
|
||||
|
||||
return &methods.RetrieveServiceContentBody{
|
||||
Res: &types.RetrieveServiceContentResponse{
|
||||
Returnval: s.Content,
|
||||
|
9
vendor/github.com/vmware/govmomi/nfc/lease.go
generated
vendored
9
vendor/github.com/vmware/govmomi/nfc/lease.go
generated
vendored
@@ -18,16 +18,15 @@ package nfc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"path"
|
||||
|
||||
"github.com/vmware/govmomi/property"
|
||||
"github.com/vmware/govmomi/task"
|
||||
"github.com/vmware/govmomi/vim25"
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/progress"
|
||||
"github.com/vmware/govmomi/vim25/soap"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
@@ -195,7 +194,7 @@ func (l *Lease) Wait(ctx context.Context, items []types.OvfFileItem) (*LeaseInfo
|
||||
}
|
||||
|
||||
if lease.Error != nil {
|
||||
return nil, errors.New(lease.Error.LocalizedMessage)
|
||||
return nil, &task.Error{LocalizedMethodFault: lease.Error}
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("unexpected nfc lease state: %s", lease.State)
|
||||
@@ -208,8 +207,6 @@ func (l *Lease) StartUpdater(ctx context.Context, info *LeaseInfo) *LeaseUpdater
|
||||
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.
|
||||
@@ -230,8 +227,6 @@ func (l *Lease) Upload(ctx context.Context, item FileItem, f io.Reader, opts soa
|
||||
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(ctx, file, item.URL, &opts)
|
||||
|
4
vendor/github.com/vmware/govmomi/nfc/lease_updater.go
generated
vendored
4
vendor/github.com/vmware/govmomi/nfc/lease_updater.go
generated
vendored
@@ -57,8 +57,8 @@ func (o FileItem) File() types.OvfFile {
|
||||
}
|
||||
|
||||
type LeaseUpdater struct {
|
||||
pos int64 // Number of bytes (keep first to ensure 64 bit aligment)
|
||||
total int64 // Total number of bytes (keep first to ensure 64 bit aligment)
|
||||
pos int64 // Number of bytes (keep first to ensure 64 bit alignment)
|
||||
total int64 // Total number of bytes (keep first to ensure 64 bit alignment)
|
||||
|
||||
lease *Lease
|
||||
|
||||
|
47
vendor/github.com/vmware/govmomi/object/authorization_manager.go
generated
vendored
47
vendor/github.com/vmware/govmomi/object/authorization_manager.go
generated
vendored
@@ -172,3 +172,50 @@ func (m AuthorizationManager) UpdateRole(ctx context.Context, id int32, name str
|
||||
_, err := methods.UpdateAuthorizationRole(ctx, m.Client(), &req)
|
||||
return err
|
||||
}
|
||||
|
||||
func (m AuthorizationManager) HasUserPrivilegeOnEntities(ctx context.Context, entities []types.ManagedObjectReference, userName string, privID []string) ([]types.EntityPrivilege, error) {
|
||||
req := types.HasUserPrivilegeOnEntities{
|
||||
This: m.Reference(),
|
||||
Entities: entities,
|
||||
UserName: userName,
|
||||
PrivId: privID,
|
||||
}
|
||||
|
||||
res, err := methods.HasUserPrivilegeOnEntities(ctx, m.Client(), &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res.Returnval, nil
|
||||
}
|
||||
|
||||
func (m AuthorizationManager) HasPrivilegeOnEntity(ctx context.Context, entity types.ManagedObjectReference, sessionID string, privID []string) ([]bool, error) {
|
||||
req := types.HasPrivilegeOnEntity{
|
||||
This: m.Reference(),
|
||||
Entity: entity,
|
||||
SessionId: sessionID,
|
||||
PrivId: privID,
|
||||
}
|
||||
|
||||
res, err := methods.HasPrivilegeOnEntity(ctx, m.Client(), &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res.Returnval, nil
|
||||
}
|
||||
|
||||
func (m AuthorizationManager) FetchUserPrivilegeOnEntities(ctx context.Context, entities []types.ManagedObjectReference, userName string) ([]types.UserPrivilegeResult, error) {
|
||||
req := types.FetchUserPrivilegeOnEntities{
|
||||
This: m.Reference(),
|
||||
Entities: entities,
|
||||
UserName: userName,
|
||||
}
|
||||
|
||||
res, err := methods.FetchUserPrivilegeOnEntities(ctx, m.Client(), &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res.Returnval, nil
|
||||
}
|
||||
|
14
vendor/github.com/vmware/govmomi/object/cluster_compute_resource.go
generated
vendored
14
vendor/github.com/vmware/govmomi/object/cluster_compute_resource.go
generated
vendored
@@ -87,3 +87,17 @@ func (c ClusterComputeResource) MoveInto(ctx context.Context, hosts ...*HostSyst
|
||||
|
||||
return NewTask(c.c, res.Returnval), nil
|
||||
}
|
||||
|
||||
func (c ClusterComputeResource) PlaceVm(ctx context.Context, spec types.PlacementSpec) (*types.PlacementResult, error) {
|
||||
req := types.PlaceVm{
|
||||
This: c.Reference(),
|
||||
PlacementSpec: spec,
|
||||
}
|
||||
|
||||
res, err := methods.PlaceVm(ctx, c.c, &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &res.Returnval, nil
|
||||
}
|
||||
|
34
vendor/github.com/vmware/govmomi/object/common.go
generated
vendored
34
vendor/github.com/vmware/govmomi/object/common.go
generated
vendored
@@ -75,29 +75,22 @@ func (c *Common) SetInventoryPath(p string) {
|
||||
c.InventoryPath = p
|
||||
}
|
||||
|
||||
// ObjectName returns the base name of the InventoryPath field if set,
|
||||
// otherwise fetches the mo.ManagedEntity.Name field via the property collector.
|
||||
// ObjectName fetches the mo.ManagedEntity.Name field via the property collector.
|
||||
func (c Common) ObjectName(ctx context.Context) (string, error) {
|
||||
var o mo.ManagedEntity
|
||||
var content []types.ObjectContent
|
||||
|
||||
err := c.Properties(ctx, c.Reference(), []string{"name"}, &o)
|
||||
err := c.Properties(ctx, c.Reference(), []string{"name"}, &content)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if o.Name != "" {
|
||||
return o.Name, nil
|
||||
for i := range content {
|
||||
for _, prop := range content[i].PropSet {
|
||||
return prop.Val.(string), nil
|
||||
}
|
||||
}
|
||||
|
||||
// Network has its own "name" field...
|
||||
var n mo.Network
|
||||
|
||||
err = c.Properties(ctx, c.Reference(), []string{"name"}, &n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return n.Name, nil
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// Properties is a wrapper for property.DefaultCollector().RetrieveOne()
|
||||
@@ -142,3 +135,14 @@ func (c Common) SetCustomValue(ctx context.Context, key string, value string) er
|
||||
_, err := methods.SetCustomValue(ctx, c.c, &req)
|
||||
return err
|
||||
}
|
||||
|
||||
func ReferenceFromString(s string) *types.ManagedObjectReference {
|
||||
var ref types.ManagedObjectReference
|
||||
if !ref.FromString(s) {
|
||||
return nil
|
||||
}
|
||||
if mo.IsManagedObjectType(ref.Type) {
|
||||
return &ref
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
7
vendor/github.com/vmware/govmomi/object/customization_spec_manager.go
generated
vendored
7
vendor/github.com/vmware/govmomi/object/customization_spec_manager.go
generated
vendored
@@ -21,6 +21,7 @@ import (
|
||||
|
||||
"github.com/vmware/govmomi/vim25"
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
@@ -36,6 +37,12 @@ func NewCustomizationSpecManager(c *vim25.Client) *CustomizationSpecManager {
|
||||
return &cs
|
||||
}
|
||||
|
||||
func (cs CustomizationSpecManager) Info(ctx context.Context) ([]types.CustomizationSpecInfo, error) {
|
||||
var m mo.CustomizationSpecManager
|
||||
err := cs.Properties(ctx, cs.Reference(), []string{"info"}, &m)
|
||||
return m.Info, err
|
||||
}
|
||||
|
||||
func (cs CustomizationSpecManager) DoesCustomizationSpecExist(ctx context.Context, name string) (bool, error) {
|
||||
req := types.DoesCustomizationSpecExist{
|
||||
This: cs.Reference(),
|
||||
|
5
vendor/github.com/vmware/govmomi/object/datastore.go
generated
vendored
5
vendor/github.com/vmware/govmomi/object/datastore.go
generated
vendored
@@ -68,6 +68,11 @@ func NewDatastore(c *vim25.Client, ref types.ManagedObjectReference) *Datastore
|
||||
}
|
||||
|
||||
func (d Datastore) Path(path string) string {
|
||||
var p DatastorePath
|
||||
if p.FromString(path) {
|
||||
return p.String() // already in "[datastore] path" format
|
||||
}
|
||||
|
||||
return (&DatastorePath{
|
||||
Datastore: d.Name(),
|
||||
Path: path,
|
||||
|
6
vendor/github.com/vmware/govmomi/object/datastore_file.go
generated
vendored
6
vendor/github.com/vmware/govmomi/object/datastore_file.go
generated
vendored
@@ -297,10 +297,8 @@ func (f *DatastoreFile) TailFunc(lines int, include func(line int, message strin
|
||||
|
||||
nread = bsize + remain
|
||||
eof = true
|
||||
} else {
|
||||
if pos, err = f.Seek(offset, io.SeekEnd); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if pos, err = f.Seek(offset, io.SeekEnd); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = io.CopyN(buf, f, nread); err != nil {
|
||||
|
2
vendor/github.com/vmware/govmomi/object/datastore_path.go
generated
vendored
2
vendor/github.com/vmware/govmomi/object/datastore_path.go
generated
vendored
@@ -31,7 +31,7 @@ type DatastorePath struct {
|
||||
// FromString parses a datastore path.
|
||||
// Returns true if the path could be parsed, false otherwise.
|
||||
func (p *DatastorePath) FromString(s string) bool {
|
||||
if len(s) == 0 {
|
||||
if s == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
|
6
vendor/github.com/vmware/govmomi/object/diagnostic_manager.go
generated
vendored
6
vendor/github.com/vmware/govmomi/object/diagnostic_manager.go
generated
vendored
@@ -71,10 +71,8 @@ func (m DiagnosticManager) GenerateLogBundles(ctx context.Context, includeDefaul
|
||||
IncludeDefault: includeDefault,
|
||||
}
|
||||
|
||||
if host != nil {
|
||||
for _, h := range host {
|
||||
req.Host = append(req.Host, h.Reference())
|
||||
}
|
||||
for _, h := range host {
|
||||
req.Host = append(req.Host, h.Reference())
|
||||
}
|
||||
|
||||
res, err := methods.GenerateLogBundles_Task(ctx, m.c, &req)
|
||||
|
12
vendor/github.com/vmware/govmomi/object/distributed_virtual_portgroup.go
generated
vendored
12
vendor/github.com/vmware/govmomi/object/distributed_virtual_portgroup.go
generated
vendored
@@ -36,6 +36,10 @@ func NewDistributedVirtualPortgroup(c *vim25.Client, ref types.ManagedObjectRefe
|
||||
}
|
||||
}
|
||||
|
||||
func (p DistributedVirtualPortgroup) GetInventoryPath() string {
|
||||
return p.InventoryPath
|
||||
}
|
||||
|
||||
// EthernetCardBackingInfo returns the VirtualDeviceBackingInfo for this DistributedVirtualPortgroup
|
||||
func (p DistributedVirtualPortgroup) EthernetCardBackingInfo(ctx context.Context) (types.BaseVirtualDeviceBackingInfo, error) {
|
||||
var dvp mo.DistributedVirtualPortgroup
|
||||
@@ -46,9 +50,15 @@ func (p DistributedVirtualPortgroup) EthernetCardBackingInfo(ctx context.Context
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// From the docs at https://code.vmware.com/apis/196/vsphere/doc/vim.dvs.DistributedVirtualPortgroup.ConfigInfo.html:
|
||||
// "This property should always be set unless the user's setting does not have System.Read privilege on the object referred to by this property."
|
||||
// Note that "the object" refers to the Switch, not the PortGroup.
|
||||
if dvp.Config.DistributedVirtualSwitch == nil {
|
||||
return nil, fmt.Errorf("no System.Read privilege on: %s.%s", p.Reference(), prop)
|
||||
name := p.InventoryPath
|
||||
if name == "" {
|
||||
name = p.Reference().String()
|
||||
}
|
||||
return nil, fmt.Errorf("failed to create EthernetCardBackingInfo for %s: System.Read privilege required for %s", name, prop)
|
||||
}
|
||||
|
||||
if err := p.Properties(ctx, *dvp.Config.DistributedVirtualSwitch, []string{"uuid"}, &dvs); err != nil {
|
||||
|
40
vendor/github.com/vmware/govmomi/object/distributed_virtual_switch.go
generated
vendored
40
vendor/github.com/vmware/govmomi/object/distributed_virtual_switch.go
generated
vendored
@@ -18,6 +18,7 @@ package object
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/vmware/govmomi/vim25"
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
@@ -34,8 +35,17 @@ func NewDistributedVirtualSwitch(c *vim25.Client, ref types.ManagedObjectReferen
|
||||
}
|
||||
}
|
||||
|
||||
func (s DistributedVirtualSwitch) GetInventoryPath() string {
|
||||
return s.InventoryPath
|
||||
}
|
||||
|
||||
func (s DistributedVirtualSwitch) EthernetCardBackingInfo(ctx context.Context) (types.BaseVirtualDeviceBackingInfo, error) {
|
||||
return nil, ErrNotSupported // TODO: just to satisfy NetworkReference interface for the finder
|
||||
ref := s.Reference()
|
||||
name := s.InventoryPath
|
||||
if name == "" {
|
||||
name = ref.String()
|
||||
}
|
||||
return nil, fmt.Errorf("type %s (%s) cannot be used for EthernetCardBackingInfo", ref.Type, name)
|
||||
}
|
||||
|
||||
func (s DistributedVirtualSwitch) Reconfigure(ctx context.Context, spec types.BaseDVSConfigSpec) (*Task, error) {
|
||||
@@ -78,3 +88,31 @@ func (s DistributedVirtualSwitch) FetchDVPorts(ctx context.Context, criteria *ty
|
||||
}
|
||||
return res.Returnval, nil
|
||||
}
|
||||
|
||||
func (s DistributedVirtualSwitch) ReconfigureDVPort(ctx context.Context, spec []types.DVPortConfigSpec) (*Task, error) {
|
||||
req := types.ReconfigureDVPort_Task{
|
||||
This: s.Reference(),
|
||||
Port: spec,
|
||||
}
|
||||
|
||||
res, err := methods.ReconfigureDVPort_Task(ctx, s.Client(), &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewTask(s.Client(), res.Returnval), nil
|
||||
}
|
||||
|
||||
func (s DistributedVirtualSwitch) ReconfigureLACP(ctx context.Context, spec []types.VMwareDvsLacpGroupSpec) (*Task, error) {
|
||||
req := types.UpdateDVSLacpGroupConfig_Task{
|
||||
This: s.Reference(),
|
||||
LacpGroupSpec: spec,
|
||||
}
|
||||
|
||||
res, err := methods.UpdateDVSLacpGroupConfig_Task(ctx, s.Client(), &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewTask(s.Client(), res.Returnval), nil
|
||||
}
|
||||
|
14
vendor/github.com/vmware/govmomi/object/folder.go
generated
vendored
14
vendor/github.com/vmware/govmomi/object/folder.go
generated
vendored
@@ -225,3 +225,17 @@ func (f Folder) MoveInto(ctx context.Context, list []types.ManagedObjectReferenc
|
||||
|
||||
return NewTask(f.c, res.Returnval), nil
|
||||
}
|
||||
|
||||
func (f Folder) PlaceVmsXCluster(ctx context.Context, spec types.PlaceVmsXClusterSpec) (*types.PlaceVmsXClusterResult, error) {
|
||||
req := types.PlaceVmsXCluster{
|
||||
This: f.Reference(),
|
||||
PlacementSpec: spec,
|
||||
}
|
||||
|
||||
res, err := methods.PlaceVmsXCluster(ctx, f.c, &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &res.Returnval, nil
|
||||
}
|
||||
|
72
vendor/github.com/vmware/govmomi/object/history_collector.go
generated
vendored
72
vendor/github.com/vmware/govmomi/object/history_collector.go
generated
vendored
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
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 HistoryCollector struct {
|
||||
Common
|
||||
}
|
||||
|
||||
func NewHistoryCollector(c *vim25.Client, ref types.ManagedObjectReference) *HistoryCollector {
|
||||
return &HistoryCollector{
|
||||
Common: NewCommon(c, ref),
|
||||
}
|
||||
}
|
||||
|
||||
func (h HistoryCollector) Destroy(ctx context.Context) error {
|
||||
req := types.DestroyCollector{
|
||||
This: h.Reference(),
|
||||
}
|
||||
|
||||
_, err := methods.DestroyCollector(ctx, h.c, &req)
|
||||
return err
|
||||
}
|
||||
|
||||
func (h HistoryCollector) Reset(ctx context.Context) error {
|
||||
req := types.ResetCollector{
|
||||
This: h.Reference(),
|
||||
}
|
||||
|
||||
_, err := methods.ResetCollector(ctx, h.c, &req)
|
||||
return err
|
||||
}
|
||||
|
||||
func (h HistoryCollector) Rewind(ctx context.Context) error {
|
||||
req := types.RewindCollector{
|
||||
This: h.Reference(),
|
||||
}
|
||||
|
||||
_, err := methods.RewindCollector(ctx, h.c, &req)
|
||||
return err
|
||||
}
|
||||
|
||||
func (h HistoryCollector) SetPageSize(ctx context.Context, maxCount int32) error {
|
||||
req := types.SetCollectorPageSize{
|
||||
This: h.Reference(),
|
||||
MaxCount: maxCount,
|
||||
}
|
||||
|
||||
_, err := methods.SetCollectorPageSize(ctx, h.c, &req)
|
||||
return err
|
||||
}
|
151
vendor/github.com/vmware/govmomi/object/host_config_manager.go
generated
vendored
151
vendor/github.com/vmware/govmomi/object/host_config_manager.go
generated
vendored
@@ -18,9 +18,9 @@ package object
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/vmware/govmomi/vim25"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
@@ -34,163 +34,138 @@ func NewHostConfigManager(c *vim25.Client, ref types.ManagedObjectReference) *Ho
|
||||
}
|
||||
}
|
||||
|
||||
func (m HostConfigManager) DatastoreSystem(ctx context.Context) (*HostDatastoreSystem, error) {
|
||||
var h mo.HostSystem
|
||||
// reference returns the ManagedObjectReference for the given HostConfigManager property name.
|
||||
// An error is returned if the field is nil, of type ErrNotSupported if versioned is true.
|
||||
func (m HostConfigManager) reference(ctx context.Context, name string, versioned ...bool) (types.ManagedObjectReference, error) {
|
||||
prop := "configManager." + name
|
||||
var content []types.ObjectContent
|
||||
|
||||
err := m.Properties(ctx, m.Reference(), []string{"configManager.datastoreSystem"}, &h)
|
||||
err := m.Properties(ctx, m.Reference(), []string{prop}, &content)
|
||||
if err != nil {
|
||||
return types.ManagedObjectReference{}, err
|
||||
}
|
||||
|
||||
for _, c := range content {
|
||||
for _, p := range c.PropSet {
|
||||
if p.Name != prop {
|
||||
continue
|
||||
}
|
||||
if ref, ok := p.Val.(types.ManagedObjectReference); ok {
|
||||
return ref, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = fmt.Errorf("%s %s is nil", m.Reference(), prop)
|
||||
if len(versioned) == 1 && versioned[0] {
|
||||
err = ErrNotSupported
|
||||
}
|
||||
return types.ManagedObjectReference{}, err
|
||||
}
|
||||
|
||||
func (m HostConfigManager) DatastoreSystem(ctx context.Context) (*HostDatastoreSystem, error) {
|
||||
ref, err := m.reference(ctx, "datastoreSystem")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewHostDatastoreSystem(m.c, *h.ConfigManager.DatastoreSystem), nil
|
||||
return NewHostDatastoreSystem(m.c, ref), nil
|
||||
}
|
||||
|
||||
func (m HostConfigManager) NetworkSystem(ctx context.Context) (*HostNetworkSystem, error) {
|
||||
var h mo.HostSystem
|
||||
|
||||
err := m.Properties(ctx, m.Reference(), []string{"configManager.networkSystem"}, &h)
|
||||
ref, err := m.reference(ctx, "networkSystem")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewHostNetworkSystem(m.c, *h.ConfigManager.NetworkSystem), nil
|
||||
return NewHostNetworkSystem(m.c, ref), nil
|
||||
}
|
||||
|
||||
func (m HostConfigManager) FirewallSystem(ctx context.Context) (*HostFirewallSystem, error) {
|
||||
var h mo.HostSystem
|
||||
|
||||
err := m.Properties(ctx, m.Reference(), []string{"configManager.firewallSystem"}, &h)
|
||||
ref, err := m.reference(ctx, "firewallSystem")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewHostFirewallSystem(m.c, *h.ConfigManager.FirewallSystem), nil
|
||||
return NewHostFirewallSystem(m.c, ref), nil
|
||||
}
|
||||
|
||||
func (m HostConfigManager) StorageSystem(ctx context.Context) (*HostStorageSystem, error) {
|
||||
var h mo.HostSystem
|
||||
|
||||
err := m.Properties(ctx, m.Reference(), []string{"configManager.storageSystem"}, &h)
|
||||
ref, err := m.reference(ctx, "storageSystem")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewHostStorageSystem(m.c, *h.ConfigManager.StorageSystem), nil
|
||||
return NewHostStorageSystem(m.c, ref), nil
|
||||
}
|
||||
|
||||
func (m HostConfigManager) VirtualNicManager(ctx context.Context) (*HostVirtualNicManager, error) {
|
||||
var h mo.HostSystem
|
||||
|
||||
err := m.Properties(ctx, m.Reference(), []string{"configManager.virtualNicManager"}, &h)
|
||||
ref, err := m.reference(ctx, "virtualNicManager")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewHostVirtualNicManager(m.c, *h.ConfigManager.VirtualNicManager, m.Reference()), nil
|
||||
return NewHostVirtualNicManager(m.c, ref, m.Reference()), nil
|
||||
}
|
||||
|
||||
func (m HostConfigManager) VsanSystem(ctx context.Context) (*HostVsanSystem, error) {
|
||||
var h mo.HostSystem
|
||||
|
||||
err := m.Properties(ctx, m.Reference(), []string{"configManager.vsanSystem"}, &h)
|
||||
ref, err := m.reference(ctx, "vsanSystem", true) // Added in 5.5
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Added in 5.5
|
||||
if h.ConfigManager.VsanSystem == nil {
|
||||
return nil, ErrNotSupported
|
||||
}
|
||||
|
||||
return NewHostVsanSystem(m.c, *h.ConfigManager.VsanSystem), nil
|
||||
return NewHostVsanSystem(m.c, ref), nil
|
||||
}
|
||||
|
||||
func (m HostConfigManager) VsanInternalSystem(ctx context.Context) (*HostVsanInternalSystem, error) {
|
||||
var h mo.HostSystem
|
||||
|
||||
err := m.Properties(ctx, m.Reference(), []string{"configManager.vsanInternalSystem"}, &h)
|
||||
ref, err := m.reference(ctx, "vsanInternalSystem", true) // Added in 5.5
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Added in 5.5
|
||||
if h.ConfigManager.VsanInternalSystem == nil {
|
||||
return nil, ErrNotSupported
|
||||
}
|
||||
|
||||
return NewHostVsanInternalSystem(m.c, *h.ConfigManager.VsanInternalSystem), nil
|
||||
return NewHostVsanInternalSystem(m.c, ref), nil
|
||||
}
|
||||
|
||||
func (m HostConfigManager) AccountManager(ctx context.Context) (*HostAccountManager, error) {
|
||||
var h mo.HostSystem
|
||||
|
||||
err := m.Properties(ctx, m.Reference(), []string{"configManager.accountManager"}, &h)
|
||||
ref, err := m.reference(ctx, "accountManager", true) // Added in 5.5
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ref := h.ConfigManager.AccountManager // Added in 6.0
|
||||
if ref == nil {
|
||||
// Versions < 5.5 can use the ServiceContent ref,
|
||||
// but we can only use it when connected directly to ESX.
|
||||
c := m.Client()
|
||||
if !c.IsVC() {
|
||||
ref = c.ServiceContent.AccountManager
|
||||
}
|
||||
|
||||
if ref == nil {
|
||||
return nil, ErrNotSupported
|
||||
if err == ErrNotSupported {
|
||||
// Versions < 5.5 can use the ServiceContent ref,
|
||||
// but only when connected directly to ESX.
|
||||
if m.c.ServiceContent.AccountManager == nil {
|
||||
return nil, err
|
||||
}
|
||||
ref = *m.c.ServiceContent.AccountManager
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return NewHostAccountManager(m.c, *ref), nil
|
||||
return NewHostAccountManager(m.c, ref), nil
|
||||
}
|
||||
|
||||
func (m HostConfigManager) OptionManager(ctx context.Context) (*OptionManager, error) {
|
||||
var h mo.HostSystem
|
||||
|
||||
err := m.Properties(ctx, m.Reference(), []string{"configManager.advancedOption"}, &h)
|
||||
ref, err := m.reference(ctx, "advancedOption")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewOptionManager(m.c, *h.ConfigManager.AdvancedOption), nil
|
||||
return NewOptionManager(m.c, ref), nil
|
||||
}
|
||||
|
||||
func (m HostConfigManager) ServiceSystem(ctx context.Context) (*HostServiceSystem, error) {
|
||||
var h mo.HostSystem
|
||||
|
||||
err := m.Properties(ctx, m.Reference(), []string{"configManager.serviceSystem"}, &h)
|
||||
ref, err := m.reference(ctx, "serviceSystem")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewHostServiceSystem(m.c, *h.ConfigManager.ServiceSystem), nil
|
||||
return NewHostServiceSystem(m.c, ref), nil
|
||||
}
|
||||
|
||||
func (m HostConfigManager) CertificateManager(ctx context.Context) (*HostCertificateManager, error) {
|
||||
var h mo.HostSystem
|
||||
|
||||
err := m.Properties(ctx, m.Reference(), []string{"configManager.certificateManager"}, &h)
|
||||
ref, err := m.reference(ctx, "certificateManager", true) // Added in 6.0
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Added in 6.0
|
||||
if h.ConfigManager.CertificateManager == nil {
|
||||
return nil, ErrNotSupported
|
||||
}
|
||||
|
||||
return NewHostCertificateManager(m.c, *h.ConfigManager.CertificateManager, m.Reference()), nil
|
||||
return NewHostCertificateManager(m.c, ref, m.Reference()), nil
|
||||
}
|
||||
|
||||
func (m HostConfigManager) DateTimeSystem(ctx context.Context) (*HostDateTimeSystem, error) {
|
||||
var h mo.HostSystem
|
||||
|
||||
err := m.Properties(ctx, m.Reference(), []string{"configManager.dateTimeSystem"}, &h)
|
||||
ref, err := m.reference(ctx, "dateTimeSystem")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewHostDateTimeSystem(m.c, *h.ConfigManager.DateTimeSystem), nil
|
||||
return NewHostDateTimeSystem(m.c, ref), nil
|
||||
}
|
||||
|
16
vendor/github.com/vmware/govmomi/object/host_datastore_system.go
generated
vendored
16
vendor/github.com/vmware/govmomi/object/host_datastore_system.go
generated
vendored
@@ -117,3 +117,19 @@ func (s HostDatastoreSystem) QueryVmfsDatastoreCreateOptions(ctx context.Context
|
||||
|
||||
return res.Returnval, nil
|
||||
}
|
||||
|
||||
func (s HostDatastoreSystem) ResignatureUnresolvedVmfsVolumes(ctx context.Context, devicePaths []string) (*Task, error) {
|
||||
req := &types.ResignatureUnresolvedVmfsVolume_Task{
|
||||
This: s.Reference(),
|
||||
ResolutionSpec: types.HostUnresolvedVmfsResignatureSpec{
|
||||
ExtentDevicePath: devicePaths,
|
||||
},
|
||||
}
|
||||
|
||||
res, err := methods.ResignatureUnresolvedVmfsVolume_Task(ctx, s.Client(), req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewTask(s.c, res.Returnval), nil
|
||||
}
|
||||
|
8
vendor/github.com/vmware/govmomi/object/host_network_system.go
generated
vendored
8
vendor/github.com/vmware/govmomi/object/host_network_system.go
generated
vendored
@@ -98,18 +98,18 @@ func (o HostNetworkSystem) AddVirtualSwitch(ctx context.Context, vswitchName str
|
||||
}
|
||||
|
||||
// QueryNetworkHint wraps methods.QueryNetworkHint
|
||||
func (o HostNetworkSystem) QueryNetworkHint(ctx context.Context, device []string) error {
|
||||
func (o HostNetworkSystem) QueryNetworkHint(ctx context.Context, device []string) ([]types.PhysicalNicHintInfo, error) {
|
||||
req := types.QueryNetworkHint{
|
||||
This: o.Reference(),
|
||||
Device: device,
|
||||
}
|
||||
|
||||
_, err := methods.QueryNetworkHint(ctx, o.c, &req)
|
||||
res, err := methods.QueryNetworkHint(ctx, o.c, &req)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil
|
||||
return res.Returnval, err
|
||||
}
|
||||
|
||||
// RefreshNetworkSystem wraps methods.RefreshNetworkSystem
|
||||
|
26
vendor/github.com/vmware/govmomi/object/host_storage_system.go
generated
vendored
26
vendor/github.com/vmware/govmomi/object/host_storage_system.go
generated
vendored
@@ -172,3 +172,29 @@ func (s HostStorageSystem) AttachScsiLun(ctx context.Context, uuid string) error
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (s HostStorageSystem) QueryUnresolvedVmfsVolumes(ctx context.Context) ([]types.HostUnresolvedVmfsVolume, error) {
|
||||
req := &types.QueryUnresolvedVmfsVolume{
|
||||
This: s.Reference(),
|
||||
}
|
||||
|
||||
res, err := methods.QueryUnresolvedVmfsVolume(ctx, s.Client(), req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.Returnval, nil
|
||||
}
|
||||
|
||||
func (s HostStorageSystem) UnmountVmfsVolume(ctx context.Context, vmfsUuid string) error {
|
||||
req := &types.UnmountVmfsVolume{
|
||||
This: s.Reference(),
|
||||
VmfsUuid: vmfsUuid,
|
||||
}
|
||||
|
||||
_, err := methods.UnmountVmfsVolume(ctx, s.Client(), req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
19
vendor/github.com/vmware/govmomi/object/host_system.go
generated
vendored
19
vendor/github.com/vmware/govmomi/object/host_system.go
generated
vendored
@@ -21,6 +21,7 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/vmware/govmomi/internal"
|
||||
"github.com/vmware/govmomi/vim25"
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
@@ -81,17 +82,17 @@ func (h HostSystem) ManagementIPs(ctx context.Context) ([]net.IP, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var ips []net.IP
|
||||
for _, nc := range mh.Config.VirtualNicManagerInfo.NetConfig {
|
||||
if nc.NicType == "management" && len(nc.CandidateVnic) > 0 {
|
||||
ip := net.ParseIP(nc.CandidateVnic[0].Spec.Ip.IpAddress)
|
||||
if ip != nil {
|
||||
ips = append(ips, ip)
|
||||
}
|
||||
}
|
||||
config := mh.Config
|
||||
if config == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return ips, nil
|
||||
info := config.VirtualNicManagerInfo
|
||||
if info == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return internal.HostSystemManagementIPs(info.NetConfig), nil
|
||||
}
|
||||
|
||||
func (h HostSystem) Disconnect(ctx context.Context) (*Task, error) {
|
||||
|
14
vendor/github.com/vmware/govmomi/object/network.go
generated
vendored
14
vendor/github.com/vmware/govmomi/object/network.go
generated
vendored
@@ -20,7 +20,6 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/vmware/govmomi/vim25"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
@@ -34,21 +33,20 @@ func NewNetwork(c *vim25.Client, ref types.ManagedObjectReference) *Network {
|
||||
}
|
||||
}
|
||||
|
||||
func (n Network) GetInventoryPath() string {
|
||||
return n.InventoryPath
|
||||
}
|
||||
|
||||
// EthernetCardBackingInfo returns the VirtualDeviceBackingInfo for this Network
|
||||
func (n Network) EthernetCardBackingInfo(ctx context.Context) (types.BaseVirtualDeviceBackingInfo, error) {
|
||||
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)
|
||||
name, err := n.ObjectName(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
backing := &types.VirtualEthernetCardNetworkBackingInfo{
|
||||
VirtualDeviceDeviceBackingInfo: types.VirtualDeviceDeviceBackingInfo{
|
||||
DeviceName: e.Name,
|
||||
DeviceName: name,
|
||||
},
|
||||
}
|
||||
|
||||
|
2
vendor/github.com/vmware/govmomi/object/network_reference.go
generated
vendored
2
vendor/github.com/vmware/govmomi/object/network_reference.go
generated
vendored
@@ -26,6 +26,6 @@ import (
|
||||
// which can be used as the backing for a VirtualEthernetCard.
|
||||
type NetworkReference interface {
|
||||
Reference
|
||||
|
||||
GetInventoryPath() string
|
||||
EthernetCardBackingInfo(ctx context.Context) (types.BaseVirtualDeviceBackingInfo, error)
|
||||
}
|
||||
|
31
vendor/github.com/vmware/govmomi/object/opaque_network.go
generated
vendored
31
vendor/github.com/vmware/govmomi/object/opaque_network.go
generated
vendored
@@ -35,19 +35,17 @@ func NewOpaqueNetwork(c *vim25.Client, ref types.ManagedObjectReference) *Opaque
|
||||
}
|
||||
}
|
||||
|
||||
func (n OpaqueNetwork) GetInventoryPath() string {
|
||||
return n.InventoryPath
|
||||
}
|
||||
|
||||
// EthernetCardBackingInfo returns the VirtualDeviceBackingInfo for this Network
|
||||
func (n OpaqueNetwork) EthernetCardBackingInfo(ctx context.Context) (types.BaseVirtualDeviceBackingInfo, error) {
|
||||
var net mo.OpaqueNetwork
|
||||
|
||||
if err := n.Properties(ctx, n.Reference(), []string{"summary"}, &net); err != nil {
|
||||
summary, err := n.Summary(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
summary, ok := net.Summary.(*types.OpaqueNetworkSummary)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("%s unsupported network type: %T", n, net.Summary)
|
||||
}
|
||||
|
||||
backing := &types.VirtualEthernetCardOpaqueNetworkBackingInfo{
|
||||
OpaqueNetworkId: summary.OpaqueNetworkId,
|
||||
OpaqueNetworkType: summary.OpaqueNetworkType,
|
||||
@@ -55,3 +53,20 @@ func (n OpaqueNetwork) EthernetCardBackingInfo(ctx context.Context) (types.BaseV
|
||||
|
||||
return backing, nil
|
||||
}
|
||||
|
||||
// Summary returns the mo.OpaqueNetwork.Summary property
|
||||
func (n OpaqueNetwork) Summary(ctx context.Context) (*types.OpaqueNetworkSummary, error) {
|
||||
var props mo.OpaqueNetwork
|
||||
|
||||
err := n.Properties(ctx, n.Reference(), []string{"summary"}, &props)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
summary, ok := props.Summary.(*types.OpaqueNetworkSummary)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("%s unsupported network summary type: %T", n, props.Summary)
|
||||
}
|
||||
|
||||
return summary, nil
|
||||
}
|
||||
|
13
vendor/github.com/vmware/govmomi/object/resource_pool.go
generated
vendored
13
vendor/github.com/vmware/govmomi/object/resource_pool.go
generated
vendored
@@ -22,6 +22,7 @@ import (
|
||||
"github.com/vmware/govmomi/nfc"
|
||||
"github.com/vmware/govmomi/vim25"
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
@@ -35,6 +36,18 @@ func NewResourcePool(c *vim25.Client, ref types.ManagedObjectReference) *Resourc
|
||||
}
|
||||
}
|
||||
|
||||
// Owner returns the ResourcePool owner as a ClusterComputeResource or ComputeResource.
|
||||
func (p ResourcePool) Owner(ctx context.Context) (Reference, error) {
|
||||
var pool mo.ResourcePool
|
||||
|
||||
err := p.Properties(ctx, p.Reference(), []string{"owner"}, &pool)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewReference(p.Client(), pool.Owner), nil
|
||||
}
|
||||
|
||||
func (p ResourcePool) ImportVApp(ctx context.Context, spec types.BaseImportSpec, folder *Folder, host *HostSystem) (*nfc.Lease, error) {
|
||||
req := types.ImportVApp{
|
||||
This: p.Reference(),
|
||||
|
85
vendor/github.com/vmware/govmomi/object/search_index.go
generated
vendored
85
vendor/github.com/vmware/govmomi/object/search_index.go
generated
vendored
@@ -161,3 +161,88 @@ func (s SearchIndex) FindChild(ctx context.Context, entity Reference, name strin
|
||||
}
|
||||
return NewReference(s.c, *res.Returnval), nil
|
||||
}
|
||||
|
||||
// FindAllByDnsName finds all virtual machines or hosts by DNS name.
|
||||
func (s SearchIndex) FindAllByDnsName(ctx context.Context, dc *Datacenter, dnsName string, vmSearch bool) ([]Reference, error) {
|
||||
req := types.FindAllByDnsName{
|
||||
This: s.Reference(),
|
||||
DnsName: dnsName,
|
||||
VmSearch: vmSearch,
|
||||
}
|
||||
if dc != nil {
|
||||
ref := dc.Reference()
|
||||
req.Datacenter = &ref
|
||||
}
|
||||
|
||||
res, err := methods.FindAllByDnsName(ctx, s.c, &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(res.Returnval) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var references []Reference
|
||||
for _, returnval := range res.Returnval {
|
||||
references = append(references, NewReference(s.c, returnval))
|
||||
}
|
||||
return references, nil
|
||||
}
|
||||
|
||||
// FindAllByIp finds all virtual machines or hosts by IP address.
|
||||
func (s SearchIndex) FindAllByIp(ctx context.Context, dc *Datacenter, ip string, vmSearch bool) ([]Reference, error) {
|
||||
req := types.FindAllByIp{
|
||||
This: s.Reference(),
|
||||
Ip: ip,
|
||||
VmSearch: vmSearch,
|
||||
}
|
||||
if dc != nil {
|
||||
ref := dc.Reference()
|
||||
req.Datacenter = &ref
|
||||
}
|
||||
|
||||
res, err := methods.FindAllByIp(ctx, s.c, &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(res.Returnval) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var references []Reference
|
||||
for _, returnval := range res.Returnval {
|
||||
references = append(references, NewReference(s.c, returnval))
|
||||
}
|
||||
return references, nil
|
||||
}
|
||||
|
||||
// FindAllByUuid finds all virtual machines or hosts by UUID.
|
||||
func (s SearchIndex) FindAllByUuid(ctx context.Context, dc *Datacenter, uuid string, vmSearch bool, instanceUuid *bool) ([]Reference, error) {
|
||||
req := types.FindAllByUuid{
|
||||
This: s.Reference(),
|
||||
Uuid: uuid,
|
||||
VmSearch: vmSearch,
|
||||
InstanceUuid: instanceUuid,
|
||||
}
|
||||
if dc != nil {
|
||||
ref := dc.Reference()
|
||||
req.Datacenter = &ref
|
||||
}
|
||||
|
||||
res, err := methods.FindAllByUuid(ctx, s.c, &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(res.Returnval) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var references []Reference
|
||||
for _, returnval := range res.Returnval {
|
||||
references = append(references, NewReference(s.c, returnval))
|
||||
}
|
||||
return references, nil
|
||||
}
|
||||
|
42
vendor/github.com/vmware/govmomi/object/task.go
generated
vendored
42
vendor/github.com/vmware/govmomi/object/task.go
generated
vendored
@@ -48,9 +48,13 @@ func (t *Task) Wait(ctx context.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (t *Task) WaitForResult(ctx context.Context, s progress.Sinker) (*types.TaskInfo, error) {
|
||||
func (t *Task) WaitForResult(ctx context.Context, s ...progress.Sinker) (*types.TaskInfo, error) {
|
||||
var pr progress.Sinker
|
||||
if len(s) == 1 {
|
||||
pr = s[0]
|
||||
}
|
||||
p := property.DefaultCollector(t.c)
|
||||
return task.Wait(ctx, t.Reference(), p, s)
|
||||
return task.Wait(ctx, t.Reference(), p, pr)
|
||||
}
|
||||
|
||||
func (t *Task) Cancel(ctx context.Context) error {
|
||||
@@ -60,3 +64,37 @@ func (t *Task) Cancel(ctx context.Context) error {
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// SetState sets task state and optionally sets results or fault, as appropriate for state.
|
||||
func (t *Task) SetState(ctx context.Context, state types.TaskInfoState, result types.AnyType, fault *types.LocalizedMethodFault) error {
|
||||
req := types.SetTaskState{
|
||||
This: t.Reference(),
|
||||
State: state,
|
||||
Result: result,
|
||||
Fault: fault,
|
||||
}
|
||||
_, err := methods.SetTaskState(ctx, t.Common.Client(), &req)
|
||||
return err
|
||||
}
|
||||
|
||||
// SetDescription updates task description to describe the current phase of the task.
|
||||
func (t *Task) SetDescription(ctx context.Context, description types.LocalizableMessage) error {
|
||||
req := types.SetTaskDescription{
|
||||
This: t.Reference(),
|
||||
Description: description,
|
||||
}
|
||||
_, err := methods.SetTaskDescription(ctx, t.Common.Client(), &req)
|
||||
return err
|
||||
}
|
||||
|
||||
// UpdateProgress Sets percentage done for this task and recalculates overall percentage done.
|
||||
// If a percentDone value of less than zero or greater than 100 is specified,
|
||||
// a value of zero or 100 respectively is used.
|
||||
func (t *Task) UpdateProgress(ctx context.Context, percentDone int) error {
|
||||
req := types.UpdateProgress{
|
||||
This: t.Reference(),
|
||||
PercentDone: int32(percentDone),
|
||||
}
|
||||
_, err := methods.UpdateProgress(ctx, t.Common.Client(), &req)
|
||||
return err
|
||||
}
|
||||
|
78
vendor/github.com/vmware/govmomi/object/tenant_manager.go
generated
vendored
Normal file
78
vendor/github.com/vmware/govmomi/object/tenant_manager.go
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
Copyright (c) 2021 VMware, Inc. All 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 TenantManager struct {
|
||||
Common
|
||||
}
|
||||
|
||||
func NewTenantManager(c *vim25.Client) *TenantManager {
|
||||
t := TenantManager{
|
||||
Common: NewCommon(c, *c.ServiceContent.TenantManager),
|
||||
}
|
||||
|
||||
return &t
|
||||
}
|
||||
|
||||
func (t TenantManager) MarkServiceProviderEntities(ctx context.Context, entities []types.ManagedObjectReference) error {
|
||||
req := types.MarkServiceProviderEntities{
|
||||
This: t.Reference(),
|
||||
Entity: entities,
|
||||
}
|
||||
|
||||
_, err := methods.MarkServiceProviderEntities(ctx, t.Client(), &req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t TenantManager) UnmarkServiceProviderEntities(ctx context.Context, entities []types.ManagedObjectReference) error {
|
||||
req := types.UnmarkServiceProviderEntities{
|
||||
This: t.Reference(),
|
||||
Entity: entities,
|
||||
}
|
||||
|
||||
_, err := methods.UnmarkServiceProviderEntities(ctx, t.Client(), &req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t TenantManager) RetrieveServiceProviderEntities(ctx context.Context) ([]types.ManagedObjectReference, error) {
|
||||
req := types.RetrieveServiceProviderEntities{
|
||||
This: t.Reference(),
|
||||
}
|
||||
|
||||
res, err := methods.RetrieveServiceProviderEntities(ctx, t.Client(), &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res.Returnval, nil
|
||||
}
|
16
vendor/github.com/vmware/govmomi/object/virtual_app.go
generated
vendored
16
vendor/github.com/vmware/govmomi/object/virtual_app.go
generated
vendored
@@ -103,3 +103,19 @@ func (p VirtualApp) Suspend(ctx context.Context) (*Task, error) {
|
||||
|
||||
return NewTask(p.c, res.Returnval), nil
|
||||
}
|
||||
|
||||
func (p VirtualApp) Clone(ctx context.Context, name string, target types.ManagedObjectReference, spec types.VAppCloneSpec) (*Task, error) {
|
||||
req := types.CloneVApp_Task{
|
||||
This: p.Reference(),
|
||||
Name: name,
|
||||
Target: target,
|
||||
Spec: spec,
|
||||
}
|
||||
|
||||
res, err := methods.CloneVApp_Task(ctx, p.c, &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewTask(p.c, res.Returnval), nil
|
||||
}
|
||||
|
76
vendor/github.com/vmware/govmomi/object/virtual_device_list.go
generated
vendored
76
vendor/github.com/vmware/govmomi/object/virtual_device_list.go
generated
vendored
@@ -19,6 +19,7 @@ package object
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"regexp"
|
||||
@@ -63,11 +64,12 @@ func EthernetCardTypes() VirtualDeviceList {
|
||||
&types.VirtualE1000e{},
|
||||
&types.VirtualVmxnet2{},
|
||||
&types.VirtualVmxnet3{},
|
||||
&types.VirtualVmxnet3Vrdma{},
|
||||
&types.VirtualPCNet32{},
|
||||
&types.VirtualSriovEthernetCard{},
|
||||
}).Select(func(device types.BaseVirtualDevice) bool {
|
||||
c := device.(types.BaseVirtualEthernetCard).GetVirtualEthernetCard()
|
||||
c.GetVirtualDevice().Key = -1
|
||||
c.GetVirtualDevice().Key = VirtualDeviceList{}.newRandomKey()
|
||||
return true
|
||||
})
|
||||
}
|
||||
@@ -134,6 +136,9 @@ func (l VirtualDeviceList) SelectByBackingInfo(backing types.BaseVirtualDeviceBa
|
||||
b := backing.(*types.VirtualEthernetCardDistributedVirtualPortBackingInfo)
|
||||
return a.Port.SwitchUuid == b.Port.SwitchUuid &&
|
||||
a.Port.PortgroupKey == b.Port.PortgroupKey
|
||||
case *types.VirtualEthernetCardOpaqueNetworkBackingInfo:
|
||||
b := backing.(*types.VirtualEthernetCardOpaqueNetworkBackingInfo)
|
||||
return a.OpaqueNetworkId == b.OpaqueNetworkId
|
||||
case *types.VirtualDiskFlatVer2BackingInfo:
|
||||
b := backing.(*types.VirtualDiskFlatVer2BackingInfo)
|
||||
if a.Parent != nil && b.Parent != nil {
|
||||
@@ -146,6 +151,25 @@ func (l VirtualDeviceList) SelectByBackingInfo(backing types.BaseVirtualDeviceBa
|
||||
case types.BaseVirtualDeviceFileBackingInfo:
|
||||
b := backing.(types.BaseVirtualDeviceFileBackingInfo)
|
||||
return a.GetVirtualDeviceFileBackingInfo().FileName == b.GetVirtualDeviceFileBackingInfo().FileName
|
||||
case *types.VirtualPCIPassthroughVmiopBackingInfo:
|
||||
b := backing.(*types.VirtualPCIPassthroughVmiopBackingInfo)
|
||||
return a.Vgpu == b.Vgpu
|
||||
case *types.VirtualPCIPassthroughDynamicBackingInfo:
|
||||
b := backing.(*types.VirtualPCIPassthroughDynamicBackingInfo)
|
||||
if b.CustomLabel != "" && b.CustomLabel != a.CustomLabel {
|
||||
return false
|
||||
}
|
||||
if len(b.AllowedDevice) == 0 {
|
||||
return true
|
||||
}
|
||||
for _, x := range a.AllowedDevice {
|
||||
for _, y := range b.AllowedDevice {
|
||||
if x.DeviceId == y.DeviceId && x.VendorId == y.VendorId {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
default:
|
||||
return false
|
||||
}
|
||||
@@ -229,8 +253,10 @@ func (l VirtualDeviceList) FindSCSIController(name string) (*types.VirtualSCSICo
|
||||
func (l VirtualDeviceList) CreateSCSIController(name string) (types.BaseVirtualDevice, error) {
|
||||
ctypes := SCSIControllerTypes()
|
||||
|
||||
if name == "scsi" || name == "" {
|
||||
if name == "" || name == "scsi" {
|
||||
name = ctypes.Type(ctypes[0])
|
||||
} else if name == "virtualscsi" {
|
||||
name = "pvscsi" // ovf VirtualSCSI mapping
|
||||
}
|
||||
|
||||
found := ctypes.Select(func(device types.BaseVirtualDevice) bool {
|
||||
@@ -431,10 +457,22 @@ func (l VirtualDeviceList) AssignController(device types.BaseVirtualDevice, c ty
|
||||
d.UnitNumber = new(int32)
|
||||
*d.UnitNumber = l.newUnitNumber(c)
|
||||
if d.Key == 0 {
|
||||
d.Key = -1
|
||||
d.Key = l.newRandomKey()
|
||||
}
|
||||
}
|
||||
|
||||
// newRandomKey returns a random negative device key.
|
||||
// The generated key can be used for devices you want to add so that it does not collide with existing ones.
|
||||
func (l VirtualDeviceList) newRandomKey() int32 {
|
||||
// NOTE: rand.Uint32 cannot be used here because conversion from uint32 to int32 may change the sign
|
||||
key := rand.Int31() * -1
|
||||
if key == 0 {
|
||||
return -1
|
||||
}
|
||||
|
||||
return key
|
||||
}
|
||||
|
||||
// CreateDisk creates a new VirtualDisk device which can be added to a VM.
|
||||
func (l VirtualDeviceList) CreateDisk(c types.BaseVirtualController, ds types.ManagedObjectReference, name string) *types.VirtualDisk {
|
||||
// If name is not specified, one will be chosen for you.
|
||||
@@ -862,6 +900,8 @@ func (l VirtualDeviceList) Type(device types.BaseVirtualDevice) string {
|
||||
return "lsilogic-sas"
|
||||
case *types.VirtualNVMEController:
|
||||
return "nvme"
|
||||
case *types.VirtualPrecisionClock:
|
||||
return "clock"
|
||||
default:
|
||||
return l.deviceName(device)
|
||||
}
|
||||
@@ -879,7 +919,13 @@ func (l VirtualDeviceList) Name(device types.BaseVirtualDevice) string {
|
||||
dtype := l.Type(device)
|
||||
switch dtype {
|
||||
case DeviceTypeEthernet:
|
||||
key = fmt.Sprintf("%d", UnitNumber-7)
|
||||
// Ethernet devices of UnitNumber 7-19 are non-SRIOV. Ethernet devices of
|
||||
// UnitNumber 45-36 descending are SRIOV
|
||||
if UnitNumber <= 45 && UnitNumber >= 36 {
|
||||
key = fmt.Sprintf("sriov-%d", 45-UnitNumber)
|
||||
} else {
|
||||
key = fmt.Sprintf("%d", UnitNumber-7)
|
||||
}
|
||||
case DeviceTypeDisk:
|
||||
key = fmt.Sprintf("%d-%d", d.ControllerKey, UnitNumber)
|
||||
default:
|
||||
@@ -907,25 +953,9 @@ func (l VirtualDeviceList) ConfigSpec(op types.VirtualDeviceConfigSpecOperation)
|
||||
var res []types.BaseVirtualDeviceConfigSpec
|
||||
for _, device := range l {
|
||||
config := &types.VirtualDeviceConfigSpec{
|
||||
Device: device,
|
||||
Operation: op,
|
||||
}
|
||||
|
||||
if disk, ok := device.(*types.VirtualDisk); ok {
|
||||
config.FileOperation = fop
|
||||
|
||||
// Special case to attach an existing disk
|
||||
if op == types.VirtualDeviceConfigSpecOperationAdd && disk.CapacityInKB == 0 {
|
||||
childDisk := false
|
||||
if b, ok := disk.Backing.(*types.VirtualDiskFlatVer2BackingInfo); ok {
|
||||
childDisk = b.Parent != nil
|
||||
}
|
||||
|
||||
if !childDisk {
|
||||
// Existing disk, clear file operation
|
||||
config.FileOperation = ""
|
||||
}
|
||||
}
|
||||
Device: device,
|
||||
Operation: op,
|
||||
FileOperation: diskFileOperation(op, fop, device),
|
||||
}
|
||||
|
||||
res = append(res, config)
|
||||
|
295
vendor/github.com/vmware/govmomi/object/virtual_machine.go
generated
vendored
295
vendor/github.com/vmware/govmomi/object/virtual_machine.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2015-2017 VMware, Inc. All Rights Reserved.
|
||||
Copyright (c) 2015-2021 VMware, Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/vmware/govmomi/nfc"
|
||||
"github.com/vmware/govmomi/property"
|
||||
@@ -33,12 +34,41 @@ import (
|
||||
|
||||
const (
|
||||
PropRuntimePowerState = "summary.runtime.powerState"
|
||||
PropConfigTemplate = "summary.config.template"
|
||||
)
|
||||
|
||||
type VirtualMachine struct {
|
||||
Common
|
||||
}
|
||||
|
||||
// extractDiskLayoutFiles is a helper function used to extract file keys for
|
||||
// all disk files attached to the virtual machine at the current point of
|
||||
// running.
|
||||
func extractDiskLayoutFiles(diskLayoutList []types.VirtualMachineFileLayoutExDiskLayout) []int {
|
||||
var result []int
|
||||
|
||||
for _, layoutExDisk := range diskLayoutList {
|
||||
for _, link := range layoutExDisk.Chain {
|
||||
for i := range link.FileKey { // diskDescriptor, diskExtent pairs
|
||||
result = append(result, int(link.FileKey[i]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// removeKey is a helper function for removing a specific file key from a list
|
||||
// of keys associated with disks attached to a virtual machine.
|
||||
func removeKey(l *[]int, key int) {
|
||||
for i, k := range *l {
|
||||
if k == key {
|
||||
*l = append((*l)[:i], (*l)[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func NewVirtualMachine(c *vim25.Client, ref types.ManagedObjectReference) *VirtualMachine {
|
||||
return &VirtualMachine{
|
||||
Common: NewCommon(c, ref),
|
||||
@@ -56,6 +86,17 @@ func (v VirtualMachine) PowerState(ctx context.Context) (types.VirtualMachinePow
|
||||
return o.Summary.Runtime.PowerState, nil
|
||||
}
|
||||
|
||||
func (v VirtualMachine) IsTemplate(ctx context.Context) (bool, error) {
|
||||
var o mo.VirtualMachine
|
||||
|
||||
err := v.Properties(ctx, v.Reference(), []string{PropConfigTemplate}, &o)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return o.Summary.Config.Template, nil
|
||||
}
|
||||
|
||||
func (v VirtualMachine) PowerOn(ctx context.Context) (*Task, error) {
|
||||
req := types.PowerOnVM_Task{
|
||||
This: v.Reference(),
|
||||
@@ -169,6 +210,20 @@ func (v VirtualMachine) Clone(ctx context.Context, folder *Folder, name string,
|
||||
return NewTask(v.c, res.Returnval), nil
|
||||
}
|
||||
|
||||
func (v VirtualMachine) InstantClone(ctx context.Context, config types.VirtualMachineInstantCloneSpec) (*Task, error) {
|
||||
req := types.InstantClone_Task{
|
||||
This: v.Reference(),
|
||||
Spec: config,
|
||||
}
|
||||
|
||||
res, err := methods.InstantClone_Task(ctx, v.c, &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewTask(v.c, res.Returnval), nil
|
||||
}
|
||||
|
||||
func (v VirtualMachine) Customize(ctx context.Context, spec types.CustomizationSpec) (*Task, error) {
|
||||
req := types.CustomizeVM_Task{
|
||||
This: v.Reference(),
|
||||
@@ -221,7 +276,9 @@ func (v VirtualMachine) RefreshStorageInfo(ctx context.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (v VirtualMachine) WaitForIP(ctx context.Context) (string, error) {
|
||||
// WaitForIP waits for the VM guest.ipAddress property to report an IP address.
|
||||
// Waits for an IPv4 address if the v4 param is true.
|
||||
func (v VirtualMachine) WaitForIP(ctx context.Context, v4 ...bool) (string, error) {
|
||||
var ip string
|
||||
|
||||
p := property.DefaultCollector(v.c)
|
||||
@@ -238,6 +295,11 @@ func (v VirtualMachine) WaitForIP(ctx context.Context) (string, error) {
|
||||
}
|
||||
|
||||
ip = c.Val.(string)
|
||||
if len(v4) == 1 && v4[0] {
|
||||
if net.ParseIP(ip).To4() == nil {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -272,7 +334,9 @@ func (v VirtualMachine) WaitForNetIP(ctx context.Context, v4 bool, device ...str
|
||||
devices := VirtualDeviceList(c.Val.(types.ArrayOfVirtualDevice).VirtualDevice)
|
||||
for _, d := range devices {
|
||||
if nic, ok := d.(types.BaseVirtualEthernetCard); ok {
|
||||
mac := nic.GetVirtualEthernetCard().MacAddress
|
||||
// Convert to lower so that e.g. 00:50:56:83:3A:5D is treated the
|
||||
// same as 00:50:56:83:3a:5d
|
||||
mac := strings.ToLower(nic.GetVirtualEthernetCard().MacAddress)
|
||||
if mac == "" {
|
||||
return false
|
||||
}
|
||||
@@ -285,6 +349,10 @@ func (v VirtualMachine) WaitForNetIP(ctx context.Context, v4 bool, device ...str
|
||||
return true
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(device) != 0 {
|
||||
// Only wait for specific NIC(s)
|
||||
macs = make(map[string][]string)
|
||||
@@ -304,7 +372,9 @@ func (v VirtualMachine) WaitForNetIP(ctx context.Context, v4 bool, device ...str
|
||||
|
||||
nics := c.Val.(types.ArrayOfGuestNicInfo).GuestNicInfo
|
||||
for _, nic := range nics {
|
||||
mac := nic.MacAddress
|
||||
// Convert to lower so that e.g. 00:50:56:83:3A:5D is treated the
|
||||
// same as 00:50:56:83:3a:5d
|
||||
mac := strings.ToLower(nic.MacAddress)
|
||||
if mac == "" || nic.IpConfig == nil {
|
||||
continue
|
||||
}
|
||||
@@ -391,29 +461,33 @@ func (v VirtualMachine) ResourcePool(ctx context.Context) (*ResourcePool, error)
|
||||
return NewResourcePool(v.c, *rp), nil
|
||||
}
|
||||
|
||||
func diskFileOperation(op types.VirtualDeviceConfigSpecOperation, fop types.VirtualDeviceConfigSpecFileOperation, device types.BaseVirtualDevice) types.VirtualDeviceConfigSpecFileOperation {
|
||||
if disk, ok := device.(*types.VirtualDisk); ok {
|
||||
// Special case to attach an existing disk
|
||||
if op == types.VirtualDeviceConfigSpecOperationAdd && disk.CapacityInKB == 0 && disk.CapacityInBytes == 0 {
|
||||
childDisk := false
|
||||
if b, ok := disk.Backing.(*types.VirtualDiskFlatVer2BackingInfo); ok {
|
||||
childDisk = b.Parent != nil
|
||||
}
|
||||
|
||||
if !childDisk {
|
||||
fop = "" // existing disk
|
||||
}
|
||||
}
|
||||
return fop
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func (v VirtualMachine) configureDevice(ctx context.Context, op types.VirtualDeviceConfigSpecOperation, fop types.VirtualDeviceConfigSpecFileOperation, devices ...types.BaseVirtualDevice) error {
|
||||
spec := types.VirtualMachineConfigSpec{}
|
||||
|
||||
for _, device := range devices {
|
||||
config := &types.VirtualDeviceConfigSpec{
|
||||
Device: device,
|
||||
Operation: op,
|
||||
}
|
||||
|
||||
if disk, ok := device.(*types.VirtualDisk); ok {
|
||||
config.FileOperation = fop
|
||||
|
||||
// Special case to attach an existing disk
|
||||
if op == types.VirtualDeviceConfigSpecOperationAdd && disk.CapacityInKB == 0 {
|
||||
childDisk := false
|
||||
if b, ok := disk.Backing.(*types.VirtualDiskFlatVer2BackingInfo); ok {
|
||||
childDisk = b.Parent != nil
|
||||
}
|
||||
|
||||
if !childDisk {
|
||||
config.FileOperation = "" // existing disk
|
||||
}
|
||||
}
|
||||
Device: device,
|
||||
Operation: op,
|
||||
FileOperation: diskFileOperation(op, fop, device),
|
||||
}
|
||||
|
||||
spec.DeviceChange = append(spec.DeviceChange, config)
|
||||
@@ -446,6 +520,41 @@ func (v VirtualMachine) RemoveDevice(ctx context.Context, keepFiles bool, device
|
||||
return v.configureDevice(ctx, types.VirtualDeviceConfigSpecOperationRemove, fop, device...)
|
||||
}
|
||||
|
||||
// AttachDisk attaches the given disk to the VirtualMachine
|
||||
func (v VirtualMachine) AttachDisk(ctx context.Context, id string, datastore *Datastore, controllerKey int32, unitNumber int32) error {
|
||||
req := types.AttachDisk_Task{
|
||||
This: v.Reference(),
|
||||
DiskId: types.ID{Id: id},
|
||||
Datastore: datastore.Reference(),
|
||||
ControllerKey: controllerKey,
|
||||
UnitNumber: &unitNumber,
|
||||
}
|
||||
|
||||
res, err := methods.AttachDisk_Task(ctx, v.c, &req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
task := NewTask(v.c, res.Returnval)
|
||||
return task.Wait(ctx)
|
||||
}
|
||||
|
||||
// DetachDisk detaches the given disk from the VirtualMachine
|
||||
func (v VirtualMachine) DetachDisk(ctx context.Context, id string) error {
|
||||
req := types.DetachDisk_Task{
|
||||
This: v.Reference(),
|
||||
DiskId: types.ID{Id: id},
|
||||
}
|
||||
|
||||
res, err := methods.DetachDisk_Task(ctx, v.c, &req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
task := NewTask(v.c, res.Returnval)
|
||||
return task.Wait(ctx)
|
||||
}
|
||||
|
||||
// BootOptions returns the VirtualMachine's config.bootOptions property.
|
||||
func (v VirtualMachine) BootOptions(ctx context.Context) (*types.VirtualMachineBootOptions, error) {
|
||||
var o mo.VirtualMachine
|
||||
@@ -556,6 +665,63 @@ func (m snapshotMap) add(parent string, tree []types.VirtualMachineSnapshotTree)
|
||||
}
|
||||
}
|
||||
|
||||
// SnapshotSize calculates the size of a given snapshot in bytes. If the
|
||||
// snapshot is current, disk files not associated with any parent snapshot are
|
||||
// included in size calculations. This allows for measuring and including the
|
||||
// growth from the last fixed snapshot to the present state.
|
||||
func SnapshotSize(info types.ManagedObjectReference, parent *types.ManagedObjectReference, vmlayout *types.VirtualMachineFileLayoutEx, isCurrent bool) int {
|
||||
var fileKeyList []int
|
||||
var parentFiles []int
|
||||
var allSnapshotFiles []int
|
||||
|
||||
diskFiles := extractDiskLayoutFiles(vmlayout.Disk)
|
||||
|
||||
for _, layout := range vmlayout.Snapshot {
|
||||
diskLayout := extractDiskLayoutFiles(layout.Disk)
|
||||
allSnapshotFiles = append(allSnapshotFiles, diskLayout...)
|
||||
|
||||
if layout.Key.Value == info.Value {
|
||||
fileKeyList = append(fileKeyList, int(layout.DataKey)) // The .vmsn file
|
||||
fileKeyList = append(fileKeyList, diskLayout...) // The .vmdk files
|
||||
} else if parent != nil && layout.Key.Value == parent.Value {
|
||||
parentFiles = append(parentFiles, diskLayout...)
|
||||
}
|
||||
}
|
||||
|
||||
for _, parentFile := range parentFiles {
|
||||
removeKey(&fileKeyList, parentFile)
|
||||
}
|
||||
|
||||
for _, file := range allSnapshotFiles {
|
||||
removeKey(&diskFiles, file)
|
||||
}
|
||||
|
||||
fileKeyMap := make(map[int]types.VirtualMachineFileLayoutExFileInfo)
|
||||
for _, file := range vmlayout.File {
|
||||
fileKeyMap[int(file.Key)] = file
|
||||
}
|
||||
|
||||
size := 0
|
||||
|
||||
for _, fileKey := range fileKeyList {
|
||||
file := fileKeyMap[fileKey]
|
||||
if parent != nil ||
|
||||
(file.Type != string(types.VirtualMachineFileLayoutExFileTypeDiskDescriptor) &&
|
||||
file.Type != string(types.VirtualMachineFileLayoutExFileTypeDiskExtent)) {
|
||||
size += int(file.Size)
|
||||
}
|
||||
}
|
||||
|
||||
if isCurrent {
|
||||
for _, diskFile := range diskFiles {
|
||||
file := fileKeyMap[diskFile]
|
||||
size += int(file.Size)
|
||||
}
|
||||
}
|
||||
|
||||
return size
|
||||
}
|
||||
|
||||
// FindSnapshot supports snapshot lookup by name, where name can be:
|
||||
// 1) snapshot ManagedObjectReference.Value (unique)
|
||||
// 2) snapshot name (may not be unique)
|
||||
@@ -569,7 +735,7 @@ func (v VirtualMachine) FindSnapshot(ctx context.Context, name string) (*types.M
|
||||
}
|
||||
|
||||
if o.Snapshot == nil || len(o.Snapshot.RootSnapshotList) == 0 {
|
||||
return nil, errors.New("No snapshots for this VM")
|
||||
return nil, errors.New("no snapshots for this VM")
|
||||
}
|
||||
|
||||
m := make(snapshotMap)
|
||||
@@ -832,6 +998,85 @@ func (v VirtualMachine) UUID(ctx context.Context) string {
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return o.Config.Uuid
|
||||
if o.Config != nil {
|
||||
return o.Config.Uuid
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (v VirtualMachine) QueryChangedDiskAreas(ctx context.Context, baseSnapshot, curSnapshot *types.ManagedObjectReference, disk *types.VirtualDisk, offset int64) (types.DiskChangeInfo, error) {
|
||||
var noChange types.DiskChangeInfo
|
||||
var err error
|
||||
|
||||
if offset > disk.CapacityInBytes {
|
||||
return noChange, fmt.Errorf("offset is greater than the disk size (%#x and %#x)", offset, disk.CapacityInBytes)
|
||||
} else if offset == disk.CapacityInBytes {
|
||||
return types.DiskChangeInfo{StartOffset: offset, Length: 0}, nil
|
||||
}
|
||||
|
||||
var b mo.VirtualMachineSnapshot
|
||||
err = v.Properties(ctx, baseSnapshot.Reference(), []string{"config.hardware"}, &b)
|
||||
if err != nil {
|
||||
return noChange, fmt.Errorf("failed to fetch config.hardware of snapshot %s: %s", baseSnapshot, err)
|
||||
}
|
||||
|
||||
var changeId *string
|
||||
for _, vd := range b.Config.Hardware.Device {
|
||||
d := vd.GetVirtualDevice()
|
||||
if d.Key != disk.Key {
|
||||
continue
|
||||
}
|
||||
|
||||
// As per VDDK programming guide, these are the four types of disks
|
||||
// that support CBT, see "Gathering Changed Block Information".
|
||||
if b, ok := d.Backing.(*types.VirtualDiskFlatVer2BackingInfo); ok {
|
||||
changeId = &b.ChangeId
|
||||
break
|
||||
}
|
||||
if b, ok := d.Backing.(*types.VirtualDiskSparseVer2BackingInfo); ok {
|
||||
changeId = &b.ChangeId
|
||||
break
|
||||
}
|
||||
if b, ok := d.Backing.(*types.VirtualDiskRawDiskMappingVer1BackingInfo); ok {
|
||||
changeId = &b.ChangeId
|
||||
break
|
||||
}
|
||||
if b, ok := d.Backing.(*types.VirtualDiskRawDiskVer2BackingInfo); ok {
|
||||
changeId = &b.ChangeId
|
||||
break
|
||||
}
|
||||
|
||||
return noChange, fmt.Errorf("disk %d has backing info without .ChangeId: %t", disk.Key, d.Backing)
|
||||
}
|
||||
if changeId == nil || *changeId == "" {
|
||||
return noChange, fmt.Errorf("CBT is not enabled on disk %d", disk.Key)
|
||||
}
|
||||
|
||||
req := types.QueryChangedDiskAreas{
|
||||
This: v.Reference(),
|
||||
Snapshot: curSnapshot,
|
||||
DeviceKey: disk.Key,
|
||||
StartOffset: offset,
|
||||
ChangeId: *changeId,
|
||||
}
|
||||
|
||||
res, err := methods.QueryChangedDiskAreas(ctx, v.Client(), &req)
|
||||
if err != nil {
|
||||
return noChange, err
|
||||
}
|
||||
|
||||
return res.Returnval, nil
|
||||
}
|
||||
|
||||
// ExportSnapshot exports all VMDK-files up to (but not including) a specified snapshot. This
|
||||
// is useful when exporting a running VM.
|
||||
func (v *VirtualMachine) ExportSnapshot(ctx context.Context, snapshot *types.ManagedObjectReference) (*nfc.Lease, error) {
|
||||
req := types.ExportSnapshot{
|
||||
This: *snapshot,
|
||||
}
|
||||
resp, err := methods.ExportSnapshot(ctx, v.Client(), &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nfc.NewLease(v.c, resp.Returnval), nil
|
||||
}
|
||||
|
4
vendor/github.com/vmware/govmomi/object/vmware_distributed_virtual_switch.go
generated
vendored
4
vendor/github.com/vmware/govmomi/object/vmware_distributed_virtual_switch.go
generated
vendored
@@ -19,3 +19,7 @@ package object
|
||||
type VmwareDistributedVirtualSwitch struct {
|
||||
DistributedVirtualSwitch
|
||||
}
|
||||
|
||||
func (s VmwareDistributedVirtualSwitch) GetInventoryPath() string {
|
||||
return s.InventoryPath
|
||||
}
|
||||
|
128
vendor/github.com/vmware/govmomi/ovf/cim.go
generated
vendored
Normal file
128
vendor/github.com/vmware/govmomi/ovf/cim.go
generated
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package ovf
|
||||
|
||||
import (
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
/*
|
||||
Source: http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2.24.0/CIM_VirtualSystemSettingData.xsd
|
||||
*/
|
||||
|
||||
type CIMVirtualSystemSettingData struct {
|
||||
ElementName string `xml:"ElementName"`
|
||||
InstanceID string `xml:"InstanceID"`
|
||||
|
||||
AutomaticRecoveryAction *uint8 `xml:"AutomaticRecoveryAction"`
|
||||
AutomaticShutdownAction *uint8 `xml:"AutomaticShutdownAction"`
|
||||
AutomaticStartupAction *uint8 `xml:"AutomaticStartupAction"`
|
||||
AutomaticStartupActionDelay *string `xml:"AutomaticStartupActionDelay>Interval"`
|
||||
AutomaticStartupActionSequenceNumber *uint16 `xml:"AutomaticStartupActionSequenceNumber"`
|
||||
Caption *string `xml:"Caption"`
|
||||
ConfigurationDataRoot *string `xml:"ConfigurationDataRoot"`
|
||||
ConfigurationFile *string `xml:"ConfigurationFile"`
|
||||
ConfigurationID *string `xml:"ConfigurationID"`
|
||||
CreationTime *string `xml:"CreationTime"`
|
||||
Description *string `xml:"Description"`
|
||||
LogDataRoot *string `xml:"LogDataRoot"`
|
||||
Notes []string `xml:"Notes"`
|
||||
RecoveryFile *string `xml:"RecoveryFile"`
|
||||
SnapshotDataRoot *string `xml:"SnapshotDataRoot"`
|
||||
SuspendDataRoot *string `xml:"SuspendDataRoot"`
|
||||
SwapFileDataRoot *string `xml:"SwapFileDataRoot"`
|
||||
VirtualSystemIdentifier *string `xml:"VirtualSystemIdentifier"`
|
||||
VirtualSystemType *string `xml:"VirtualSystemType"`
|
||||
}
|
||||
|
||||
/*
|
||||
Source: http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2.24.0/CIM_ResourceAllocationSettingData.xsd
|
||||
*/
|
||||
|
||||
type CIMResourceAllocationSettingData struct {
|
||||
ElementName string `xml:"ElementName"`
|
||||
InstanceID string `xml:"InstanceID"`
|
||||
|
||||
ResourceType *uint16 `xml:"ResourceType"`
|
||||
OtherResourceType *string `xml:"OtherResourceType"`
|
||||
ResourceSubType *string `xml:"ResourceSubType"`
|
||||
|
||||
AddressOnParent *string `xml:"AddressOnParent"`
|
||||
Address *string `xml:"Address"`
|
||||
AllocationUnits *string `xml:"AllocationUnits"`
|
||||
AutomaticAllocation *bool `xml:"AutomaticAllocation"`
|
||||
AutomaticDeallocation *bool `xml:"AutomaticDeallocation"`
|
||||
Caption *string `xml:"Caption"`
|
||||
Connection []string `xml:"Connection"`
|
||||
ConsumerVisibility *uint16 `xml:"ConsumerVisibility"`
|
||||
Description *string `xml:"Description"`
|
||||
HostResource []string `xml:"HostResource"`
|
||||
Limit *uint64 `xml:"Limit"`
|
||||
MappingBehavior *uint `xml:"MappingBehavior"`
|
||||
Parent *string `xml:"Parent"`
|
||||
PoolID *string `xml:"PoolID"`
|
||||
Reservation *uint64 `xml:"Reservation"`
|
||||
VirtualQuantity *uint `xml:"VirtualQuantity"`
|
||||
VirtualQuantityUnits *string `xml:"VirtualQuantityUnits"`
|
||||
Weight *uint `xml:"Weight"`
|
||||
}
|
||||
|
||||
/*
|
||||
Source: http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2.24.0/CIM_StorageAllocationSettingData.xsd
|
||||
*/
|
||||
type CIMStorageAllocationSettingData struct {
|
||||
ElementName string `xml:"ElementName"`
|
||||
InstanceID string `xml:"InstanceID"`
|
||||
|
||||
ResourceType *uint16 `xml:"ResourceType"`
|
||||
OtherResourceType *string `xml:"OtherResourceType"`
|
||||
ResourceSubType *string `xml:"ResourceSubType"`
|
||||
|
||||
Access *uint16 `xml:"Access"`
|
||||
Address *string `xml:"Address"`
|
||||
AddressOnParent *string `xml:"AddressOnParent"`
|
||||
AllocationUnits *string `xml:"AllocationUnits"`
|
||||
AutomaticAllocation *bool `xml:"AutomaticAllocation"`
|
||||
AutomaticDeallocation *bool `xml:"AutomaticDeallocation"`
|
||||
Caption *string `xml:"Caption"`
|
||||
ChangeableType *uint16 `xml:"ChangeableType"`
|
||||
ComponentSetting []types.AnyType `xml:"ComponentSetting"`
|
||||
ConfigurationName *string `xml:"ConfigurationName"`
|
||||
Connection []string `xml:"Connection"`
|
||||
ConsumerVisibility *uint16 `xml:"ConsumerVisibility"`
|
||||
Description *string `xml:"Description"`
|
||||
Generation *uint64 `xml:"Generation"`
|
||||
HostExtentName *string `xml:"HostExtentName"`
|
||||
HostExtentNameFormat *uint16 `xml:"HostExtentNameFormat"`
|
||||
HostExtentNameNamespace *uint16 `xml:"HostExtentNameNamespace"`
|
||||
HostExtentStartingAddress *uint64 `xml:"HostExtentStartingAddress"`
|
||||
HostResource []string `xml:"HostResource"`
|
||||
HostResourceBlockSize *uint64 `xml:"HostResourceBlockSize"`
|
||||
Limit *uint64 `xml:"Limit"`
|
||||
MappingBehavior *uint `xml:"MappingBehavior"`
|
||||
OtherHostExtentNameFormat *string `xml:"OtherHostExtentNameFormat"`
|
||||
OtherHostExtentNameNamespace *string `xml:"OtherHostExtentNameNamespace"`
|
||||
Parent *string `xml:"Parent"`
|
||||
PoolID *string `xml:"PoolID"`
|
||||
Reservation *uint64 `xml:"Reservation"`
|
||||
SoID *string `xml:"SoID"`
|
||||
SoOrgID *string `xml:"SoOrgID"`
|
||||
VirtualQuantity *uint `xml:"VirtualQuantity"`
|
||||
VirtualQuantityUnits *string `xml:"VirtualQuantityUnits"`
|
||||
VirtualResourceBlockSize *uint64 `xml:"VirtualResourceBlockSize"`
|
||||
Weight *uint `xml:"Weight"`
|
||||
}
|
25
vendor/github.com/vmware/govmomi/ovf/doc.go
generated
vendored
Normal file
25
vendor/github.com/vmware/govmomi/ovf/doc.go
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Package ovf provides functionality to unmarshal and inspect the structure
|
||||
of an OVF file. It is not a complete implementation of the specification and
|
||||
is intended to be used to import virtual infrastructure into vSphere.
|
||||
|
||||
For a complete specification of the OVF standard, refer to:
|
||||
https://www.dmtf.org/sites/default/files/standards/documents/DSP0243_2.1.0.pdf
|
||||
*/
|
||||
package ovf
|
99
vendor/github.com/vmware/govmomi/ovf/env.go
generated
vendored
Normal file
99
vendor/github.com/vmware/govmomi/ovf/env.go
generated
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package ovf
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
"github.com/vmware/govmomi/vim25/xml"
|
||||
)
|
||||
|
||||
const (
|
||||
ovfEnvHeader = `<Environment
|
||||
xmlns="http://schemas.dmtf.org/ovf/environment/1"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:oe="http://schemas.dmtf.org/ovf/environment/1"
|
||||
xmlns:ve="http://www.vmware.com/schema/ovfenv"
|
||||
oe:id=""
|
||||
ve:esxId="%s">`
|
||||
ovfEnvPlatformSection = `<PlatformSection>
|
||||
<Kind>%s</Kind>
|
||||
<Version>%s</Version>
|
||||
<Vendor>%s</Vendor>
|
||||
<Locale>%s</Locale>
|
||||
</PlatformSection>`
|
||||
ovfEnvPropertyHeader = `<PropertySection>`
|
||||
ovfEnvPropertyEntry = `<Property oe:key="%s" oe:value="%s"/>`
|
||||
ovfEnvPropertyFooter = `</PropertySection>`
|
||||
ovfEnvFooter = `</Environment>`
|
||||
)
|
||||
|
||||
type Env struct {
|
||||
XMLName xml.Name `xml:"http://schemas.dmtf.org/ovf/environment/1 Environment"`
|
||||
ID string `xml:"id,attr"`
|
||||
EsxID string `xml:"http://www.vmware.com/schema/ovfenv esxId,attr"`
|
||||
|
||||
Platform *PlatformSection `xml:"PlatformSection"`
|
||||
Property *PropertySection `xml:"PropertySection"`
|
||||
}
|
||||
|
||||
type PlatformSection struct {
|
||||
Kind string `xml:"Kind"`
|
||||
Version string `xml:"Version"`
|
||||
Vendor string `xml:"Vendor"`
|
||||
Locale string `xml:"Locale"`
|
||||
}
|
||||
|
||||
type PropertySection struct {
|
||||
Properties []EnvProperty `xml:"Property"`
|
||||
}
|
||||
|
||||
type EnvProperty struct {
|
||||
Key string `xml:"key,attr"`
|
||||
Value string `xml:"value,attr"`
|
||||
}
|
||||
|
||||
// Marshal marshals Env to xml by using xml.Marshal.
|
||||
func (e Env) Marshal() (string, error) {
|
||||
x, err := xml.Marshal(e)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s%s", xml.Header, x), nil
|
||||
}
|
||||
|
||||
// MarshalManual manually marshals Env to xml suitable for a vApp guest.
|
||||
// It exists to overcome the lack of expressiveness in Go's XML namespaces.
|
||||
func (e Env) MarshalManual() string {
|
||||
var buffer bytes.Buffer
|
||||
|
||||
buffer.WriteString(xml.Header)
|
||||
buffer.WriteString(fmt.Sprintf(ovfEnvHeader, e.EsxID))
|
||||
buffer.WriteString(fmt.Sprintf(ovfEnvPlatformSection, e.Platform.Kind, e.Platform.Version, e.Platform.Vendor, e.Platform.Locale))
|
||||
|
||||
buffer.WriteString(fmt.Sprint(ovfEnvPropertyHeader))
|
||||
for _, p := range e.Property.Properties {
|
||||
buffer.WriteString(fmt.Sprintf(ovfEnvPropertyEntry, p.Key, p.Value))
|
||||
}
|
||||
buffer.WriteString(fmt.Sprint(ovfEnvPropertyFooter))
|
||||
|
||||
buffer.WriteString(fmt.Sprint(ovfEnvFooter))
|
||||
|
||||
return buffer.String()
|
||||
}
|
208
vendor/github.com/vmware/govmomi/ovf/envelope.go
generated
vendored
Normal file
208
vendor/github.com/vmware/govmomi/ovf/envelope.go
generated
vendored
Normal file
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package ovf
|
||||
|
||||
type Envelope struct {
|
||||
References []File `xml:"References>File"`
|
||||
|
||||
// Package level meta-data
|
||||
Annotation *AnnotationSection `xml:"AnnotationSection"`
|
||||
Product *ProductSection `xml:"ProductSection"`
|
||||
Network *NetworkSection `xml:"NetworkSection"`
|
||||
Disk *DiskSection `xml:"DiskSection"`
|
||||
OperatingSystem *OperatingSystemSection `xml:"OperatingSystemSection"`
|
||||
Eula *EulaSection `xml:"EulaSection"`
|
||||
VirtualHardware *VirtualHardwareSection `xml:"VirtualHardwareSection"`
|
||||
ResourceAllocation *ResourceAllocationSection `xml:"ResourceAllocationSection"`
|
||||
DeploymentOption *DeploymentOptionSection `xml:"DeploymentOptionSection"`
|
||||
|
||||
// Content: A VirtualSystem or a VirtualSystemCollection
|
||||
VirtualSystem *VirtualSystem `xml:"VirtualSystem"`
|
||||
}
|
||||
|
||||
type VirtualSystem struct {
|
||||
Content
|
||||
|
||||
Annotation []AnnotationSection `xml:"AnnotationSection"`
|
||||
Product []ProductSection `xml:"ProductSection"`
|
||||
OperatingSystem []OperatingSystemSection `xml:"OperatingSystemSection"`
|
||||
Eula []EulaSection `xml:"EulaSection"`
|
||||
VirtualHardware []VirtualHardwareSection `xml:"VirtualHardwareSection"`
|
||||
}
|
||||
|
||||
type File struct {
|
||||
ID string `xml:"id,attr"`
|
||||
Href string `xml:"href,attr"`
|
||||
Size uint `xml:"size,attr"`
|
||||
Compression *string `xml:"compression,attr"`
|
||||
ChunkSize *int `xml:"chunkSize,attr"`
|
||||
}
|
||||
|
||||
type Content struct {
|
||||
ID string `xml:"id,attr"`
|
||||
Info string `xml:"Info"`
|
||||
Name *string `xml:"Name"`
|
||||
}
|
||||
|
||||
type Section struct {
|
||||
Required *bool `xml:"required,attr"`
|
||||
Info string `xml:"Info"`
|
||||
}
|
||||
|
||||
type AnnotationSection struct {
|
||||
Section
|
||||
|
||||
Annotation string `xml:"Annotation"`
|
||||
}
|
||||
|
||||
type ProductSection struct {
|
||||
Section
|
||||
|
||||
Class *string `xml:"class,attr"`
|
||||
Instance *string `xml:"instance,attr"`
|
||||
|
||||
Product string `xml:"Product"`
|
||||
Vendor string `xml:"Vendor"`
|
||||
Version string `xml:"Version"`
|
||||
FullVersion string `xml:"FullVersion"`
|
||||
ProductURL string `xml:"ProductUrl"`
|
||||
VendorURL string `xml:"VendorUrl"`
|
||||
AppURL string `xml:"AppUrl"`
|
||||
Property []Property `xml:"Property"`
|
||||
}
|
||||
|
||||
type Property struct {
|
||||
Key string `xml:"key,attr"`
|
||||
Type string `xml:"type,attr"`
|
||||
Qualifiers *string `xml:"qualifiers,attr"`
|
||||
UserConfigurable *bool `xml:"userConfigurable,attr"`
|
||||
Default *string `xml:"value,attr"`
|
||||
Password *bool `xml:"password,attr"`
|
||||
|
||||
Label *string `xml:"Label"`
|
||||
Description *string `xml:"Description"`
|
||||
|
||||
Values []PropertyConfigurationValue `xml:"Value"`
|
||||
}
|
||||
|
||||
type PropertyConfigurationValue struct {
|
||||
Value string `xml:"value,attr"`
|
||||
Configuration *string `xml:"configuration,attr"`
|
||||
}
|
||||
|
||||
type NetworkSection struct {
|
||||
Section
|
||||
|
||||
Networks []Network `xml:"Network"`
|
||||
}
|
||||
|
||||
type Network struct {
|
||||
Name string `xml:"name,attr"`
|
||||
|
||||
Description string `xml:"Description"`
|
||||
}
|
||||
|
||||
type DiskSection struct {
|
||||
Section
|
||||
|
||||
Disks []VirtualDiskDesc `xml:"Disk"`
|
||||
}
|
||||
|
||||
type VirtualDiskDesc struct {
|
||||
DiskID string `xml:"diskId,attr"`
|
||||
FileRef *string `xml:"fileRef,attr"`
|
||||
Capacity string `xml:"capacity,attr"`
|
||||
CapacityAllocationUnits *string `xml:"capacityAllocationUnits,attr"`
|
||||
Format *string `xml:"format,attr"`
|
||||
PopulatedSize *int `xml:"populatedSize,attr"`
|
||||
ParentRef *string `xml:"parentRef,attr"`
|
||||
}
|
||||
|
||||
type OperatingSystemSection struct {
|
||||
Section
|
||||
|
||||
ID int16 `xml:"id,attr"`
|
||||
Version *string `xml:"version,attr"`
|
||||
OSType *string `xml:"osType,attr"`
|
||||
|
||||
Description *string `xml:"Description"`
|
||||
}
|
||||
|
||||
type EulaSection struct {
|
||||
Section
|
||||
|
||||
License string `xml:"License"`
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Required *bool `xml:"required,attr"`
|
||||
Key string `xml:"key,attr"`
|
||||
Value string `xml:"value,attr"`
|
||||
}
|
||||
|
||||
type VirtualHardwareSection struct {
|
||||
Section
|
||||
|
||||
ID *string `xml:"id,attr"`
|
||||
Transport *string `xml:"transport,attr"`
|
||||
|
||||
System *VirtualSystemSettingData `xml:"System"`
|
||||
Item []ResourceAllocationSettingData `xml:"Item"`
|
||||
StorageItem []StorageAllocationSettingData `xml:"StorageItem"`
|
||||
Config []Config `xml:"Config"`
|
||||
ExtraConfig []Config `xml:"ExtraConfig"`
|
||||
}
|
||||
|
||||
type VirtualSystemSettingData struct {
|
||||
CIMVirtualSystemSettingData
|
||||
}
|
||||
|
||||
type ResourceAllocationSettingData struct {
|
||||
CIMResourceAllocationSettingData
|
||||
|
||||
Required *bool `xml:"required,attr"`
|
||||
Configuration *string `xml:"configuration,attr"`
|
||||
Bound *string `xml:"bound,attr"`
|
||||
}
|
||||
|
||||
type StorageAllocationSettingData struct {
|
||||
CIMStorageAllocationSettingData
|
||||
|
||||
Required *bool `xml:"required,attr"`
|
||||
Configuration *string `xml:"configuration,attr"`
|
||||
Bound *string `xml:"bound,attr"`
|
||||
}
|
||||
|
||||
type ResourceAllocationSection struct {
|
||||
Section
|
||||
|
||||
Item []ResourceAllocationSettingData `xml:"Item"`
|
||||
}
|
||||
|
||||
type DeploymentOptionSection struct {
|
||||
Section
|
||||
|
||||
Configuration []DeploymentOptionConfiguration `xml:"Configuration"`
|
||||
}
|
||||
|
||||
type DeploymentOptionConfiguration struct {
|
||||
ID string `xml:"id,attr"`
|
||||
Default *bool `xml:"default,attr"`
|
||||
|
||||
Label string `xml:"Label"`
|
||||
Description string `xml:"Description"`
|
||||
}
|
103
vendor/github.com/vmware/govmomi/ovf/manager.go
generated
vendored
Normal file
103
vendor/github.com/vmware/govmomi/ovf/manager.go
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
Copyright (c) 2015-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 ovf
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/vmware/govmomi/vim25"
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
type Manager struct {
|
||||
types.ManagedObjectReference
|
||||
|
||||
c *vim25.Client
|
||||
}
|
||||
|
||||
func NewManager(c *vim25.Client) *Manager {
|
||||
return &Manager{*c.ServiceContent.OvfManager, c}
|
||||
}
|
||||
|
||||
// CreateDescriptor wraps methods.CreateDescriptor
|
||||
func (m *Manager) CreateDescriptor(ctx context.Context, obj mo.Reference, cdp types.OvfCreateDescriptorParams) (*types.OvfCreateDescriptorResult, error) {
|
||||
req := types.CreateDescriptor{
|
||||
This: m.Reference(),
|
||||
Obj: obj.Reference(),
|
||||
Cdp: cdp,
|
||||
}
|
||||
|
||||
res, err := methods.CreateDescriptor(ctx, m.c, &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &res.Returnval, nil
|
||||
}
|
||||
|
||||
// CreateImportSpec wraps methods.CreateImportSpec
|
||||
func (m *Manager) CreateImportSpec(ctx context.Context, ovfDescriptor string, resourcePool mo.Reference, datastore mo.Reference, cisp types.OvfCreateImportSpecParams) (*types.OvfCreateImportSpecResult, error) {
|
||||
req := types.CreateImportSpec{
|
||||
This: m.Reference(),
|
||||
OvfDescriptor: ovfDescriptor,
|
||||
ResourcePool: resourcePool.Reference(),
|
||||
Datastore: datastore.Reference(),
|
||||
Cisp: cisp,
|
||||
}
|
||||
|
||||
res, err := methods.CreateImportSpec(ctx, m.c, &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &res.Returnval, nil
|
||||
}
|
||||
|
||||
// ParseDescriptor wraps methods.ParseDescriptor
|
||||
func (m *Manager) ParseDescriptor(ctx context.Context, ovfDescriptor string, pdp types.OvfParseDescriptorParams) (*types.OvfParseDescriptorResult, error) {
|
||||
req := types.ParseDescriptor{
|
||||
This: m.Reference(),
|
||||
OvfDescriptor: ovfDescriptor,
|
||||
Pdp: pdp,
|
||||
}
|
||||
|
||||
res, err := methods.ParseDescriptor(ctx, m.c, &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &res.Returnval, nil
|
||||
}
|
||||
|
||||
// ValidateHost wraps methods.ValidateHost
|
||||
func (m *Manager) ValidateHost(ctx context.Context, ovfDescriptor string, host mo.Reference, vhp types.OvfValidateHostParams) (*types.OvfValidateHostResult, error) {
|
||||
req := types.ValidateHost{
|
||||
This: m.Reference(),
|
||||
OvfDescriptor: ovfDescriptor,
|
||||
Host: host.Reference(),
|
||||
Vhp: vhp,
|
||||
}
|
||||
|
||||
res, err := methods.ValidateHost(ctx, m.c, &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &res.Returnval, nil
|
||||
}
|
@@ -1,7 +1,5 @@
|
||||
//+build !windows
|
||||
|
||||
/*
|
||||
Copyright (c) 2017 VMware, Inc. All Rights Reserved.
|
||||
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -16,23 +14,22 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package simulator
|
||||
package ovf
|
||||
|
||||
import "syscall"
|
||||
import (
|
||||
"io"
|
||||
|
||||
func (ds *Datastore) stat() error {
|
||||
info := ds.Info.GetDatastoreInfo()
|
||||
var stat syscall.Statfs_t
|
||||
"github.com/vmware/govmomi/vim25/xml"
|
||||
)
|
||||
|
||||
err := syscall.Statfs(info.Url, &stat)
|
||||
func Unmarshal(r io.Reader) (*Envelope, error) {
|
||||
var e Envelope
|
||||
|
||||
dec := xml.NewDecoder(r)
|
||||
err := dec.Decode(&e)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info.FreeSpace = int64(stat.Bfree * uint64(stat.Bsize))
|
||||
|
||||
ds.Summary.FreeSpace = info.FreeSpace
|
||||
ds.Summary.Capacity = int64(stat.Blocks * uint64(stat.Bsize))
|
||||
|
||||
return nil
|
||||
return &e, nil
|
||||
}
|
63
vendor/github.com/vmware/govmomi/pbm/client.go
generated
vendored
63
vendor/github.com/vmware/govmomi/pbm/client.go
generated
vendored
@@ -43,6 +43,8 @@ type Client struct {
|
||||
*soap.Client
|
||||
|
||||
ServiceContent types.PbmServiceInstanceContent
|
||||
|
||||
RoundTripper soap.RoundTripper
|
||||
}
|
||||
|
||||
func NewClient(ctx context.Context, c *vim25.Client) (*Client, error) {
|
||||
@@ -57,7 +59,12 @@ func NewClient(ctx context.Context, c *vim25.Client) (*Client, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Client{sc, res.Returnval}, nil
|
||||
return &Client{sc, res.Returnval, sc}, nil
|
||||
}
|
||||
|
||||
// RoundTrip dispatches to the RoundTripper field.
|
||||
func (c *Client) RoundTrip(ctx context.Context, req, res soap.HasFault) error {
|
||||
return c.RoundTripper.RoundTrip(ctx, req, res)
|
||||
}
|
||||
|
||||
func (c *Client) QueryProfile(ctx context.Context, rtype types.PbmProfileResourceType, category string) ([]types.PbmProfileId, error) {
|
||||
@@ -224,3 +231,57 @@ func (c *Client) ProfileIDByName(ctx context.Context, profileName string) (strin
|
||||
}
|
||||
return "", fmt.Errorf("no pbm profile found with name: %q", profileName)
|
||||
}
|
||||
|
||||
func (c *Client) FetchCapabilityMetadata(ctx context.Context, rtype *types.PbmProfileResourceType, vendorUuid string) ([]types.PbmCapabilityMetadataPerCategory, error) {
|
||||
req := types.PbmFetchCapabilityMetadata{
|
||||
This: c.ServiceContent.ProfileManager,
|
||||
ResourceType: rtype,
|
||||
VendorUuid: vendorUuid,
|
||||
}
|
||||
|
||||
res, err := methods.PbmFetchCapabilityMetadata(ctx, c, &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res.Returnval, nil
|
||||
}
|
||||
|
||||
func (c *Client) FetchComplianceResult(ctx context.Context, entities []types.PbmServerObjectRef) ([]types.PbmComplianceResult, error) {
|
||||
req := types.PbmFetchComplianceResult{
|
||||
This: c.ServiceContent.ComplianceManager,
|
||||
Entities: entities,
|
||||
}
|
||||
|
||||
res, err := methods.PbmFetchComplianceResult(ctx, c, &req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res.Returnval, nil
|
||||
}
|
||||
|
||||
// GetProfileNameByID gets storage profile name by ID
|
||||
func (c *Client) GetProfileNameByID(ctx context.Context, profileID string) (string, error) {
|
||||
resourceType := types.PbmProfileResourceType{
|
||||
ResourceType: string(types.PbmProfileResourceTypeEnumSTORAGE),
|
||||
}
|
||||
category := types.PbmProfileCategoryEnumREQUIREMENT
|
||||
ids, err := c.QueryProfile(ctx, resourceType, string(category))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
profiles, err := c.RetrieveContent(ctx, ids)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for i := range profiles {
|
||||
profile := profiles[i].GetPbmProfile()
|
||||
if profile.ProfileId.UniqueId == profileID {
|
||||
return profile.Name, nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("no pbm profile found with id: %q", profileID)
|
||||
}
|
||||
|
2
vendor/github.com/vmware/govmomi/pbm/methods/methods.go
generated
vendored
2
vendor/github.com/vmware/govmomi/pbm/methods/methods.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2014-2018 VMware, Inc. All Rights Reserved.
|
||||
Copyright (c) 2014-2022 VMware, Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
2
vendor/github.com/vmware/govmomi/pbm/pbm_util.go
generated
vendored
2
vendor/github.com/vmware/govmomi/pbm/pbm_util.go
generated
vendored
@@ -27,6 +27,7 @@ import (
|
||||
// A struct to capture pbm create spec details.
|
||||
type CapabilityProfileCreateSpec struct {
|
||||
Name string
|
||||
SubProfileName string
|
||||
Description string
|
||||
Category string
|
||||
CapabilityList []Capability
|
||||
@@ -64,6 +65,7 @@ func CreateCapabilityProfileSpec(pbmCreateSpec CapabilityProfileCreateSpec) (*ty
|
||||
SubProfiles: []types.PbmCapabilitySubProfile{
|
||||
types.PbmCapabilitySubProfile{
|
||||
Capability: capabilities,
|
||||
Name: pbmCreateSpec.SubProfileName,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
89
vendor/github.com/vmware/govmomi/pbm/types/enum.go
generated
vendored
89
vendor/github.com/vmware/govmomi/pbm/types/enum.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2014-2018 VMware, Inc. All Rights Reserved.
|
||||
Copyright (c) 2014-2022 VMware, Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -22,6 +22,18 @@ import (
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
type PbmAssociateAndApplyPolicyStatusPolicyStatus string
|
||||
|
||||
const (
|
||||
PbmAssociateAndApplyPolicyStatusPolicyStatusSuccess = PbmAssociateAndApplyPolicyStatusPolicyStatus("success")
|
||||
PbmAssociateAndApplyPolicyStatusPolicyStatusFailed = PbmAssociateAndApplyPolicyStatusPolicyStatus("failed")
|
||||
PbmAssociateAndApplyPolicyStatusPolicyStatusInvalid = PbmAssociateAndApplyPolicyStatusPolicyStatus("invalid")
|
||||
)
|
||||
|
||||
func init() {
|
||||
types.Add("pbm:PbmAssociateAndApplyPolicyStatusPolicyStatus", reflect.TypeOf((*PbmAssociateAndApplyPolicyStatusPolicyStatus)(nil)).Elem())
|
||||
}
|
||||
|
||||
type PbmBuiltinGenericType string
|
||||
|
||||
const (
|
||||
@@ -104,6 +116,30 @@ func init() {
|
||||
types.Add("pbm:PbmComplianceStatus", reflect.TypeOf((*PbmComplianceStatus)(nil)).Elem())
|
||||
}
|
||||
|
||||
type PbmDebugManagerKeystoreName string
|
||||
|
||||
const (
|
||||
PbmDebugManagerKeystoreNameSMS = PbmDebugManagerKeystoreName("SMS")
|
||||
PbmDebugManagerKeystoreNameTRUSTED_ROOTS = PbmDebugManagerKeystoreName("TRUSTED_ROOTS")
|
||||
)
|
||||
|
||||
func init() {
|
||||
types.Add("pbm:PbmDebugManagerKeystoreName", reflect.TypeOf((*PbmDebugManagerKeystoreName)(nil)).Elem())
|
||||
}
|
||||
|
||||
type PbmHealthStatusForEntity string
|
||||
|
||||
const (
|
||||
PbmHealthStatusForEntityRed = PbmHealthStatusForEntity("red")
|
||||
PbmHealthStatusForEntityYellow = PbmHealthStatusForEntity("yellow")
|
||||
PbmHealthStatusForEntityGreen = PbmHealthStatusForEntity("green")
|
||||
PbmHealthStatusForEntityUnknown = PbmHealthStatusForEntity("unknown")
|
||||
)
|
||||
|
||||
func init() {
|
||||
types.Add("pbm:PbmHealthStatusForEntity", reflect.TypeOf((*PbmHealthStatusForEntity)(nil)).Elem())
|
||||
}
|
||||
|
||||
type PbmIofilterInfoFilterType string
|
||||
|
||||
const (
|
||||
@@ -131,12 +167,42 @@ const (
|
||||
PbmLineOfServiceInfoLineOfServiceEnumPERSISTENCE = PbmLineOfServiceInfoLineOfServiceEnum("PERSISTENCE")
|
||||
PbmLineOfServiceInfoLineOfServiceEnumDATA_PROVIDER = PbmLineOfServiceInfoLineOfServiceEnum("DATA_PROVIDER")
|
||||
PbmLineOfServiceInfoLineOfServiceEnumDATASTORE_IO_CONTROL = PbmLineOfServiceInfoLineOfServiceEnum("DATASTORE_IO_CONTROL")
|
||||
PbmLineOfServiceInfoLineOfServiceEnumDATA_PROTECTION = PbmLineOfServiceInfoLineOfServiceEnum("DATA_PROTECTION")
|
||||
)
|
||||
|
||||
func init() {
|
||||
types.Add("pbm:PbmLineOfServiceInfoLineOfServiceEnum", reflect.TypeOf((*PbmLineOfServiceInfoLineOfServiceEnum)(nil)).Elem())
|
||||
}
|
||||
|
||||
type PbmLoggingConfigurationComponent string
|
||||
|
||||
const (
|
||||
PbmLoggingConfigurationComponentPbm = PbmLoggingConfigurationComponent("pbm")
|
||||
PbmLoggingConfigurationComponentVslm = PbmLoggingConfigurationComponent("vslm")
|
||||
PbmLoggingConfigurationComponentSms = PbmLoggingConfigurationComponent("sms")
|
||||
PbmLoggingConfigurationComponentSpbm = PbmLoggingConfigurationComponent("spbm")
|
||||
PbmLoggingConfigurationComponentSps = PbmLoggingConfigurationComponent("sps")
|
||||
PbmLoggingConfigurationComponentHttpclient_header = PbmLoggingConfigurationComponent("httpclient_header")
|
||||
PbmLoggingConfigurationComponentHttpclient_content = PbmLoggingConfigurationComponent("httpclient_content")
|
||||
PbmLoggingConfigurationComponentVmomi = PbmLoggingConfigurationComponent("vmomi")
|
||||
)
|
||||
|
||||
func init() {
|
||||
types.Add("pbm:PbmLoggingConfigurationComponent", reflect.TypeOf((*PbmLoggingConfigurationComponent)(nil)).Elem())
|
||||
}
|
||||
|
||||
type PbmLoggingConfigurationLogLevel string
|
||||
|
||||
const (
|
||||
PbmLoggingConfigurationLogLevelINFO = PbmLoggingConfigurationLogLevel("INFO")
|
||||
PbmLoggingConfigurationLogLevelDEBUG = PbmLoggingConfigurationLogLevel("DEBUG")
|
||||
PbmLoggingConfigurationLogLevelTRACE = PbmLoggingConfigurationLogLevel("TRACE")
|
||||
)
|
||||
|
||||
func init() {
|
||||
types.Add("pbm:PbmLoggingConfigurationLogLevel", reflect.TypeOf((*PbmLoggingConfigurationLogLevel)(nil)).Elem())
|
||||
}
|
||||
|
||||
type PbmObjectType string
|
||||
|
||||
const (
|
||||
@@ -145,6 +211,8 @@ const (
|
||||
PbmObjectTypeVirtualDiskId = PbmObjectType("virtualDiskId")
|
||||
PbmObjectTypeVirtualDiskUUID = PbmObjectType("virtualDiskUUID")
|
||||
PbmObjectTypeDatastore = PbmObjectType("datastore")
|
||||
PbmObjectTypeVsanObjectId = PbmObjectType("vsanObjectId")
|
||||
PbmObjectTypeFileShareId = PbmObjectType("fileShareId")
|
||||
PbmObjectTypeUnknown = PbmObjectType("unknown")
|
||||
)
|
||||
|
||||
@@ -166,6 +234,18 @@ func init() {
|
||||
types.Add("pbm:PbmOperation", reflect.TypeOf((*PbmOperation)(nil)).Elem())
|
||||
}
|
||||
|
||||
type PbmPolicyAssociationVolumeAllocationType string
|
||||
|
||||
const (
|
||||
PbmPolicyAssociationVolumeAllocationTypeFullyInitialized = PbmPolicyAssociationVolumeAllocationType("FullyInitialized")
|
||||
PbmPolicyAssociationVolumeAllocationTypeReserveSpace = PbmPolicyAssociationVolumeAllocationType("ReserveSpace")
|
||||
PbmPolicyAssociationVolumeAllocationTypeConserveSpaceWhenPossible = PbmPolicyAssociationVolumeAllocationType("ConserveSpaceWhenPossible")
|
||||
)
|
||||
|
||||
func init() {
|
||||
types.Add("pbm:PbmPolicyAssociationVolumeAllocationType", reflect.TypeOf((*PbmPolicyAssociationVolumeAllocationType)(nil)).Elem())
|
||||
}
|
||||
|
||||
type PbmProfileCategoryEnum string
|
||||
|
||||
const (
|
||||
@@ -191,9 +271,10 @@ func init() {
|
||||
type PbmSystemCreatedProfileType string
|
||||
|
||||
const (
|
||||
PbmSystemCreatedProfileTypeVsanDefaultProfile = PbmSystemCreatedProfileType("VsanDefaultProfile")
|
||||
PbmSystemCreatedProfileTypeVVolDefaultProfile = PbmSystemCreatedProfileType("VVolDefaultProfile")
|
||||
PbmSystemCreatedProfileTypePmemDefaultProfile = PbmSystemCreatedProfileType("PmemDefaultProfile")
|
||||
PbmSystemCreatedProfileTypeVsanDefaultProfile = PbmSystemCreatedProfileType("VsanDefaultProfile")
|
||||
PbmSystemCreatedProfileTypeVVolDefaultProfile = PbmSystemCreatedProfileType("VVolDefaultProfile")
|
||||
PbmSystemCreatedProfileTypePmemDefaultProfile = PbmSystemCreatedProfileType("PmemDefaultProfile")
|
||||
PbmSystemCreatedProfileTypeVsanMaxDefaultProfile = PbmSystemCreatedProfileType("VsanMaxDefaultProfile")
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
2
vendor/github.com/vmware/govmomi/pbm/types/if.go
generated
vendored
2
vendor/github.com/vmware/govmomi/pbm/types/if.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2014-2018 VMware, Inc. All Rights Reserved.
|
||||
Copyright (c) 2014-2022 VMware, Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
35
vendor/github.com/vmware/govmomi/pbm/types/types.go
generated
vendored
35
vendor/github.com/vmware/govmomi/pbm/types/types.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2014-2018 VMware, Inc. All Rights Reserved.
|
||||
Copyright (c) 2014-2022 VMware, Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -909,6 +909,17 @@ func init() {
|
||||
types.Add("pbm:PbmFaultInvalidLoginFault", reflect.TypeOf((*PbmFaultInvalidLoginFault)(nil)).Elem())
|
||||
}
|
||||
|
||||
type PbmFaultNoPermissionEntityPrivileges struct {
|
||||
types.DynamicData
|
||||
|
||||
ProfileId *PbmProfileId `xml:"profileId,omitempty"`
|
||||
PrivilegeIds []string `xml:"privilegeIds,omitempty"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
types.Add("pbm:PbmFaultNoPermissionEntityPrivileges", reflect.TypeOf((*PbmFaultNoPermissionEntityPrivileges)(nil)).Elem())
|
||||
}
|
||||
|
||||
type PbmFaultNotFound struct {
|
||||
PbmFault
|
||||
}
|
||||
@@ -997,6 +1008,17 @@ type PbmFetchComplianceResultResponse struct {
|
||||
Returnval []PbmComplianceResult `xml:"returnval,omitempty"`
|
||||
}
|
||||
|
||||
type PbmFetchEntityHealthStatusSpec struct {
|
||||
types.DynamicData
|
||||
|
||||
ObjectRef PbmServerObjectRef `xml:"objectRef"`
|
||||
BackingId string `xml:"backingId,omitempty"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
types.Add("pbm:PbmFetchEntityHealthStatusSpec", reflect.TypeOf((*PbmFetchEntityHealthStatusSpec)(nil)).Elem())
|
||||
}
|
||||
|
||||
type PbmFetchResourceType PbmFetchResourceTypeRequestType
|
||||
|
||||
func init() {
|
||||
@@ -1114,6 +1136,17 @@ func init() {
|
||||
types.Add("pbm:PbmLineOfServiceInfo", reflect.TypeOf((*PbmLineOfServiceInfo)(nil)).Elem())
|
||||
}
|
||||
|
||||
type PbmLoggingConfiguration struct {
|
||||
types.DynamicData
|
||||
|
||||
Component string `xml:"component"`
|
||||
LogLevel string `xml:"logLevel"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
types.Add("pbm:PbmLoggingConfiguration", reflect.TypeOf((*PbmLoggingConfiguration)(nil)).Elem())
|
||||
}
|
||||
|
||||
type PbmNonExistentHubs struct {
|
||||
PbmFault
|
||||
|
||||
|
5
vendor/github.com/vmware/govmomi/program.mk
generated
vendored
5
vendor/github.com/vmware/govmomi/program.mk
generated
vendored
@@ -1,3 +1,6 @@
|
||||
# Copyright (c) 2021 VMware, Inc. All Rights Reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
ifneq (,$(strip $(GOOS)))
|
||||
ifeq (,$(strip $(GOARCH)))
|
||||
GOARCH := $(shell go env | grep GOARCH | awk -F= '{print $$2}' | tr -d '"')
|
||||
@@ -30,7 +33,7 @@ $(PROGRAM):
|
||||
CGO_ENABLED=0 go build -a $(BUILD_ARGS) -o $@
|
||||
|
||||
install:
|
||||
CGO_ENABLED=0 go install $(BUILD_ARGS)
|
||||
CGO_ENABLED=0 go install -v $(BUILD_ARGS)
|
||||
|
||||
ifneq (,$(strip $(BUILD_OS)))
|
||||
ifneq (,$(strip $(BUILD_ARCH)))
|
||||
|
14
vendor/github.com/vmware/govmomi/property/collector.go
generated
vendored
14
vendor/github.com/vmware/govmomi/property/collector.go
generated
vendored
@@ -97,10 +97,16 @@ func (p *Collector) CreateFilter(ctx context.Context, req types.CreateFilter) er
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Collector) WaitForUpdates(ctx context.Context, v string) (*types.UpdateSet, error) {
|
||||
func (p *Collector) WaitForUpdates(ctx context.Context, version string, opts ...*types.WaitOptions) (*types.UpdateSet, error) {
|
||||
req := types.WaitForUpdatesEx{
|
||||
This: p.Reference(),
|
||||
Version: v,
|
||||
Version: version,
|
||||
}
|
||||
|
||||
if len(opts) == 1 {
|
||||
req.Options = opts[0]
|
||||
} else if len(opts) > 1 {
|
||||
panic("only one option may be specified")
|
||||
}
|
||||
|
||||
res, err := methods.WaitForUpdatesEx(ctx, p.roundTripper, &req)
|
||||
@@ -143,7 +149,7 @@ func (p *Collector) Retrieve(ctx context.Context, objs []types.ManagedObjectRefe
|
||||
spec := types.PropertySpec{
|
||||
Type: obj.Type,
|
||||
}
|
||||
if ps == nil {
|
||||
if len(ps) == 0 {
|
||||
spec.All = types.NewBool(true)
|
||||
} else {
|
||||
spec.PathSet = ps
|
||||
@@ -179,7 +185,7 @@ func (p *Collector) Retrieve(ctx context.Context, objs []types.ManagedObjectRefe
|
||||
return nil
|
||||
}
|
||||
|
||||
return mo.LoadRetrievePropertiesResponse(res, dst)
|
||||
return mo.LoadObjectContent(res.Returnval, dst)
|
||||
}
|
||||
|
||||
// RetrieveWithFilter populates dst as Retrieve does, but only for entities matching the given filter.
|
||||
|
35
vendor/github.com/vmware/govmomi/property/filter.go
generated
vendored
35
vendor/github.com/vmware/govmomi/property/filter.go
generated
vendored
@@ -42,6 +42,9 @@ func (f Filter) Keys() []string {
|
||||
|
||||
// MatchProperty returns true if a Filter entry matches the given prop.
|
||||
func (f Filter) MatchProperty(prop types.DynamicProperty) bool {
|
||||
if prop.Val == nil {
|
||||
return false
|
||||
}
|
||||
match, ok := f[prop.Name]
|
||||
if !ok {
|
||||
return false
|
||||
@@ -74,7 +77,7 @@ func (f Filter) MatchProperty(prop types.DynamicProperty) bool {
|
||||
}
|
||||
|
||||
// convert if we can
|
||||
switch prop.Val.(type) {
|
||||
switch val := prop.Val.(type) {
|
||||
case bool:
|
||||
match, _ = strconv.ParseBool(s)
|
||||
case int16:
|
||||
@@ -91,7 +94,9 @@ func (f Filter) MatchProperty(prop types.DynamicProperty) bool {
|
||||
case float64:
|
||||
match, _ = strconv.ParseFloat(s, 64)
|
||||
case fmt.Stringer:
|
||||
prop.Val = prop.Val.(fmt.Stringer).String()
|
||||
prop.Val = val.String()
|
||||
case *types.CustomFieldStringValue:
|
||||
prop.Val = fmt.Sprintf("%d:%s", val.Key, val.Value)
|
||||
default:
|
||||
if ptype.Kind() != reflect.String {
|
||||
return false
|
||||
@@ -125,7 +130,7 @@ func (f Filter) MatchPropertyList(props []types.DynamicProperty) bool {
|
||||
return len(f) == len(props) // false if a property such as VM "guest" is unset
|
||||
}
|
||||
|
||||
// MatchObjectContent returns a list of ObjectContent.Obj where the ObjectContent.PropSet matches the Filter.
|
||||
// MatchObjectContent returns a list of ObjectContent.Obj where the ObjectContent.PropSet matches all properties the Filter.
|
||||
func (f Filter) MatchObjectContent(objects []types.ObjectContent) []types.ManagedObjectReference {
|
||||
var refs []types.ManagedObjectReference
|
||||
|
||||
@@ -137,3 +142,27 @@ func (f Filter) MatchObjectContent(objects []types.ObjectContent) []types.Manage
|
||||
|
||||
return refs
|
||||
}
|
||||
|
||||
// MatchAnyPropertyList returns true if any given props match the Filter.
|
||||
func (f Filter) MatchAnyPropertyList(props []types.DynamicProperty) bool {
|
||||
for _, p := range props {
|
||||
if f.MatchProperty(p) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// MatchAnyObjectContent returns a list of ObjectContent.Obj where the ObjectContent.PropSet matches any property in the Filter.
|
||||
func (f Filter) MatchAnyObjectContent(objects []types.ObjectContent) []types.ManagedObjectReference {
|
||||
var refs []types.ManagedObjectReference
|
||||
|
||||
for _, o := range objects {
|
||||
if f.MatchAnyPropertyList(o.PropSet) {
|
||||
refs = append(refs, o.Obj)
|
||||
}
|
||||
}
|
||||
|
||||
return refs
|
||||
}
|
||||
|
24
vendor/github.com/vmware/govmomi/property/wait.go
generated
vendored
24
vendor/github.com/vmware/govmomi/property/wait.go
generated
vendored
@@ -20,13 +20,16 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/vim25/soap"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
// WaitFilter provides helpers to construct a types.CreateFilter for use with property.Wait
|
||||
type WaitFilter struct {
|
||||
types.CreateFilter
|
||||
Options *types.WaitOptions
|
||||
Options *types.WaitOptions
|
||||
PropagateMissing bool
|
||||
Truncated bool
|
||||
}
|
||||
|
||||
// Add a new ObjectSpec and PropertySpec to the WaitFilter
|
||||
@@ -81,6 +84,8 @@ func Wait(ctx context.Context, c *Collector, obj types.ManagedObjectReference, p
|
||||
// The newly created collector is destroyed before this function returns (both
|
||||
// in case of success or error).
|
||||
//
|
||||
// By default, ObjectUpdate.MissingSet faults are not propagated to the returned error,
|
||||
// set WaitFilter.PropagateMissing=true to enable MissingSet fault propagation.
|
||||
func WaitForUpdates(ctx context.Context, c *Collector, filter *WaitFilter, f func([]types.ObjectUpdate) bool) error {
|
||||
p, err := c.Create(ctx)
|
||||
if err != nil {
|
||||
@@ -89,7 +94,9 @@ func WaitForUpdates(ctx context.Context, c *Collector, filter *WaitFilter, f fun
|
||||
|
||||
// Attempt to destroy the collector using the background context, as the
|
||||
// specified context may have timed out or have been canceled.
|
||||
defer p.Destroy(context.Background())
|
||||
defer func() {
|
||||
_ = p.Destroy(context.Background())
|
||||
}()
|
||||
|
||||
err = p.CreateFilter(ctx, filter.CreateFilter)
|
||||
if err != nil {
|
||||
@@ -121,8 +128,21 @@ func WaitForUpdates(ctx context.Context, c *Collector, filter *WaitFilter, f fun
|
||||
}
|
||||
|
||||
req.Version = set.Version
|
||||
filter.Truncated = false
|
||||
if set.Truncated != nil {
|
||||
filter.Truncated = *set.Truncated
|
||||
}
|
||||
|
||||
for _, fs := range set.FilterSet {
|
||||
if filter.PropagateMissing {
|
||||
for i := range fs.ObjectSet {
|
||||
for _, p := range fs.ObjectSet[i].MissingSet {
|
||||
// Same behavior as mo.ObjectContentToType()
|
||||
return soap.WrapVimFault(p.Fault.Fault)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if f(fs.ObjectSet) {
|
||||
return nil
|
||||
}
|
||||
|
106
vendor/github.com/vmware/govmomi/session/keep_alive.go
generated
vendored
106
vendor/github.com/vmware/govmomi/session/keep_alive.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
|
||||
Copyright (c) 2015-2020 VMware, Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -17,110 +17,24 @@ limitations under the License.
|
||||
package session
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/session/keepalive"
|
||||
"github.com/vmware/govmomi/vim25/soap"
|
||||
)
|
||||
|
||||
type keepAlive struct {
|
||||
sync.Mutex
|
||||
|
||||
roundTripper soap.RoundTripper
|
||||
idleTime time.Duration
|
||||
notifyRequest chan struct{}
|
||||
notifyStop chan struct{}
|
||||
notifyWaitGroup sync.WaitGroup
|
||||
|
||||
// keepAlive executes a request in the background with the purpose of
|
||||
// keeping the session active. The response for this request is discarded.
|
||||
keepAlive func(soap.RoundTripper) error
|
||||
}
|
||||
|
||||
func defaultKeepAlive(roundTripper soap.RoundTripper) error {
|
||||
_, _ = methods.GetCurrentTime(context.Background(), roundTripper)
|
||||
return nil
|
||||
}
|
||||
|
||||
// KeepAlive wraps the specified soap.RoundTripper and executes a meaningless
|
||||
// API request in the background after the RoundTripper has been idle for the
|
||||
// specified amount of idle time. The keep alive process only starts once a
|
||||
// user logs in and runs until the user logs out again.
|
||||
// KeepAlive is a backward compatible wrapper around KeepAliveHandler.
|
||||
func KeepAlive(roundTripper soap.RoundTripper, idleTime time.Duration) soap.RoundTripper {
|
||||
return KeepAliveHandler(roundTripper, idleTime, defaultKeepAlive)
|
||||
return KeepAliveHandler(roundTripper, idleTime, nil)
|
||||
}
|
||||
|
||||
// KeepAliveHandler works as KeepAlive() does, but the handler param can decide how to handle errors.
|
||||
// For example, if connectivity to ESX/VC is down long enough for a session to expire, a handler can choose to
|
||||
// Login() on a types.NotAuthenticated error. If handler returns non-nil, the keep alive go routine will be stopped.
|
||||
// KeepAliveHandler is a backward compatible wrapper around keepalive.NewHandlerSOAP.
|
||||
func KeepAliveHandler(roundTripper soap.RoundTripper, idleTime time.Duration, handler func(soap.RoundTripper) error) soap.RoundTripper {
|
||||
k := &keepAlive{
|
||||
roundTripper: roundTripper,
|
||||
idleTime: idleTime,
|
||||
notifyRequest: make(chan struct{}),
|
||||
}
|
||||
|
||||
k.keepAlive = handler
|
||||
|
||||
return k
|
||||
}
|
||||
|
||||
func (k *keepAlive) start() {
|
||||
k.Lock()
|
||||
defer k.Unlock()
|
||||
|
||||
if k.notifyStop != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// This channel must be closed to terminate idle timer.
|
||||
k.notifyStop = make(chan struct{})
|
||||
k.notifyWaitGroup.Add(1)
|
||||
|
||||
go func() {
|
||||
defer k.notifyWaitGroup.Done()
|
||||
|
||||
for t := time.NewTimer(k.idleTime); ; {
|
||||
select {
|
||||
case <-k.notifyStop:
|
||||
return
|
||||
case <-k.notifyRequest:
|
||||
t.Reset(k.idleTime)
|
||||
case <-t.C:
|
||||
if err := k.keepAlive(k.roundTripper); err != nil {
|
||||
k.stop()
|
||||
}
|
||||
t = time.NewTimer(k.idleTime)
|
||||
}
|
||||
var f func() error
|
||||
if handler != nil {
|
||||
f = func() error {
|
||||
return handler(roundTripper)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (k *keepAlive) stop() {
|
||||
k.Lock()
|
||||
defer k.Unlock()
|
||||
|
||||
if k.notifyStop != nil {
|
||||
close(k.notifyStop)
|
||||
k.notifyWaitGroup.Wait()
|
||||
k.notifyStop = nil
|
||||
}
|
||||
}
|
||||
|
||||
func (k *keepAlive) RoundTrip(ctx context.Context, req, res soap.HasFault) error {
|
||||
err := k.roundTripper.RoundTrip(ctx, req, res)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Start ticker on login, stop ticker on logout.
|
||||
switch req.(type) {
|
||||
case *methods.LoginBody, *methods.LoginExtensionByCertificateBody, *methods.LoginByTokenBody:
|
||||
k.start()
|
||||
case *methods.LogoutBody:
|
||||
k.stop()
|
||||
}
|
||||
|
||||
return nil
|
||||
return keepalive.NewHandlerSOAP(roundTripper, idleTime, f)
|
||||
}
|
||||
|
204
vendor/github.com/vmware/govmomi/session/keepalive/handler.go
generated
vendored
Normal file
204
vendor/github.com/vmware/govmomi/session/keepalive/handler.go
generated
vendored
Normal file
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
Copyright (c) 2020 VMware, Inc. All 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 keepalive
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/vmware/govmomi/vapi/rest"
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/vim25/soap"
|
||||
)
|
||||
|
||||
// handler contains the generic keep alive settings and logic
|
||||
type handler struct {
|
||||
mu sync.Mutex
|
||||
notifyStop chan struct{}
|
||||
notifyWaitGroup sync.WaitGroup
|
||||
|
||||
idle time.Duration
|
||||
send func() error
|
||||
}
|
||||
|
||||
// NewHandlerSOAP returns a soap.RoundTripper for use with a vim25.Client
|
||||
// The idle time specifies the interval in between send() requests. Defaults to 10 minutes.
|
||||
// The send func is used to keep a session alive. Defaults to calling vim25 GetCurrentTime().
|
||||
// The keep alive goroutine starts when a Login method is called and runs until Logout is called or send returns an error.
|
||||
func NewHandlerSOAP(c soap.RoundTripper, idle time.Duration, send func() error) *HandlerSOAP {
|
||||
h := &handler{
|
||||
idle: idle,
|
||||
send: send,
|
||||
}
|
||||
|
||||
if send == nil {
|
||||
h.send = func() error {
|
||||
return h.keepAliveSOAP(c)
|
||||
}
|
||||
}
|
||||
|
||||
return &HandlerSOAP{h, c}
|
||||
}
|
||||
|
||||
// NewHandlerREST returns an http.RoundTripper for use with a rest.Client
|
||||
// The idle time specifies the interval in between send() requests. Defaults to 10 minutes.
|
||||
// The send func is used to keep a session alive. Defaults to calling the rest.Client.Session() method
|
||||
// The keep alive goroutine starts when a Login method is called and runs until Logout is called or send returns an error.
|
||||
func NewHandlerREST(c *rest.Client, idle time.Duration, send func() error) *HandlerREST {
|
||||
h := &handler{
|
||||
idle: idle,
|
||||
send: send,
|
||||
}
|
||||
|
||||
if send == nil {
|
||||
h.send = func() error {
|
||||
return h.keepAliveREST(c)
|
||||
}
|
||||
}
|
||||
|
||||
return &HandlerREST{h, c.Transport}
|
||||
}
|
||||
|
||||
func (h *handler) keepAliveSOAP(rt soap.RoundTripper) error {
|
||||
ctx := context.Background()
|
||||
_, err := methods.GetCurrentTime(ctx, rt)
|
||||
return err
|
||||
}
|
||||
|
||||
func (h *handler) keepAliveREST(c *rest.Client) error {
|
||||
ctx := context.Background()
|
||||
|
||||
s, err := c.Session(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if s != nil {
|
||||
return nil
|
||||
}
|
||||
return errors.New(http.StatusText(http.StatusUnauthorized))
|
||||
}
|
||||
|
||||
// Start explicitly starts the keep alive go routine.
|
||||
// For use with session cache.Client, as cached sessions may not involve Login/Logout via RoundTripper.
|
||||
func (h *handler) Start() {
|
||||
h.mu.Lock()
|
||||
defer h.mu.Unlock()
|
||||
|
||||
if h.notifyStop != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if h.idle == 0 {
|
||||
h.idle = time.Minute * 10
|
||||
}
|
||||
|
||||
// This channel must be closed to terminate idle timer.
|
||||
h.notifyStop = make(chan struct{})
|
||||
h.notifyWaitGroup.Add(1)
|
||||
|
||||
go func() {
|
||||
for t := time.NewTimer(h.idle); ; {
|
||||
select {
|
||||
case <-h.notifyStop:
|
||||
h.notifyWaitGroup.Done()
|
||||
t.Stop()
|
||||
return
|
||||
case <-t.C:
|
||||
if err := h.send(); err != nil {
|
||||
h.notifyWaitGroup.Done()
|
||||
h.Stop()
|
||||
return
|
||||
}
|
||||
t.Reset(h.idle)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// Stop explicitly stops the keep alive go routine.
|
||||
// For use with session cache.Client, as cached sessions may not involve Login/Logout via RoundTripper.
|
||||
func (h *handler) Stop() {
|
||||
h.mu.Lock()
|
||||
defer h.mu.Unlock()
|
||||
|
||||
if h.notifyStop != nil {
|
||||
close(h.notifyStop)
|
||||
h.notifyWaitGroup.Wait()
|
||||
h.notifyStop = nil
|
||||
}
|
||||
}
|
||||
|
||||
// HandlerSOAP is a keep alive implementation for use with vim25.Client
|
||||
type HandlerSOAP struct {
|
||||
*handler
|
||||
|
||||
roundTripper soap.RoundTripper
|
||||
}
|
||||
|
||||
// RoundTrip implements soap.RoundTripper
|
||||
func (h *HandlerSOAP) RoundTrip(ctx context.Context, req, res soap.HasFault) error {
|
||||
// Stop ticker on logout.
|
||||
switch req.(type) {
|
||||
case *methods.LogoutBody:
|
||||
h.Stop()
|
||||
}
|
||||
|
||||
err := h.roundTripper.RoundTrip(ctx, req, res)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Start ticker on login.
|
||||
switch req.(type) {
|
||||
case *methods.LoginBody, *methods.LoginExtensionByCertificateBody, *methods.LoginByTokenBody:
|
||||
h.Start()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// HandlerREST is a keep alive implementation for use with rest.Client
|
||||
type HandlerREST struct {
|
||||
*handler
|
||||
|
||||
roundTripper http.RoundTripper
|
||||
}
|
||||
|
||||
// RoundTrip implements http.RoundTripper
|
||||
func (h *HandlerREST) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
if req.URL.Path != "/rest/com/vmware/cis/session" {
|
||||
return h.roundTripper.RoundTrip(req)
|
||||
}
|
||||
|
||||
if req.Method == http.MethodDelete { // Logout
|
||||
h.Stop()
|
||||
}
|
||||
|
||||
res, err := h.roundTripper.RoundTrip(req)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
if req.Method == http.MethodPost { // Login
|
||||
h.Start()
|
||||
}
|
||||
|
||||
return res, err
|
||||
}
|
31
vendor/github.com/vmware/govmomi/session/manager.go
generated
vendored
31
vendor/github.com/vmware/govmomi/session/manager.go
generated
vendored
@@ -18,9 +18,10 @@ package session
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/vmware/govmomi/property"
|
||||
"github.com/vmware/govmomi/vim25"
|
||||
@@ -41,6 +42,21 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
// Secret returns the contents if a file path value is given, otherwise returns value itself.
|
||||
func Secret(value string) (string, error) {
|
||||
if len(value) == 0 {
|
||||
return value, nil
|
||||
}
|
||||
contents, err := ioutil.ReadFile(value)
|
||||
if err != nil {
|
||||
if os.IsPermission(err) {
|
||||
return "", err
|
||||
}
|
||||
return value, nil
|
||||
}
|
||||
return strings.TrimSpace(string(contents)), nil
|
||||
}
|
||||
|
||||
type Manager struct {
|
||||
client *vim25.Client
|
||||
userSession *types.UserSession
|
||||
@@ -107,7 +123,7 @@ func (sm *Manager) LoginExtensionByCertificate(ctx context.Context, key string)
|
||||
// "Post https://sdkTunnel:8089/sdk: x509: certificate is valid for $vcenter_hostname, not sdkTunnel"
|
||||
// The only easy way around this is to disable verification for the call to LoginExtensionByCertificate().
|
||||
// TODO: find a way to avoid disabling InsecureSkipVerify.
|
||||
c.Transport.(*http.Transport).TLSClientConfig.InsecureSkipVerify = true
|
||||
c.DefaultTransport().TLSClientConfig.InsecureSkipVerify = true
|
||||
}
|
||||
|
||||
req := types.LoginExtensionByCertificate{
|
||||
@@ -265,3 +281,14 @@ func (sm *Manager) CloneSession(ctx context.Context, ticket string) error {
|
||||
sm.userSession = &res.Returnval
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sm *Manager) UpdateServiceMessage(ctx context.Context, message string) error {
|
||||
req := types.UpdateServiceMessage{
|
||||
This: sm.Reference(),
|
||||
Message: message,
|
||||
}
|
||||
|
||||
_, err := methods.UpdateServiceMessage(ctx, sm.client, &req)
|
||||
|
||||
return err
|
||||
}
|
||||
|
94
vendor/github.com/vmware/govmomi/simulator/authorization_manager.go
generated
vendored
94
vendor/github.com/vmware/govmomi/simulator/authorization_manager.go
generated
vendored
@@ -36,11 +36,12 @@ type AuthorizationManager struct {
|
||||
nextID int32
|
||||
}
|
||||
|
||||
func NewAuthorizationManager(ref types.ManagedObjectReference) object.Reference {
|
||||
m := &AuthorizationManager{}
|
||||
m.Self = ref
|
||||
m.RoleList = make([]types.AuthorizationRole, len(esx.RoleList))
|
||||
copy(m.RoleList, esx.RoleList)
|
||||
func (m *AuthorizationManager) init(r *Registry) {
|
||||
if len(m.RoleList) == 0 {
|
||||
m.RoleList = make([]types.AuthorizationRole, len(esx.RoleList))
|
||||
copy(m.RoleList, esx.RoleList)
|
||||
}
|
||||
|
||||
m.permissions = make(map[types.ManagedObjectReference][]types.Permission)
|
||||
|
||||
l := object.AuthorizationRoleList(m.RoleList)
|
||||
@@ -52,7 +53,7 @@ func NewAuthorizationManager(ref types.ManagedObjectReference) object.Reference
|
||||
m.privileges[id] = struct{}{}
|
||||
}
|
||||
|
||||
root := Map.content().RootFolder
|
||||
root := r.content().RootFolder
|
||||
|
||||
for _, u := range DefaultUserGroup {
|
||||
m.permissions[root] = append(m.permissions[root], types.Permission{
|
||||
@@ -63,8 +64,6 @@ func NewAuthorizationManager(ref types.ManagedObjectReference) object.Reference
|
||||
Propagate: true,
|
||||
})
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *AuthorizationManager) RetrieveEntityPermissions(req *types.RetrieveEntityPermissions) soap.HasFault {
|
||||
@@ -149,6 +148,85 @@ func (m *AuthorizationManager) RetrieveRolePermissions(req *types.RetrieveRolePe
|
||||
}
|
||||
}
|
||||
|
||||
func (m *AuthorizationManager) HasPrivilegeOnEntities(req *types.HasPrivilegeOnEntities) soap.HasFault {
|
||||
var p []types.EntityPrivilege
|
||||
|
||||
for _, e := range req.Entity {
|
||||
priv := types.EntityPrivilege{Entity: e}
|
||||
|
||||
for _, id := range req.PrivId {
|
||||
priv.PrivAvailability = append(priv.PrivAvailability, types.PrivilegeAvailability{
|
||||
PrivId: id,
|
||||
IsGranted: true,
|
||||
})
|
||||
}
|
||||
|
||||
p = append(p, priv)
|
||||
}
|
||||
|
||||
return &methods.HasPrivilegeOnEntitiesBody{
|
||||
Res: &types.HasPrivilegeOnEntitiesResponse{
|
||||
Returnval: p,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (m *AuthorizationManager) HasPrivilegeOnEntity(req *types.HasPrivilegeOnEntity) soap.HasFault {
|
||||
p := make([]bool, len(req.PrivId))
|
||||
|
||||
for i := range req.PrivId {
|
||||
p[i] = true
|
||||
}
|
||||
|
||||
return &methods.HasPrivilegeOnEntityBody{
|
||||
Res: &types.HasPrivilegeOnEntityResponse{
|
||||
Returnval: p,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (m *AuthorizationManager) HasUserPrivilegeOnEntities(req *types.HasUserPrivilegeOnEntities) soap.HasFault {
|
||||
var p []types.EntityPrivilege
|
||||
|
||||
for _, e := range req.Entities {
|
||||
priv := types.EntityPrivilege{Entity: e}
|
||||
|
||||
for _, id := range req.PrivId {
|
||||
priv.PrivAvailability = append(priv.PrivAvailability, types.PrivilegeAvailability{
|
||||
PrivId: id,
|
||||
IsGranted: true,
|
||||
})
|
||||
}
|
||||
|
||||
p = append(p, priv)
|
||||
}
|
||||
|
||||
return &methods.HasUserPrivilegeOnEntitiesBody{
|
||||
Res: &types.HasUserPrivilegeOnEntitiesResponse{
|
||||
Returnval: p,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (m *AuthorizationManager) FetchUserPrivilegeOnEntities(req *types.FetchUserPrivilegeOnEntities) soap.HasFault {
|
||||
admin := object.AuthorizationRoleList(m.RoleList).ByName("Admin").Privilege
|
||||
|
||||
var p []types.UserPrivilegeResult
|
||||
|
||||
for _, e := range req.Entities {
|
||||
p = append(p, types.UserPrivilegeResult{
|
||||
Entity: e,
|
||||
Privileges: admin,
|
||||
})
|
||||
}
|
||||
|
||||
return &methods.FetchUserPrivilegeOnEntitiesBody{
|
||||
Res: &types.FetchUserPrivilegeOnEntitiesResponse{
|
||||
Returnval: p,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (m *AuthorizationManager) AddAuthorizationRole(req *types.AddAuthorizationRole) soap.HasFault {
|
||||
body := &methods.AddAuthorizationRoleBody{}
|
||||
|
||||
|
148
vendor/github.com/vmware/govmomi/simulator/cluster_compute_resource.go
generated
vendored
148
vendor/github.com/vmware/govmomi/simulator/cluster_compute_resource.go
generated
vendored
@@ -17,9 +17,13 @@ limitations under the License.
|
||||
package simulator
|
||||
|
||||
import (
|
||||
"log"
|
||||
"math/rand"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/vmware/govmomi/simulator/esx"
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
@@ -33,8 +37,8 @@ type ClusterComputeResource struct {
|
||||
ruleKey int32
|
||||
}
|
||||
|
||||
func (c *ClusterComputeResource) RenameTask(req *types.Rename_Task) soap.HasFault {
|
||||
return RenameTask(c, req)
|
||||
func (c *ClusterComputeResource) RenameTask(ctx *Context, req *types.Rename_Task) soap.HasFault {
|
||||
return RenameTask(ctx, c, req)
|
||||
}
|
||||
|
||||
type addHost struct {
|
||||
@@ -50,17 +54,21 @@ func (add *addHost) Run(task *Task) (types.AnyType, types.BaseMethodFault) {
|
||||
return nil, &types.NoHost{}
|
||||
}
|
||||
|
||||
host := NewHostSystem(esx.HostSystem)
|
||||
host.Summary.Config.Name = spec.HostName
|
||||
host.Name = host.Summary.Config.Name
|
||||
if add.req.AsConnected {
|
||||
host.Runtime.ConnectionState = types.HostSystemConnectionStateConnected
|
||||
cr := add.ClusterComputeResource
|
||||
template := esx.HostSystem
|
||||
|
||||
if h := task.ctx.Map.FindByName(spec.UserName, cr.Host); h != nil {
|
||||
// "clone" an existing host from the inventory
|
||||
template = h.(*HostSystem).HostSystem
|
||||
template.Vm = nil
|
||||
} else {
|
||||
host.Runtime.ConnectionState = types.HostSystemConnectionStateDisconnected
|
||||
template.Network = cr.Network[:1] // VM Network
|
||||
}
|
||||
|
||||
cr := add.ClusterComputeResource
|
||||
Map.PutEntity(cr, Map.NewEntity(host))
|
||||
host := NewHostSystem(template)
|
||||
host.configure(spec, add.req.AsConnected)
|
||||
|
||||
task.ctx.Map.PutEntity(cr, task.ctx.Map.NewEntity(host))
|
||||
host.Summary.Host = &host.Self
|
||||
|
||||
cr.Host = append(cr.Host, host.Reference())
|
||||
@@ -69,10 +77,10 @@ func (add *addHost) Run(task *Task) (types.AnyType, types.BaseMethodFault) {
|
||||
return host.Reference(), nil
|
||||
}
|
||||
|
||||
func (c *ClusterComputeResource) AddHostTask(add *types.AddHost_Task) soap.HasFault {
|
||||
func (c *ClusterComputeResource) AddHostTask(ctx *Context, add *types.AddHost_Task) soap.HasFault {
|
||||
return &methods.AddHost_TaskBody{
|
||||
Res: &types.AddHost_TaskResponse{
|
||||
Returnval: NewTask(&addHost{c, add}).Run(),
|
||||
Returnval: NewTask(&addHost{c, add}).Run(ctx),
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -265,7 +273,53 @@ func (c *ClusterComputeResource) updateOverridesDRS(cfg *types.ClusterConfigInfo
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ClusterComputeResource) ReconfigureComputeResourceTask(req *types.ReconfigureComputeResource_Task) soap.HasFault {
|
||||
func (c *ClusterComputeResource) updateOverridesVmOrchestration(cfg *types.ClusterConfigInfoEx, cspec *types.ClusterConfigSpecEx) types.BaseMethodFault {
|
||||
for _, spec := range cspec.VmOrchestrationSpec {
|
||||
var i int
|
||||
var key types.ManagedObjectReference
|
||||
exists := false
|
||||
|
||||
if spec.Operation == types.ArrayUpdateOperationRemove {
|
||||
key = spec.RemoveKey.(types.ManagedObjectReference)
|
||||
} else {
|
||||
key = spec.Info.Vm
|
||||
}
|
||||
|
||||
for i = range cfg.VmOrchestration {
|
||||
if cfg.VmOrchestration[i].Vm == key {
|
||||
exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
switch spec.Operation {
|
||||
case types.ArrayUpdateOperationAdd:
|
||||
if exists {
|
||||
return new(types.InvalidArgument)
|
||||
}
|
||||
cfg.VmOrchestration = append(cfg.VmOrchestration, *spec.Info)
|
||||
case types.ArrayUpdateOperationEdit:
|
||||
if !exists {
|
||||
return new(types.InvalidArgument)
|
||||
}
|
||||
if spec.Info.VmReadiness.ReadyCondition != "" {
|
||||
cfg.VmOrchestration[i].VmReadiness.ReadyCondition = spec.Info.VmReadiness.ReadyCondition
|
||||
}
|
||||
if spec.Info.VmReadiness.PostReadyDelay != 0 {
|
||||
cfg.VmOrchestration[i].VmReadiness.PostReadyDelay = spec.Info.VmReadiness.PostReadyDelay
|
||||
}
|
||||
case types.ArrayUpdateOperationRemove:
|
||||
if !exists {
|
||||
return new(types.InvalidArgument)
|
||||
}
|
||||
cfg.VmOrchestration = append(cfg.VmOrchestration[:i], cfg.VmOrchestration[i+1:]...)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ClusterComputeResource) ReconfigureComputeResourceTask(ctx *Context, req *types.ReconfigureComputeResource_Task) soap.HasFault {
|
||||
task := CreateTask(c, "reconfigureCluster", func(*Task) (types.AnyType, types.BaseMethodFault) {
|
||||
spec, ok := req.Spec.(*types.ClusterConfigSpecEx)
|
||||
if !ok {
|
||||
@@ -277,6 +331,7 @@ func (c *ClusterComputeResource) ReconfigureComputeResourceTask(req *types.Recon
|
||||
c.updateGroups,
|
||||
c.updateOverridesDAS,
|
||||
c.updateOverridesDRS,
|
||||
c.updateOverridesVmOrchestration,
|
||||
}
|
||||
|
||||
for _, update := range updates {
|
||||
@@ -290,13 +345,69 @@ func (c *ClusterComputeResource) ReconfigureComputeResourceTask(req *types.Recon
|
||||
|
||||
return &methods.ReconfigureComputeResource_TaskBody{
|
||||
Res: &types.ReconfigureComputeResource_TaskResponse{
|
||||
Returnval: task.Run(),
|
||||
Returnval: task.Run(ctx),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func CreateClusterComputeResource(f *Folder, name string, spec types.ClusterConfigSpecEx) (*ClusterComputeResource, types.BaseMethodFault) {
|
||||
if e := Map.FindByName(name, f.ChildEntity); e != nil {
|
||||
func (c *ClusterComputeResource) PlaceVm(ctx *Context, req *types.PlaceVm) soap.HasFault {
|
||||
body := new(methods.PlaceVmBody)
|
||||
|
||||
if len(c.Host) == 0 {
|
||||
body.Fault_ = Fault("", new(types.InvalidState))
|
||||
return body
|
||||
}
|
||||
|
||||
res := types.ClusterRecommendation{
|
||||
Key: "1",
|
||||
Type: "V1",
|
||||
Time: time.Now(),
|
||||
Rating: 1,
|
||||
Reason: string(types.RecommendationReasonCodeXvmotionPlacement),
|
||||
ReasonText: string(types.RecommendationReasonCodeXvmotionPlacement),
|
||||
Target: &c.Self,
|
||||
}
|
||||
|
||||
hosts := req.PlacementSpec.Hosts
|
||||
if len(hosts) == 0 {
|
||||
hosts = c.Host
|
||||
}
|
||||
|
||||
datastores := req.PlacementSpec.Datastores
|
||||
if len(datastores) == 0 {
|
||||
datastores = c.Datastore
|
||||
}
|
||||
|
||||
spec := &types.VirtualMachineRelocateSpec{
|
||||
Datastore: &datastores[rand.Intn(len(c.Datastore))],
|
||||
Host: &hosts[rand.Intn(len(c.Host))],
|
||||
Pool: c.ResourcePool,
|
||||
}
|
||||
|
||||
switch types.PlacementSpecPlacementType(req.PlacementSpec.PlacementType) {
|
||||
case types.PlacementSpecPlacementTypeClone, types.PlacementSpecPlacementTypeCreate:
|
||||
res.Action = append(res.Action, &types.PlacementAction{
|
||||
Vm: req.PlacementSpec.Vm,
|
||||
TargetHost: spec.Host,
|
||||
RelocateSpec: spec,
|
||||
})
|
||||
default:
|
||||
log.Printf("unsupported placement type: %s", req.PlacementSpec.PlacementType)
|
||||
body.Fault_ = Fault("", new(types.NotSupported))
|
||||
return body
|
||||
}
|
||||
|
||||
body.Res = &types.PlaceVmResponse{
|
||||
Returnval: types.PlacementResult{
|
||||
Recommendations: []types.ClusterRecommendation{res},
|
||||
},
|
||||
}
|
||||
|
||||
return body
|
||||
}
|
||||
|
||||
func CreateClusterComputeResource(ctx *Context, f *Folder, name string, spec types.ClusterConfigSpecEx) (*ClusterComputeResource, types.BaseMethodFault) {
|
||||
if e := ctx.Map.FindByName(name, f.ChildEntity); e != nil {
|
||||
return nil, &types.DuplicateName{
|
||||
Name: e.Entity().Name,
|
||||
Object: e.Reference(),
|
||||
@@ -306,6 +417,7 @@ func CreateClusterComputeResource(f *Folder, name string, spec types.ClusterConf
|
||||
cluster := &ClusterComputeResource{}
|
||||
cluster.EnvironmentBrowser = newEnvironmentBrowser()
|
||||
cluster.Name = name
|
||||
cluster.Network = ctx.Map.getEntityDatacenter(f).defaultNetwork()
|
||||
cluster.Summary = &types.ClusterComputeResourceSummary{
|
||||
UsageSummary: new(types.ClusterUsageSummary),
|
||||
}
|
||||
@@ -317,10 +429,10 @@ func CreateClusterComputeResource(f *Folder, name string, spec types.ClusterConf
|
||||
config.DrsConfig.Enabled = types.NewBool(true)
|
||||
|
||||
pool := NewResourcePool()
|
||||
Map.PutEntity(cluster, Map.NewEntity(pool))
|
||||
ctx.Map.PutEntity(cluster, ctx.Map.NewEntity(pool))
|
||||
cluster.ResourcePool = &pool.Self
|
||||
|
||||
f.putChild(cluster)
|
||||
folderPutChild(ctx, &f.Folder, cluster)
|
||||
pool.Owner = cluster.Self
|
||||
|
||||
return cluster, nil
|
||||
|
440
vendor/github.com/vmware/govmomi/simulator/container.go
generated
vendored
440
vendor/github.com/vmware/govmomi/simulator/container.go
generated
vendored
@@ -17,18 +17,49 @@ limitations under the License.
|
||||
package simulator
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
var (
|
||||
shell = "/bin/sh"
|
||||
)
|
||||
|
||||
func init() {
|
||||
if sh, err := exec.LookPath("bash"); err != nil {
|
||||
shell = sh
|
||||
}
|
||||
}
|
||||
|
||||
// container provides methods to manage a container within a simulator VM lifecycle.
|
||||
type container struct {
|
||||
id string
|
||||
id string
|
||||
name string
|
||||
}
|
||||
|
||||
type networkSettings struct {
|
||||
Gateway string
|
||||
IPAddress string
|
||||
IPPrefixLen int
|
||||
MacAddress string
|
||||
}
|
||||
|
||||
// inspect applies container network settings to vm.Guest properties.
|
||||
@@ -38,11 +69,13 @@ func (c *container) inspect(vm *VirtualMachine) error {
|
||||
}
|
||||
|
||||
var objects []struct {
|
||||
State struct {
|
||||
Running bool
|
||||
Paused bool
|
||||
}
|
||||
NetworkSettings struct {
|
||||
Gateway string
|
||||
IPAddress string
|
||||
IPPrefixLen int
|
||||
MacAddress string
|
||||
networkSettings
|
||||
Networks map[string]networkSettings
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,9 +92,19 @@ func (c *container) inspect(vm *VirtualMachine) error {
|
||||
vm.logPrintf("%s: %s", vm.Config.Annotation, string(out))
|
||||
|
||||
for _, o := range objects {
|
||||
s := o.NetworkSettings
|
||||
if s.IPAddress == "" {
|
||||
continue
|
||||
s := o.NetworkSettings.networkSettings
|
||||
|
||||
for _, n := range o.NetworkSettings.Networks {
|
||||
s = n
|
||||
break
|
||||
}
|
||||
|
||||
if o.State.Paused {
|
||||
vm.Runtime.PowerState = types.VirtualMachinePowerStateSuspended
|
||||
} else if o.State.Running {
|
||||
vm.Runtime.PowerState = types.VirtualMachinePowerStatePoweredOn
|
||||
} else {
|
||||
vm.Runtime.PowerState = types.VirtualMachinePowerStatePoweredOff
|
||||
}
|
||||
|
||||
vm.Guest.IpAddress = s.IPAddress
|
||||
@@ -77,8 +120,104 @@ func (c *container) inspect(vm *VirtualMachine) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *container) prepareGuestOperation(
|
||||
vm *VirtualMachine,
|
||||
auth types.BaseGuestAuthentication) types.BaseMethodFault {
|
||||
|
||||
if c.id == "" {
|
||||
return new(types.GuestOperationsUnavailable)
|
||||
}
|
||||
if vm.Runtime.PowerState != types.VirtualMachinePowerStatePoweredOn {
|
||||
return &types.InvalidPowerState{
|
||||
RequestedState: types.VirtualMachinePowerStatePoweredOn,
|
||||
ExistingState: vm.Runtime.PowerState,
|
||||
}
|
||||
}
|
||||
switch creds := auth.(type) {
|
||||
case *types.NamePasswordAuthentication:
|
||||
if creds.Username == "" || creds.Password == "" {
|
||||
return new(types.InvalidGuestLogin)
|
||||
}
|
||||
default:
|
||||
return new(types.InvalidGuestLogin)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var sanitizeNameRx = regexp.MustCompile(`[\(\)\s]`)
|
||||
|
||||
func sanitizeName(name string) string {
|
||||
return sanitizeNameRx.ReplaceAllString(name, "-")
|
||||
}
|
||||
|
||||
// createDMI writes BIOS UUID DMI files to a container volume
|
||||
func (c *container) createDMI(vm *VirtualMachine, name string) error {
|
||||
image := os.Getenv("VCSIM_BUSYBOX")
|
||||
if image == "" {
|
||||
image = "busybox"
|
||||
}
|
||||
|
||||
cmd := exec.Command("docker", "run", "--rm", "-i", "-v", name+":"+"/"+name, image, "tar", "-C", "/"+name, "-xf", "-")
|
||||
stdin, err := cmd.StdinPipe()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tw := tar.NewWriter(stdin)
|
||||
|
||||
dmi := []struct {
|
||||
name string
|
||||
val func(uuid.UUID) string
|
||||
}{
|
||||
{"product_uuid", productUUID},
|
||||
{"product_serial", productSerial},
|
||||
}
|
||||
|
||||
for _, file := range dmi {
|
||||
val := file.val(vm.uid)
|
||||
_ = tw.WriteHeader(&tar.Header{
|
||||
Name: file.name,
|
||||
Size: int64(len(val) + 1),
|
||||
Mode: 0444,
|
||||
ModTime: time.Now(),
|
||||
})
|
||||
_, _ = fmt.Fprintln(tw, val)
|
||||
}
|
||||
|
||||
_ = tw.Close()
|
||||
_ = stdin.Close()
|
||||
|
||||
if err := cmd.Wait(); err != nil {
|
||||
stderr := ""
|
||||
if xerr, ok := err.(*exec.ExitError); ok {
|
||||
stderr = string(xerr.Stderr)
|
||||
}
|
||||
log.Printf("%s %s: %s %s", vm.Name, cmd.Args, err, stderr)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
toolsRunning = []types.PropertyChange{
|
||||
{Name: "guest.toolsStatus", Val: types.VirtualMachineToolsStatusToolsOk},
|
||||
{Name: "guest.toolsRunningStatus", Val: string(types.VirtualMachineToolsRunningStatusGuestToolsRunning)},
|
||||
}
|
||||
|
||||
toolsNotRunning = []types.PropertyChange{
|
||||
{Name: "guest.toolsStatus", Val: types.VirtualMachineToolsStatusToolsNotRunning},
|
||||
{Name: "guest.toolsRunningStatus", Val: string(types.VirtualMachineToolsRunningStatusGuestToolsNotRunning)},
|
||||
}
|
||||
)
|
||||
|
||||
// start runs the container if specified by the RUN.container extraConfig property.
|
||||
func (c *container) start(vm *VirtualMachine) {
|
||||
func (c *container) start(ctx *Context, vm *VirtualMachine) {
|
||||
if c.id != "" {
|
||||
start := "start"
|
||||
if vm.Runtime.PowerState == types.VirtualMachinePowerStateSuspended {
|
||||
@@ -88,11 +227,14 @@ func (c *container) start(vm *VirtualMachine) {
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
log.Printf("%s %s: %s", vm.Name, cmd.Args, err)
|
||||
} else {
|
||||
ctx.Map.Update(vm, toolsRunning)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var args []string
|
||||
var env []string
|
||||
|
||||
for _, opt := range vm.Config.ExtraConfig {
|
||||
val := opt.GetOptionValue()
|
||||
@@ -103,32 +245,124 @@ func (c *container) start(vm *VirtualMachine) {
|
||||
args = []string{run}
|
||||
}
|
||||
|
||||
break
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(val.Key, "guestinfo.") {
|
||||
key := strings.Replace(strings.ToUpper(val.Key), ".", "_", -1)
|
||||
env = append(env, "--env", fmt.Sprintf("VMX_%s=%s", key, val.Value.(string)))
|
||||
}
|
||||
}
|
||||
|
||||
if len(args) == 0 {
|
||||
return
|
||||
}
|
||||
if len(env) != 0 {
|
||||
// Configure env as the data access method for cloud-init-vmware-guestinfo
|
||||
env = append(env, "--env", "VMX_GUESTINFO=true")
|
||||
}
|
||||
|
||||
args = append([]string{"run", "-d", "--name", vm.Name}, args...)
|
||||
cmd := exec.Command("docker", args...)
|
||||
c.name = fmt.Sprintf("vcsim-%s-%s", sanitizeName(vm.Name), vm.uid)
|
||||
run := append([]string{"docker", "run", "-d", "--name", c.name}, env...)
|
||||
|
||||
if err := c.createDMI(vm, c.name); err != nil {
|
||||
return
|
||||
}
|
||||
run = append(run, "-v", fmt.Sprintf("%s:%s:ro", c.name, "/sys/class/dmi/id"))
|
||||
|
||||
args = append(run, args...)
|
||||
cmd := exec.Command(shell, "-c", strings.Join(args, " "))
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
log.Printf("%s %s: %s", vm.Name, cmd.Args, err)
|
||||
stderr := ""
|
||||
if xerr, ok := err.(*exec.ExitError); ok {
|
||||
stderr = string(xerr.Stderr)
|
||||
}
|
||||
log.Printf("%s %s: %s %s", vm.Name, cmd.Args, err, stderr)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Map.Update(vm, toolsRunning)
|
||||
c.id = strings.TrimSpace(string(out))
|
||||
vm.logPrintf("%s %s: %s", cmd.Path, cmd.Args, c.id)
|
||||
|
||||
if err = c.inspect(vm); err != nil {
|
||||
log.Printf("%s inspect %s: %s", vm.Name, c.id, err)
|
||||
}
|
||||
|
||||
// Start watching the container resource.
|
||||
go c.watchContainer(vm)
|
||||
}
|
||||
|
||||
// watchContainer monitors the underlying container and updates the VM
|
||||
// properties based on the container status. This occurs until either
|
||||
// the container or the VM is removed.
|
||||
func (c *container) watchContainer(vm *VirtualMachine) {
|
||||
|
||||
inspectInterval := time.Duration(5 * time.Second)
|
||||
if d, err := time.ParseDuration(os.Getenv("VCSIM_INSPECT_INTERVAL")); err == nil {
|
||||
inspectInterval = d
|
||||
}
|
||||
|
||||
var (
|
||||
ctx = SpoofContext()
|
||||
done = make(chan struct{})
|
||||
ticker = time.NewTicker(inspectInterval)
|
||||
)
|
||||
|
||||
stopUpdatingVmFromContainer := func() {
|
||||
ticker.Stop()
|
||||
close(done)
|
||||
}
|
||||
|
||||
destroyVm := func() {
|
||||
// If the container cannot be found then destroy this VM.
|
||||
taskRef := vm.DestroyTask(ctx, &types.Destroy_Task{
|
||||
This: vm.Self,
|
||||
}).(*methods.Destroy_TaskBody).Res.Returnval
|
||||
task := ctx.Map.Get(taskRef).(*Task)
|
||||
|
||||
// Wait for the task to complete and see if there is an error.
|
||||
task.Wait()
|
||||
if task.Info.Error != nil {
|
||||
vm.logPrintf("failed to destroy vm: err=%v", *task.Info.Error)
|
||||
}
|
||||
}
|
||||
|
||||
updateVmFromContainer := func() {
|
||||
// Exit the monitor loop if the VM was removed from the API side.
|
||||
if c.id == "" {
|
||||
stopUpdatingVmFromContainer()
|
||||
return
|
||||
}
|
||||
|
||||
if err := c.inspect(vm); err != nil {
|
||||
// If there is an error inspecting the container because it no
|
||||
// longer exists, then destroy the VM as well. Please note the
|
||||
// reason this logic does not invoke stopUpdatingVmFromContainer
|
||||
// is because that will be handled the next time this function
|
||||
// is entered and c.id is empty.
|
||||
if err, ok := err.(*exec.ExitError); ok {
|
||||
if strings.Contains(string(err.Stderr), "No such object") {
|
||||
destroyVm()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the VM from the container at regular intervals until the done
|
||||
// channel is closed.
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
ctx.WithLock(vm, updateVmFromContainer)
|
||||
case <-done:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// stop the container (if any) for the given vm.
|
||||
func (c *container) stop(vm *VirtualMachine) {
|
||||
func (c *container) stop(ctx *Context, vm *VirtualMachine) {
|
||||
if c.id == "" {
|
||||
return
|
||||
}
|
||||
@@ -137,11 +371,13 @@ func (c *container) stop(vm *VirtualMachine) {
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
log.Printf("%s %s: %s", vm.Name, cmd.Args, err)
|
||||
} else {
|
||||
ctx.Map.Update(vm, toolsNotRunning)
|
||||
}
|
||||
}
|
||||
|
||||
// pause the container (if any) for the given vm.
|
||||
func (c *container) pause(vm *VirtualMachine) {
|
||||
func (c *container) pause(ctx *Context, vm *VirtualMachine) {
|
||||
if c.id == "" {
|
||||
return
|
||||
}
|
||||
@@ -150,6 +386,23 @@ func (c *container) pause(vm *VirtualMachine) {
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
log.Printf("%s %s: %s", vm.Name, cmd.Args, err)
|
||||
} else {
|
||||
ctx.Map.Update(vm, toolsNotRunning)
|
||||
}
|
||||
}
|
||||
|
||||
// restart the container (if any) for the given vm.
|
||||
func (c *container) restart(ctx *Context, vm *VirtualMachine) {
|
||||
if c.id == "" {
|
||||
return
|
||||
}
|
||||
|
||||
cmd := exec.Command("docker", "restart", c.id)
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
log.Printf("%s %s: %s", vm.Name, cmd.Args, err)
|
||||
} else {
|
||||
ctx.Map.Update(vm, toolsRunning)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,9 +412,160 @@ func (c *container) remove(vm *VirtualMachine) {
|
||||
return
|
||||
}
|
||||
|
||||
cmd := exec.Command("docker", "rm", "-f", c.id)
|
||||
err := cmd.Run()
|
||||
args := [][]string{
|
||||
{"rm", "-v", "-f", c.id},
|
||||
{"volume", "rm", "-f", c.name},
|
||||
}
|
||||
|
||||
for i := range args {
|
||||
cmd := exec.Command("docker", args[i]...)
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
log.Printf("%s %s: %s", vm.Name, cmd.Args, err)
|
||||
}
|
||||
}
|
||||
|
||||
c.id = ""
|
||||
}
|
||||
|
||||
func (c *container) exec(ctx *Context, vm *VirtualMachine, auth types.BaseGuestAuthentication, args []string) (string, types.BaseMethodFault) {
|
||||
fault := vm.run.prepareGuestOperation(vm, auth)
|
||||
if fault != nil {
|
||||
return "", fault
|
||||
}
|
||||
|
||||
args = append([]string{"exec", vm.run.id}, args...)
|
||||
cmd := exec.Command("docker", args...)
|
||||
|
||||
res, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
log.Printf("%s %s: %s", vm.Name, cmd.Args, err)
|
||||
log.Printf("%s: %s (%s)", vm.Self, cmd.Args, string(res))
|
||||
return "", new(types.GuestOperationsFault)
|
||||
}
|
||||
|
||||
return strings.TrimSpace(string(res)), nil
|
||||
}
|
||||
|
||||
// From https://docs.docker.com/engine/reference/commandline/cp/ :
|
||||
// > It is not possible to copy certain system files such as resources under /proc, /sys, /dev, tmpfs, and mounts created by the user in the container.
|
||||
// > However, you can still copy such files by manually running tar in docker exec.
|
||||
func guestUpload(id string, file string, r *http.Request) error {
|
||||
cmd := exec.Command("docker", "exec", "-i", id, "tar", "Cxf", path.Dir(file), "-")
|
||||
cmd.Stderr = os.Stderr
|
||||
stdin, err := cmd.StdinPipe()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = cmd.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tw := tar.NewWriter(stdin)
|
||||
_ = tw.WriteHeader(&tar.Header{
|
||||
Name: path.Base(file),
|
||||
Size: r.ContentLength,
|
||||
Mode: 0444,
|
||||
ModTime: time.Now(),
|
||||
})
|
||||
|
||||
_, _ = io.Copy(tw, r.Body)
|
||||
|
||||
_ = tw.Close()
|
||||
_ = stdin.Close()
|
||||
_ = r.Body.Close()
|
||||
|
||||
return cmd.Wait()
|
||||
}
|
||||
|
||||
func guestDownload(id string, file string, w http.ResponseWriter) error {
|
||||
cmd := exec.Command("docker", "exec", id, "tar", "Ccf", path.Dir(file), "-", path.Base(file))
|
||||
cmd.Stderr = os.Stderr
|
||||
stdout, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = cmd.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tr := tar.NewReader(stdout)
|
||||
header, err := tr.Next()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Length", strconv.FormatInt(header.Size, 10))
|
||||
_, _ = io.Copy(w, tr)
|
||||
|
||||
return cmd.Wait()
|
||||
}
|
||||
|
||||
const guestPrefix = "/guestFile/"
|
||||
|
||||
// ServeGuest handles container guest file upload/download
|
||||
func ServeGuest(w http.ResponseWriter, r *http.Request) {
|
||||
// Real vCenter form: /guestFile?id=139&token=...
|
||||
// vcsim form: /guestFile/tmp/foo/bar?id=ebc8837b8cb6&token=...
|
||||
|
||||
id := r.URL.Query().Get("id")
|
||||
file := strings.TrimPrefix(r.URL.Path, guestPrefix[:len(guestPrefix)-1])
|
||||
var err error
|
||||
|
||||
switch r.Method {
|
||||
case http.MethodPut:
|
||||
err = guestUpload(id, file, r)
|
||||
case http.MethodGet:
|
||||
err = guestDownload(id, file, w)
|
||||
default:
|
||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Printf("%s %s: %s", r.Method, r.URL, err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
// productSerial returns the uuid in /sys/class/dmi/id/product_serial format
|
||||
func productSerial(id uuid.UUID) string {
|
||||
var dst [len(id)*2 + len(id) - 1]byte
|
||||
|
||||
j := 0
|
||||
for i := 0; i < len(id); i++ {
|
||||
hex.Encode(dst[j:j+2], id[i:i+1])
|
||||
j += 3
|
||||
if j < len(dst) {
|
||||
s := j - 1
|
||||
if s == len(dst)/2 {
|
||||
dst[s] = '-'
|
||||
} else {
|
||||
dst[s] = ' '
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Sprintf("VMware-%s", string(dst[:]))
|
||||
}
|
||||
|
||||
// productUUID returns the uuid in /sys/class/dmi/id/product_uuid format
|
||||
func productUUID(id uuid.UUID) string {
|
||||
var dst [36]byte
|
||||
|
||||
hex.Encode(dst[0:2], id[3:4])
|
||||
hex.Encode(dst[2:4], id[2:3])
|
||||
hex.Encode(dst[4:6], id[1:2])
|
||||
hex.Encode(dst[6:8], id[0:1])
|
||||
dst[8] = '-'
|
||||
hex.Encode(dst[9:11], id[5:6])
|
||||
hex.Encode(dst[11:13], id[4:5])
|
||||
dst[13] = '-'
|
||||
hex.Encode(dst[14:16], id[7:8])
|
||||
hex.Encode(dst[16:18], id[6:7])
|
||||
dst[18] = '-'
|
||||
hex.Encode(dst[19:23], id[8:10])
|
||||
dst[23] = '-'
|
||||
hex.Encode(dst[24:], id[10:])
|
||||
|
||||
return strings.ToUpper(string(dst[:]))
|
||||
}
|
||||
|
57
vendor/github.com/vmware/govmomi/simulator/custom_fields_manager.go
generated
vendored
57
vendor/github.com/vmware/govmomi/simulator/custom_fields_manager.go
generated
vendored
@@ -17,7 +17,6 @@ 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"
|
||||
@@ -30,19 +29,13 @@ type CustomFieldsManager struct {
|
||||
nextKey int32
|
||||
}
|
||||
|
||||
func NewCustomFieldsManager(ref types.ManagedObjectReference) object.Reference {
|
||||
m := &CustomFieldsManager{}
|
||||
m.Self = ref
|
||||
return m
|
||||
}
|
||||
|
||||
// Iterates through all entities of passed field type;
|
||||
// Removes found field from their custom field properties.
|
||||
func entitiesFieldRemove(field types.CustomFieldDef) {
|
||||
entities := Map.All(field.ManagedObjectType)
|
||||
func entitiesFieldRemove(ctx *Context, field types.CustomFieldDef) {
|
||||
entities := ctx.Map.All(field.ManagedObjectType)
|
||||
for _, e := range entities {
|
||||
entity := e.Entity()
|
||||
Map.WithLock(entity, func() {
|
||||
ctx.WithLock(entity, func() {
|
||||
aFields := entity.AvailableField
|
||||
for i, aField := range aFields {
|
||||
if aField.Key == field.Key {
|
||||
@@ -72,11 +65,11 @@ func entitiesFieldRemove(field types.CustomFieldDef) {
|
||||
|
||||
// Iterates through all entities of passed field type;
|
||||
// Renames found field in entity's AvailableField property.
|
||||
func entitiesFieldRename(field types.CustomFieldDef) {
|
||||
entities := Map.All(field.ManagedObjectType)
|
||||
func entitiesFieldRename(ctx *Context, field types.CustomFieldDef) {
|
||||
entities := ctx.Map.All(field.ManagedObjectType)
|
||||
for _, e := range entities {
|
||||
entity := e.Entity()
|
||||
Map.WithLock(entity, func() {
|
||||
ctx.WithLock(entity, func() {
|
||||
aFields := entity.AvailableField
|
||||
for i, aField := range aFields {
|
||||
if aField.Key == field.Key {
|
||||
@@ -109,7 +102,7 @@ func (c *CustomFieldsManager) findByKey(key int32) (int, *types.CustomFieldDef)
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
func (c *CustomFieldsManager) AddCustomFieldDef(req *types.AddCustomFieldDef) soap.HasFault {
|
||||
func (c *CustomFieldsManager) AddCustomFieldDef(ctx *Context, req *types.AddCustomFieldDef) soap.HasFault {
|
||||
body := &methods.AddCustomFieldDefBody{}
|
||||
|
||||
_, field := c.findByNameType(req.Name, req.MoType)
|
||||
@@ -130,10 +123,10 @@ func (c *CustomFieldsManager) AddCustomFieldDef(req *types.AddCustomFieldDef) so
|
||||
FieldInstancePrivileges: req.FieldPolicy,
|
||||
}
|
||||
|
||||
entities := Map.All(req.MoType)
|
||||
entities := ctx.Map.All(req.MoType)
|
||||
for _, e := range entities {
|
||||
entity := e.Entity()
|
||||
Map.WithLock(entity, func() {
|
||||
ctx.WithLock(entity, func() {
|
||||
entity.AvailableField = append(entity.AvailableField, def)
|
||||
})
|
||||
}
|
||||
@@ -147,7 +140,7 @@ func (c *CustomFieldsManager) AddCustomFieldDef(req *types.AddCustomFieldDef) so
|
||||
return body
|
||||
}
|
||||
|
||||
func (c *CustomFieldsManager) RemoveCustomFieldDef(req *types.RemoveCustomFieldDef) soap.HasFault {
|
||||
func (c *CustomFieldsManager) RemoveCustomFieldDef(ctx *Context, req *types.RemoveCustomFieldDef) soap.HasFault {
|
||||
body := &methods.RemoveCustomFieldDefBody{}
|
||||
|
||||
i, field := c.findByKey(req.Key)
|
||||
@@ -156,7 +149,7 @@ func (c *CustomFieldsManager) RemoveCustomFieldDef(req *types.RemoveCustomFieldD
|
||||
return body
|
||||
}
|
||||
|
||||
entitiesFieldRemove(*field)
|
||||
entitiesFieldRemove(ctx, *field)
|
||||
|
||||
c.Field = append(c.Field[:i], c.Field[i+1:]...)
|
||||
|
||||
@@ -164,7 +157,7 @@ func (c *CustomFieldsManager) RemoveCustomFieldDef(req *types.RemoveCustomFieldD
|
||||
return body
|
||||
}
|
||||
|
||||
func (c *CustomFieldsManager) RenameCustomFieldDef(req *types.RenameCustomFieldDef) soap.HasFault {
|
||||
func (c *CustomFieldsManager) RenameCustomFieldDef(ctx *Context, req *types.RenameCustomFieldDef) soap.HasFault {
|
||||
body := &methods.RenameCustomFieldDefBody{}
|
||||
|
||||
_, field := c.findByKey(req.Key)
|
||||
@@ -175,7 +168,7 @@ func (c *CustomFieldsManager) RenameCustomFieldDef(req *types.RenameCustomFieldD
|
||||
|
||||
field.Name = req.Name
|
||||
|
||||
entitiesFieldRename(*field)
|
||||
entitiesFieldRename(ctx, *field)
|
||||
|
||||
body.Res = &types.RenameCustomFieldDefResponse{}
|
||||
return body
|
||||
@@ -195,8 +188,30 @@ func (c *CustomFieldsManager) SetField(ctx *Context, req *types.SetField) soap.H
|
||||
Value: req.Value,
|
||||
}
|
||||
|
||||
entity := Map.Get(req.Entity).(mo.Entity).Entity()
|
||||
removeIndex := func(s []types.BaseCustomFieldValue, i int) []types.BaseCustomFieldValue {
|
||||
new := make([]types.BaseCustomFieldValue, 0)
|
||||
new = append(new, s[:i]...)
|
||||
return append(new, s[i+1:]...)
|
||||
}
|
||||
|
||||
removeExistingValues := func(s []types.BaseCustomFieldValue) []types.BaseCustomFieldValue {
|
||||
for i := 0; i < len(s); {
|
||||
if s[i].GetCustomFieldValue().Key == newValue.GetCustomFieldValue().Key {
|
||||
s = removeIndex(s, i)
|
||||
}
|
||||
i++
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
entity := ctx.Map.Get(req.Entity).(mo.Entity).Entity()
|
||||
|
||||
ctx.WithLock(entity, func() {
|
||||
// Check if custom value and value are already set. If so, remove them.
|
||||
entity.CustomValue = removeExistingValues(entity.CustomValue)
|
||||
entity.Value = removeExistingValues(entity.Value)
|
||||
|
||||
// Add the new value
|
||||
entity.CustomValue = append(entity.CustomValue, newValue)
|
||||
entity.Value = append(entity.Value, newValue)
|
||||
})
|
||||
|
349
vendor/github.com/vmware/govmomi/simulator/customization_spec_manager.go
generated
vendored
Normal file
349
vendor/github.com/vmware/govmomi/simulator/customization_spec_manager.go
generated
vendored
Normal file
@@ -0,0 +1,349 @@
|
||||
/*
|
||||
Copyright (c) 2019 VMware, Inc. All 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 (
|
||||
"fmt"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/soap"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
var DefaultCustomizationSpec = []types.CustomizationSpecItem{
|
||||
{
|
||||
Info: types.CustomizationSpecInfo{
|
||||
Name: "vcsim-linux",
|
||||
Description: "",
|
||||
Type: "Linux",
|
||||
ChangeVersion: "1569965707",
|
||||
LastUpdateTime: types.NewTime(time.Now()),
|
||||
},
|
||||
Spec: types.CustomizationSpec{
|
||||
Options: &types.CustomizationLinuxOptions{},
|
||||
Identity: &types.CustomizationLinuxPrep{
|
||||
CustomizationIdentitySettings: types.CustomizationIdentitySettings{},
|
||||
HostName: &types.CustomizationVirtualMachineName{},
|
||||
Domain: "eng.vmware.com",
|
||||
TimeZone: "Pacific/Apia",
|
||||
HwClockUTC: types.NewBool(true),
|
||||
},
|
||||
GlobalIPSettings: types.CustomizationGlobalIPSettings{
|
||||
DnsSuffixList: nil,
|
||||
DnsServerList: []string{"127.0.1.1"},
|
||||
},
|
||||
NicSettingMap: []types.CustomizationAdapterMapping{
|
||||
{
|
||||
MacAddress: "",
|
||||
Adapter: types.CustomizationIPSettings{
|
||||
Ip: &types.CustomizationDhcpIpGenerator{},
|
||||
SubnetMask: "",
|
||||
Gateway: nil,
|
||||
IpV6Spec: (*types.CustomizationIPSettingsIpV6AddressSpec)(nil),
|
||||
DnsServerList: nil,
|
||||
DnsDomain: "",
|
||||
PrimaryWINS: "",
|
||||
SecondaryWINS: "",
|
||||
NetBIOS: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
EncryptionKey: nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
Info: types.CustomizationSpecInfo{
|
||||
Name: "vcsim-linux-static",
|
||||
Description: "",
|
||||
Type: "Linux",
|
||||
ChangeVersion: "1569969598",
|
||||
LastUpdateTime: types.NewTime(time.Now()),
|
||||
},
|
||||
Spec: types.CustomizationSpec{
|
||||
Options: &types.CustomizationLinuxOptions{},
|
||||
Identity: &types.CustomizationLinuxPrep{
|
||||
CustomizationIdentitySettings: types.CustomizationIdentitySettings{},
|
||||
HostName: &types.CustomizationPrefixName{
|
||||
CustomizationName: types.CustomizationName{},
|
||||
Base: "vcsim",
|
||||
},
|
||||
Domain: "eng.vmware.com",
|
||||
TimeZone: "Africa/Cairo",
|
||||
HwClockUTC: types.NewBool(true),
|
||||
},
|
||||
GlobalIPSettings: types.CustomizationGlobalIPSettings{
|
||||
DnsSuffixList: nil,
|
||||
DnsServerList: []string{"127.0.1.1"},
|
||||
},
|
||||
NicSettingMap: []types.CustomizationAdapterMapping{
|
||||
{
|
||||
MacAddress: "",
|
||||
Adapter: types.CustomizationIPSettings{
|
||||
Ip: &types.CustomizationUnknownIpGenerator{},
|
||||
SubnetMask: "255.255.255.0",
|
||||
Gateway: []string{"10.0.0.1"},
|
||||
IpV6Spec: (*types.CustomizationIPSettingsIpV6AddressSpec)(nil),
|
||||
DnsServerList: nil,
|
||||
DnsDomain: "",
|
||||
PrimaryWINS: "",
|
||||
SecondaryWINS: "",
|
||||
NetBIOS: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
EncryptionKey: nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
Info: types.CustomizationSpecInfo{
|
||||
Name: "vcsim-windows-static",
|
||||
Description: "",
|
||||
Type: "Windows",
|
||||
ChangeVersion: "1569978029",
|
||||
LastUpdateTime: types.NewTime(time.Now()),
|
||||
},
|
||||
Spec: types.CustomizationSpec{
|
||||
Options: &types.CustomizationWinOptions{
|
||||
CustomizationOptions: types.CustomizationOptions{},
|
||||
ChangeSID: true,
|
||||
DeleteAccounts: false,
|
||||
Reboot: "",
|
||||
},
|
||||
Identity: &types.CustomizationSysprep{
|
||||
CustomizationIdentitySettings: types.CustomizationIdentitySettings{},
|
||||
GuiUnattended: types.CustomizationGuiUnattended{
|
||||
Password: (*types.CustomizationPassword)(nil),
|
||||
TimeZone: 2,
|
||||
AutoLogon: false,
|
||||
AutoLogonCount: 1,
|
||||
},
|
||||
UserData: types.CustomizationUserData{
|
||||
FullName: "vcsim",
|
||||
OrgName: "VMware",
|
||||
ComputerName: &types.CustomizationVirtualMachineName{},
|
||||
ProductId: "",
|
||||
},
|
||||
GuiRunOnce: (*types.CustomizationGuiRunOnce)(nil),
|
||||
Identification: types.CustomizationIdentification{
|
||||
JoinWorkgroup: "WORKGROUP",
|
||||
JoinDomain: "",
|
||||
DomainAdmin: "",
|
||||
DomainAdminPassword: (*types.CustomizationPassword)(nil),
|
||||
},
|
||||
LicenseFilePrintData: &types.CustomizationLicenseFilePrintData{
|
||||
AutoMode: "perServer",
|
||||
AutoUsers: 5,
|
||||
},
|
||||
},
|
||||
GlobalIPSettings: types.CustomizationGlobalIPSettings{},
|
||||
NicSettingMap: []types.CustomizationAdapterMapping{
|
||||
{
|
||||
MacAddress: "",
|
||||
Adapter: types.CustomizationIPSettings{
|
||||
Ip: &types.CustomizationUnknownIpGenerator{},
|
||||
SubnetMask: "255.255.255.0",
|
||||
Gateway: []string{"10.0.0.1"},
|
||||
IpV6Spec: (*types.CustomizationIPSettingsIpV6AddressSpec)(nil),
|
||||
DnsServerList: nil,
|
||||
DnsDomain: "",
|
||||
PrimaryWINS: "",
|
||||
SecondaryWINS: "",
|
||||
NetBIOS: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
EncryptionKey: []uint8{0x30},
|
||||
},
|
||||
},
|
||||
{
|
||||
Info: types.CustomizationSpecInfo{
|
||||
Name: "vcsim-windows-domain",
|
||||
Description: "",
|
||||
Type: "Windows",
|
||||
ChangeVersion: "1569970234",
|
||||
LastUpdateTime: types.NewTime(time.Now()),
|
||||
},
|
||||
Spec: types.CustomizationSpec{
|
||||
Options: &types.CustomizationWinOptions{
|
||||
CustomizationOptions: types.CustomizationOptions{},
|
||||
ChangeSID: true,
|
||||
DeleteAccounts: false,
|
||||
Reboot: "",
|
||||
},
|
||||
Identity: &types.CustomizationSysprep{
|
||||
CustomizationIdentitySettings: types.CustomizationIdentitySettings{},
|
||||
GuiUnattended: types.CustomizationGuiUnattended{
|
||||
Password: &types.CustomizationPassword{
|
||||
Value: "3Gs...==",
|
||||
PlainText: false,
|
||||
},
|
||||
TimeZone: 15,
|
||||
AutoLogon: false,
|
||||
AutoLogonCount: 1,
|
||||
},
|
||||
UserData: types.CustomizationUserData{
|
||||
FullName: "dougm",
|
||||
OrgName: "VMware",
|
||||
ComputerName: &types.CustomizationVirtualMachineName{},
|
||||
ProductId: "",
|
||||
},
|
||||
GuiRunOnce: (*types.CustomizationGuiRunOnce)(nil),
|
||||
Identification: types.CustomizationIdentification{
|
||||
JoinWorkgroup: "",
|
||||
JoinDomain: "DOMAIN",
|
||||
DomainAdmin: "vcsim",
|
||||
DomainAdminPassword: &types.CustomizationPassword{
|
||||
Value: "H3g...==",
|
||||
PlainText: false,
|
||||
},
|
||||
},
|
||||
LicenseFilePrintData: &types.CustomizationLicenseFilePrintData{
|
||||
AutoMode: "perServer",
|
||||
AutoUsers: 5,
|
||||
},
|
||||
},
|
||||
GlobalIPSettings: types.CustomizationGlobalIPSettings{},
|
||||
NicSettingMap: []types.CustomizationAdapterMapping{
|
||||
{
|
||||
MacAddress: "",
|
||||
Adapter: types.CustomizationIPSettings{
|
||||
Ip: &types.CustomizationUnknownIpGenerator{},
|
||||
SubnetMask: "255.255.255.0",
|
||||
Gateway: []string{"10.0.0.1"},
|
||||
IpV6Spec: (*types.CustomizationIPSettingsIpV6AddressSpec)(nil),
|
||||
DnsServerList: nil,
|
||||
DnsDomain: "",
|
||||
PrimaryWINS: "",
|
||||
SecondaryWINS: "",
|
||||
NetBIOS: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
EncryptionKey: []uint8{0x30},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
type CustomizationSpecManager struct {
|
||||
mo.CustomizationSpecManager
|
||||
|
||||
items []types.CustomizationSpecItem
|
||||
}
|
||||
|
||||
func (m *CustomizationSpecManager) init(r *Registry) {
|
||||
m.items = DefaultCustomizationSpec
|
||||
}
|
||||
|
||||
var customizeNameCounter uint64
|
||||
|
||||
func customizeName(vm *VirtualMachine, base types.BaseCustomizationName) string {
|
||||
n := atomic.AddUint64(&customizeNameCounter, 1)
|
||||
|
||||
switch name := base.(type) {
|
||||
case *types.CustomizationPrefixName:
|
||||
return fmt.Sprintf("%s-%d", name.Base, n)
|
||||
case *types.CustomizationCustomName:
|
||||
return fmt.Sprintf("%s-%d", name.Argument, n)
|
||||
case *types.CustomizationFixedName:
|
||||
return name.Name
|
||||
case *types.CustomizationUnknownName:
|
||||
return ""
|
||||
case *types.CustomizationVirtualMachineName:
|
||||
return fmt.Sprintf("%s-%d", vm.Name, n)
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func (m *CustomizationSpecManager) DoesCustomizationSpecExist(ctx *Context, req *types.DoesCustomizationSpecExist) soap.HasFault {
|
||||
exists := false
|
||||
|
||||
for _, item := range m.items {
|
||||
if item.Info.Name == req.Name {
|
||||
exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return &methods.DoesCustomizationSpecExistBody{
|
||||
Res: &types.DoesCustomizationSpecExistResponse{
|
||||
Returnval: exists,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (m *CustomizationSpecManager) GetCustomizationSpec(ctx *Context, req *types.GetCustomizationSpec) soap.HasFault {
|
||||
body := new(methods.GetCustomizationSpecBody)
|
||||
|
||||
for _, item := range m.items {
|
||||
if item.Info.Name == req.Name {
|
||||
body.Res = &types.GetCustomizationSpecResponse{
|
||||
Returnval: item,
|
||||
}
|
||||
return body
|
||||
}
|
||||
}
|
||||
|
||||
body.Fault_ = Fault("", new(types.NotFound))
|
||||
|
||||
return body
|
||||
}
|
||||
|
||||
func (m *CustomizationSpecManager) CreateCustomizationSpec(ctx *Context, req *types.CreateCustomizationSpec) soap.HasFault {
|
||||
body := new(methods.CreateCustomizationSpecBody)
|
||||
|
||||
for _, item := range m.items {
|
||||
if item.Info.Name == req.Item.Info.Name {
|
||||
body.Fault_ = Fault("", &types.AlreadyExists{Name: req.Item.Info.Name})
|
||||
return body
|
||||
}
|
||||
}
|
||||
|
||||
m.items = append(m.items, req.Item)
|
||||
body.Res = new(types.CreateCustomizationSpecResponse)
|
||||
|
||||
return body
|
||||
}
|
||||
|
||||
func (m *CustomizationSpecManager) OverwriteCustomizationSpec(ctx *Context, req *types.OverwriteCustomizationSpec) soap.HasFault {
|
||||
body := new(methods.OverwriteCustomizationSpecBody)
|
||||
|
||||
for i, item := range m.items {
|
||||
if item.Info.Name == req.Item.Info.Name {
|
||||
m.items[i] = req.Item
|
||||
body.Res = new(types.OverwriteCustomizationSpecResponse)
|
||||
return body
|
||||
}
|
||||
}
|
||||
|
||||
body.Fault_ = Fault("", new(types.NotFound))
|
||||
|
||||
return body
|
||||
}
|
||||
|
||||
func (m *CustomizationSpecManager) Get() mo.Reference {
|
||||
clone := *m
|
||||
|
||||
for i := range clone.items {
|
||||
clone.Info = append(clone.Info, clone.items[i].Info)
|
||||
}
|
||||
|
||||
return &clone
|
||||
}
|
94
vendor/github.com/vmware/govmomi/simulator/datacenter.go
generated
vendored
94
vendor/github.com/vmware/govmomi/simulator/datacenter.go
generated
vendored
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package simulator
|
||||
|
||||
import (
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"github.com/vmware/govmomi/simulator/esx"
|
||||
@@ -33,7 +34,7 @@ type Datacenter struct {
|
||||
}
|
||||
|
||||
// NewDatacenter creates a Datacenter and its child folders.
|
||||
func NewDatacenter(f *Folder) *Datacenter {
|
||||
func NewDatacenter(ctx *Context, f *mo.Folder) *Datacenter {
|
||||
dc := &Datacenter{
|
||||
isESX: f.Self == esx.RootFolder.Self,
|
||||
}
|
||||
@@ -42,18 +43,22 @@ func NewDatacenter(f *Folder) *Datacenter {
|
||||
dc.Datacenter = esx.Datacenter
|
||||
}
|
||||
|
||||
f.putChild(dc)
|
||||
folderPutChild(ctx, f, dc)
|
||||
|
||||
dc.createFolders()
|
||||
dc.createFolders(ctx)
|
||||
|
||||
return dc
|
||||
}
|
||||
|
||||
func (dc *Datacenter) RenameTask(ctx *Context, r *types.Rename_Task) soap.HasFault {
|
||||
return RenameTask(ctx, dc, r)
|
||||
}
|
||||
|
||||
// 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 (dc *Datacenter) createFolders() {
|
||||
func (dc *Datacenter) createFolders(ctx *Context) {
|
||||
folders := []struct {
|
||||
ref *types.ManagedObjectReference
|
||||
name string
|
||||
@@ -72,10 +77,10 @@ func (dc *Datacenter) createFolders() {
|
||||
if dc.isESX {
|
||||
folder.ChildType = f.types[:1]
|
||||
folder.Self = *f.ref
|
||||
Map.PutEntity(dc, folder)
|
||||
ctx.Map.PutEntity(dc, folder)
|
||||
} else {
|
||||
folder.ChildType = f.types
|
||||
e := Map.PutEntity(dc, folder)
|
||||
e := ctx.Map.PutEntity(dc, folder)
|
||||
|
||||
// propagate the generated morefs to Datacenter
|
||||
ref := e.Reference()
|
||||
@@ -84,7 +89,7 @@ func (dc *Datacenter) createFolders() {
|
||||
}
|
||||
}
|
||||
|
||||
net := Map.Get(dc.NetworkFolder).(*Folder)
|
||||
net := ctx.Map.Get(dc.NetworkFolder).(*Folder)
|
||||
|
||||
for _, ref := range esx.Datacenter.Network {
|
||||
// Add VM Network by default to each Datacenter
|
||||
@@ -96,10 +101,41 @@ func (dc *Datacenter) createFolders() {
|
||||
network.Self.Value = "" // we want a different moid per-DC
|
||||
}
|
||||
|
||||
net.putChild(network)
|
||||
folderPutChild(ctx, &net.Folder, network)
|
||||
}
|
||||
}
|
||||
|
||||
func (dc *Datacenter) defaultNetwork() []types.ManagedObjectReference {
|
||||
return dc.Network[:1] // VM Network
|
||||
}
|
||||
|
||||
// folder returns the Datacenter folder that can contain the given object type
|
||||
func (dc *Datacenter) folder(obj mo.Entity) *mo.Folder {
|
||||
folders := []types.ManagedObjectReference{
|
||||
dc.VmFolder,
|
||||
dc.HostFolder,
|
||||
dc.DatastoreFolder,
|
||||
dc.NetworkFolder,
|
||||
}
|
||||
otype := getManagedObject(obj).Type()
|
||||
rtype := obj.Reference().Type
|
||||
|
||||
for i := range folders {
|
||||
folder, _ := asFolderMO(Map.Get(folders[i]))
|
||||
for _, kind := range folder.ChildType {
|
||||
if rtype == kind {
|
||||
return folder
|
||||
}
|
||||
if f, ok := otype.FieldByName(kind); ok && f.Anonymous {
|
||||
return folder
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.Panicf("failed to find folder for type=%s", rtype)
|
||||
return nil
|
||||
}
|
||||
|
||||
func datacenterEventArgument(obj mo.Entity) *types.DatacenterEventArgument {
|
||||
dc, ok := obj.(*Datacenter)
|
||||
if !ok {
|
||||
@@ -117,24 +153,46 @@ func (dc *Datacenter) PowerOnMultiVMTask(ctx *Context, req *types.PowerOnMultiVM
|
||||
return nil, new(types.NotImplemented)
|
||||
}
|
||||
|
||||
// Return per-VM tasks, structured as:
|
||||
// thisTask.result - DC level task
|
||||
// +- []Attempted
|
||||
// +- subTask.result - VM level powerOn task result
|
||||
// +- ...
|
||||
res := types.ClusterPowerOnVmResult{}
|
||||
res.Attempted = []types.ClusterAttemptedVmInfo{}
|
||||
|
||||
for _, ref := range req.Vm {
|
||||
vm := Map.Get(ref).(*VirtualMachine)
|
||||
Map.WithLock(vm, func() {
|
||||
vm.PowerOnVMTask(ctx, &types.PowerOnVM_Task{})
|
||||
vm := ctx.Map.Get(ref).(*VirtualMachine)
|
||||
|
||||
// This task creates multiple subtasks which violates the assumption
|
||||
// of 1:1 Context:Task, which results in data races in objects
|
||||
// like the Simulator.Event manager. This is the minimum context
|
||||
// required for the PowerOnVMTask to complete.
|
||||
taskCtx := &Context{
|
||||
Context: ctx.Context,
|
||||
Session: ctx.Session,
|
||||
Map: ctx.Map,
|
||||
}
|
||||
|
||||
// NOTE: Simulator does not actually perform any specific host-level placement
|
||||
// (equivalent to vSphere DRS).
|
||||
taskCtx.WithLock(vm, func() {
|
||||
vmTaskBody := vm.PowerOnVMTask(taskCtx, &types.PowerOnVM_Task{}).(*methods.PowerOnVM_TaskBody)
|
||||
res.Attempted = append(res.Attempted, types.ClusterAttemptedVmInfo{Vm: ref, Task: &vmTaskBody.Res.Returnval})
|
||||
})
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
return res, nil
|
||||
})
|
||||
|
||||
return &methods.PowerOnMultiVM_TaskBody{
|
||||
Res: &types.PowerOnMultiVM_TaskResponse{
|
||||
Returnval: task.Run(),
|
||||
Returnval: task.Run(ctx),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Datacenter) DestroyTask(req *types.Destroy_Task) soap.HasFault {
|
||||
func (d *Datacenter) DestroyTask(ctx *Context, req *types.Destroy_Task) soap.HasFault {
|
||||
task := CreateTask(d, "destroy", func(t *Task) (types.AnyType, types.BaseMethodFault) {
|
||||
folders := []types.ManagedObjectReference{
|
||||
d.VmFolder,
|
||||
@@ -142,19 +200,21 @@ func (d *Datacenter) DestroyTask(req *types.Destroy_Task) soap.HasFault {
|
||||
}
|
||||
|
||||
for _, ref := range folders {
|
||||
if len(Map.Get(ref).(*Folder).ChildEntity) != 0 {
|
||||
f, _ := asFolderMO(ctx.Map.Get(ref))
|
||||
if len(f.ChildEntity) != 0 {
|
||||
return nil, &types.ResourceInUse{}
|
||||
}
|
||||
}
|
||||
|
||||
Map.Get(*d.Parent).(*Folder).removeChild(d.Self)
|
||||
p, _ := asFolderMO(ctx.Map.Get(*d.Parent))
|
||||
folderRemoveChild(ctx, p, d.Self)
|
||||
|
||||
return nil, nil
|
||||
})
|
||||
|
||||
return &methods.Destroy_TaskBody{
|
||||
Res: &types.Destroy_TaskResponse{
|
||||
Returnval: task.Run(),
|
||||
Returnval: task.Run(ctx),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
65
vendor/github.com/vmware/govmomi/simulator/datastore.go
generated
vendored
65
vendor/github.com/vmware/govmomi/simulator/datastore.go
generated
vendored
@@ -17,6 +17,10 @@ limitations under the License.
|
||||
package simulator
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/vmware/govmomi/object"
|
||||
@@ -30,6 +34,32 @@ type Datastore struct {
|
||||
mo.Datastore
|
||||
}
|
||||
|
||||
func (ds *Datastore) eventArgument() *types.DatastoreEventArgument {
|
||||
return &types.DatastoreEventArgument{
|
||||
Datastore: ds.Self,
|
||||
EntityEventArgument: types.EntityEventArgument{Name: ds.Name},
|
||||
}
|
||||
}
|
||||
|
||||
func (ds *Datastore) model(m *Model) error {
|
||||
info := ds.Info.GetDatastoreInfo()
|
||||
u, _ := url.Parse(info.Url)
|
||||
if u.Scheme == "ds" {
|
||||
// rewrite saved vmfs path to a local temp dir
|
||||
u.Path = path.Clean(u.Path)
|
||||
parent := strings.ReplaceAll(path.Dir(u.Path), "/", "_")
|
||||
name := strings.ReplaceAll(path.Base(u.Path), ":", "_")
|
||||
|
||||
dir, err := m.createTempDir(parent, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
info.Url = dir
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseDatastorePath(dsPath string) (*object.DatastorePath, types.BaseMethodFault) {
|
||||
var p object.DatastorePath
|
||||
|
||||
@@ -43,7 +73,7 @@ func parseDatastorePath(dsPath string) (*object.DatastorePath, types.BaseMethodF
|
||||
func (ds *Datastore) RefreshDatastore(*types.RefreshDatastore) soap.HasFault {
|
||||
r := &methods.RefreshDatastoreBody{}
|
||||
|
||||
err := ds.stat()
|
||||
_, err := os.Stat(ds.Info.GetDatastoreInfo().Url)
|
||||
if err != nil {
|
||||
r.Fault_ = Fault(err.Error(), &types.HostConfigFault{})
|
||||
return r
|
||||
@@ -51,9 +81,36 @@ func (ds *Datastore) RefreshDatastore(*types.RefreshDatastore) soap.HasFault {
|
||||
|
||||
info := ds.Info.GetDatastoreInfo()
|
||||
|
||||
now := time.Now()
|
||||
|
||||
info.Timestamp = &now
|
||||
info.Timestamp = types.NewTime(time.Now())
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func (ds *Datastore) DestroyTask(ctx *Context, req *types.Destroy_Task) soap.HasFault {
|
||||
task := CreateTask(ds, "destroy", func(*Task) (types.AnyType, types.BaseMethodFault) {
|
||||
if len(ds.Vm) != 0 {
|
||||
return nil, &types.ResourceInUse{
|
||||
Type: ds.Self.Type,
|
||||
Name: ds.Name,
|
||||
}
|
||||
}
|
||||
|
||||
for _, mount := range ds.Host {
|
||||
host := ctx.Map.Get(mount.Key).(*HostSystem)
|
||||
ctx.Map.RemoveReference(ctx, host, &host.Datastore, ds.Self)
|
||||
parent := hostParent(&host.HostSystem)
|
||||
ctx.Map.RemoveReference(ctx, parent, &parent.Datastore, ds.Self)
|
||||
}
|
||||
|
||||
p, _ := asFolderMO(ctx.Map.Get(*ds.Parent))
|
||||
folderRemoveChild(ctx, p, ds.Self)
|
||||
|
||||
return nil, nil
|
||||
})
|
||||
|
||||
return &methods.Destroy_TaskBody{
|
||||
Res: &types.Destroy_TaskResponse{
|
||||
Returnval: task.Run(ctx),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
252
vendor/github.com/vmware/govmomi/simulator/dvs.go
generated
vendored
252
vendor/github.com/vmware/govmomi/simulator/dvs.go
generated
vendored
@@ -17,6 +17,12 @@ limitations under the License.
|
||||
package simulator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/soap"
|
||||
@@ -25,11 +31,13 @@ import (
|
||||
|
||||
type DistributedVirtualSwitch struct {
|
||||
mo.DistributedVirtualSwitch
|
||||
|
||||
types.FetchDVPortsResponse
|
||||
}
|
||||
|
||||
func (s *DistributedVirtualSwitch) AddDVPortgroupTask(c *types.AddDVPortgroup_Task) soap.HasFault {
|
||||
func (s *DistributedVirtualSwitch) AddDVPortgroupTask(ctx *Context, c *types.AddDVPortgroup_Task) soap.HasFault {
|
||||
task := CreateTask(s, "addDVPortgroup", func(t *Task) (types.AnyType, types.BaseMethodFault) {
|
||||
f := Map.getEntityParent(s, "Folder").(*Folder)
|
||||
f := ctx.Map.getEntityParent(s, "Folder").(*Folder)
|
||||
|
||||
portgroups := s.Portgroup
|
||||
portgroupNames := s.Summary.PortgroupName
|
||||
@@ -39,14 +47,26 @@ func (s *DistributedVirtualSwitch) AddDVPortgroupTask(c *types.AddDVPortgroup_Ta
|
||||
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(),
|
||||
// Standard AddDVPortgroupTask() doesn't allow duplicate names, but NSX 3.0 does create some DVPGs with the same name.
|
||||
// Allow duplicate names using this prefix so we can reproduce and test this condition.
|
||||
if strings.HasPrefix(pg.Name, "NSX-") || spec.BackingType == string(types.DistributedVirtualPortgroupBackingTypeNsx) {
|
||||
if spec.LogicalSwitchUuid == "" {
|
||||
spec.LogicalSwitchUuid = uuid.New().String()
|
||||
}
|
||||
if spec.SegmentId == "" {
|
||||
spec.SegmentId = fmt.Sprintf("/infra/segments/vnet_%s", uuid.New().String())
|
||||
}
|
||||
|
||||
} else {
|
||||
if obj := ctx.Map.FindByName(pg.Name, f.ChildEntity); obj != nil {
|
||||
return nil, &types.DuplicateName{
|
||||
Name: pg.Name,
|
||||
Object: obj.Reference(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
f.putChild(pg)
|
||||
folderPutChild(ctx, &f.Folder, pg)
|
||||
|
||||
pg.Key = pg.Self.Value
|
||||
pg.Config = types.DVPortgroupConfigInfo{
|
||||
@@ -64,15 +84,58 @@ func (s *DistributedVirtualSwitch) AddDVPortgroupTask(c *types.AddDVPortgroup_Ta
|
||||
ConfigVersion: spec.ConfigVersion,
|
||||
AutoExpand: spec.AutoExpand,
|
||||
VmVnicNetworkResourcePoolKey: spec.VmVnicNetworkResourcePoolKey,
|
||||
LogicalSwitchUuid: spec.LogicalSwitchUuid,
|
||||
SegmentId: spec.SegmentId,
|
||||
BackingType: spec.BackingType,
|
||||
}
|
||||
|
||||
if pg.Config.LogicalSwitchUuid != "" {
|
||||
if pg.Config.BackingType == "" {
|
||||
pg.Config.BackingType = "nsx"
|
||||
}
|
||||
}
|
||||
|
||||
if pg.Config.DefaultPortConfig == nil {
|
||||
pg.Config.DefaultPortConfig = &types.VMwareDVSPortSetting{
|
||||
Vlan: new(types.VmwareDistributedVirtualSwitchVlanIdSpec),
|
||||
UplinkTeamingPolicy: &types.VmwareUplinkPortTeamingPolicy{
|
||||
Policy: &types.StringPolicy{
|
||||
Value: "loadbalance_srcid",
|
||||
},
|
||||
ReversePolicy: &types.BoolPolicy{
|
||||
Value: types.NewBool(true),
|
||||
},
|
||||
NotifySwitches: &types.BoolPolicy{
|
||||
Value: types.NewBool(true),
|
||||
},
|
||||
RollingOrder: &types.BoolPolicy{
|
||||
Value: types.NewBool(true),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pg.PortKeys = []string{}
|
||||
if pg.Config.Policy == nil {
|
||||
pg.Config.Policy = &types.VMwareDVSPortgroupPolicy{
|
||||
DVPortgroupPolicy: types.DVPortgroupPolicy{
|
||||
BlockOverrideAllowed: true,
|
||||
ShapingOverrideAllowed: false,
|
||||
VendorConfigOverrideAllowed: false,
|
||||
LivePortMovingAllowed: false,
|
||||
PortConfigResetAtDisconnect: true,
|
||||
NetworkResourcePoolOverrideAllowed: types.NewBool(false),
|
||||
TrafficFilterOverrideAllowed: types.NewBool(false),
|
||||
},
|
||||
VlanOverrideAllowed: false,
|
||||
UplinkTeamingOverrideAllowed: false,
|
||||
SecurityPolicyOverrideAllowed: false,
|
||||
IpfixOverrideAllowed: types.NewBool(false),
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < int(spec.NumPorts); i++ {
|
||||
pg.PortKeys = append(pg.PortKeys, strconv.Itoa(i))
|
||||
}
|
||||
|
||||
portgroups = append(portgroups, pg.Self)
|
||||
portgroupNames = append(portgroupNames, pg.Name)
|
||||
@@ -80,18 +143,18 @@ func (s *DistributedVirtualSwitch) AddDVPortgroupTask(c *types.AddDVPortgroup_Ta
|
||||
for _, h := range s.Summary.HostMember {
|
||||
pg.Host = append(pg.Host, h)
|
||||
|
||||
host := Map.Get(h).(*HostSystem)
|
||||
Map.AppendReference(host, &host.Network, pg.Reference())
|
||||
host := ctx.Map.Get(h).(*HostSystem)
|
||||
ctx.Map.AppendReference(ctx, host, &host.Network, pg.Reference())
|
||||
|
||||
parent := Map.Get(*host.HostSystem.Parent)
|
||||
parent := ctx.Map.Get(*host.HostSystem.Parent)
|
||||
computeNetworks := append(hostParent(&host.HostSystem).Network, pg.Reference())
|
||||
Map.Update(parent, []types.PropertyChange{
|
||||
ctx.Map.Update(parent, []types.PropertyChange{
|
||||
{Name: "network", Val: computeNetworks},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Map.Update(s, []types.PropertyChange{
|
||||
ctx.Map.Update(s, []types.PropertyChange{
|
||||
{Name: "portgroup", Val: portgroups},
|
||||
{Name: "summary.portgroupName", Val: portgroupNames},
|
||||
})
|
||||
@@ -101,19 +164,19 @@ func (s *DistributedVirtualSwitch) AddDVPortgroupTask(c *types.AddDVPortgroup_Ta
|
||||
|
||||
return &methods.AddDVPortgroup_TaskBody{
|
||||
Res: &types.AddDVPortgroup_TaskResponse{
|
||||
Returnval: task.Run(),
|
||||
Returnval: task.Run(ctx),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DistributedVirtualSwitch) ReconfigureDvsTask(req *types.ReconfigureDvs_Task) soap.HasFault {
|
||||
func (s *DistributedVirtualSwitch) ReconfigureDvsTask(ctx *Context, req *types.ReconfigureDvs_Task) soap.HasFault {
|
||||
task := CreateTask(s, "reconfigureDvs", func(t *Task) (types.AnyType, types.BaseMethodFault) {
|
||||
spec := req.Spec.GetDVSConfigSpec()
|
||||
|
||||
members := s.Summary.HostMember
|
||||
|
||||
for _, member := range spec.Host {
|
||||
h := Map.Get(member.Host)
|
||||
h := ctx.Map.Get(member.Host)
|
||||
if h == nil {
|
||||
return nil, &types.ManagedObjectNotFound{Obj: member.Host}
|
||||
}
|
||||
@@ -127,29 +190,34 @@ func (s *DistributedVirtualSwitch) ReconfigureDvsTask(req *types.ReconfigureDvs_
|
||||
}
|
||||
|
||||
hostNetworks := append(host.Network, s.Portgroup...)
|
||||
Map.Update(host, []types.PropertyChange{
|
||||
ctx.Map.Update(host, []types.PropertyChange{
|
||||
{Name: "network", Val: hostNetworks},
|
||||
})
|
||||
members = append(members, member.Host)
|
||||
parent := Map.Get(*host.HostSystem.Parent)
|
||||
parent := ctx.Map.Get(*host.HostSystem.Parent)
|
||||
|
||||
var pgs []types.ManagedObjectReference
|
||||
for _, ref := range s.Portgroup {
|
||||
pg := Map.Get(ref).(*DistributedVirtualPortgroup)
|
||||
pg := ctx.Map.Get(ref).(*DistributedVirtualPortgroup)
|
||||
pgs = append(pgs, ref)
|
||||
|
||||
pgHosts := append(pg.Host, member.Host)
|
||||
Map.Update(pg, []types.PropertyChange{
|
||||
ctx.Map.Update(pg, []types.PropertyChange{
|
||||
{Name: "host", Val: pgHosts},
|
||||
})
|
||||
|
||||
cr := hostParent(&host.HostSystem)
|
||||
if FindReference(cr.Network, ref) == nil {
|
||||
computeNetworks := append(cr.Network, ref)
|
||||
ctx.Map.Update(parent, []types.PropertyChange{
|
||||
{Name: "network", Val: computeNetworks},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Map.Update(parent, []types.PropertyChange{
|
||||
{Name: "network", Val: pgs},
|
||||
})
|
||||
case types.ConfigSpecOperationRemove:
|
||||
for _, ref := range host.Vm {
|
||||
vm := Map.Get(ref).(*VirtualMachine)
|
||||
vm := ctx.Map.Get(ref).(*VirtualMachine)
|
||||
if pg := FindReference(vm.Network, s.Portgroup...); pg != nil {
|
||||
return nil, &types.ResourceInUse{
|
||||
Type: pg.Type,
|
||||
@@ -164,7 +232,7 @@ func (s *DistributedVirtualSwitch) ReconfigureDvsTask(req *types.ReconfigureDvs_
|
||||
}
|
||||
}
|
||||
|
||||
Map.Update(s, []types.PropertyChange{
|
||||
ctx.Map.Update(s, []types.PropertyChange{
|
||||
{Name: "summary.hostMember", Val: members},
|
||||
})
|
||||
|
||||
@@ -173,7 +241,7 @@ func (s *DistributedVirtualSwitch) ReconfigureDvsTask(req *types.ReconfigureDvs_
|
||||
|
||||
return &methods.ReconfigureDvs_TaskBody{
|
||||
Res: &types.ReconfigureDvs_TaskResponse{
|
||||
Returnval: task.Run(),
|
||||
Returnval: task.Run(ctx),
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -186,42 +254,142 @@ func (s *DistributedVirtualSwitch) FetchDVPorts(req *types.FetchDVPorts) soap.Ha
|
||||
return body
|
||||
}
|
||||
|
||||
func (s *DistributedVirtualSwitch) DestroyTask(req *types.Destroy_Task) soap.HasFault {
|
||||
func (s *DistributedVirtualSwitch) DestroyTask(ctx *Context, 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())
|
||||
f := ctx.Map.getEntityParent(s, "Folder").(*Folder)
|
||||
folderRemoveChild(ctx, &f.Folder, s.Reference())
|
||||
return nil, nil
|
||||
})
|
||||
|
||||
return &methods.Destroy_TaskBody{
|
||||
Res: &types.Destroy_TaskResponse{
|
||||
Returnval: task.Run(),
|
||||
Returnval: task.Run(ctx),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DistributedVirtualSwitch) dvPortgroups(_ *types.DistributedVirtualSwitchPortCriteria) []types.DistributedVirtualPort {
|
||||
// TODO(agui): Filter is not implemented yet
|
||||
var res []types.DistributedVirtualPort
|
||||
func (s *DistributedVirtualSwitch) dvPortgroups(criteria *types.DistributedVirtualSwitchPortCriteria) []types.DistributedVirtualPort {
|
||||
res := s.FetchDVPortsResponse.Returnval
|
||||
if len(res) != 0 {
|
||||
return res
|
||||
}
|
||||
|
||||
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,
|
||||
},
|
||||
})
|
||||
|
||||
for _, key := range pg.PortKeys {
|
||||
res = append(res, types.DistributedVirtualPort{
|
||||
DvsUuid: s.Uuid,
|
||||
Key: key,
|
||||
DvsUuid: s.Uuid,
|
||||
Key: key,
|
||||
PortgroupKey: pg.Key,
|
||||
Config: types.DVPortConfigInfo{
|
||||
Setting: pg.Config.DefaultPortConfig,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// filter ports by criteria
|
||||
res = s.filterDVPorts(res, criteria)
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func (s *DistributedVirtualSwitch) filterDVPorts(
|
||||
ports []types.DistributedVirtualPort,
|
||||
criteria *types.DistributedVirtualSwitchPortCriteria,
|
||||
) []types.DistributedVirtualPort {
|
||||
if criteria == nil {
|
||||
return ports
|
||||
}
|
||||
|
||||
ports = s.filterDVPortsByPortgroupKey(ports, criteria)
|
||||
ports = s.filterDVPortsByPortKey(ports, criteria)
|
||||
ports = s.filterDVPortsByConnected(ports, criteria)
|
||||
|
||||
return ports
|
||||
}
|
||||
|
||||
func (s *DistributedVirtualSwitch) filterDVPortsByPortgroupKey(
|
||||
ports []types.DistributedVirtualPort,
|
||||
criteria *types.DistributedVirtualSwitchPortCriteria,
|
||||
) []types.DistributedVirtualPort {
|
||||
if len(criteria.PortgroupKey) == 0 || criteria.Inside == nil {
|
||||
return ports
|
||||
}
|
||||
|
||||
// inside portgroup keys
|
||||
if *criteria.Inside {
|
||||
filtered := []types.DistributedVirtualPort{}
|
||||
|
||||
for _, p := range ports {
|
||||
for _, pgk := range criteria.PortgroupKey {
|
||||
if p.PortgroupKey == pgk {
|
||||
filtered = append(filtered, p)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return filtered
|
||||
}
|
||||
|
||||
// outside portgroup keys
|
||||
filtered := []types.DistributedVirtualPort{}
|
||||
|
||||
for _, p := range ports {
|
||||
found := false
|
||||
for _, pgk := range criteria.PortgroupKey {
|
||||
if p.PortgroupKey == pgk {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
filtered = append(filtered, p)
|
||||
}
|
||||
}
|
||||
return filtered
|
||||
}
|
||||
|
||||
func (s *DistributedVirtualSwitch) filterDVPortsByPortKey(
|
||||
ports []types.DistributedVirtualPort,
|
||||
criteria *types.DistributedVirtualSwitchPortCriteria,
|
||||
) []types.DistributedVirtualPort {
|
||||
if len(criteria.PortKey) == 0 {
|
||||
return ports
|
||||
}
|
||||
|
||||
filtered := []types.DistributedVirtualPort{}
|
||||
|
||||
for _, p := range ports {
|
||||
for _, pk := range criteria.PortKey {
|
||||
if p.Key == pk {
|
||||
filtered = append(filtered, p)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return filtered
|
||||
}
|
||||
|
||||
func (s *DistributedVirtualSwitch) filterDVPortsByConnected(
|
||||
ports []types.DistributedVirtualPort,
|
||||
criteria *types.DistributedVirtualSwitchPortCriteria,
|
||||
) []types.DistributedVirtualPort {
|
||||
if criteria.Connected == nil {
|
||||
return ports
|
||||
}
|
||||
|
||||
filtered := []types.DistributedVirtualPort{}
|
||||
|
||||
for _, p := range ports {
|
||||
connected := p.Connectee != nil
|
||||
if connected == *criteria.Connected {
|
||||
filtered = append(filtered, p)
|
||||
}
|
||||
}
|
||||
|
||||
return filtered
|
||||
}
|
||||
|
51
vendor/github.com/vmware/govmomi/simulator/dvs_manager.go
generated
vendored
Normal file
51
vendor/github.com/vmware/govmomi/simulator/dvs_manager.go
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
Copyright (c) 2020 VMware, Inc. All 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 DistributedVirtualSwitchManager struct {
|
||||
mo.DistributedVirtualSwitchManager
|
||||
}
|
||||
|
||||
func (m *DistributedVirtualSwitchManager) DVSManagerLookupDvPortGroup(ctx *Context, req *types.DVSManagerLookupDvPortGroup) soap.HasFault {
|
||||
body := &methods.DVSManagerLookupDvPortGroupBody{}
|
||||
|
||||
for _, obj := range ctx.Map.All("DistributedVirtualSwitch") {
|
||||
dvs := obj.(*DistributedVirtualSwitch)
|
||||
if dvs.Uuid == req.SwitchUuid {
|
||||
for _, ref := range dvs.Portgroup {
|
||||
pg := ctx.Map.Get(ref).(*DistributedVirtualPortgroup)
|
||||
if pg.Key == req.PortgroupKey {
|
||||
body.Res = &types.DVSManagerLookupDvPortGroupResponse{
|
||||
Returnval: &ref,
|
||||
}
|
||||
return body
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
body.Fault_ = Fault("", new(types.NotFound))
|
||||
|
||||
return body
|
||||
}
|
13
vendor/github.com/vmware/govmomi/simulator/entity.go
generated
vendored
13
vendor/github.com/vmware/govmomi/simulator/entity.go
generated
vendored
@@ -23,24 +23,25 @@ import (
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
func RenameTask(e mo.Entity, r *types.Rename_Task) soap.HasFault {
|
||||
func RenameTask(ctx *Context, e mo.Entity, r *types.Rename_Task, dup ...bool) soap.HasFault {
|
||||
task := CreateTask(e, "rename", func(t *Task) (types.AnyType, types.BaseMethodFault) {
|
||||
obj := Map.Get(r.This).(mo.Entity).Entity()
|
||||
obj := ctx.Map.Get(r.This).(mo.Entity).Entity()
|
||||
|
||||
if parent, ok := Map.Get(*obj.Parent).(*Folder); ok {
|
||||
if Map.FindByName(r.NewName, parent.ChildEntity) != nil {
|
||||
canDup := len(dup) == 1 && dup[0]
|
||||
if parent, ok := asFolderMO(ctx.Map.Get(*obj.Parent)); ok && !canDup {
|
||||
if ctx.Map.FindByName(r.NewName, parent.ChildEntity) != nil {
|
||||
return nil, &types.InvalidArgument{InvalidProperty: "name"}
|
||||
}
|
||||
}
|
||||
|
||||
Map.Update(e, []types.PropertyChange{{Name: "name", Val: r.NewName}})
|
||||
ctx.Map.Update(e, []types.PropertyChange{{Name: "name", Val: r.NewName}})
|
||||
|
||||
return nil, nil
|
||||
})
|
||||
|
||||
return &methods.Rename_TaskBody{
|
||||
Res: &types.Rename_TaskResponse{
|
||||
Returnval: task.Run(),
|
||||
Returnval: task.Run(ctx),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
182
vendor/github.com/vmware/govmomi/simulator/environment_browser.go
generated
vendored
182
vendor/github.com/vmware/govmomi/simulator/environment_browser.go
generated
vendored
@@ -17,6 +17,8 @@ limitations under the License.
|
||||
package simulator
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/vmware/govmomi/simulator/esx"
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
@@ -26,6 +28,8 @@ import (
|
||||
|
||||
type EnvironmentBrowser struct {
|
||||
mo.EnvironmentBrowser
|
||||
|
||||
types.QueryConfigOptionResponse
|
||||
}
|
||||
|
||||
func newEnvironmentBrowser() *types.ManagedObjectReference {
|
||||
@@ -34,12 +38,33 @@ func newEnvironmentBrowser() *types.ManagedObjectReference {
|
||||
return &env.Self
|
||||
}
|
||||
|
||||
func (b *EnvironmentBrowser) hosts(ctx *Context) []types.ManagedObjectReference {
|
||||
ctx.Map.m.Lock()
|
||||
defer ctx.Map.m.Unlock()
|
||||
for _, obj := range ctx.Map.objects {
|
||||
switch e := obj.(type) {
|
||||
case *mo.ComputeResource:
|
||||
if b.Self == *e.EnvironmentBrowser {
|
||||
return e.Host
|
||||
}
|
||||
case *ClusterComputeResource:
|
||||
if b.Self == *e.EnvironmentBrowser {
|
||||
return e.Host
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *EnvironmentBrowser) QueryConfigOption(req *types.QueryConfigOption) soap.HasFault {
|
||||
body := new(methods.QueryConfigOptionBody)
|
||||
|
||||
opt := &types.VirtualMachineConfigOption{
|
||||
Version: esx.HardwareVersion,
|
||||
DefaultDevice: esx.VirtualDevice,
|
||||
opt := b.QueryConfigOptionResponse.Returnval
|
||||
if opt == nil {
|
||||
opt = &types.VirtualMachineConfigOption{
|
||||
Version: esx.HardwareVersion,
|
||||
DefaultDevice: esx.VirtualDevice,
|
||||
}
|
||||
}
|
||||
|
||||
body.Res = &types.QueryConfigOptionResponse{
|
||||
@@ -49,12 +74,56 @@ func (b *EnvironmentBrowser) QueryConfigOption(req *types.QueryConfigOption) soa
|
||||
return body
|
||||
}
|
||||
|
||||
func guestFamily(id string) string {
|
||||
// TODO: We could capture the entire GuestOsDescriptor list from EnvironmentBrowser,
|
||||
// but it is a ton of data.. this should be good enough for now.
|
||||
switch {
|
||||
case strings.HasPrefix(id, "win"):
|
||||
return string(types.VirtualMachineGuestOsFamilyWindowsGuest)
|
||||
case strings.HasPrefix(id, "darwin"):
|
||||
return string(types.VirtualMachineGuestOsFamilyDarwinGuestFamily)
|
||||
default:
|
||||
return string(types.VirtualMachineGuestOsFamilyLinuxGuest)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *EnvironmentBrowser) QueryConfigOptionEx(req *types.QueryConfigOptionEx) soap.HasFault {
|
||||
body := new(methods.QueryConfigOptionExBody)
|
||||
|
||||
opt := &types.VirtualMachineConfigOption{
|
||||
Version: esx.HardwareVersion,
|
||||
DefaultDevice: esx.VirtualDevice,
|
||||
opt := b.QueryConfigOptionResponse.Returnval
|
||||
if opt == nil {
|
||||
opt = &types.VirtualMachineConfigOption{
|
||||
Version: esx.HardwareVersion,
|
||||
DefaultDevice: esx.VirtualDevice,
|
||||
}
|
||||
}
|
||||
|
||||
if req.Spec != nil {
|
||||
// From the SDK QueryConfigOptionEx doc:
|
||||
// "If guestId is nonempty, the guestOSDescriptor array of the config option is filtered to match against the guest IDs in the spec.
|
||||
// If there is no match, the whole list is returned."
|
||||
for _, id := range req.Spec.GuestId {
|
||||
for _, gid := range GuestID {
|
||||
if string(gid) == id {
|
||||
opt.GuestOSDescriptor = []types.GuestOsDescriptor{{
|
||||
Id: id,
|
||||
Family: guestFamily(id),
|
||||
}}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(opt.GuestOSDescriptor) == 0 {
|
||||
for i := range GuestID {
|
||||
id := string(GuestID[i])
|
||||
opt.GuestOSDescriptor = append(opt.GuestOSDescriptor, types.GuestOsDescriptor{
|
||||
Id: id,
|
||||
Family: guestFamily(id),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
body.Res = &types.QueryConfigOptionExResponse{
|
||||
@@ -63,3 +132,104 @@ func (b *EnvironmentBrowser) QueryConfigOptionEx(req *types.QueryConfigOptionEx)
|
||||
|
||||
return body
|
||||
}
|
||||
|
||||
func (b *EnvironmentBrowser) QueryConfigOptionDescriptor(ctx *Context, req *types.QueryConfigOptionDescriptor) soap.HasFault {
|
||||
body := &methods.QueryConfigOptionDescriptorBody{
|
||||
Res: new(types.QueryConfigOptionDescriptorResponse),
|
||||
}
|
||||
|
||||
body.Res.Returnval = []types.VirtualMachineConfigOptionDescriptor{{
|
||||
Key: esx.HardwareVersion,
|
||||
Description: esx.HardwareVersion,
|
||||
Host: b.hosts(ctx),
|
||||
CreateSupported: types.NewBool(true),
|
||||
DefaultConfigOption: types.NewBool(false),
|
||||
RunSupported: types.NewBool(true),
|
||||
UpgradeSupported: types.NewBool(true),
|
||||
}}
|
||||
|
||||
return body
|
||||
}
|
||||
|
||||
func (b *EnvironmentBrowser) QueryConfigTarget(ctx *Context, req *types.QueryConfigTarget) soap.HasFault {
|
||||
body := &methods.QueryConfigTargetBody{
|
||||
Res: &types.QueryConfigTargetResponse{
|
||||
Returnval: &types.ConfigTarget{
|
||||
SmcPresent: types.NewBool(false),
|
||||
},
|
||||
},
|
||||
}
|
||||
target := body.Res.Returnval
|
||||
|
||||
var hosts []types.ManagedObjectReference
|
||||
if req.Host == nil {
|
||||
hosts = b.hosts(ctx)
|
||||
} else {
|
||||
hosts = append(hosts, *req.Host)
|
||||
}
|
||||
|
||||
seen := make(map[types.ManagedObjectReference]bool)
|
||||
|
||||
for i := range hosts {
|
||||
host := ctx.Map.Get(hosts[i]).(*HostSystem)
|
||||
target.NumCpus += int32(host.Summary.Hardware.NumCpuPkgs)
|
||||
target.NumCpuCores += int32(host.Summary.Hardware.NumCpuCores)
|
||||
target.NumNumaNodes++
|
||||
|
||||
for _, ref := range host.Datastore {
|
||||
if seen[ref] {
|
||||
continue
|
||||
}
|
||||
seen[ref] = true
|
||||
|
||||
ds := ctx.Map.Get(ref).(*Datastore)
|
||||
target.Datastore = append(target.Datastore, types.VirtualMachineDatastoreInfo{
|
||||
VirtualMachineTargetInfo: types.VirtualMachineTargetInfo{
|
||||
Name: ds.Name,
|
||||
},
|
||||
Datastore: ds.Summary,
|
||||
Capability: ds.Capability,
|
||||
Mode: string(types.HostMountModeReadWrite),
|
||||
VStorageSupport: string(types.FileSystemMountInfoVStorageSupportStatusVStorageUnsupported),
|
||||
})
|
||||
}
|
||||
|
||||
for _, ref := range host.Network {
|
||||
if seen[ref] {
|
||||
continue
|
||||
}
|
||||
seen[ref] = true
|
||||
|
||||
switch n := ctx.Map.Get(ref).(type) {
|
||||
case *mo.Network:
|
||||
target.Network = append(target.Network, types.VirtualMachineNetworkInfo{
|
||||
VirtualMachineTargetInfo: types.VirtualMachineTargetInfo{
|
||||
Name: n.Name,
|
||||
},
|
||||
Network: n.Summary.GetNetworkSummary(),
|
||||
})
|
||||
case *DistributedVirtualPortgroup:
|
||||
dvs := ctx.Map.Get(*n.Config.DistributedVirtualSwitch).(*DistributedVirtualSwitch)
|
||||
target.DistributedVirtualPortgroup = append(target.DistributedVirtualPortgroup, types.DistributedVirtualPortgroupInfo{
|
||||
SwitchName: dvs.Name,
|
||||
SwitchUuid: dvs.Uuid,
|
||||
PortgroupName: n.Name,
|
||||
PortgroupKey: n.Key,
|
||||
PortgroupType: n.Config.Type,
|
||||
UplinkPortgroup: false,
|
||||
Portgroup: n.Self,
|
||||
NetworkReservationSupported: types.NewBool(false),
|
||||
})
|
||||
case *DistributedVirtualSwitch:
|
||||
target.DistributedVirtualSwitch = append(target.DistributedVirtualSwitch, types.DistributedVirtualSwitchInfo{
|
||||
SwitchName: n.Name,
|
||||
SwitchUuid: n.Uuid,
|
||||
DistributedVirtualSwitch: n.Self,
|
||||
NetworkReservationSupported: types.NewBool(false),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return body
|
||||
}
|
||||
|
2
vendor/github.com/vmware/govmomi/simulator/esx/authorization_manager.go
generated
vendored
2
vendor/github.com/vmware/govmomi/simulator/esx/authorization_manager.go
generated
vendored
File diff suppressed because one or more lines are too long
20
vendor/github.com/vmware/govmomi/simulator/esx/event_manager.go
generated
vendored
20
vendor/github.com/vmware/govmomi/simulator/esx/event_manager.go
generated
vendored
@@ -93,7 +93,7 @@ var EventInfo = []types.EventDescriptionEventDetail{
|
||||
Key: "VmMigratedEvent",
|
||||
Description: "VM migrated",
|
||||
Category: "info",
|
||||
FullFormat: "Migration of virtual machine {{.Vm.Name}} from {{.SourceHost.Name}, {{.SourceDatastore.Name}} to {{.Host.Name}, {{.Ds.Name}} completed",
|
||||
FullFormat: "Migration of virtual machine {{.Vm.Name}} from {{.SourceHost.Name}}, {{.SourceDatastore.Name}} to {{.Host.Name}}, {{.Ds.Name}} completed",
|
||||
},
|
||||
{
|
||||
Key: "VmBeingMigratedEvent",
|
||||
@@ -233,6 +233,24 @@ var EventInfo = []types.EventDescriptionEventDetail{
|
||||
Category: "info",
|
||||
FullFormat: "Completed the relocation of the virtual machine",
|
||||
},
|
||||
{
|
||||
Key: "CustomizationFailed",
|
||||
Description: "An error occurred during customization",
|
||||
Category: "info",
|
||||
FullFormat: "An error occurred during customization on VM {{.Vm.Name}}",
|
||||
},
|
||||
{
|
||||
Key: "CustomizationStartedEvent",
|
||||
Description: "Started customization",
|
||||
Category: "info",
|
||||
FullFormat: "Started customization of VM {{.Vm.Name}}",
|
||||
},
|
||||
{
|
||||
Key: "CustomizationSucceeded",
|
||||
Description: "Customization succeeded",
|
||||
Category: "info",
|
||||
FullFormat: "Customization of VM {{.Vm.Name}} succeeded",
|
||||
},
|
||||
{
|
||||
Key: "DrsVmMigratedEvent",
|
||||
Description: "DRS VM migrated",
|
||||
|
24
vendor/github.com/vmware/govmomi/simulator/esx/host_config_info.go
generated
vendored
24
vendor/github.com/vmware/govmomi/simulator/esx/host_config_info.go
generated
vendored
@@ -544,6 +544,30 @@ var HostConfigInfo = types.HostConfigInfo{
|
||||
NicType: "management",
|
||||
MultiSelectAllowed: true,
|
||||
CandidateVnic: []types.HostVirtualNic{
|
||||
{
|
||||
Device: "vmk1",
|
||||
Key: "management.key-vim.host.VirtualNic-vmk1",
|
||||
Portgroup: "",
|
||||
Spec: types.HostVirtualNicSpec{
|
||||
Ip: &types.HostIpConfig{
|
||||
Dhcp: true,
|
||||
IpAddress: "192.168.0.1",
|
||||
SubnetMask: "255.0.0.0",
|
||||
IpV6Config: (*types.HostIpConfigIpV6AddressConfiguration)(nil),
|
||||
},
|
||||
Mac: "00:0c:29:81:d8:00",
|
||||
DistributedVirtualPort: (*types.DistributedVirtualSwitchPortConnection)(nil),
|
||||
Portgroup: "Management Network",
|
||||
Mtu: 1500,
|
||||
TsoEnabled: types.NewBool(true),
|
||||
NetStackInstanceKey: "defaultTcpipStack",
|
||||
OpaqueNetwork: (*types.HostVirtualNicOpaqueNetworkSpec)(nil),
|
||||
ExternalId: "",
|
||||
PinnedPnic: "",
|
||||
IpRouteSpec: (*types.HostVirtualNicIpRouteSpec)(nil),
|
||||
},
|
||||
Port: "",
|
||||
},
|
||||
{
|
||||
Device: "vmk0",
|
||||
Key: "management.key-vim.host.VirtualNic-vmk0",
|
||||
|
16
vendor/github.com/vmware/govmomi/simulator/esx/host_system.go
generated
vendored
16
vendor/github.com/vmware/govmomi/simulator/esx/host_system.go
generated
vendored
@@ -1740,9 +1740,19 @@ var HostSystem = mo.HostSystem{
|
||||
CurrentEVCModeKey: "",
|
||||
Gateway: (*types.HostListSummaryGatewaySummary)(nil),
|
||||
},
|
||||
Hardware: (*types.HostHardwareInfo)(nil),
|
||||
Capability: (*types.HostCapability)(nil),
|
||||
LicensableResource: types.HostLicensableResourceInfo{},
|
||||
Hardware: (*types.HostHardwareInfo)(nil),
|
||||
Capability: (*types.HostCapability)(nil),
|
||||
LicensableResource: types.HostLicensableResourceInfo{
|
||||
Resource: []types.KeyAnyValue{
|
||||
{
|
||||
Key: "numCpuPackages",
|
||||
Value: types.KeyValue{
|
||||
Key: "numCpuPackages",
|
||||
Value: "2",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
ConfigManager: types.HostConfigManager{
|
||||
DynamicData: types.DynamicData{},
|
||||
CpuScheduler: &types.ManagedObjectReference{Type: "HostCpuSchedulerSystem", Value: "cpuSchedulerSystem"},
|
||||
|
4
vendor/github.com/vmware/govmomi/simulator/esx/task_manager.go
generated
vendored
4
vendor/github.com/vmware/govmomi/simulator/esx/task_manager.go
generated
vendored
@@ -9735,7 +9735,7 @@ var Description = types.TaskDescription{
|
||||
&types.ElementDescription{
|
||||
Description: types.Description{
|
||||
Label: "Retrieve Managed Method Executer",
|
||||
Summary: "Retrieves a referemce to Managed Method Executer",
|
||||
Summary: "Retrieves a reference to Managed Method Executer",
|
||||
},
|
||||
Key: "HostSystem.retrieveManagedMethodExecuter",
|
||||
},
|
||||
@@ -9819,7 +9819,7 @@ var Description = types.TaskDescription{
|
||||
&types.ElementDescription{
|
||||
Description: types.Description{
|
||||
Label: "Query feature capabilities for vSphere Distributed Switch specification",
|
||||
Summary: "Queries feature capabilites available for a given vSphere Distributed Switch specification",
|
||||
Summary: "Queries feature capabilities available for a given vSphere Distributed Switch specification",
|
||||
},
|
||||
Key: "dvs.DistributedVirtualSwitchManager.queryFeatureCapability",
|
||||
},
|
||||
|
218
vendor/github.com/vmware/govmomi/simulator/event_manager.go
generated
vendored
218
vendor/github.com/vmware/govmomi/simulator/event_manager.go
generated
vendored
@@ -18,13 +18,12 @@ package simulator
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"container/ring"
|
||||
"container/list"
|
||||
"log"
|
||||
"reflect"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/simulator/esx"
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
@@ -40,27 +39,26 @@ var (
|
||||
type EventManager struct {
|
||||
mo.EventManager
|
||||
|
||||
root types.ManagedObjectReference
|
||||
page *ring.Ring
|
||||
key int32
|
||||
root types.ManagedObjectReference
|
||||
|
||||
history *list.List
|
||||
key int32
|
||||
|
||||
collectors map[types.ManagedObjectReference]*EventHistoryCollector
|
||||
templates map[string]*template.Template
|
||||
}
|
||||
|
||||
func NewEventManager(ref types.ManagedObjectReference) object.Reference {
|
||||
return &EventManager{
|
||||
EventManager: mo.EventManager{
|
||||
Self: ref,
|
||||
Description: types.EventDescription{
|
||||
EventInfo: esx.EventInfo,
|
||||
},
|
||||
MaxCollector: 1000,
|
||||
},
|
||||
root: Map.content().RootFolder,
|
||||
page: ring.New(maxPageSize),
|
||||
collectors: make(map[types.ManagedObjectReference]*EventHistoryCollector),
|
||||
templates: make(map[string]*template.Template),
|
||||
func (m *EventManager) init(r *Registry) {
|
||||
if len(m.Description.EventInfo) == 0 {
|
||||
m.Description.EventInfo = esx.EventInfo
|
||||
}
|
||||
if m.MaxCollector == 0 {
|
||||
m.MaxCollector = 1000
|
||||
}
|
||||
m.root = r.content().RootFolder
|
||||
m.history = list.New()
|
||||
m.collectors = make(map[types.ManagedObjectReference]*EventHistoryCollector)
|
||||
m.templates = make(map[string]*template.Template)
|
||||
}
|
||||
|
||||
func (m *EventManager) createCollector(ctx *Context, req *types.CreateCollectorForEvents) (*EventHistoryCollector, *soap.Fault) {
|
||||
@@ -75,10 +73,11 @@ func (m *EventManager) createCollector(ctx *Context, req *types.CreateCollectorF
|
||||
|
||||
collector := &EventHistoryCollector{
|
||||
m: m,
|
||||
page: ring.New(size),
|
||||
page: list.New(),
|
||||
size: size,
|
||||
}
|
||||
collector.Filter = req.Filter
|
||||
collector.fillPage(size)
|
||||
collector.fillPage()
|
||||
|
||||
return collector, nil
|
||||
}
|
||||
@@ -151,6 +150,13 @@ func (m *EventManager) formatMessage(event types.BaseEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
func pushEvent(l *list.List, event types.BaseEvent) {
|
||||
if l.Len() > maxPageSize*5 {
|
||||
l.Remove(l.Front()) // Prune history
|
||||
}
|
||||
l.PushBack(event)
|
||||
}
|
||||
|
||||
func (m *EventManager) PostEvent(ctx *Context, req *types.PostEvent) soap.HasFault {
|
||||
m.key++
|
||||
event := req.EventToPost.GetEvent()
|
||||
@@ -159,15 +165,14 @@ func (m *EventManager) PostEvent(ctx *Context, req *types.PostEvent) soap.HasFau
|
||||
event.CreatedTime = time.Now()
|
||||
event.UserName = ctx.Session.UserName
|
||||
|
||||
m.page = m.page.Prev()
|
||||
m.page.Value = req.EventToPost
|
||||
m.formatMessage(req.EventToPost)
|
||||
|
||||
pushEvent(m.history, req.EventToPost)
|
||||
|
||||
for _, c := range m.collectors {
|
||||
ctx.WithLock(c, func() {
|
||||
if c.eventMatches(req.EventToPost) {
|
||||
c.page = c.page.Prev()
|
||||
c.page.Value = req.EventToPost
|
||||
pushEvent(c.page, req.EventToPost)
|
||||
Map.Update(c, []types.PropertyChange{{Name: "latestPage", Val: c.GetLatestPage()}})
|
||||
}
|
||||
})
|
||||
@@ -182,8 +187,9 @@ type EventHistoryCollector struct {
|
||||
mo.EventHistoryCollector
|
||||
|
||||
m *EventManager
|
||||
page *ring.Ring
|
||||
pos int
|
||||
size int
|
||||
page *list.List
|
||||
pos *list.Element
|
||||
}
|
||||
|
||||
// doEntityEventArgument calls f for each entity argument in the event.
|
||||
@@ -316,54 +322,55 @@ func (c *EventHistoryCollector) typeMatches(event types.BaseEvent, spec *types.E
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *EventHistoryCollector) timeMatches(event types.BaseEvent, spec *types.EventFilterSpec) bool {
|
||||
if spec.Time == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
created := event.GetEvent().CreatedTime
|
||||
|
||||
if begin := spec.Time.BeginTime; begin != nil {
|
||||
if created.Before(*begin) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if end := spec.Time.EndTime; end != nil {
|
||||
if created.After(*end) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// eventMatches returns true one of the filters matches the event.
|
||||
func (c *EventHistoryCollector) eventMatches(event types.BaseEvent) bool {
|
||||
spec := c.Filter.(types.EventFilterSpec)
|
||||
|
||||
if !c.typeMatches(event, &spec) {
|
||||
return false
|
||||
matchers := []func(types.BaseEvent, *types.EventFilterSpec) bool{
|
||||
c.typeMatches,
|
||||
c.timeMatches,
|
||||
c.entityMatches,
|
||||
// TODO: spec.UserName, etc
|
||||
}
|
||||
|
||||
// TODO: spec.Time, spec.UserName, etc
|
||||
for _, match := range matchers {
|
||||
if !match(event, &spec) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return c.entityMatches(event, &spec)
|
||||
return true
|
||||
}
|
||||
|
||||
// filePage copies the manager's latest events into the collector's page with Filter applied.
|
||||
func (c *EventHistoryCollector) fillPage(size int) {
|
||||
c.pos = 0
|
||||
l := c.page.Len()
|
||||
delta := size - l
|
||||
|
||||
if delta < 0 {
|
||||
// Shrink ring size
|
||||
c.page = c.page.Unlink(-delta)
|
||||
return
|
||||
}
|
||||
|
||||
matches := 0
|
||||
mpage := c.m.page
|
||||
page := c.page
|
||||
|
||||
if delta != 0 {
|
||||
// Grow ring size
|
||||
c.page = c.page.Link(ring.New(delta))
|
||||
}
|
||||
|
||||
for i := 0; i < maxPageSize; i++ {
|
||||
event, ok := mpage.Value.(types.BaseEvent)
|
||||
mpage = mpage.Prev()
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
// fillPage copies the manager's latest events into the collector's page with Filter applied.
|
||||
func (c *EventHistoryCollector) fillPage() {
|
||||
for e := c.m.history.Front(); e != nil; e = e.Next() {
|
||||
event := e.Value.(types.BaseEvent)
|
||||
|
||||
if c.eventMatches(event) {
|
||||
page.Value = event
|
||||
page = page.Prev()
|
||||
matches++
|
||||
if matches == size {
|
||||
break
|
||||
}
|
||||
c.page.PushBack(event)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -388,21 +395,47 @@ func (c *EventHistoryCollector) SetCollectorPageSize(ctx *Context, req *types.Se
|
||||
return body
|
||||
}
|
||||
|
||||
ctx.WithLock(c.m, func() {
|
||||
c.fillPage(size)
|
||||
})
|
||||
c.size = size
|
||||
c.page = list.New()
|
||||
ctx.WithLock(c.m, c.fillPage)
|
||||
|
||||
body.Res = new(types.SetCollectorPageSizeResponse)
|
||||
return body
|
||||
}
|
||||
|
||||
func (c *EventHistoryCollector) ResetCollector(ctx *Context, req *types.ResetCollector) soap.HasFault {
|
||||
c.pos = c.page.Back()
|
||||
|
||||
return &methods.ResetCollectorBody{
|
||||
Res: new(types.ResetCollectorResponse),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *EventHistoryCollector) RewindCollector(ctx *Context, req *types.RewindCollector) soap.HasFault {
|
||||
c.pos = 0
|
||||
c.pos = c.page.Front()
|
||||
|
||||
return &methods.RewindCollectorBody{
|
||||
Res: new(types.RewindCollectorResponse),
|
||||
}
|
||||
}
|
||||
|
||||
// readEvents returns the next max Events from the EventManager's history
|
||||
func (c *EventHistoryCollector) readEvents(ctx *Context, max int32, next func() *list.Element) []types.BaseEvent {
|
||||
var events []types.BaseEvent
|
||||
|
||||
for i := 0; i < int(max); i++ {
|
||||
e := next()
|
||||
if e == nil {
|
||||
break
|
||||
}
|
||||
|
||||
events = append(events, e.Value.(types.BaseEvent))
|
||||
c.pos = e
|
||||
}
|
||||
|
||||
return events
|
||||
}
|
||||
|
||||
func (c *EventHistoryCollector) ReadNextEvents(ctx *Context, req *types.ReadNextEvents) soap.HasFault {
|
||||
body := &methods.ReadNextEventsBody{}
|
||||
if req.MaxCount <= 0 {
|
||||
@@ -411,21 +444,14 @@ func (c *EventHistoryCollector) ReadNextEvents(ctx *Context, req *types.ReadNext
|
||||
}
|
||||
body.Res = new(types.ReadNextEventsResponse)
|
||||
|
||||
events := c.GetLatestPage()
|
||||
nevents := len(events)
|
||||
if c.pos == nevents {
|
||||
return body // already read to EOF
|
||||
next := func() *list.Element {
|
||||
if c.pos != nil {
|
||||
return c.pos.Next()
|
||||
}
|
||||
return c.page.Front()
|
||||
}
|
||||
|
||||
start := c.pos
|
||||
end := start + int(req.MaxCount)
|
||||
c.pos += int(req.MaxCount)
|
||||
if end > nevents {
|
||||
end = nevents
|
||||
c.pos = nevents
|
||||
}
|
||||
|
||||
body.Res.Returnval = events[start:end]
|
||||
body.Res.Returnval = c.readEvents(ctx, req.MaxCount, next)
|
||||
|
||||
return body
|
||||
}
|
||||
@@ -438,26 +464,20 @@ func (c *EventHistoryCollector) ReadPreviousEvents(ctx *Context, req *types.Read
|
||||
}
|
||||
body.Res = new(types.ReadPreviousEventsResponse)
|
||||
|
||||
events := c.GetLatestPage()
|
||||
if c.pos == 0 {
|
||||
return body // already read to EOF
|
||||
next := func() *list.Element {
|
||||
if c.pos != nil {
|
||||
return c.pos.Prev()
|
||||
}
|
||||
return c.page.Back()
|
||||
}
|
||||
|
||||
start := c.pos - int(req.MaxCount)
|
||||
end := c.pos
|
||||
c.pos -= int(req.MaxCount)
|
||||
if start < 0 {
|
||||
start = 0
|
||||
c.pos = 0
|
||||
}
|
||||
|
||||
body.Res.Returnval = events[start:end]
|
||||
body.Res.Returnval = c.readEvents(ctx, req.MaxCount, next)
|
||||
|
||||
return body
|
||||
}
|
||||
|
||||
func (c *EventHistoryCollector) DestroyCollector(ctx *Context, req *types.DestroyCollector) soap.HasFault {
|
||||
ctx.Session.Remove(req.This)
|
||||
ctx.Session.Remove(ctx, req.This)
|
||||
|
||||
ctx.WithLock(c.m, func() {
|
||||
delete(c.m.collectors, req.This)
|
||||
@@ -471,12 +491,14 @@ func (c *EventHistoryCollector) DestroyCollector(ctx *Context, req *types.Destro
|
||||
func (c *EventHistoryCollector) GetLatestPage() []types.BaseEvent {
|
||||
var latestPage []types.BaseEvent
|
||||
|
||||
c.page.Do(func(val interface{}) {
|
||||
if val == nil {
|
||||
return
|
||||
e := c.page.Back()
|
||||
for i := 0; i < c.size; i++ {
|
||||
if e == nil {
|
||||
break
|
||||
}
|
||||
latestPage = append(latestPage, val.(types.BaseEvent))
|
||||
})
|
||||
latestPage = append(latestPage, e.Value.(types.BaseEvent))
|
||||
e = e.Prev()
|
||||
}
|
||||
|
||||
return latestPage
|
||||
}
|
||||
|
50
vendor/github.com/vmware/govmomi/simulator/file_manager.go
generated
vendored
50
vendor/github.com/vmware/govmomi/simulator/file_manager.go
generated
vendored
@@ -20,8 +20,8 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/simulator/esx"
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
@@ -33,30 +33,30 @@ 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
|
||||
if d, ok := asFolderMO(ref); ok {
|
||||
refs = d.ChildEntity
|
||||
}
|
||||
if p, ok := ref.(*StoragePod); ok {
|
||||
refs = p.ChildEntity
|
||||
}
|
||||
|
||||
for _, ref := range refs {
|
||||
switch obj := Map.Get(ref).(type) {
|
||||
case *Datastore:
|
||||
if obj.Name == name {
|
||||
return obj, nil
|
||||
obj := Map.Get(ref)
|
||||
|
||||
if ds, ok := obj.(*Datastore); ok && ds.Name == name {
|
||||
return ds, nil
|
||||
}
|
||||
if p, ok := obj.(*StoragePod); ok {
|
||||
ds, _ := f.findDatastore(p, name)
|
||||
if ds != nil {
|
||||
return ds, nil
|
||||
}
|
||||
case *Folder, *StoragePod:
|
||||
ds, _ := f.findDatastore(obj, name)
|
||||
}
|
||||
if d, ok := asFolderMO(obj); ok {
|
||||
ds, _ := f.findDatastore(d, name)
|
||||
if ds != nil {
|
||||
return ds, nil
|
||||
}
|
||||
@@ -126,14 +126,14 @@ func (f *FileManager) deleteDatastoreFile(req *types.DeleteDatastoreFile_Task) t
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FileManager) DeleteDatastoreFileTask(req *types.DeleteDatastoreFile_Task) soap.HasFault {
|
||||
func (f *FileManager) DeleteDatastoreFileTask(ctx *Context, 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(),
|
||||
Returnval: task.Run(ctx),
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -190,14 +190,14 @@ func (f *FileManager) moveDatastoreFile(req *types.MoveDatastoreFile_Task) types
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FileManager) MoveDatastoreFileTask(req *types.MoveDatastoreFile_Task) soap.HasFault {
|
||||
func (f *FileManager) MoveDatastoreFileTask(ctx *Context, 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(),
|
||||
Returnval: task.Run(ctx),
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -220,7 +220,7 @@ func (f *FileManager) copyDatastoreFile(req *types.CopyDatastoreFile_Task) types
|
||||
}
|
||||
}
|
||||
|
||||
r, err := os.Open(src)
|
||||
r, err := os.Open(filepath.Clean(src))
|
||||
if err != nil {
|
||||
return f.fault(dst, err, new(types.CannotAccessFile))
|
||||
}
|
||||
@@ -239,14 +239,14 @@ func (f *FileManager) copyDatastoreFile(req *types.CopyDatastoreFile_Task) types
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FileManager) CopyDatastoreFileTask(req *types.CopyDatastoreFile_Task) soap.HasFault {
|
||||
func (f *FileManager) CopyDatastoreFileTask(ctx *Context, 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(),
|
||||
Returnval: task.Run(ctx),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
480
vendor/github.com/vmware/govmomi/simulator/folder.go
generated
vendored
480
vendor/github.com/vmware/govmomi/simulator/folder.go
generated
vendored
@@ -17,12 +17,16 @@ limitations under the License.
|
||||
package simulator
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net/url"
|
||||
"path"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
@@ -34,7 +38,15 @@ type Folder struct {
|
||||
mo.Folder
|
||||
}
|
||||
|
||||
func (f *Folder) eventArgument() types.FolderEventArgument {
|
||||
func asFolderMO(obj mo.Reference) (*mo.Folder, bool) {
|
||||
if obj == nil {
|
||||
return nil, false
|
||||
}
|
||||
f, ok := getManagedObject(obj).Addr().Interface().(*mo.Folder)
|
||||
return f, ok
|
||||
}
|
||||
|
||||
func folderEventArgument(f *mo.Folder) types.FolderEventArgument {
|
||||
return types.FolderEventArgument{
|
||||
Folder: f.Self,
|
||||
EntityEventArgument: types.EntityEventArgument{Name: f.Name},
|
||||
@@ -42,7 +54,7 @@ func (f *Folder) eventArgument() types.FolderEventArgument {
|
||||
}
|
||||
|
||||
// update references when objects are added/removed from a Folder
|
||||
func (f *Folder) update(o mo.Reference, u func(mo.Reference, *[]types.ManagedObjectReference, types.ManagedObjectReference)) {
|
||||
func folderUpdate(ctx *Context, f *mo.Folder, o mo.Reference, u func(*Context, mo.Reference, *[]types.ManagedObjectReference, types.ManagedObjectReference)) {
|
||||
ref := o.Reference()
|
||||
|
||||
if f.Parent == nil {
|
||||
@@ -54,17 +66,20 @@ func (f *Folder) update(o mo.Reference, u func(mo.Reference, *[]types.ManagedObj
|
||||
return // nothing to update
|
||||
}
|
||||
|
||||
dc := Map.getEntityDatacenter(f)
|
||||
dc := ctx.Map.getEntityDatacenter(f)
|
||||
|
||||
switch ref.Type {
|
||||
case "Network", "DistributedVirtualSwitch", "DistributedVirtualPortgroup":
|
||||
u(dc, &dc.Network, ref)
|
||||
u(ctx, dc, &dc.Network, ref)
|
||||
case "Datastore":
|
||||
u(dc, &dc.Datastore, ref)
|
||||
u(ctx, dc, &dc.Datastore, ref)
|
||||
}
|
||||
}
|
||||
|
||||
func networkSummary(n *mo.Network) *types.NetworkSummary {
|
||||
func networkSummary(n *mo.Network) types.BaseNetworkSummary {
|
||||
if n.Summary != nil {
|
||||
return n.Summary
|
||||
}
|
||||
return &types.NetworkSummary{
|
||||
Network: &n.Self,
|
||||
Name: n.Name,
|
||||
@@ -72,32 +87,38 @@ func networkSummary(n *mo.Network) *types.NetworkSummary {
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Folder) putChild(o mo.Entity) {
|
||||
Map.PutEntity(f, o)
|
||||
func folderPutChild(ctx *Context, f *mo.Folder, o mo.Entity) {
|
||||
ctx.WithLock(f, func() {
|
||||
// Need to update ChildEntity before Map.Put for ContainerView updates to work properly
|
||||
f.ChildEntity = append(f.ChildEntity, ctx.Map.reference(o))
|
||||
ctx.Map.PutEntity(f, o)
|
||||
|
||||
f.ChildEntity = append(f.ChildEntity, o.Reference())
|
||||
folderUpdate(ctx, f, o, ctx.Map.AddReference)
|
||||
|
||||
f.update(o, Map.AddReference)
|
||||
|
||||
switch e := o.(type) {
|
||||
case *mo.Network:
|
||||
e.Summary = networkSummary(e)
|
||||
case *mo.OpaqueNetwork:
|
||||
e.Summary = networkSummary(&e.Network)
|
||||
case *DistributedVirtualPortgroup:
|
||||
e.Summary = networkSummary(&e.Network)
|
||||
}
|
||||
ctx.WithLock(o, func() {
|
||||
switch e := o.(type) {
|
||||
case *mo.Network:
|
||||
e.Summary = networkSummary(e)
|
||||
case *mo.OpaqueNetwork:
|
||||
e.Summary = networkSummary(&e.Network)
|
||||
case *DistributedVirtualPortgroup:
|
||||
e.Summary = networkSummary(&e.Network)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func (f *Folder) removeChild(o mo.Reference) {
|
||||
Map.Remove(o.Reference())
|
||||
func folderRemoveChild(ctx *Context, f *mo.Folder, o mo.Reference) {
|
||||
ctx.Map.Remove(ctx, o.Reference())
|
||||
|
||||
RemoveReference(&f.ChildEntity, o.Reference())
|
||||
ctx.WithLock(f, func() {
|
||||
RemoveReference(&f.ChildEntity, o.Reference())
|
||||
|
||||
f.update(o, Map.RemoveReference)
|
||||
folderUpdate(ctx, f, o, ctx.Map.RemoveReference)
|
||||
})
|
||||
}
|
||||
|
||||
func (f *Folder) hasChildType(kind string) bool {
|
||||
func folderHasChildType(f *mo.Folder, kind string) bool {
|
||||
for _, t := range f.ChildType {
|
||||
if t == kind {
|
||||
return true
|
||||
@@ -110,14 +131,46 @@ func (f *Folder) typeNotSupported() *soap.Fault {
|
||||
return Fault(fmt.Sprintf("%s supports types: %#v", f.Self, f.ChildType), &types.NotSupported{})
|
||||
}
|
||||
|
||||
// AddOpaqueNetwork adds an OpaqueNetwork type to the inventory, with default backing to that of an nsx.LogicalSwitch.
|
||||
// The vSphere API does not have a method to add this directly, so it must either be called directly or via Model.OpaqueNetwork setting.
|
||||
func (f *Folder) AddOpaqueNetwork(ctx *Context, summary types.OpaqueNetworkSummary) error {
|
||||
if !folderHasChildType(&f.Folder, "Network") {
|
||||
return errors.New("not a network folder")
|
||||
}
|
||||
|
||||
if summary.OpaqueNetworkId == "" {
|
||||
summary.OpaqueNetworkId = uuid.New().String()
|
||||
}
|
||||
if summary.OpaqueNetworkType == "" {
|
||||
summary.OpaqueNetworkType = "nsx.LogicalSwitch"
|
||||
}
|
||||
if summary.Name == "" {
|
||||
summary.Name = summary.OpaqueNetworkType + "-" + summary.OpaqueNetworkId
|
||||
}
|
||||
|
||||
net := new(mo.OpaqueNetwork)
|
||||
if summary.Network == nil {
|
||||
summary.Network = &net.Self
|
||||
} else {
|
||||
net.Self = *summary.Network
|
||||
}
|
||||
summary.Accessible = true
|
||||
net.Network.Name = summary.Name
|
||||
net.Summary = &summary
|
||||
|
||||
folderPutChild(ctx, &f.Folder, net)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type addStandaloneHost struct {
|
||||
*Folder
|
||||
|
||||
ctx *Context
|
||||
req *types.AddStandaloneHost_Task
|
||||
}
|
||||
|
||||
func (add *addStandaloneHost) Run(task *Task) (types.AnyType, types.BaseMethodFault) {
|
||||
host, err := CreateStandaloneHost(add.Folder, add.req.Spec)
|
||||
host, err := CreateStandaloneHost(add.ctx, add.Folder, add.req.Spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -129,12 +182,12 @@ func (add *addStandaloneHost) Run(task *Task) (types.AnyType, types.BaseMethodFa
|
||||
return host.Reference(), nil
|
||||
}
|
||||
|
||||
func (f *Folder) AddStandaloneHostTask(a *types.AddStandaloneHost_Task) soap.HasFault {
|
||||
func (f *Folder) AddStandaloneHostTask(ctx *Context, a *types.AddStandaloneHost_Task) soap.HasFault {
|
||||
r := &methods.AddStandaloneHost_TaskBody{}
|
||||
|
||||
if f.hasChildType("ComputeResource") && f.hasChildType("Folder") {
|
||||
if folderHasChildType(&f.Folder, "ComputeResource") && folderHasChildType(&f.Folder, "Folder") {
|
||||
r.Res = &types.AddStandaloneHost_TaskResponse{
|
||||
Returnval: NewTask(&addStandaloneHost{f, a}).Run(),
|
||||
Returnval: NewTask(&addStandaloneHost{f, ctx, a}).Run(ctx),
|
||||
}
|
||||
} else {
|
||||
r.Fault_ = f.typeNotSupported()
|
||||
@@ -143,16 +196,27 @@ func (f *Folder) AddStandaloneHostTask(a *types.AddStandaloneHost_Task) soap.Has
|
||||
return r
|
||||
}
|
||||
|
||||
func (f *Folder) CreateFolder(c *types.CreateFolder) soap.HasFault {
|
||||
func (f *Folder) CreateFolder(ctx *Context, c *types.CreateFolder) soap.HasFault {
|
||||
r := &methods.CreateFolderBody{}
|
||||
|
||||
if f.hasChildType("Folder") {
|
||||
if folderHasChildType(&f.Folder, "Folder") {
|
||||
name := escapeSpecialCharacters(c.Name)
|
||||
|
||||
if obj := ctx.Map.FindByName(name, f.ChildEntity); obj != nil {
|
||||
r.Fault_ = Fault("", &types.DuplicateName{
|
||||
Name: name,
|
||||
Object: f.Self,
|
||||
})
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
folder := &Folder{}
|
||||
|
||||
folder.Name = c.Name
|
||||
folder.Name = name
|
||||
folder.ChildType = f.ChildType
|
||||
|
||||
f.putChild(folder)
|
||||
folderPutChild(ctx, &f.Folder, folder)
|
||||
|
||||
r.Res = &types.CreateFolderResponse{
|
||||
Returnval: folder.Self,
|
||||
@@ -164,15 +228,31 @@ func (f *Folder) CreateFolder(c *types.CreateFolder) soap.HasFault {
|
||||
return r
|
||||
}
|
||||
|
||||
func escapeSpecialCharacters(name string) string {
|
||||
name = strings.ReplaceAll(name, `%`, strings.ToLower(url.QueryEscape(`%`)))
|
||||
name = strings.ReplaceAll(name, `/`, strings.ToLower(url.QueryEscape(`/`)))
|
||||
name = strings.ReplaceAll(name, `\`, strings.ToLower(url.QueryEscape(`\`)))
|
||||
return name
|
||||
}
|
||||
|
||||
// StoragePod aka "Datastore Cluster"
|
||||
type StoragePod struct {
|
||||
mo.StoragePod
|
||||
}
|
||||
|
||||
func (f *Folder) CreateStoragePod(c *types.CreateStoragePod) soap.HasFault {
|
||||
func (f *Folder) CreateStoragePod(ctx *Context, c *types.CreateStoragePod) soap.HasFault {
|
||||
r := &methods.CreateStoragePodBody{}
|
||||
|
||||
if f.hasChildType("StoragePod") {
|
||||
if folderHasChildType(&f.Folder, "StoragePod") {
|
||||
if obj := ctx.Map.FindByName(c.Name, f.ChildEntity); obj != nil {
|
||||
r.Fault_ = Fault("", &types.DuplicateName{
|
||||
Name: c.Name,
|
||||
Object: f.Self,
|
||||
})
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
pod := &StoragePod{}
|
||||
|
||||
pod.Name = c.Name
|
||||
@@ -181,7 +261,7 @@ func (f *Folder) CreateStoragePod(c *types.CreateStoragePod) soap.HasFault {
|
||||
pod.PodStorageDrsEntry = new(types.PodStorageDrsEntry)
|
||||
pod.PodStorageDrsEntry.StorageDrsConfig.PodConfig.Enabled = true
|
||||
|
||||
f.putChild(pod)
|
||||
folderPutChild(ctx, &f.Folder, pod)
|
||||
|
||||
r.Res = &types.CreateStoragePodResponse{
|
||||
Returnval: pod.Self,
|
||||
@@ -193,20 +273,34 @@ func (f *Folder) CreateStoragePod(c *types.CreateStoragePod) soap.HasFault {
|
||||
return r
|
||||
}
|
||||
|
||||
func (p *StoragePod) MoveIntoFolderTask(c *types.MoveIntoFolder_Task) soap.HasFault {
|
||||
f := &Folder{Folder: p.Folder}
|
||||
res := f.MoveIntoFolderTask(c)
|
||||
p.ChildEntity = append(p.ChildEntity, f.ChildEntity...)
|
||||
return res
|
||||
func (p *StoragePod) MoveIntoFolderTask(ctx *Context, c *types.MoveIntoFolder_Task) soap.HasFault {
|
||||
task := CreateTask(p, "moveIntoFolder", func(*Task) (types.AnyType, types.BaseMethodFault) {
|
||||
f := &Folder{Folder: p.Folder}
|
||||
id := f.MoveIntoFolderTask(ctx, c).(*methods.MoveIntoFolder_TaskBody).Res.Returnval
|
||||
ftask := ctx.Map.Get(id).(*Task)
|
||||
ftask.Wait()
|
||||
if ftask.Info.Error != nil {
|
||||
return nil, ftask.Info.Error.Fault
|
||||
}
|
||||
p.ChildEntity = append(p.ChildEntity, f.ChildEntity...)
|
||||
return nil, nil
|
||||
})
|
||||
return &methods.MoveIntoFolder_TaskBody{
|
||||
Res: &types.MoveIntoFolder_TaskResponse{
|
||||
Returnval: task.Run(ctx),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Folder) CreateDatacenter(ctx *Context, c *types.CreateDatacenter) soap.HasFault {
|
||||
r := &methods.CreateDatacenterBody{}
|
||||
|
||||
if f.hasChildType("Datacenter") && f.hasChildType("Folder") {
|
||||
dc := NewDatacenter(f)
|
||||
if folderHasChildType(&f.Folder, "Datacenter") && folderHasChildType(&f.Folder, "Folder") {
|
||||
dc := NewDatacenter(ctx, &f.Folder)
|
||||
|
||||
dc.Name = c.Name
|
||||
ctx.Map.Update(dc, []types.PropertyChange{
|
||||
{Name: "name", Val: c.Name},
|
||||
})
|
||||
|
||||
r.Res = &types.CreateDatacenterResponse{
|
||||
Returnval: dc.Self,
|
||||
@@ -218,7 +312,7 @@ func (f *Folder) CreateDatacenter(ctx *Context, c *types.CreateDatacenter) soap.
|
||||
Datacenter: datacenterEventArgument(dc),
|
||||
},
|
||||
},
|
||||
Parent: f.eventArgument(),
|
||||
Parent: folderEventArgument(&f.Folder),
|
||||
})
|
||||
} else {
|
||||
r.Fault_ = f.typeNotSupported()
|
||||
@@ -227,11 +321,11 @@ func (f *Folder) CreateDatacenter(ctx *Context, c *types.CreateDatacenter) soap.
|
||||
return r
|
||||
}
|
||||
|
||||
func (f *Folder) CreateClusterEx(c *types.CreateClusterEx) soap.HasFault {
|
||||
func (f *Folder) CreateClusterEx(ctx *Context, c *types.CreateClusterEx) soap.HasFault {
|
||||
r := &methods.CreateClusterExBody{}
|
||||
|
||||
if f.hasChildType("ComputeResource") && f.hasChildType("Folder") {
|
||||
cluster, err := CreateClusterComputeResource(f, c.Name, c.Spec)
|
||||
if folderHasChildType(&f.Folder, "ComputeResource") && folderHasChildType(&f.Folder, "Folder") {
|
||||
cluster, err := CreateClusterComputeResource(ctx, f, c.Name, c.Spec)
|
||||
if err != nil {
|
||||
r.Fault_ = Fault("", err)
|
||||
return r
|
||||
@@ -273,36 +367,45 @@ func hostsWithDatastore(hosts []types.ManagedObjectReference, path string) []typ
|
||||
}
|
||||
|
||||
func (c *createVM) Run(task *Task) (types.AnyType, types.BaseMethodFault) {
|
||||
vm, err := NewVirtualMachine(c.Folder.Self, &c.req.Config)
|
||||
config := &c.req.Config
|
||||
// escape special characters in vm name
|
||||
if config.Name != escapeSpecialCharacters(config.Name) {
|
||||
deepCopy(c.req.Config, config)
|
||||
config.Name = escapeSpecialCharacters(config.Name)
|
||||
}
|
||||
|
||||
vm, err := NewVirtualMachine(c.ctx, c.Folder.Self, &c.req.Config)
|
||||
if err != nil {
|
||||
c.Folder.removeChild(vm)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
vm.ResourcePool = &c.req.Pool
|
||||
|
||||
if c.req.Host == nil {
|
||||
var hosts []types.ManagedObjectReference
|
||||
pool := c.ctx.Map.Get(c.req.Pool).(mo.Entity)
|
||||
cr := c.ctx.Map.getEntityComputeResource(pool)
|
||||
|
||||
pool := Map.Get(c.req.Pool).(mo.Entity)
|
||||
c.ctx.WithLock(cr, func() {
|
||||
var hosts []types.ManagedObjectReference
|
||||
switch cr := cr.(type) {
|
||||
case *mo.ComputeResource:
|
||||
hosts = cr.Host
|
||||
case *ClusterComputeResource:
|
||||
hosts = cr.Host
|
||||
}
|
||||
|
||||
switch cr := Map.getEntityComputeResource(pool).(type) {
|
||||
case *mo.ComputeResource:
|
||||
hosts = cr.Host
|
||||
case *ClusterComputeResource:
|
||||
hosts = cr.Host
|
||||
}
|
||||
|
||||
hosts = hostsWithDatastore(hosts, c.req.Config.Files.VmPathName)
|
||||
host := hosts[rand.Intn(len(hosts))]
|
||||
vm.Runtime.Host = &host
|
||||
hosts = hostsWithDatastore(hosts, c.req.Config.Files.VmPathName)
|
||||
host := hosts[rand.Intn(len(hosts))]
|
||||
vm.Runtime.Host = &host
|
||||
})
|
||||
} else {
|
||||
vm.Runtime.Host = c.req.Host
|
||||
}
|
||||
|
||||
vm.Guest = &types.GuestInfo{
|
||||
ToolsStatus: types.VirtualMachineToolsStatusToolsNotInstalled,
|
||||
ToolsVersion: "0",
|
||||
ToolsStatus: types.VirtualMachineToolsStatusToolsNotInstalled,
|
||||
ToolsVersion: "0",
|
||||
ToolsRunningStatus: string(types.VirtualMachineToolsRunningStatusGuestToolsNotRunning),
|
||||
}
|
||||
|
||||
vm.Summary.Guest = &types.VirtualMachineGuestSummary{
|
||||
@@ -311,30 +414,30 @@ func (c *createVM) Run(task *Task) (types.AnyType, types.BaseMethodFault) {
|
||||
vm.Summary.Config.VmPathName = vm.Config.Files.VmPathName
|
||||
vm.Summary.Runtime.Host = vm.Runtime.Host
|
||||
|
||||
err = vm.create(&c.req.Config, c.register)
|
||||
err = vm.create(c.ctx, &c.req.Config, c.register)
|
||||
if err != nil {
|
||||
c.Folder.removeChild(vm)
|
||||
folderRemoveChild(c.ctx, &c.Folder.Folder, vm)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
host := Map.Get(*vm.Runtime.Host).(*HostSystem)
|
||||
Map.AppendReference(host, &host.Vm, vm.Self)
|
||||
host := c.ctx.Map.Get(*vm.Runtime.Host).(*HostSystem)
|
||||
c.ctx.Map.AppendReference(c.ctx, host, &host.Vm, vm.Self)
|
||||
vm.EnvironmentBrowser = *hostParent(&host.HostSystem).EnvironmentBrowser
|
||||
|
||||
for i := range vm.Datastore {
|
||||
ds := Map.Get(vm.Datastore[i]).(*Datastore)
|
||||
Map.AppendReference(ds, &ds.Vm, vm.Self)
|
||||
ds := c.ctx.Map.Get(vm.Datastore[i]).(*Datastore)
|
||||
c.ctx.Map.AppendReference(c.ctx, ds, &ds.Vm, vm.Self)
|
||||
}
|
||||
|
||||
pool := Map.Get(*vm.ResourcePool)
|
||||
pool := c.ctx.Map.Get(*vm.ResourcePool)
|
||||
// This can be an internal call from VirtualApp.CreateChildVMTask, where pool is already locked.
|
||||
c.ctx.WithLock(pool, func() {
|
||||
switch rp := pool.(type) {
|
||||
case *ResourcePool:
|
||||
rp.Vm = append(rp.Vm, vm.Self)
|
||||
case *VirtualApp:
|
||||
if rp, ok := asResourcePoolMO(pool); ok {
|
||||
rp.Vm = append(rp.Vm, vm.Self)
|
||||
}
|
||||
if vapp, ok := pool.(*VirtualApp); ok {
|
||||
vapp.Vm = append(vapp.Vm, vm.Self)
|
||||
}
|
||||
})
|
||||
|
||||
event := vm.event()
|
||||
@@ -358,13 +461,17 @@ func (c *createVM) Run(task *Task) (types.AnyType, types.BaseMethodFault) {
|
||||
|
||||
vm.RefreshStorageInfo(c.ctx, nil)
|
||||
|
||||
c.ctx.Map.Update(vm, []types.PropertyChange{
|
||||
{Name: "name", Val: c.req.Config.Name},
|
||||
})
|
||||
|
||||
return vm.Reference(), nil
|
||||
}
|
||||
|
||||
func (f *Folder) CreateVMTask(ctx *Context, c *types.CreateVM_Task) soap.HasFault {
|
||||
return &methods.CreateVM_TaskBody{
|
||||
Res: &types.CreateVM_TaskResponse{
|
||||
Returnval: NewTask(&createVM{f, ctx, c, false}).Run(),
|
||||
Returnval: NewTask(&createVM{f, ctx, c, false}).Run(ctx),
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -387,7 +494,7 @@ func (c *registerVM) Run(task *Task) (types.AnyType, types.BaseMethodFault) {
|
||||
return nil, &types.InvalidArgument{InvalidProperty: "pool"}
|
||||
}
|
||||
|
||||
pool = hostParent(&Map.Get(*host).(*HostSystem).HostSystem).ResourcePool
|
||||
pool = hostParent(&c.ctx.Map.Get(*host).(*HostSystem).HostSystem).ResourcePool
|
||||
} else {
|
||||
if pool == nil {
|
||||
return nil, &types.InvalidArgument{InvalidProperty: "pool"}
|
||||
@@ -398,11 +505,11 @@ func (c *registerVM) Run(task *Task) (types.AnyType, types.BaseMethodFault) {
|
||||
return nil, &types.InvalidArgument{InvalidProperty: "path"}
|
||||
}
|
||||
|
||||
s := Map.SearchIndex()
|
||||
s := c.ctx.Map.SearchIndex()
|
||||
r := s.FindByDatastorePath(&types.FindByDatastorePath{
|
||||
This: s.Reference(),
|
||||
Path: c.req.Path,
|
||||
Datacenter: Map.getEntityDatacenter(c.Folder).Reference(),
|
||||
Datacenter: c.ctx.Map.getEntityDatacenter(c.Folder).Reference(),
|
||||
})
|
||||
|
||||
if ref := r.(*methods.FindByDatastorePathBody).Res.Returnval; ref != nil {
|
||||
@@ -435,7 +542,7 @@ func (c *registerVM) Run(task *Task) (types.AnyType, types.BaseMethodFault) {
|
||||
},
|
||||
})
|
||||
|
||||
create.Run()
|
||||
create.RunBlocking(c.ctx)
|
||||
|
||||
if create.Info.Error != nil {
|
||||
return nil, create.Info.Error.Fault
|
||||
@@ -445,28 +552,26 @@ func (c *registerVM) Run(task *Task) (types.AnyType, types.BaseMethodFault) {
|
||||
}
|
||||
|
||||
func (f *Folder) RegisterVMTask(ctx *Context, c *types.RegisterVM_Task) soap.HasFault {
|
||||
ctx.Caller = &f.Self
|
||||
|
||||
return &methods.RegisterVM_TaskBody{
|
||||
Res: &types.RegisterVM_TaskResponse{
|
||||
Returnval: NewTask(®isterVM{f, ctx, c}).Run(),
|
||||
Returnval: NewTask(®isterVM{f, ctx, c}).Run(ctx),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Folder) MoveIntoFolderTask(c *types.MoveIntoFolder_Task) soap.HasFault {
|
||||
func (f *Folder) MoveIntoFolderTask(ctx *Context, c *types.MoveIntoFolder_Task) soap.HasFault {
|
||||
task := CreateTask(f, "moveIntoFolder", func(t *Task) (types.AnyType, types.BaseMethodFault) {
|
||||
for _, ref := range c.List {
|
||||
obj := Map.Get(ref).(mo.Entity)
|
||||
obj := ctx.Map.Get(ref).(mo.Entity)
|
||||
|
||||
parent, ok := Map.Get(*(obj.Entity()).Parent).(*Folder)
|
||||
parent, ok := ctx.Map.Get(*(obj.Entity()).Parent).(*Folder)
|
||||
|
||||
if !ok || !f.hasChildType(ref.Type) {
|
||||
if !ok || !folderHasChildType(&f.Folder, ref.Type) {
|
||||
return nil, &types.NotSupported{}
|
||||
}
|
||||
|
||||
parent.removeChild(ref)
|
||||
f.putChild(obj)
|
||||
folderRemoveChild(ctx, &parent.Folder, ref)
|
||||
folderPutChild(ctx, &f.Folder, obj)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
@@ -474,25 +579,25 @@ func (f *Folder) MoveIntoFolderTask(c *types.MoveIntoFolder_Task) soap.HasFault
|
||||
|
||||
return &methods.MoveIntoFolder_TaskBody{
|
||||
Res: &types.MoveIntoFolder_TaskResponse{
|
||||
Returnval: task.Run(),
|
||||
Returnval: task.Run(ctx),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Folder) CreateDVSTask(req *types.CreateDVS_Task) soap.HasFault {
|
||||
func (f *Folder) CreateDVSTask(ctx *Context, req *types.CreateDVS_Task) soap.HasFault {
|
||||
task := CreateTask(f, "createDVS", func(t *Task) (types.AnyType, types.BaseMethodFault) {
|
||||
spec := req.Spec.ConfigSpec.GetDVSConfigSpec()
|
||||
dvs := &DistributedVirtualSwitch{}
|
||||
dvs.Name = spec.Name
|
||||
dvs.Entity().Name = dvs.Name
|
||||
|
||||
if Map.FindByName(dvs.Name, f.ChildEntity) != nil {
|
||||
if ctx.Map.FindByName(dvs.Name, f.ChildEntity) != nil {
|
||||
return nil, &types.InvalidArgument{InvalidProperty: "name"}
|
||||
}
|
||||
|
||||
dvs.Uuid = uuid.New().String()
|
||||
dvs.Uuid = newUUID(dvs.Name)
|
||||
|
||||
f.putChild(dvs)
|
||||
folderPutChild(ctx, &f.Folder, dvs)
|
||||
|
||||
dvs.Summary = types.DVSSummary{
|
||||
Name: dvs.Name,
|
||||
@@ -530,7 +635,7 @@ func (f *Folder) CreateDVSTask(req *types.CreateDVS_Task) soap.HasFault {
|
||||
dvs.Config = configInfo
|
||||
|
||||
if dvs.Summary.ProductInfo == nil {
|
||||
product := Map.content().About
|
||||
product := ctx.Map.content().About
|
||||
dvs.Summary.ProductInfo = &types.DistributedVirtualSwitchProductSpec{
|
||||
Name: "DVS",
|
||||
Vendor: product.Vendor,
|
||||
@@ -540,13 +645,29 @@ func (f *Folder) CreateDVSTask(req *types.CreateDVS_Task) soap.HasFault {
|
||||
}
|
||||
}
|
||||
|
||||
dvs.AddDVPortgroupTask(&types.AddDVPortgroup_Task{
|
||||
dvs.AddDVPortgroupTask(ctx, &types.AddDVPortgroup_Task{
|
||||
Spec: []types.DVPortgroupConfigSpec{{
|
||||
Name: dvs.Name + "-DVUplinks" + strings.TrimPrefix(dvs.Self.Value, "dvs"),
|
||||
Name: dvs.Name + "-DVUplinks" + strings.TrimPrefix(dvs.Self.Value, "dvs"),
|
||||
Type: string(types.DistributedVirtualPortgroupPortgroupTypeEarlyBinding),
|
||||
NumPorts: 1,
|
||||
DefaultPortConfig: &types.VMwareDVSPortSetting{
|
||||
Vlan: &types.VmwareDistributedVirtualSwitchTrunkVlanSpec{
|
||||
VlanId: []types.NumericRange{{Start: 0, End: 4094}},
|
||||
},
|
||||
UplinkTeamingPolicy: &types.VmwareUplinkPortTeamingPolicy{
|
||||
Policy: &types.StringPolicy{
|
||||
Value: "loadbalance_srcid",
|
||||
},
|
||||
ReversePolicy: &types.BoolPolicy{
|
||||
Value: types.NewBool(true),
|
||||
},
|
||||
NotifySwitches: &types.BoolPolicy{
|
||||
Value: types.NewBool(true),
|
||||
},
|
||||
RollingOrder: &types.BoolPolicy{
|
||||
Value: types.NewBool(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
}},
|
||||
})
|
||||
@@ -556,16 +677,16 @@ func (f *Folder) CreateDVSTask(req *types.CreateDVS_Task) soap.HasFault {
|
||||
|
||||
return &methods.CreateDVS_TaskBody{
|
||||
Res: &types.CreateDVS_TaskResponse{
|
||||
Returnval: task.Run(),
|
||||
Returnval: task.Run(ctx),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Folder) RenameTask(r *types.Rename_Task) soap.HasFault {
|
||||
return RenameTask(f, r)
|
||||
func (f *Folder) RenameTask(ctx *Context, r *types.Rename_Task) soap.HasFault {
|
||||
return RenameTask(ctx, f, r)
|
||||
}
|
||||
|
||||
func (f *Folder) DestroyTask(req *types.Destroy_Task) soap.HasFault {
|
||||
func (f *Folder) DestroyTask(ctx *Context, req *types.Destroy_Task) soap.HasFault {
|
||||
type destroyer interface {
|
||||
mo.Reference
|
||||
DestroyTask(*types.Destroy_Task) soap.HasFault
|
||||
@@ -574,18 +695,19 @@ func (f *Folder) DestroyTask(req *types.Destroy_Task) soap.HasFault {
|
||||
task := CreateTask(f, "destroy", func(*Task) (types.AnyType, types.BaseMethodFault) {
|
||||
// Attempt to destroy all children
|
||||
for _, c := range f.ChildEntity {
|
||||
obj, ok := Map.Get(c).(destroyer)
|
||||
obj, ok := ctx.Map.Get(c).(destroyer)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
var fault types.BaseMethodFault
|
||||
Map.WithLock(obj, func() {
|
||||
ctx.WithLock(obj, func() {
|
||||
id := obj.DestroyTask(&types.Destroy_Task{
|
||||
This: c,
|
||||
}).(*methods.Destroy_TaskBody).Res.Returnval
|
||||
|
||||
t := Map.Get(id).(*Task)
|
||||
t := ctx.Map.Get(id).(*Task)
|
||||
t.Wait()
|
||||
if t.Info.Error != nil {
|
||||
fault = t.Info.Error.Fault // For example, can't destroy a powered on VM
|
||||
}
|
||||
@@ -596,13 +718,159 @@ func (f *Folder) DestroyTask(req *types.Destroy_Task) soap.HasFault {
|
||||
}
|
||||
|
||||
// Remove the folder itself
|
||||
Map.Get(*f.Parent).(*Folder).removeChild(f.Self)
|
||||
folderRemoveChild(ctx, &ctx.Map.Get(*f.Parent).(*Folder).Folder, f.Self)
|
||||
return nil, nil
|
||||
})
|
||||
|
||||
return &methods.Destroy_TaskBody{
|
||||
Res: &types.Destroy_TaskResponse{
|
||||
Returnval: task.Run(),
|
||||
Returnval: task.Run(ctx),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Folder) PlaceVmsXCluster(ctx *Context, req *types.PlaceVmsXCluster) soap.HasFault {
|
||||
body := new(methods.PlaceVmsXClusterBody)
|
||||
|
||||
// Reject the request if it is against any folder other than the root folder.
|
||||
if req.This != ctx.Map.content().RootFolder {
|
||||
body.Fault_ = Fault("", new(types.InvalidRequest))
|
||||
return body
|
||||
}
|
||||
|
||||
pools := req.PlacementSpec.ResourcePools
|
||||
specs := req.PlacementSpec.VmPlacementSpecs
|
||||
|
||||
if len(pools) == 0 {
|
||||
body.Fault_ = Fault("", &types.InvalidArgument{InvalidProperty: "resourcePools"})
|
||||
return body
|
||||
}
|
||||
|
||||
// Do not allow duplicate clusters.
|
||||
clusters := map[mo.Reference]struct{}{}
|
||||
for _, obj := range pools {
|
||||
o := ctx.Map.Get(obj)
|
||||
pool, ok := o.(*ResourcePool)
|
||||
if !ok {
|
||||
body.Fault_ = Fault("", &types.InvalidArgument{InvalidProperty: "resourcePool"})
|
||||
return body
|
||||
}
|
||||
if _, exists := clusters[pool.Owner]; exists {
|
||||
body.Fault_ = Fault("", &types.InvalidArgument{InvalidProperty: "clusters"})
|
||||
return body
|
||||
}
|
||||
clusters[pool.Owner] = struct{}{}
|
||||
}
|
||||
|
||||
// MVP: Only a single VM is supported.
|
||||
if len(specs) != 1 {
|
||||
body.Fault_ = Fault("", &types.InvalidArgument{InvalidProperty: "vmPlacementSpecs"})
|
||||
return body
|
||||
}
|
||||
|
||||
for _, spec := range specs {
|
||||
if spec.ConfigSpec.Name == "" {
|
||||
body.Fault_ = Fault("", &types.InvalidArgument{InvalidProperty: "configSpec.name"})
|
||||
return body
|
||||
}
|
||||
}
|
||||
|
||||
body.Res = new(types.PlaceVmsXClusterResponse)
|
||||
hostRequired := req.PlacementSpec.HostRecommRequired != nil && *req.PlacementSpec.HostRecommRequired
|
||||
datastoreRequired := req.PlacementSpec.DatastoreRecommRequired != nil && *req.PlacementSpec.DatastoreRecommRequired
|
||||
|
||||
for _, spec := range specs {
|
||||
pool := ctx.Map.Get(pools[rand.Intn(len(pools))]).(*ResourcePool)
|
||||
cluster := ctx.Map.Get(pool.Owner).(*ClusterComputeResource)
|
||||
|
||||
if len(cluster.Host) == 0 {
|
||||
faults := types.PlaceVmsXClusterResultPlacementFaults{
|
||||
VmName: spec.ConfigSpec.Name,
|
||||
ResourcePool: pool.Self,
|
||||
Faults: []types.LocalizedMethodFault{
|
||||
{
|
||||
Fault: &types.GenericDrsFault{},
|
||||
},
|
||||
},
|
||||
}
|
||||
body.Res.Returnval.Faults = append(body.Res.Returnval.Faults, faults)
|
||||
} else {
|
||||
var configSpec *types.VirtualMachineConfigSpec
|
||||
|
||||
res := types.ClusterRecommendation{
|
||||
Key: "1",
|
||||
Type: "V1",
|
||||
Time: time.Now(),
|
||||
Rating: 1,
|
||||
Reason: string(types.RecommendationReasonCodeXClusterPlacement),
|
||||
ReasonText: string(types.RecommendationReasonCodeXClusterPlacement),
|
||||
Target: &cluster.Self,
|
||||
}
|
||||
|
||||
placementAction := types.ClusterClusterInitialPlacementAction{
|
||||
Pool: pool.Self,
|
||||
}
|
||||
|
||||
if hostRequired {
|
||||
randomHost := cluster.Host[rand.Intn(len(cluster.Host))]
|
||||
placementAction.TargetHost = &randomHost
|
||||
}
|
||||
|
||||
if datastoreRequired {
|
||||
configSpec = &spec.ConfigSpec
|
||||
|
||||
// TODO: This is just an initial implementation aimed at returning some data but it is not
|
||||
// necessarily fully consistent, like we should ensure the host, if also required, has the
|
||||
// datastore mounted.
|
||||
ds := ctx.Map.Get(cluster.Datastore[rand.Intn(len(cluster.Datastore))]).(*Datastore)
|
||||
|
||||
if configSpec.Files == nil {
|
||||
configSpec.Files = new(types.VirtualMachineFileInfo)
|
||||
}
|
||||
configSpec.Files.VmPathName = fmt.Sprintf("[%[1]s] %[2]s/%[2]s.vmx", ds.Name, spec.ConfigSpec.Name)
|
||||
|
||||
for _, change := range configSpec.DeviceChange {
|
||||
dspec := change.GetVirtualDeviceConfigSpec()
|
||||
|
||||
if dspec.FileOperation != types.VirtualDeviceConfigSpecFileOperationCreate {
|
||||
continue
|
||||
}
|
||||
|
||||
switch dspec.Operation {
|
||||
case types.VirtualDeviceConfigSpecOperationAdd:
|
||||
device := dspec.Device
|
||||
d := device.GetVirtualDevice()
|
||||
|
||||
switch device.(type) {
|
||||
case *types.VirtualDisk:
|
||||
switch b := d.Backing.(type) {
|
||||
case types.BaseVirtualDeviceFileBackingInfo:
|
||||
info := b.GetVirtualDeviceFileBackingInfo()
|
||||
info.Datastore = types.NewReference(ds.Reference())
|
||||
|
||||
var dsPath object.DatastorePath
|
||||
if dsPath.FromString(info.FileName) {
|
||||
dsPath.Datastore = ds.Name
|
||||
info.FileName = dsPath.String()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
placementAction.ConfigSpec = configSpec
|
||||
}
|
||||
|
||||
res.Action = append(res.Action, &placementAction)
|
||||
|
||||
body.Res.Returnval.PlacementInfos = append(body.Res.Returnval.PlacementInfos,
|
||||
types.PlaceVmsXClusterResultPlacementInfo{
|
||||
VmName: spec.ConfigSpec.Name,
|
||||
Recommendation: res,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return body
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user