Skip to content

Commit

Permalink
Datastore create: ensure targetHypervisorClusterId exists
Browse files Browse the repository at this point in the history
A change in server behaviour means that a POST request
to create a datastore such as:

```
{
  "name": "mclaren-dsx24",
  "sizeInBytes": 17179869184,
  "storageSystemId": "f9689284-0bbd-5bf1-981f-b9799bbc106c",
  "targetHypervisorClusterId": "",
  "datastoreType": "VMFS"
}

```

will return a 400 error such as

```
{
  "debugId": "df4c4f566584ca1fc4511d77fe668f0d",
  "errorCode": "HPE_GL_VIRTUALIZATION_BAD_REQUEST",
  "httpStatusCode": 400,
  "message": "input attributes name, type, sizeInBytes, storageSystemID and targetHypervisorClusterID are mandatory parameters. Error: Key: 'CreateDatastoreVirtRequest.TargetHypervisorClusterID' Error:Field validation for 'TargetHypervisorClusterID' failed on the 'required' tag"
}
```

To avoid this error, rather than have the system set a default
value for targetHypervisorClusterId, we set it expliclity like
this:

```
{
  "name": "mclaren-dsx24",
  "sizeInBytes": 17179869184,
  "storageSystemId": "f9689284-0bbd-5bf1-981f-b9799bbc106c",
  "targetHypervisorClusterId": "ef277a80-6891-534a-9a36-5c7fa67d582a",
  "datastoreType": "VMFS"
}
```

This requires an additional REST API call to determine the
cluster id value based on the name.
  • Loading branch information
stuart-mclaren-hpe committed Nov 12, 2024
1 parent da1477c commit 23ddaf1
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 6 deletions.
8 changes: 5 additions & 3 deletions internal/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
package constants

const (
ProviderType = "hpegl"
ProviderBlock = "pc"
NameFilter = "name eq "
ProviderType = "hpegl"
ProviderBlock = "pc"
NameFilter = "name eq "
HciClusterUUIDFilter = "hciClusterUuid eq "
AndFilter = " and "
)
87 changes: 84 additions & 3 deletions internal/resources/datastore/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -329,12 +329,96 @@ func doRead(
DatacentersInfo.ElementType(ctx), datacentersInfoValues)
}

func createHypervisorClusterFilter(
hciClusterUUID string,
hypervisorClusterName string,
) string {
return constants.HciClusterUUIDFilter + hciClusterUUID +
constants.AndFilter +
constants.NameFilter + hypervisorClusterName
}

func getTargetHypervisorClusterID(
ctx context.Context,
client client.PCBeClient,
hciClusterUUID string, // "system" ID
hypervisorClusterName string,
) (string, error) {
virtClient, _, err := client.NewVirtClient(ctx)
if err != nil {
msg := "error getting hypervisor cluster ID for " +
hypervisorClusterName + err.Error()
tflog.Error(ctx, msg)

return "", errors.New(msg)
}
qp := virtualization.V1beta1HypervisorClustersRequestBuilderGetQueryParameters{}
filter := createHypervisorClusterFilter(hciClusterUUID, hypervisorClusterName)
qp.Filter = &filter
grc := virtualization.
V1beta1HypervisorClustersRequestBuilderGetRequestConfiguration{}
grc.QueryParameters = &qp

hypervisorClusters, err := virtClient.Virtualization().
V1beta1().
HypervisorClusters().
GetAsHypervisorClustersGetResponse(ctx, &grc)
if err != nil {
msg := "error getting hypervisor cluster ID for " +
hypervisorClusterName + err.Error()
tflog.Error(ctx, msg)

return "", errors.New(msg)
}

if hypervisorClusters.GetTotal() == nil {
msg := "error getting hypervisor cluster ID for " +
hypervisorClusterName + " 'total' field is nil"
tflog.Error(ctx, msg)

return "", errors.New(msg)
}

total := *(hypervisorClusters.GetTotal())
if total != 1 {
msg := "error getting hypervisor cluster ID for " +
hypervisorClusterName +
fmt.Sprintf("required 1 hypervisorCluster with name %s, got %d",
hypervisorClusterName, total)
tflog.Error(ctx, msg)

return "", errors.New(msg)
}
id := hypervisorClusters.GetItems()[0].GetId()

return *id, nil
}

func doCreate(
ctx context.Context,
client client.PCBeClient,
dataP *DatastoreModel,
diagsP *diag.Diagnostics,
) {
hciClusterUUID := (*dataP).HciClusterUuid.ValueString()
clusterInfoName := (*dataP).ClusterInfo.Name.ValueString()

targetHypervisorClusterID, err := getTargetHypervisorClusterID(
ctx,
client,
hciClusterUUID,
clusterInfoName,
)
if err != nil {
(*diagsP).AddError(
"error creating datastore",
"could not get id of hypervisor cluster: "+
clusterInfoName+" "+err.Error(),
)

return
}

virtClient, virtHeaderOpts, err := client.NewVirtClient(ctx)
if err != nil {
(*diagsP).AddError(
Expand Down Expand Up @@ -381,10 +465,7 @@ func doCreate(
sizeInBytes := (*dataP).CapacityInBytes.ValueInt64()
prb.SetSizeInBytes(&sizeInBytes)

targetHypervisorClusterID := (*dataP).ClusterInfo.Id.ValueString()
prb.SetTargetHypervisorClusterId(&targetHypervisorClusterID)

hciClusterUUID := (*dataP).HciClusterUuid.ValueString()
prb.SetStorageSystemId(&hciClusterUUID)

datastoreType := datastores.VMFS_DATASTORESPOSTREQUESTBODY_DATASTORETYPE
Expand Down
13 changes: 13 additions & 0 deletions internal/simulator/datastore_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import (
"github.com/h2non/gock"
)

//go:embed fixtures/datastores/create/hypervisorclustersfiltered.json
var hcFilter string

//go:embed fixtures/datastores/create/async1.json
var dsAsync1 string

Expand All @@ -33,6 +36,16 @@ func datastoreCreate() {
taskID := "be55685c-f84f-4ad5-a3d1-2d7692ed47b1"
datastoreID := "698de955-87b5-5fe6-b683-78c3948beede"
datastoreName := "mclaren-ds19"
hypervisorClusterID := "126fd201-9e6e-5e31-9ffb-a766265b1fd3" // nolint goconst
clusterName := "5305-CL"

gock.New("http://localhost").
Get("/virtualization/v1beta1/hypervisor-clusters").
MatchParam("filter", "hciClusterUuid eq "+hypervisorClusterID+
" and name eq "+clusterName).
Reply(200).
SetHeader("Content-Type", "application/json").
BodyString(hcFilter)

gock.New("http://localhost").
Post("/virtualization/v1beta1/datastore").
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{"items": [{"appInfo":{"vmware":{"datacenterInfo":{"displayName":"","id":"7d8051ab-4224-5075-93be-c1c0fa645e7d","moref":"datacenter-3","name":"5305-DC"},"moref":"domain-c19"}},"clusterPerfMetricInfo":{"cpuCapacityInMhz":0,"cpuUsageInMhz":0,"memorySizeInBytes":0,"memoryUsageInMb":0,"totalStorageInBytes":0,"usedStorageInBytes":0},"clusterType":"ESX_CLUSTER","createdAt":"2024-07-17T15:57:09Z","customerId":"bb20052ac81011ed895f7a6e2fba2c57","displayName":"mclaren01","drsConfigInfo":{"defaultVmBehavior":"fullyAutomated","enableVmBehaviorOverrides":true,"enabled":true,"vmotionRate":3},"generation":1,"hciClusterUuid":"126fd201-9e6e-5e31-9ffb-a766265b1fd3","hypervisorHosts":null,"hypervisorManagerInfo":{"displayName":"16.182.107.157","id":"c47b89e9-3a66-4fb9-9a22-cdec3c51604d","name":"16.182.107.157","resourceUri":"/virtualization/v1beta1/hypervisor-managers/c47b89e9-3a66-4fb9-9a22-cdec3c51604d","type":"virtualization/hypervisor-manager"},"id":"298a299e-78f5-5acb-86ce-4e9fdc290ab7","name":"mclaren01","networksInfo":null,"resourceUri":"/virtualization/v1beta1/hypervisor-clusters/298a299e-78f5-5acb-86ce-4e9fdc290ab7","services":["hci-manager"],"state":"OK","stateReason":"OK","status":"OK","type":"virtualization/hypervisor-cluster","updatedAt":"2024-07-17T15:57:09Z"} ], "count": 1, "offset": 0, "total": 1}

0 comments on commit 23ddaf1

Please sign in to comment.