1/* 2Copyright (c) 2017 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 simulator 18 19import ( 20 "strings" 21 22 "github.com/vmware/govmomi/simulator/esx" 23 "github.com/vmware/govmomi/vim25/methods" 24 "github.com/vmware/govmomi/vim25/mo" 25 "github.com/vmware/govmomi/vim25/soap" 26 "github.com/vmware/govmomi/vim25/types" 27) 28 29type Datacenter struct { 30 mo.Datacenter 31 32 isESX bool 33} 34 35// NewDatacenter creates a Datacenter and its child folders. 36func NewDatacenter(f *Folder) *Datacenter { 37 dc := &Datacenter{ 38 isESX: f.Self == esx.RootFolder.Self, 39 } 40 41 if dc.isESX { 42 dc.Datacenter = esx.Datacenter 43 } 44 45 f.putChild(dc) 46 47 dc.createFolders() 48 49 return dc 50} 51 52// Create Datacenter Folders. 53// Every Datacenter has 4 inventory Folders: Vm, Host, Datastore and Network. 54// The ESX folder child types are limited to 1 type. 55// The VC folders have additional child types, including nested folders. 56func (dc *Datacenter) createFolders() { 57 folders := []struct { 58 ref *types.ManagedObjectReference 59 name string 60 types []string 61 }{ 62 {&dc.VmFolder, "vm", []string{"VirtualMachine", "VirtualApp", "Folder"}}, 63 {&dc.HostFolder, "host", []string{"ComputeResource", "Folder"}}, 64 {&dc.DatastoreFolder, "datastore", []string{"Datastore", "StoragePod", "Folder"}}, 65 {&dc.NetworkFolder, "network", []string{"Network", "DistributedVirtualSwitch", "Folder"}}, 66 } 67 68 for _, f := range folders { 69 folder := &Folder{} 70 folder.Name = f.name 71 72 if dc.isESX { 73 folder.ChildType = f.types[:1] 74 folder.Self = *f.ref 75 Map.PutEntity(dc, folder) 76 } else { 77 folder.ChildType = f.types 78 e := Map.PutEntity(dc, folder) 79 80 // propagate the generated morefs to Datacenter 81 ref := e.Reference() 82 f.ref.Type = ref.Type 83 f.ref.Value = ref.Value 84 } 85 } 86 87 net := Map.Get(dc.NetworkFolder).(*Folder) 88 89 for _, ref := range esx.Datacenter.Network { 90 // Add VM Network by default to each Datacenter 91 network := &mo.Network{} 92 network.Self = ref 93 network.Name = strings.Split(ref.Value, "-")[1] 94 network.Entity().Name = network.Name 95 if !dc.isESX { 96 network.Self.Value = "" // we want a different moid per-DC 97 } 98 99 net.putChild(network) 100 } 101} 102 103func datacenterEventArgument(obj mo.Entity) *types.DatacenterEventArgument { 104 dc, ok := obj.(*Datacenter) 105 if !ok { 106 dc = Map.getEntityDatacenter(obj) 107 } 108 return &types.DatacenterEventArgument{ 109 Datacenter: dc.Self, 110 EntityEventArgument: types.EntityEventArgument{Name: dc.Name}, 111 } 112} 113 114func (dc *Datacenter) PowerOnMultiVMTask(ctx *Context, req *types.PowerOnMultiVM_Task) soap.HasFault { 115 task := CreateTask(dc, "powerOnMultiVM", func(_ *Task) (types.AnyType, types.BaseMethodFault) { 116 if dc.isESX { 117 return nil, new(types.NotImplemented) 118 } 119 120 for _, ref := range req.Vm { 121 vm := Map.Get(ref).(*VirtualMachine) 122 Map.WithLock(vm, func() { 123 vm.PowerOnVMTask(ctx, &types.PowerOnVM_Task{}) 124 }) 125 } 126 127 return nil, nil 128 }) 129 130 return &methods.PowerOnMultiVM_TaskBody{ 131 Res: &types.PowerOnMultiVM_TaskResponse{ 132 Returnval: task.Run(), 133 }, 134 } 135} 136 137func (d *Datacenter) DestroyTask(req *types.Destroy_Task) soap.HasFault { 138 task := CreateTask(d, "destroy", func(t *Task) (types.AnyType, types.BaseMethodFault) { 139 folders := []types.ManagedObjectReference{ 140 d.VmFolder, 141 d.HostFolder, 142 } 143 144 for _, ref := range folders { 145 if len(Map.Get(ref).(*Folder).ChildEntity) != 0 { 146 return nil, &types.ResourceInUse{} 147 } 148 } 149 150 Map.Get(*d.Parent).(*Folder).removeChild(d.Self) 151 152 return nil, nil 153 }) 154 155 return &methods.Destroy_TaskBody{ 156 Res: &types.Destroy_TaskResponse{ 157 Returnval: task.Run(), 158 }, 159 } 160} 161