1/* 2Copyright (c) 2015 VMware, Inc. All Rights Reserved. 3 4Licensed under the Apache License, Version 2.0 (the "License"); 5you may not use this file except in compliance with the License. 6You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10Unless required by applicable law or agreed to in writing, software 11distributed under the License is distributed on an "AS IS" BASIS, 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13See the License for the specific language governing permissions and 14limitations under the License. 15*/ 16 17package object 18 19import ( 20 "context" 21 "fmt" 22 23 "github.com/vmware/govmomi/vim25" 24 "github.com/vmware/govmomi/vim25/methods" 25 "github.com/vmware/govmomi/vim25/mo" 26 "github.com/vmware/govmomi/vim25/types" 27) 28 29type DatacenterFolders struct { 30 VmFolder *Folder 31 HostFolder *Folder 32 DatastoreFolder *Folder 33 NetworkFolder *Folder 34} 35 36type Datacenter struct { 37 Common 38} 39 40func NewDatacenter(c *vim25.Client, ref types.ManagedObjectReference) *Datacenter { 41 return &Datacenter{ 42 Common: NewCommon(c, ref), 43 } 44} 45 46func (d *Datacenter) Folders(ctx context.Context) (*DatacenterFolders, error) { 47 var md mo.Datacenter 48 49 ps := []string{"name", "vmFolder", "hostFolder", "datastoreFolder", "networkFolder"} 50 err := d.Properties(ctx, d.Reference(), ps, &md) 51 if err != nil { 52 return nil, err 53 } 54 55 df := &DatacenterFolders{ 56 VmFolder: NewFolder(d.c, md.VmFolder), 57 HostFolder: NewFolder(d.c, md.HostFolder), 58 DatastoreFolder: NewFolder(d.c, md.DatastoreFolder), 59 NetworkFolder: NewFolder(d.c, md.NetworkFolder), 60 } 61 62 paths := []struct { 63 name string 64 path *string 65 }{ 66 {"vm", &df.VmFolder.InventoryPath}, 67 {"host", &df.HostFolder.InventoryPath}, 68 {"datastore", &df.DatastoreFolder.InventoryPath}, 69 {"network", &df.NetworkFolder.InventoryPath}, 70 } 71 72 for _, p := range paths { 73 *p.path = fmt.Sprintf("/%s/%s", md.Name, p.name) 74 } 75 76 return df, nil 77} 78 79func (d Datacenter) Destroy(ctx context.Context) (*Task, error) { 80 req := types.Destroy_Task{ 81 This: d.Reference(), 82 } 83 84 res, err := methods.Destroy_Task(ctx, d.c, &req) 85 if err != nil { 86 return nil, err 87 } 88 89 return NewTask(d.c, res.Returnval), nil 90} 91 92// PowerOnVM powers on multiple virtual machines with a single vCenter call. 93// If called against ESX, serially powers on the list of VMs and the returned *Task will always be nil. 94func (d Datacenter) PowerOnVM(ctx context.Context, vm []types.ManagedObjectReference, option ...types.BaseOptionValue) (*Task, error) { 95 if d.Client().IsVC() { 96 req := types.PowerOnMultiVM_Task{ 97 This: d.Reference(), 98 Vm: vm, 99 Option: option, 100 } 101 102 res, err := methods.PowerOnMultiVM_Task(ctx, d.c, &req) 103 if err != nil { 104 return nil, err 105 } 106 107 return NewTask(d.c, res.Returnval), nil 108 } 109 110 for _, ref := range vm { 111 obj := NewVirtualMachine(d.Client(), ref) 112 task, err := obj.PowerOn(ctx) 113 if err != nil { 114 return nil, err 115 } 116 117 err = task.Wait(ctx) 118 if err != nil { 119 // Ignore any InvalidPowerState fault, as it indicates the VM is already powered on 120 if f, ok := err.(types.HasFault); ok { 121 if _, ok = f.Fault().(*types.InvalidPowerState); !ok { 122 return nil, err 123 } 124 } 125 } 126 } 127 128 return nil, nil 129} 130