diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index ec91ef731e7..bfeeba07572 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -2015,78 +2015,78 @@ }, { "ImportPath": "github.com/vmware/govmomi", - "Comment": "v0.6.2", - "Rev": "9051bd6b44125d9472e0c148b5965692ab283d4a" + "Comment": "v0.8.0-9-gb5ee639", + "Rev": "b5ee639d7aa4b8dbb48ab4f75dddc19f71b5c514" }, { "ImportPath": "github.com/vmware/govmomi/find", - "Comment": "v0.6.2", - "Rev": "9051bd6b44125d9472e0c148b5965692ab283d4a" + "Comment": "v0.8.0-9-gb5ee639", + "Rev": "b5ee639d7aa4b8dbb48ab4f75dddc19f71b5c514" }, { "ImportPath": "github.com/vmware/govmomi/list", - "Comment": "v0.6.2", - "Rev": "9051bd6b44125d9472e0c148b5965692ab283d4a" + "Comment": "v0.8.0-9-gb5ee639", + "Rev": "b5ee639d7aa4b8dbb48ab4f75dddc19f71b5c514" }, { "ImportPath": "github.com/vmware/govmomi/object", - "Comment": "v0.6.2", - "Rev": "9051bd6b44125d9472e0c148b5965692ab283d4a" + "Comment": "v0.8.0-9-gb5ee639", + "Rev": "b5ee639d7aa4b8dbb48ab4f75dddc19f71b5c514" }, { "ImportPath": "github.com/vmware/govmomi/property", - "Comment": "v0.6.2", - "Rev": "9051bd6b44125d9472e0c148b5965692ab283d4a" + "Comment": "v0.8.0-9-gb5ee639", + "Rev": "b5ee639d7aa4b8dbb48ab4f75dddc19f71b5c514" }, { "ImportPath": "github.com/vmware/govmomi/session", - "Comment": "v0.6.2", - "Rev": "9051bd6b44125d9472e0c148b5965692ab283d4a" + "Comment": "v0.8.0-9-gb5ee639", + "Rev": "b5ee639d7aa4b8dbb48ab4f75dddc19f71b5c514" }, { "ImportPath": "github.com/vmware/govmomi/task", - "Comment": "v0.6.2", - "Rev": "9051bd6b44125d9472e0c148b5965692ab283d4a" + "Comment": "v0.8.0-9-gb5ee639", + "Rev": "b5ee639d7aa4b8dbb48ab4f75dddc19f71b5c514" }, { "ImportPath": "github.com/vmware/govmomi/vim25", - "Comment": "v0.6.2", - "Rev": "9051bd6b44125d9472e0c148b5965692ab283d4a" + "Comment": "v0.8.0-9-gb5ee639", + "Rev": "b5ee639d7aa4b8dbb48ab4f75dddc19f71b5c514" }, { "ImportPath": "github.com/vmware/govmomi/vim25/debug", - "Comment": "v0.6.2", - "Rev": "9051bd6b44125d9472e0c148b5965692ab283d4a" + "Comment": "v0.8.0-9-gb5ee639", + "Rev": "b5ee639d7aa4b8dbb48ab4f75dddc19f71b5c514" }, { "ImportPath": "github.com/vmware/govmomi/vim25/methods", - "Comment": "v0.6.2", - "Rev": "9051bd6b44125d9472e0c148b5965692ab283d4a" + "Comment": "v0.8.0-9-gb5ee639", + "Rev": "b5ee639d7aa4b8dbb48ab4f75dddc19f71b5c514" }, { "ImportPath": "github.com/vmware/govmomi/vim25/mo", - "Comment": "v0.6.2", - "Rev": "9051bd6b44125d9472e0c148b5965692ab283d4a" + "Comment": "v0.8.0-9-gb5ee639", + "Rev": "b5ee639d7aa4b8dbb48ab4f75dddc19f71b5c514" }, { "ImportPath": "github.com/vmware/govmomi/vim25/progress", - "Comment": "v0.6.2", - "Rev": "9051bd6b44125d9472e0c148b5965692ab283d4a" + "Comment": "v0.8.0-9-gb5ee639", + "Rev": "b5ee639d7aa4b8dbb48ab4f75dddc19f71b5c514" }, { "ImportPath": "github.com/vmware/govmomi/vim25/soap", - "Comment": "v0.6.2", - "Rev": "9051bd6b44125d9472e0c148b5965692ab283d4a" + "Comment": "v0.8.0-9-gb5ee639", + "Rev": "b5ee639d7aa4b8dbb48ab4f75dddc19f71b5c514" }, { "ImportPath": "github.com/vmware/govmomi/vim25/types", - "Comment": "v0.6.2", - "Rev": "9051bd6b44125d9472e0c148b5965692ab283d4a" + "Comment": "v0.8.0-9-gb5ee639", + "Rev": "b5ee639d7aa4b8dbb48ab4f75dddc19f71b5c514" }, { "ImportPath": "github.com/vmware/govmomi/vim25/xml", - "Comment": "v0.6.2", - "Rev": "9051bd6b44125d9472e0c148b5965692ab283d4a" + "Comment": "v0.8.0-9-gb5ee639", + "Rev": "b5ee639d7aa4b8dbb48ab4f75dddc19f71b5c514" }, { "ImportPath": "github.com/xiang90/probing", diff --git a/pkg/cloudprovider/providers/vsphere/vsphere.go b/pkg/cloudprovider/providers/vsphere/vsphere.go index e451a38d622..b32f52ae249 100644 --- a/pkg/cloudprovider/providers/vsphere/vsphere.go +++ b/pkg/cloudprovider/providers/vsphere/vsphere.go @@ -23,6 +23,7 @@ import ( "net" "net/url" "path" + "path/filepath" "strings" "github.com/vmware/govmomi" @@ -74,24 +75,35 @@ type VSphere struct { type VSphereConfig struct { Global struct { - User string `gcfg:"user"` - Password string `gcfg:"password"` - VCenterIP string `gcfg:"server"` - VCenterPort string `gcfg:"port"` - InsecureFlag bool `gcfg:"insecure-flag"` - Datacenter string `gcfg:"datacenter"` - Datastore string `gcfg:"datastore"` - WorkingDir string `gcfg:"working-dir"` + // vCenter username. + User string `gcfg:"user"` + // vCenter password in clear text. + Password string `gcfg:"password"` + // vCenter IP. + VCenterIP string `gcfg:"server"` + // vCenter port. + VCenterPort string `gcfg:"port"` + // True if vCenter uses self-signed cert. + InsecureFlag bool `gcfg:"insecure-flag"` + // Datacenter in which VMs are located. + Datacenter string `gcfg:"datacenter"` + // Datastore in which vmdks are stored. + Datastore string `gcfg:"datastore"` + // WorkingDir is path where VMs can be found. + WorkingDir string `gcfg:"working-dir"` } Network struct { + // PublicNetwork is name of the network the VMs are joined to. PublicNetwork string `gcfg:"public-network"` } Disk struct { + // SCSIControllerType defines SCSI controller to be used. SCSIControllerType string `dcfg:"scsicontrollertype"` } } +// Parses vSphere cloud config file and stores it into VSphereConfig. func readConfig(config io.Reader) (VSphereConfig, error) { if config == nil { err := fmt.Errorf("no vSphere cloud provider config file given") @@ -113,6 +125,9 @@ func init() { }) } +// Returns the name of the VM on which this code is running. +// This is done by searching for the name of virtual machine by current IP. +// Prerequisite: this code assumes VMWare vmtools or open-vm-tools to be installed in the VM. func readInstanceID(cfg *VSphereConfig) (string, error) { addrs, err := net.InterfaceAddrs() if err != nil { @@ -153,6 +168,7 @@ func readInstanceID(cfg *VSphereConfig) (string, error) { return "", fmt.Errorf("unable to parse cidr from ip") } + // Finds a virtual machine or host by IP address. svm, err = s.FindByIp(ctx, dc, ip.String(), true) if err == nil && svm != nil { break @@ -192,6 +208,7 @@ func newVSphere(cfg VSphereConfig) (*VSphere, error) { return &vs, nil } +// Returns if the given controller type is supported by the plugin func checkControllerSupported(ctrlType string) bool { for _, c := range supportedSCSIControllerType { if ctrlType == c { @@ -201,8 +218,9 @@ func checkControllerSupported(ctrlType string) bool { return false } +// Returns a client which communicates with vCenter. +// This client can used to perform further vCenter operations. func vsphereLogin(cfg *VSphereConfig, ctx context.Context) (*govmomi.Client, error) { - // Parse URL from string u, err := url.Parse(fmt.Sprintf("https://%s:%s/sdk", cfg.Global.VCenterIP, cfg.Global.VCenterPort)) if err != nil { @@ -220,6 +238,7 @@ func vsphereLogin(cfg *VSphereConfig, ctx context.Context) (*govmomi.Client, err return c, nil } +// Returns vSphere object `virtual machine` by its name. func getVirtualMachineByName(cfg *VSphereConfig, ctx context.Context, c *govmomi.Client, name string) (*object.VirtualMachine, error) { // Create a new finder f := find.NewFinder(c.Client, true) @@ -254,6 +273,7 @@ func getVirtualMachineManagedObjectReference(ctx context.Context, c *govmomi.Cli return nil } +// Returns names of running VMs inside VM folder. func getInstances(cfg *VSphereConfig, ctx context.Context, c *govmomi.Client, filter string) ([]string, error) { f := find.NewFinder(c.Client, true) dc, err := f.Datacenter(ctx, cfg.Global.Datacenter) @@ -305,7 +325,7 @@ func (vs *VSphere) Instances() (cloudprovider.Instances, bool) { return &Instances{vs.cfg, vs.localInstanceID}, true } -// List is an implementation of Instances.List. +// List returns names of VMs (inside vm folder) by applying filter and which are currently running. func (i *Instances) List(filter string) ([]string, error) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -492,40 +512,40 @@ func (vs *VSphere) ScrubDNS(nameservers, searches []string) (nsOut, srchOut []st return nameservers, searches } -func getVirtualMachineDevices(cfg *VSphereConfig, ctx context.Context, c *govmomi.Client, name string) (*object.VirtualMachine, object.VirtualDeviceList, *object.Datastore, error) { - +// Returns vSphere objects virtual machine, virtual device list, datastore and datacenter. +func getVirtualMachineDevices(cfg *VSphereConfig, ctx context.Context, c *govmomi.Client, name string) (*object.VirtualMachine, object.VirtualDeviceList, *object.Datastore, *object.Datacenter, error) { // Create a new finder f := find.NewFinder(c.Client, true) // Fetch and set data center dc, err := f.Datacenter(ctx, cfg.Global.Datacenter) if err != nil { - return nil, nil, nil, err + return nil, nil, nil, nil, err } f.SetDatacenter(dc) // Find datastores ds, err := f.Datastore(ctx, cfg.Global.Datastore) if err != nil { - return nil, nil, nil, err + return nil, nil, nil, nil, err } vmRegex := cfg.Global.WorkingDir + name vm, err := f.VirtualMachine(ctx, vmRegex) if err != nil { - return nil, nil, nil, err + return nil, nil, nil, nil, err } // Get devices from VM vmDevices, err := vm.Device(ctx) if err != nil { - return nil, nil, nil, err + return nil, nil, nil, nil, err } - return vm, vmDevices, ds, nil + return vm, vmDevices, ds, dc, nil } -//cleaning up the controller +// Removes SCSI controller which is latest attached to VM. func cleanUpController(newSCSIController types.BaseVirtualDevice, vmDevices object.VirtualDeviceList, vm *object.VirtualMachine, ctx context.Context) error { ctls := vmDevices.SelectByType(newSCSIController) if len(ctls) < 1 { @@ -561,7 +581,7 @@ func (vs *VSphere) AttachDisk(vmDiskPath string, nodeName string) (diskID string } // Get VM device list - vm, vmDevices, ds, err := getVirtualMachineDevices(vs.cfg, ctx, c, vSphereInstance) + vm, vmDevices, ds, _, err := getVirtualMachineDevices(vs.cfg, ctx, c, vSphereInstance) if err != nil { return "", "", err } @@ -606,7 +626,7 @@ func (vs *VSphere) AttachDisk(vmDiskPath string, nodeName string) (diskID string // verify scsi controller in virtual machine vmDevices, err = vm.Device(ctx) if err != nil { - //cannot cleanup if there is no device list + // cannot cleanup if there is no device list return "", "", err } @@ -747,33 +767,77 @@ func getAvailableSCSIController(scsiControllers []*types.VirtualController) *typ return nil } +// Returns formatted UUID for a virtual disk device. func getVirtualDiskUUID(newDevice types.BaseVirtualDevice) (string, error) { vd := newDevice.GetVirtualDevice() if b, ok := vd.Backing.(*types.VirtualDiskFlatVer2BackingInfo); ok { - uuidWithNoHypens := strings.Replace(b.Uuid, "-", "", -1) - return strings.ToLower(uuidWithNoHypens), nil + uuid := formatVirtualDiskUUID(b.Uuid) + return uuid, nil } return "", ErrNoDiskUUIDFound } -func getVirtualDiskID(volPath string, vmDevices object.VirtualDeviceList) (string, error) { +func formatVirtualDiskUUID(uuid string) string { + uuidwithNoSpace := strings.Replace(uuid, " ", "", -1) + uuidWithNoHypens := strings.Replace(uuidwithNoSpace, "-", "", -1) + return strings.ToLower(uuidWithNoHypens) +} + +// Gets virtual disk UUID by datastore (namespace) path +// +// volPath can be namespace path (e.g. "[vsanDatastore] volumes/test.vmdk") or +// uuid path (e.g. "[vsanDatastore] 59427457-6c5a-a917-7997-0200103eedbc/test.vmdk"). +// `volumes` in this case would be a symlink to +// `59427457-6c5a-a917-7997-0200103eedbc`. +// +// We want users to use namespace path. It is good for attaching the disk, +// but for detaching the API requires uuid path. Hence, to detach the right +// device we have to convert the namespace path to uuid path. +func getVirtualDiskUUIDByPath(volPath string, dc *object.Datacenter, client *govmomi.Client) (string, error) { + if len(volPath) > 0 && filepath.Ext(volPath) != ".vmdk" { + volPath += ".vmdk" + } + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + // VirtualDiskManager provides a way to manage and manipulate virtual disks on vmware datastores. + vdm := object.NewVirtualDiskManager(client.Client) + // Returns uuid of vmdk virtual disk + diskUUID, err := vdm.QueryVirtualDiskUuid(ctx, volPath, dc) + + if err != nil { + return "", ErrNoDiskUUIDFound + } + + diskUUID = formatVirtualDiskUUID(diskUUID) + + return diskUUID, nil +} + +// Returns a device id which is internal vSphere API identifier for the attached virtual disk. +func getVirtualDiskID(volPath string, vmDevices object.VirtualDeviceList, dc *object.Datacenter, client *govmomi.Client) (string, error) { + volumeUUID, err := getVirtualDiskUUIDByPath(volPath, dc, client) + + if err != nil { + glog.Warningf("disk uuid not found for %v ", volPath) + return "", err + } + // filter vm devices to retrieve disk ID for the given vmdk file for _, device := range vmDevices { if vmDevices.TypeName(device) == "VirtualDisk" { - d := device.GetVirtualDevice() - if b, ok := d.Backing.(types.BaseVirtualDeviceFileBackingInfo); ok { - fileName := b.GetVirtualDeviceFileBackingInfo().FileName - if fileName == volPath { - return vmDevices.Name(device), nil - } + diskUUID, _ := getVirtualDiskUUID(device) + if diskUUID == volumeUUID { + return vmDevices.Name(device), nil } } } return "", ErrNoDiskIDFound } -// Detaches given virtual disk volume from the compute running kubelet. +// DetachDisk detaches given virtual disk volume from the compute running kubelet. func (vs *VSphere) DetachDisk(volPath string, nodeName string) error { // Create context ctx, cancel := context.WithCancel(context.Background()) @@ -794,23 +858,24 @@ func (vs *VSphere) DetachDisk(volPath string, nodeName string) error { vSphereInstance = nodeName } - vm, vmDevices, _, err := getVirtualMachineDevices(vs.cfg, ctx, c, vSphereInstance) + vm, vmDevices, _, dc, err := getVirtualMachineDevices(vs.cfg, ctx, c, vSphereInstance) if err != nil { return err } - diskID, err := getVirtualDiskID(volPath, vmDevices) + diskID, err := getVirtualDiskID(volPath, vmDevices, dc, c) if err != nil { glog.Warningf("disk ID not found for %v ", volPath) return err } - // Remove disk from VM + // Gets virtual disk device device := vmDevices.Find(diskID) if device == nil { return fmt.Errorf("device '%s' not found", diskID) } + // Detach disk from VM err = vm.RemoveDevice(ctx, true, device) if err != nil { return err @@ -819,7 +884,7 @@ func (vs *VSphere) DetachDisk(volPath string, nodeName string) error { return nil } -// Create a volume of given size (in KiB). +// CreateVolume creates a volume of given size (in KiB). func (vs *VSphere) CreateVolume(name string, size int, tags *map[string]string) (volumePath string, err error) { // Create context ctx, cancel := context.WithCancel(context.Background()) @@ -865,7 +930,7 @@ func (vs *VSphere) CreateVolume(name string, size int, tags *map[string]string) return vmDiskPath, nil } -// Deletes a volume given volume name. +// DeleteVolume deletes a volume given volume name. func (vs *VSphere) DeleteVolume(vmDiskPath string) error { // Create context ctx, cancel := context.WithCancel(context.Background()) diff --git a/pkg/volume/vsphere_volume/vsphere_volume.go b/pkg/volume/vsphere_volume/vsphere_volume.go index a640342a75a..62f26c56a33 100644 --- a/pkg/volume/vsphere_volume/vsphere_volume.go +++ b/pkg/volume/vsphere_volume/vsphere_volume.go @@ -292,11 +292,13 @@ func (v *vsphereVolumeUnmounter) TearDownAt(dir string) error { return fmt.Errorf("directory %s is not mounted", dir) } + mountPath := refs[0] + // Assumption: No file or folder is named starting with '[' in datastore + volumePath := mountPath[strings.LastIndex(mountPath, "["):] // space between datastore and vmdk name in volumePath is encoded as '\040' when returned by GetMountRefs(). // volumePath eg: "[local] xxx.vmdk" provided to attach/mount // replacing \040 with space to match the actual volumePath - mountPath := strings.Replace(path.Base(refs[0]), "\\040", " ", -1) - v.volPath = mountPath + v.volPath = strings.Replace(volumePath, "\\040", " ", -1) glog.V(4).Infof("Found volume %s mounted to %s", v.volPath, dir) // Reload list of references, there might be SetUpAt finished in the meantime diff --git a/vendor/github.com/vmware/govmomi/CHANGELOG.md b/vendor/github.com/vmware/govmomi/CHANGELOG.md index c695d4a1a10..de1bfad33d9 100644 --- a/vendor/github.com/vmware/govmomi/CHANGELOG.md +++ b/vendor/github.com/vmware/govmomi/CHANGELOG.md @@ -1,5 +1,35 @@ # changelog +### 0.8.0 (2016-06-30) + +* Add session.Manager.AcquireLocalTicket + +* Include StoragePod in Finder.FolderList + +* Add Finder methods for finding by ManagedObjectReference: Element, ObjectReference + +* Add mo.ManagedObjectReference methods: Reference, String, FromString + +* Add support using SessionManagerGenericServiceTicket.HostName for Datastore HTTP access + +### 0.7.1 (2016-06-03) + +* Fix object.ObjectName method + +### 0.7.0 (2016-06-02) + +* Move InventoryPath field to object.Common + +* Add HostDatastoreSystem.CreateLocalDatastore method + +* Add DatastoreNamespaceManager methods: CreateDirectory, DeleteDirectory + +* Add HostServiceSystem + +* Add HostStorageSystem methods: MarkAsSdd, MarkAsNonSdd, MarkAsLocal, MarkAsNonLocal + +* Add HostStorageSystem.RescanAllHba method + ### 0.6.2 (2016-05-11) * Get complete file details in Datastore.Stat diff --git a/vendor/github.com/vmware/govmomi/CONTRIBUTING.md b/vendor/github.com/vmware/govmomi/CONTRIBUTING.md index 18c7be510f4..f87c6061029 100644 --- a/vendor/github.com/vmware/govmomi/CONTRIBUTING.md +++ b/vendor/github.com/vmware/govmomi/CONTRIBUTING.md @@ -9,10 +9,8 @@ Change _$USER_ below to your github username if they are not the same. ``` shell export GOPATH=$HOME/govmomi -mkdir -p $GOPATH/src/github.com/vmware -cd $GOPATH/src/github.com/vmware -git clone git@github.com:vmware/govmomi.git -cd 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 git remote rename origin vmware git remote add $USER git@github.com:$USER/govmomi.git @@ -26,6 +24,7 @@ This is a rough outline of what a contributor's workflow looks like: - 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. diff --git a/vendor/github.com/vmware/govmomi/CONTRIBUTORS b/vendor/github.com/vmware/govmomi/CONTRIBUTORS index 11b2194367f..e088ff77df2 100644 --- a/vendor/github.com/vmware/govmomi/CONTRIBUTORS +++ b/vendor/github.com/vmware/govmomi/CONTRIBUTORS @@ -10,10 +10,12 @@ Arran Walker Austin Parker Bob Killen Bruce Downs -Clint Greenwood Cédric Blomart +Christian Höltje +Clint Greenwood Danny Lockard Dave Tucker +David Stark Doug MacEachern Eloy Coto Eric Yutao @@ -31,8 +33,8 @@ Pieter Noordhuis runner.mei S.Çağlar Onur Sergey Ignatov -Takaaki Furukawa Steve Purcell +Takaaki Furukawa Yang Yang Yuya Kusakabe Zach Tucker diff --git a/vendor/github.com/vmware/govmomi/Makefile b/vendor/github.com/vmware/govmomi/Makefile index af148963401..7aa0c861027 100644 --- a/vendor/github.com/vmware/govmomi/Makefile +++ b/vendor/github.com/vmware/govmomi/Makefile @@ -4,21 +4,17 @@ all: check test check: goimports govet -vendor: - go get golang.org/x/tools/cmd/goimports - go get github.com/davecgh/go-spew/spew - go get golang.org/x/net/context - -goimports: vendor +goimports: @echo checking go imports... + @go get golang.org/x/tools/cmd/goimports @! goimports -d . 2>&1 | egrep -v '^$$' govet: @echo checking go vet... @go tool vet -structtags=false -methods=false . -test: vendor +test: go test -v $(TEST_OPTS) ./... -install: vendor +install: go install github.com/vmware/govmomi/govc diff --git a/vendor/github.com/vmware/govmomi/find/finder.go b/vendor/github.com/vmware/govmomi/find/finder.go index 3e9c3acb351..d9b6393885c 100644 --- a/vendor/github.com/vmware/govmomi/find/finder.go +++ b/vendor/github.com/vmware/govmomi/find/finder.go @@ -25,6 +25,7 @@ import ( "github.com/vmware/govmomi/property" "github.com/vmware/govmomi/vim25" "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/types" "golang.org/x/net/context" ) @@ -192,6 +193,48 @@ func (f *Finder) managedObjectList(ctx context.Context, path string, tl bool) ([ return f.find(ctx, fn, tl, path) } +// Element returns an Element for the given ManagedObjectReference +// This method is only useful for looking up the InventoryPath of a ManagedObjectReference. +func (f *Finder) Element(ctx context.Context, ref types.ManagedObjectReference) (*list.Element, error) { + rl := func(_ context.Context) (object.Reference, error) { + return ref, nil + } + + e, err := f.find(ctx, rl, false, ".") + if err != nil { + return nil, err + } + + if len(e) == 0 { + return nil, &NotFoundError{ref.Type, ref.Value} + } + + if len(e) > 1 { + panic("ManagedObjectReference must be unique") + } + + return &e[0], nil +} + +// 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) + if err != nil { + return nil, err + } + + r := object.NewReference(f.client, ref) + + type common interface { + SetInventoryPath(string) + } + + r.(common).SetInventoryPath(e.Path) + + return r, nil +} + func (f *Finder) ManagedObjectList(ctx context.Context, path string) ([]list.Element, error) { return f.managedObjectList(ctx, path, false) } @@ -210,7 +253,9 @@ func (f *Finder) DatacenterList(ctx context.Context, path string) ([]*object.Dat for _, e := range es { ref := e.Object.Reference() if ref.Type == "Datacenter" { - dcs = append(dcs, object.NewDatacenter(f.client, ref)) + dc := object.NewDatacenter(f.client, ref) + dc.InventoryPath = e.Path + dcs = append(dcs, dc) } } @@ -772,7 +817,7 @@ func (f *Finder) FolderList(ctx context.Context, path string) ([]*object.Folder, for _, e := range es { switch o := e.Object.(type) { - case mo.Folder: + case mo.Folder, mo.StoragePod: folder := object.NewFolder(f.client, o.Reference()) folder.InventoryPath = e.Path folders = append(folders, folder) diff --git a/vendor/github.com/vmware/govmomi/object/cluster_compute_resource.go b/vendor/github.com/vmware/govmomi/object/cluster_compute_resource.go index 3cd52f705f9..2bae7bdb979 100644 --- a/vendor/github.com/vmware/govmomi/object/cluster_compute_resource.go +++ b/vendor/github.com/vmware/govmomi/object/cluster_compute_resource.go @@ -25,8 +25,6 @@ import ( type ClusterComputeResource struct { ComputeResource - - InventoryPath string } func NewClusterComputeResource(c *vim25.Client, ref types.ManagedObjectReference) *ClusterComputeResource { diff --git a/vendor/github.com/vmware/govmomi/object/common.go b/vendor/github.com/vmware/govmomi/object/common.go index 97972849f9b..0488818897b 100644 --- a/vendor/github.com/vmware/govmomi/object/common.go +++ b/vendor/github.com/vmware/govmomi/object/common.go @@ -19,10 +19,12 @@ package object import ( "errors" "fmt" + "path" "github.com/vmware/govmomi/property" "github.com/vmware/govmomi/vim25" "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/mo" "github.com/vmware/govmomi/vim25/types" "golang.org/x/net/context" ) @@ -33,12 +35,20 @@ var ( // Common contains the fields and functions common to all objects. type Common struct { + InventoryPath string + c *vim25.Client r types.ManagedObjectReference } func (c Common) String() string { - return fmt.Sprintf("%v", c.Reference()) + ref := fmt.Sprintf("%v", c.Reference()) + + if c.InventoryPath == "" { + return ref + } + + return fmt.Sprintf("%s @ %s", ref, c.InventoryPath) } func NewCommon(c *vim25.Client, r types.ManagedObjectReference) Common { @@ -53,6 +63,36 @@ func (c Common) Client() *vim25.Client { return c.c } +// Name returns the base name of the InventoryPath field +func (c Common) Name() string { + if c.InventoryPath == "" { + return "" + } + return path.Base(c.InventoryPath) +} + +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. +func (c Common) ObjectName(ctx context.Context) (string, error) { + var o mo.ManagedEntity + + name := c.Name() + if name != "" { + return name, nil + } + + err := c.Properties(ctx, c.Reference(), []string{"name"}, &o) + if err != nil { + return "", err + } + + return o.Name, nil +} + func (c Common) Properties(ctx context.Context, r types.ManagedObjectReference, ps []string, dst interface{}) error { return property.DefaultCollector(c.c).RetrieveOne(ctx, r, ps, dst) } diff --git a/vendor/github.com/vmware/govmomi/object/compute_resource.go b/vendor/github.com/vmware/govmomi/object/compute_resource.go index 328c2e07cb4..0304a4af66c 100644 --- a/vendor/github.com/vmware/govmomi/object/compute_resource.go +++ b/vendor/github.com/vmware/govmomi/object/compute_resource.go @@ -29,8 +29,6 @@ import ( type ComputeResource struct { Common - - InventoryPath string } func NewComputeResource(c *vim25.Client, ref types.ManagedObjectReference) *ComputeResource { diff --git a/vendor/github.com/vmware/govmomi/object/datastore.go b/vendor/github.com/vmware/govmomi/object/datastore.go index 123dde8a83f..6a56f6ec5e8 100644 --- a/vendor/github.com/vmware/govmomi/object/datastore.go +++ b/vendor/github.com/vmware/govmomi/object/datastore.go @@ -20,6 +20,7 @@ import ( "fmt" "io" "math/rand" + "os" "path" "strings" @@ -57,8 +58,6 @@ func (e DatastoreNoSuchFileError) Error() string { type Datastore struct { Common - - InventoryPath string } func NewDatastore(c *vim25.Client, ref types.ManagedObjectReference) *Datastore { @@ -67,10 +66,6 @@ func NewDatastore(c *vim25.Client, ref types.ManagedObjectReference) *Datastore } } -func (d Datastore) Name() string { - return path.Base(d.InventoryPath) -} - func (d Datastore) Path(path string) string { name := d.Name() if name == "" { @@ -116,6 +111,42 @@ func (d Datastore) Browser(ctx context.Context) (*HostDatastoreBrowser, error) { return NewHostDatastoreBrowser(d.c, do.Browser), nil } +func (d Datastore) useServiceTicketHostName(name string) bool { + // No need if talking directly to ESX. + if !d.c.IsVC() { + return false + } + + // If version happens to be < 5.1 + if name == "" { + return false + } + + // If the HostSystem is using DHCP on a network without dynamic DNS, + // HostSystem.Config.Network.DnsConfig.HostName is set to "localhost" by default. + // This resolves to "localhost.localdomain" by default via /etc/hosts on ESX. + // In that case, we will stick with the HostSystem.Name which is the IP address that + // was used to connect the host to VC. + if name == "localhost.localdomain" { + return false + } + + // Still possible to have HostName that don't resolve via DNS, + // so we default to false. + key := "GOVMOMI_USE_SERVICE_TICKET_HOSTNAME" + + val := d.c.URL().Query().Get(key) + if val == "" { + val = os.Getenv(key) + } + + if val == "1" || val == "true" { + return true + } + + return false +} + // ServiceTicket obtains a ticket via AcquireGenericServiceTicket and returns it an http.Cookie with the url.URL // that can be used along with the ticket cookie to access the given path. func (d Datastore) ServiceTicket(ctx context.Context, path string, method string) (*url.URL, *http.Cookie, error) { @@ -142,7 +173,7 @@ func (d Datastore) ServiceTicket(ctx context.Context, path string, method string // Pick a random attached host host := hosts[rand.Intn(len(hosts))] - name, err := host.Name(ctx) + name, err := host.ObjectName(ctx) if err != nil { return nil, nil, err } @@ -167,6 +198,10 @@ func (d Datastore) ServiceTicket(ctx context.Context, path string, method string Value: ticket.Id, } + if d.useServiceTicketHostName(ticket.HostName) { + u.Host = ticket.HostName + } + return u, cookie, nil } diff --git a/vendor/github.com/vmware/govmomi/object/distributed_virtual_portgroup.go b/vendor/github.com/vmware/govmomi/object/distributed_virtual_portgroup.go index 0dbd4b589f6..19319dbd1c5 100644 --- a/vendor/github.com/vmware/govmomi/object/distributed_virtual_portgroup.go +++ b/vendor/github.com/vmware/govmomi/object/distributed_virtual_portgroup.go @@ -17,8 +17,6 @@ limitations under the License. package object import ( - "path" - "github.com/vmware/govmomi/vim25" "github.com/vmware/govmomi/vim25/mo" "github.com/vmware/govmomi/vim25/types" @@ -27,8 +25,6 @@ import ( type DistributedVirtualPortgroup struct { Common - - InventoryPath string } func NewDistributedVirtualPortgroup(c *vim25.Client, ref types.ManagedObjectReference) *DistributedVirtualPortgroup { @@ -36,9 +32,6 @@ func NewDistributedVirtualPortgroup(c *vim25.Client, ref types.ManagedObjectRefe Common: NewCommon(c, ref), } } -func (p DistributedVirtualPortgroup) Name() string { - return path.Base(p.InventoryPath) -} // EthernetCardBackingInfo returns the VirtualDeviceBackingInfo for this DistributedVirtualPortgroup func (p DistributedVirtualPortgroup) EthernetCardBackingInfo(ctx context.Context) (types.BaseVirtualDeviceBackingInfo, error) { diff --git a/vendor/github.com/vmware/govmomi/object/distributed_virtual_switch.go b/vendor/github.com/vmware/govmomi/object/distributed_virtual_switch.go index f2fb0abeeff..326dd8ea457 100644 --- a/vendor/github.com/vmware/govmomi/object/distributed_virtual_switch.go +++ b/vendor/github.com/vmware/govmomi/object/distributed_virtual_switch.go @@ -25,8 +25,6 @@ import ( type DistributedVirtualSwitch struct { Common - - InventoryPath string } func NewDistributedVirtualSwitch(c *vim25.Client, ref types.ManagedObjectReference) *DistributedVirtualSwitch { diff --git a/vendor/github.com/vmware/govmomi/object/folder.go b/vendor/github.com/vmware/govmomi/object/folder.go index 97c793470aa..365ec2e5612 100644 --- a/vendor/github.com/vmware/govmomi/object/folder.go +++ b/vendor/github.com/vmware/govmomi/object/folder.go @@ -26,8 +26,6 @@ import ( type Folder struct { Common - - InventoryPath string } func NewFolder(c *vim25.Client, ref types.ManagedObjectReference) *Folder { @@ -113,6 +111,20 @@ func (f Folder) CreateFolder(ctx context.Context, name string) (*Folder, error) return NewFolder(f.c, res.Returnval), err } +func (f Folder) CreateStoragePod(ctx context.Context, name string) (*StoragePod, error) { + req := types.CreateStoragePod{ + This: f.Reference(), + Name: name, + } + + res, err := methods.CreateStoragePod(ctx, f.c, &req) + if err != nil { + return nil, err + } + + return NewStoragePod(f.c, res.Returnval), err +} + func (f Folder) AddStandaloneHost(ctx context.Context, spec types.HostConnectSpec, addConnected bool, license *string, compResSpec *types.BaseComputeResourceConfigSpec) (*Task, error) { req := types.AddStandaloneHost_Task{ This: f.Reference(), diff --git a/vendor/github.com/vmware/govmomi/object/host_config_manager.go b/vendor/github.com/vmware/govmomi/object/host_config_manager.go index 12327ee0f0d..3bb571ae5e1 100644 --- a/vendor/github.com/vmware/govmomi/object/host_config_manager.go +++ b/vendor/github.com/vmware/govmomi/object/host_config_manager.go @@ -120,3 +120,14 @@ func (m HostConfigManager) OptionManager(ctx context.Context) (*OptionManager, e return NewOptionManager(m.c, *h.ConfigManager.AdvancedOption), nil } + +func (m HostConfigManager) ServiceSystem(ctx context.Context) (*HostServiceSystem, error) { + var h mo.HostSystem + + err := m.Properties(ctx, m.Reference(), []string{"configManager.serviceSystem"}, &h) + if err != nil { + return nil, err + } + + return NewHostServiceSystem(m.c, *h.ConfigManager.ServiceSystem), nil +} diff --git a/vendor/github.com/vmware/govmomi/object/host_datastore_system.go b/vendor/github.com/vmware/govmomi/object/host_datastore_system.go index 632b7d255ba..828d97a8349 100644 --- a/vendor/github.com/vmware/govmomi/object/host_datastore_system.go +++ b/vendor/github.com/vmware/govmomi/object/host_datastore_system.go @@ -33,6 +33,21 @@ func NewHostDatastoreSystem(c *vim25.Client, ref types.ManagedObjectReference) * } } +func (s HostDatastoreSystem) CreateLocalDatastore(ctx context.Context, name string, path string) (*Datastore, error) { + req := types.CreateLocalDatastore{ + This: s.Reference(), + Name: name, + Path: path, + } + + res, err := methods.CreateLocalDatastore(ctx, s.Client(), &req) + if err != nil { + return nil, err + } + + return NewDatastore(s.Client(), res.Returnval), nil +} + func (s HostDatastoreSystem) CreateNasDatastore(ctx context.Context, spec types.HostNasVolumeSpec) (*Datastore, error) { req := types.CreateNasDatastore{ This: s.Reference(), diff --git a/vendor/github.com/vmware/govmomi/object/host_service_system.go b/vendor/github.com/vmware/govmomi/object/host_service_system.go new file mode 100644 index 00000000000..0a65cd999df --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/host_service_system.go @@ -0,0 +1,87 @@ +/* +Copyright (c) 2016 VMware, Inc. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type HostServiceSystem struct { + Common +} + +func NewHostServiceSystem(c *vim25.Client, ref types.ManagedObjectReference) *HostServiceSystem { + return &HostServiceSystem{ + Common: NewCommon(c, ref), + } +} + +func (s HostServiceSystem) Service(ctx context.Context) ([]types.HostService, error) { + var ss mo.HostServiceSystem + + err := s.Properties(ctx, s.Reference(), []string{"serviceInfo.service"}, &ss) + if err != nil { + return nil, err + } + + return ss.ServiceInfo.Service, nil +} + +func (s HostServiceSystem) Start(ctx context.Context, id string) error { + req := types.StartService{ + This: s.Reference(), + Id: id, + } + + _, err := methods.StartService(ctx, s.Client(), &req) + return err +} + +func (s HostServiceSystem) Stop(ctx context.Context, id string) error { + req := types.StopService{ + This: s.Reference(), + Id: id, + } + + _, err := methods.StopService(ctx, s.Client(), &req) + return err +} + +func (s HostServiceSystem) Restart(ctx context.Context, id string) error { + req := types.RestartService{ + This: s.Reference(), + Id: id, + } + + _, err := methods.RestartService(ctx, s.Client(), &req) + return err +} + +func (s HostServiceSystem) UpdatePolicy(ctx context.Context, id string, policy string) error { + req := types.UpdateServicePolicy{ + This: s.Reference(), + Id: id, + Policy: policy, + } + + _, err := methods.UpdateServicePolicy(ctx, s.Client(), &req) + return err +} diff --git a/vendor/github.com/vmware/govmomi/object/host_storage_system.go b/vendor/github.com/vmware/govmomi/object/host_storage_system.go index 36cd68e3ad9..e996d55341d 100644 --- a/vendor/github.com/vmware/govmomi/object/host_storage_system.go +++ b/vendor/github.com/vmware/govmomi/object/host_storage_system.go @@ -78,3 +78,68 @@ func (s HostStorageSystem) UpdateDiskPartitionInfo(ctx context.Context, devicePa _, err := methods.UpdateDiskPartitions(ctx, s.c, &req) return err } + +func (s HostStorageSystem) RescanAllHba(ctx context.Context) error { + req := types.RescanAllHba{ + This: s.Reference(), + } + + _, err := methods.RescanAllHba(ctx, s.c, &req) + return err +} + +func (s HostStorageSystem) MarkAsSsd(ctx context.Context, uuid string) (*Task, error) { + req := types.MarkAsSsd_Task{ + This: s.Reference(), + ScsiDiskUuid: uuid, + } + + res, err := methods.MarkAsSsd_Task(ctx, s.c, &req) + if err != nil { + return nil, err + } + + return NewTask(s.c, res.Returnval), nil +} + +func (s HostStorageSystem) MarkAsNonSsd(ctx context.Context, uuid string) (*Task, error) { + req := types.MarkAsNonSsd_Task{ + This: s.Reference(), + ScsiDiskUuid: uuid, + } + + res, err := methods.MarkAsNonSsd_Task(ctx, s.c, &req) + if err != nil { + return nil, err + } + + return NewTask(s.c, res.Returnval), nil +} + +func (s HostStorageSystem) MarkAsLocal(ctx context.Context, uuid string) (*Task, error) { + req := types.MarkAsLocal_Task{ + This: s.Reference(), + ScsiDiskUuid: uuid, + } + + res, err := methods.MarkAsLocal_Task(ctx, s.c, &req) + if err != nil { + return nil, err + } + + return NewTask(s.c, res.Returnval), nil +} + +func (s HostStorageSystem) MarkAsNonLocal(ctx context.Context, uuid string) (*Task, error) { + req := types.MarkAsNonLocal_Task{ + This: s.Reference(), + ScsiDiskUuid: uuid, + } + + res, err := methods.MarkAsNonLocal_Task(ctx, s.c, &req) + if err != nil { + return nil, err + } + + return NewTask(s.c, res.Returnval), nil +} diff --git a/vendor/github.com/vmware/govmomi/object/host_system.go b/vendor/github.com/vmware/govmomi/object/host_system.go index 0146d9ae509..42d79b6f922 100644 --- a/vendor/github.com/vmware/govmomi/object/host_system.go +++ b/vendor/github.com/vmware/govmomi/object/host_system.go @@ -29,15 +29,6 @@ import ( type HostSystem struct { Common - - InventoryPath string -} - -func (h HostSystem) String() string { - if h.InventoryPath == "" { - return h.Common.String() - } - return fmt.Sprintf("%v @ %v", h.Common, h.InventoryPath) } func NewHostSystem(c *vim25.Client, ref types.ManagedObjectReference) *HostSystem { @@ -46,17 +37,6 @@ func NewHostSystem(c *vim25.Client, ref types.ManagedObjectReference) *HostSyste } } -func (h HostSystem) Name(ctx context.Context) (string, error) { - var mh mo.HostSystem - - err := h.Properties(ctx, h.Reference(), []string{"name"}, &mh) - if err != nil { - return "", err - } - - return mh.Name, nil -} - func (h HostSystem) ConfigManager() *HostConfigManager { return NewHostConfigManager(h.c, h.Reference()) } diff --git a/vendor/github.com/vmware/govmomi/object/namespace_manager.go b/vendor/github.com/vmware/govmomi/object/namespace_manager.go new file mode 100644 index 00000000000..32f849f9337 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/namespace_manager.go @@ -0,0 +1,75 @@ +/* +Copyright (c) 2015 VMware, Inc. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type DatastoreNamespaceManager struct { + Common +} + +func NewDatastoreNamespaceManager(c *vim25.Client) *DatastoreNamespaceManager { + n := DatastoreNamespaceManager{ + Common: NewCommon(c, *c.ServiceContent.DatastoreNamespaceManager), + } + + return &n +} + +// CreateDirectory creates a top-level directory on the given vsan datastore, using +// the given user display name hint and opaque storage policy. +func (nm DatastoreNamespaceManager) CreateDirectory(ctx context.Context, ds *Datastore, displayName string, policy string) (string, error) { + + req := &types.CreateDirectory{ + This: nm.Reference(), + Datastore: ds.Reference(), + DisplayName: displayName, + Policy: policy, + } + + resp, err := methods.CreateDirectory(ctx, nm.c, req) + if err != nil { + return "", err + } + + return resp.Returnval, nil +} + +// DeleteDirectory deletes the given top-level directory from a vsan datastore. +func (nm DatastoreNamespaceManager) DeleteDirectory(ctx context.Context, dc *Datacenter, datastorePath string) error { + + req := &types.DeleteDirectory{ + This: nm.Reference(), + DatastorePath: datastorePath, + } + + if dc != nil { + ref := dc.Reference() + req.Datacenter = &ref + } + + if _, err := methods.DeleteDirectory(ctx, nm.c, req); err != nil { + return err + } + + return nil +} diff --git a/vendor/github.com/vmware/govmomi/object/network.go b/vendor/github.com/vmware/govmomi/object/network.go index 9963744aa77..a5a72271c44 100644 --- a/vendor/github.com/vmware/govmomi/object/network.go +++ b/vendor/github.com/vmware/govmomi/object/network.go @@ -17,8 +17,6 @@ limitations under the License. package object import ( - "path" - "github.com/vmware/govmomi/vim25" "github.com/vmware/govmomi/vim25/types" "golang.org/x/net/context" @@ -26,8 +24,6 @@ import ( type Network struct { Common - - InventoryPath string } func NewNetwork(c *vim25.Client, ref types.ManagedObjectReference) *Network { @@ -36,10 +32,6 @@ func NewNetwork(c *vim25.Client, ref types.ManagedObjectReference) *Network { } } -func (n Network) Name() string { - return path.Base(n.InventoryPath) -} - // EthernetCardBackingInfo returns the VirtualDeviceBackingInfo for this Network func (n Network) EthernetCardBackingInfo(_ context.Context) (types.BaseVirtualDeviceBackingInfo, error) { name := n.Name() diff --git a/vendor/github.com/vmware/govmomi/object/resource_pool.go b/vendor/github.com/vmware/govmomi/object/resource_pool.go index e03460854e5..8b29b0ef833 100644 --- a/vendor/github.com/vmware/govmomi/object/resource_pool.go +++ b/vendor/github.com/vmware/govmomi/object/resource_pool.go @@ -17,26 +17,14 @@ limitations under the License. package object import ( - "fmt" - "github.com/vmware/govmomi/vim25" "github.com/vmware/govmomi/vim25/methods" - "github.com/vmware/govmomi/vim25/mo" "github.com/vmware/govmomi/vim25/types" "golang.org/x/net/context" ) type ResourcePool struct { Common - - InventoryPath string -} - -func (p ResourcePool) String() string { - if p.InventoryPath == "" { - return p.Common.String() - } - return fmt.Sprintf("%v @ %v", p.Common, p.InventoryPath) } func NewResourcePool(c *vim25.Client, ref types.ManagedObjectReference) *ResourcePool { @@ -45,17 +33,6 @@ func NewResourcePool(c *vim25.Client, ref types.ManagedObjectReference) *Resourc } } -func (p ResourcePool) Name(ctx context.Context) (string, error) { - var o mo.ResourcePool - - err := p.Properties(ctx, p.Reference(), []string{"name"}, &o) - if err != nil { - return "", err - } - - return o.Name, nil -} - func (p ResourcePool) ImportVApp(ctx context.Context, spec types.BaseImportSpec, folder *Folder, host *HostSystem) (*HttpNfcLease, error) { req := types.ImportVApp{ This: p.Reference(), diff --git a/vendor/github.com/vmware/govmomi/object/virtual_app.go b/vendor/github.com/vmware/govmomi/object/virtual_app.go index 5b93f618f7f..1d80472b59b 100644 --- a/vendor/github.com/vmware/govmomi/object/virtual_app.go +++ b/vendor/github.com/vmware/govmomi/object/virtual_app.go @@ -17,13 +17,10 @@ limitations under the License. package object import ( - "fmt" - "golang.org/x/net/context" "github.com/vmware/govmomi/vim25" "github.com/vmware/govmomi/vim25/methods" - "github.com/vmware/govmomi/vim25/mo" "github.com/vmware/govmomi/vim25/types" ) @@ -37,24 +34,6 @@ func NewVirtualApp(c *vim25.Client, ref types.ManagedObjectReference) *VirtualAp } } -func (p VirtualApp) String() string { - if p.InventoryPath == "" { - return p.Common.String() - } - return fmt.Sprintf("%v @ %v", p.Common, p.InventoryPath) -} - -func (p VirtualApp) Name(ctx context.Context) (string, error) { - var o mo.VirtualApp - - err := p.Properties(ctx, p.Reference(), []string{"name"}, &o) - if err != nil { - return "", err - } - - return o.Name, nil -} - func (p VirtualApp) CreateChildVM_Task(ctx context.Context, config types.VirtualMachineConfigSpec, host *HostSystem) (*Task, error) { req := types.CreateChildVM_Task{ This: p.Reference(), diff --git a/vendor/github.com/vmware/govmomi/object/virtual_disk_manager.go b/vendor/github.com/vmware/govmomi/object/virtual_disk_manager.go index 800cfa07661..485053a9962 100644 --- a/vendor/github.com/vmware/govmomi/object/virtual_disk_manager.go +++ b/vendor/github.com/vmware/govmomi/object/virtual_disk_manager.go @@ -143,3 +143,27 @@ func (m VirtualDiskManager) DeleteVirtualDisk(ctx context.Context, name string, return NewTask(m.c, res.Returnval), nil } + +// Queries virtual disk uuid +func (m VirtualDiskManager) QueryVirtualDiskUuid(ctx context.Context, name string, dc *Datacenter) (string, error) { + req := types.QueryVirtualDiskUuid{ + This: m.Reference(), + Name: name, + } + + if dc != nil { + ref := dc.Reference() + req.Datacenter = &ref + } + + res, err := methods.QueryVirtualDiskUuid(ctx, m.c, &req) + if err != nil { + return "", err + } + + if res == nil { + return "", nil + } + + return res.Returnval, nil +} diff --git a/vendor/github.com/vmware/govmomi/object/virtual_machine.go b/vendor/github.com/vmware/govmomi/object/virtual_machine.go index 4faeae75e39..313c50069d8 100644 --- a/vendor/github.com/vmware/govmomi/object/virtual_machine.go +++ b/vendor/github.com/vmware/govmomi/object/virtual_machine.go @@ -18,7 +18,6 @@ package object import ( "errors" - "fmt" "net" "github.com/vmware/govmomi/property" @@ -35,15 +34,6 @@ const ( type VirtualMachine struct { Common - - InventoryPath string -} - -func (v VirtualMachine) String() string { - if v.InventoryPath == "" { - return v.Common.String() - } - return fmt.Sprintf("%v @ %v", v.Common, v.InventoryPath) } func NewVirtualMachine(c *vim25.Client, ref types.ManagedObjectReference) *VirtualMachine { @@ -52,17 +42,6 @@ func NewVirtualMachine(c *vim25.Client, ref types.ManagedObjectReference) *Virtu } } -func (v VirtualMachine) Name(ctx context.Context) (string, error) { - var o mo.VirtualMachine - - err := v.Properties(ctx, v.Reference(), []string{"name"}, &o) - if err != nil { - return "", err - } - - return o.Name, nil -} - func (v VirtualMachine) PowerState(ctx context.Context) (types.VirtualMachinePowerState, error) { var o mo.VirtualMachine diff --git a/vendor/github.com/vmware/govmomi/session/manager.go b/vendor/github.com/vmware/govmomi/session/manager.go index 5df6ebfc4bd..ed688839206 100644 --- a/vendor/github.com/vmware/govmomi/session/manager.go +++ b/vendor/github.com/vmware/govmomi/session/manager.go @@ -161,3 +161,17 @@ func (sm *Manager) AcquireGenericServiceTicket(ctx context.Context, spec types.B return &res.Returnval, nil } + +func (sm *Manager) AcquireLocalTicket(ctx context.Context, userName string) (*types.SessionManagerLocalTicket, error) { + req := types.AcquireLocalTicket{ + This: sm.Reference(), + UserName: userName, + } + + res, err := methods.AcquireLocalTicket(ctx, sm.client, &req) + if err != nil { + return nil, err + } + + return &res.Returnval, nil +} diff --git a/vendor/github.com/vmware/govmomi/vim25/mo/ancestors.go b/vendor/github.com/vmware/govmomi/vim25/mo/ancestors.go index 4bea1552c51..c3e7e536e03 100644 --- a/vendor/github.com/vmware/govmomi/vim25/mo/ancestors.go +++ b/vendor/github.com/vmware/govmomi/vim25/mo/ancestors.go @@ -17,6 +17,8 @@ limitations under the License. package mo import ( + "fmt" + "github.com/vmware/govmomi/vim25/soap" "github.com/vmware/govmomi/vim25/types" "golang.org/x/net/context" @@ -76,6 +78,24 @@ func Ancestors(ctx context.Context, rt soap.RoundTripper, pc, obj types.ManagedO // Find entity we're looking for given the last entity in the current tree. for _, iface := range ifaces { me := iface.(IsManagedEntity).GetManagedEntity() + + if me.Name == "" { + // The types below have their own 'Name' field, so ManagedEntity.Name (me.Name) is empty. + // We only hit this case when the 'obj' param is one of these types. + // In most cases, 'obj' is a Folder so Name isn't collected in this call. + switch x := iface.(type) { + case Network: + me.Name = x.Name + case DistributedVirtualSwitch: + me.Name = x.Name + case DistributedVirtualPortgroup: + me.Name = x.Name + default: + // ManagedEntity always has a Name, if we hit this point we missed a case above. + panic(fmt.Sprintf("%#v Name is empty", me.Reference())) + } + } + if me.Parent == nil { out = append(out, me) break diff --git a/vendor/github.com/vmware/govmomi/vim25/mo/extra.go b/vendor/github.com/vmware/govmomi/vim25/mo/extra.go index 36ed5ff0f80..254ef35949b 100644 --- a/vendor/github.com/vmware/govmomi/vim25/mo/extra.go +++ b/vendor/github.com/vmware/govmomi/vim25/mo/extra.go @@ -36,6 +36,10 @@ func (m DistributedVirtualSwitch) GetManagedEntity() ManagedEntity { return m.ManagedEntity } +func (m DistributedVirtualPortgroup) GetManagedEntity() ManagedEntity { + return m.ManagedEntity +} + func (m Folder) GetManagedEntity() ManagedEntity { return m.ManagedEntity } diff --git a/vendor/github.com/vmware/govmomi/vim25/soap/soap.go b/vendor/github.com/vmware/govmomi/vim25/soap/soap.go index e3b1a97dc47..ea35e77ad7b 100644 --- a/vendor/github.com/vmware/govmomi/vim25/soap/soap.go +++ b/vendor/github.com/vmware/govmomi/vim25/soap/soap.go @@ -36,7 +36,7 @@ type Fault struct { Code string `xml:"faultcode"` String string `xml:"faultstring"` Detail struct { - Fault types.AnyType `xml:",any"` + Fault types.AnyType `xml:",any,typeattr"` } `xml:"detail"` } diff --git a/vendor/github.com/vmware/govmomi/vim25/types/helpers.go b/vendor/github.com/vmware/govmomi/vim25/types/helpers.go index 75c82cab3f9..7b72358b25d 100644 --- a/vendor/github.com/vmware/govmomi/vim25/types/helpers.go +++ b/vendor/github.com/vmware/govmomi/vim25/types/helpers.go @@ -16,6 +16,8 @@ limitations under the License. package types +import "strings" + func NewBool(v bool) *bool { return &v } @@ -23,3 +25,24 @@ func NewBool(v bool) *bool { func NewReference(r ManagedObjectReference) *ManagedObjectReference { return &r } + +func (r ManagedObjectReference) Reference() ManagedObjectReference { + return r +} + +func (r ManagedObjectReference) String() string { + return strings.Join([]string{r.Type, r.Value}, ":") +} + +func (r *ManagedObjectReference) FromString(o string) bool { + s := strings.SplitN(o, ":", 2) + + if len(s) < 2 { + return false + } + + r.Type = s[0] + r.Value = s[1] + + return true +}