github.com/vmware/govmomi@v0.43.0/simulator/storage_resource_manager.go (about) 1 /* 2 Copyright (c) 2018 VMware, Inc. All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package simulator 18 19 import ( 20 "strconv" 21 "time" 22 23 "github.com/vmware/govmomi/object" 24 "github.com/vmware/govmomi/vim25/methods" 25 "github.com/vmware/govmomi/vim25/mo" 26 "github.com/vmware/govmomi/vim25/soap" 27 "github.com/vmware/govmomi/vim25/types" 28 ) 29 30 type StorageResourceManager struct { 31 mo.StorageResourceManager 32 } 33 34 func (m *StorageResourceManager) ConfigureStorageDrsForPodTask(ctx *Context, req *types.ConfigureStorageDrsForPod_Task) soap.HasFault { 35 task := CreateTask(m, "configureStorageDrsForPod", func(*Task) (types.AnyType, types.BaseMethodFault) { 36 cluster := Map.Get(req.Pod).(*StoragePod) 37 38 if s := req.Spec.PodConfigSpec; s != nil { 39 config := &cluster.PodStorageDrsEntry.StorageDrsConfig.PodConfig 40 41 if s.Enabled != nil { 42 config.Enabled = *s.Enabled 43 } 44 if s.DefaultVmBehavior != "" { 45 config.DefaultVmBehavior = s.DefaultVmBehavior 46 } 47 } 48 49 return nil, nil 50 }) 51 52 return &methods.ConfigureStorageDrsForPod_TaskBody{ 53 Res: &types.ConfigureStorageDrsForPod_TaskResponse{ 54 Returnval: task.Run(ctx), 55 }, 56 } 57 } 58 59 func (m *StorageResourceManager) pod(ref *types.ManagedObjectReference) *StoragePod { 60 if ref == nil { 61 return nil 62 } 63 cluster := Map.Get(*ref).(*StoragePod) 64 config := &cluster.PodStorageDrsEntry.StorageDrsConfig.PodConfig 65 66 if !config.Enabled { 67 return nil 68 } 69 70 if len(cluster.ChildEntity) == 0 { 71 return nil 72 } 73 74 return cluster 75 } 76 77 func (m *StorageResourceManager) RecommendDatastores(req *types.RecommendDatastores) soap.HasFault { 78 spec := req.StorageSpec.PodSelectionSpec 79 body := new(methods.RecommendDatastoresBody) 80 res := new(types.RecommendDatastoresResponse) 81 key := 0 82 invalid := func(prop string) soap.HasFault { 83 body.Fault_ = Fault("", &types.InvalidArgument{ 84 InvalidProperty: prop, 85 }) 86 return body 87 } 88 add := func(cluster *StoragePod, ds types.ManagedObjectReference) { 89 key++ 90 res.Returnval.Recommendations = append(res.Returnval.Recommendations, types.ClusterRecommendation{ 91 Key: strconv.Itoa(key), 92 Type: "V1", 93 Time: time.Now(), 94 Rating: 1, 95 Reason: "storagePlacement", 96 ReasonText: "Satisfy storage initial placement requests", 97 WarningText: "", 98 WarningDetails: (*types.LocalizableMessage)(nil), 99 Prerequisite: nil, 100 Action: []types.BaseClusterAction{ 101 &types.StoragePlacementAction{ 102 ClusterAction: types.ClusterAction{ 103 Type: "StoragePlacementV1", 104 Target: (*types.ManagedObjectReference)(nil), 105 }, 106 Vm: (*types.ManagedObjectReference)(nil), 107 RelocateSpec: types.VirtualMachineRelocateSpec{ 108 Service: (*types.ServiceLocator)(nil), 109 Folder: (*types.ManagedObjectReference)(nil), 110 Datastore: &ds, 111 DiskMoveType: "moveAllDiskBackingsAndAllowSharing", 112 Pool: (*types.ManagedObjectReference)(nil), 113 Host: (*types.ManagedObjectReference)(nil), 114 Disk: nil, 115 Transform: "", 116 DeviceChange: nil, 117 Profile: nil, 118 }, 119 Destination: ds, 120 SpaceUtilBefore: 5.00297212600708, 121 SpaceDemandBefore: 5.00297212600708, 122 SpaceUtilAfter: 5.16835880279541, 123 SpaceDemandAfter: 5.894514083862305, 124 IoLatencyBefore: 0, 125 }, 126 }, 127 Target: &cluster.Self, 128 }) 129 } 130 131 var devices object.VirtualDeviceList 132 133 switch types.StoragePlacementSpecPlacementType(req.StorageSpec.Type) { 134 case types.StoragePlacementSpecPlacementTypeCreate: 135 if req.StorageSpec.ResourcePool == nil { 136 return invalid("resourcePool") 137 } 138 if req.StorageSpec.ConfigSpec == nil { 139 return invalid("configSpec") 140 } 141 for _, d := range req.StorageSpec.ConfigSpec.DeviceChange { 142 devices = append(devices, d.GetVirtualDeviceConfigSpec().Device) 143 } 144 cluster := m.pod(spec.StoragePod) 145 if cluster == nil { 146 if f := req.StorageSpec.ConfigSpec.Files; f == nil || f.VmPathName == "" { 147 return invalid("configSpec.files") 148 } 149 } 150 case types.StoragePlacementSpecPlacementTypeClone: 151 if req.StorageSpec.Folder == nil { 152 return invalid("folder") 153 } 154 if req.StorageSpec.Vm == nil { 155 return invalid("vm") 156 } 157 if req.StorageSpec.CloneName == "" { 158 return invalid("cloneName") 159 } 160 if req.StorageSpec.CloneSpec == nil { 161 return invalid("cloneSpec") 162 } 163 } 164 165 for _, placement := range spec.InitialVmConfig { 166 cluster := m.pod(&placement.StoragePod) 167 if cluster == nil { 168 return invalid("podSelectionSpec.storagePod") 169 } 170 171 for _, disk := range placement.Disk { 172 if devices.FindByKey(disk.DiskId) == nil { 173 return invalid("podSelectionSpec.initialVmConfig.disk.fileBacking") 174 } 175 } 176 177 for _, ds := range cluster.ChildEntity { 178 add(cluster, ds) 179 } 180 } 181 182 body.Res = res 183 return body 184 }