github.com/vmware/govmomi@v0.51.0/simulator/storage_resource_manager.go (about)

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