From 77fcc74607d3e92f94cf76b49b4b8597b9505388 Mon Sep 17 00:00:00 2001 From: sam Date: Mon, 18 Nov 2024 14:24:47 +0000 Subject: [PATCH] Add hypervisor cluster delete Now that the server API supports hypervisor cluster delete, we can add support in the Terraform provider. --- .../resources/hypervisorcluster/resource.go | 50 ++++++++++++++++++- .../hypervisorclusters/delete/async1.json | 1 + .../hypervisorclusters/delete/async2.json | 2 + internal/simulator/hypervisorcluster.go | 8 +++ .../simulator/hypervisorcluster_create.go | 6 --- .../simulator/hypervisorcluster_delete.go | 41 +++++++++++++++ .../hypervisorcluster_test.go | 19 ++++++- 7 files changed, 118 insertions(+), 9 deletions(-) create mode 100644 internal/simulator/fixtures/hypervisorclusters/delete/async1.json create mode 100644 internal/simulator/fixtures/hypervisorclusters/delete/async2.json create mode 100644 internal/simulator/hypervisorcluster.go create mode 100644 internal/simulator/hypervisorcluster_delete.go diff --git a/internal/resources/hypervisorcluster/resource.go b/internal/resources/hypervisorcluster/resource.go index 29ee91e..b45b3aa 100644 --- a/internal/resources/hypervisorcluster/resource.go +++ b/internal/resources/hypervisorcluster/resource.go @@ -407,8 +407,54 @@ func (r *Resource) Delete( req resource.DeleteRequest, resp *resource.DeleteResponse, ) { - // TODO: (API) Implement delete hypervisorcluster when API supports it - tflog.Error(ctx, "delete hypervisorcluster is not implemented") + var data HypervisorclusterModel + + resp.Diagnostics.Append(req.State.Get(ctx, &data)...) + + if resp.Diagnostics.HasError() { + return + } + + id := data.Id.ValueString() + client := *r.client + sysClient, sysHeaderOpts, err := client.NewSysClient(ctx) + if err != nil { + resp.Diagnostics.AddError( + "error deleting hypervisorcluster "+id, + "unexpected error creating client: "+err.Error(), + ) + + return + } + + prb := privatecloudbusiness. + NewV1beta1SystemsItemRemoveHypervisorClustersPostRequestBody() + prb.SetHypervisorClusterIds([]string{id}) + prc := privatecloudbusiness. + V1beta1SystemsItemRemoveHypervisorClustersRequestBuilderPostRequestConfiguration{} + + _, err = sysClient.PrivateCloudBusiness(). + V1beta1(). + Systems(). + ById(data.HciClusterUuid.ValueString()). + RemoveHypervisorClusters().Post(ctx, prb, &prc) + + if err != nil { + resp.Diagnostics.AddError( + "error deleting hypervisorcluster "+id, + "unexpected error: "+err.Error(), + ) + + return + } + + location := sysHeaderOpts.GetResponseHeaders().Get("Location")[0] + sysHeaderOpts.ResponseHeaders.Clear() + operationID := path.Base(location) + // If resp.Diagnostics is not empty, then Delete is + // considered to have failed; the hypervisor cluster entry + // in the tfstate file will not be removed + poll.AsyncOperation(ctx, client, operationID, &resp.Diagnostics) } func (r *Resource) ImportState( diff --git a/internal/simulator/fixtures/hypervisorclusters/delete/async1.json b/internal/simulator/fixtures/hypervisorclusters/delete/async1.json new file mode 100644 index 0000000..c4e0c0f --- /dev/null +++ b/internal/simulator/fixtures/hypervisorclusters/delete/async1.json @@ -0,0 +1 @@ +{"associatedResources":[],"createdAt":"2024-11-18T13:44:13.288731414Z","customerId":"131608da3faa11efb5afca2247c626ef","displayName":"Remove Hypervisor Clusters","endedAt":null,"error":null,"estimatedRunningDurationMinutes":10,"generation":1,"groups":[{"id":"131608da3faa11efb5afca2247c626ef","name":"Default Group"}],"hasChildOperations":false,"healthStatus":"OK","id":"a73607cc-ae57-4efe-b573-615813e6c77d","logMessages":[{"message":"Remove hypervisor clusters from hci system group-mip-array5305 starting","timestamp":"2024-11-18T13:44:13.288733298Z"}],"name":"Remove Hypervisor Clusters","parent":null,"progressPercent":0,"recommendations":[],"resourceUri":"/data-services/v1beta1/async-operations/a73607cc-ae57-4efe-b573-615813e6c77d","rootOperation":{"id":"a73607cc-ae57-4efe-b573-615813e6c77d","name":"","resourceUri":"/data-services/v1beta1/async-operations/a73607cc-ae57-4efe-b573-615813e6c77d","type":"task"},"services":["private-cloud-business-edition"],"sourceResourceUri":"/private-cloud-business/v1beta1/systems/126fd201-9e6e-5e31-9ffb-a766265b1fd3","startedAt":"2024-11-18T13:44:13.288731842Z","state":"RUNNING","subtreeOperationCount":0,"suggestedPollingIntervalSeconds":2,"type":"task","updatedAt":"2024-11-18T13:44:13.304000116Z","userId":"stuart.mclaren@hpe.com"} diff --git a/internal/simulator/fixtures/hypervisorclusters/delete/async2.json b/internal/simulator/fixtures/hypervisorclusters/delete/async2.json new file mode 100644 index 0000000..4e0b611 --- /dev/null +++ b/internal/simulator/fixtures/hypervisorclusters/delete/async2.json @@ -0,0 +1,2 @@ +{"associatedResources":[],"createdAt":"2024-11-18T13:44:13.288731414Z","customerId":"131608da3faa11efb5afca2247c626ef","displayName":"Remove Hypervisor Clusters","endedAt":"2024-11-18T13:45:47.844753953Z","error":null,"estimatedRunningDurationMinutes":10,"generation":3,"groups":[{"id":"131608da3faa11efb5afca2247c626ef","name":"Default Group"}],"hasChildOperations":false,"healthStatus":"OK","id":"a73607cc-ae57-4efe-b573-615813e6c77d","logMessages":[{"message":"Remove hypervisor clusters from hci system group-mip-array5305 starting","timestamp":"2024-11-18T13:44:13.288733298Z"},{"message":"Deleted hypervisor cluster mclaren01 in datacenter mip-array5305-DC on HCI system group-mip-array5305","timestamp":"2024-11-18T13:45:47.806931074Z"},{"message":"Remove hypervisor clusters from hci system group-mip-array5305 done","timestamp":"2024-11-18T13:45:47.844715917Z"}],"name":"Remove Hypervisor Clusters","parent":null,"progressPercent":100,"recommendations":[],"resourceUri":"/data-services/v1beta1/async-operations/a73607cc-ae57-4efe-b573-615813e6c77d","rootOperation":{"id":"a73607cc-ae57-4efe-b573-615813e6c77d","name":"","resourceUri":"/data-services/v1beta1/async-operations/a73607cc-ae57-4efe-b573-615813e6c77d","type":"task"},"services":["private-cloud-business-edition"],"sourceResourceUri":"/private-cloud-business/v1beta1/systems/126fd201-9e6e-5e31-9ffb-a766265b1fd3","startedAt":"2024-11-18T13:44:13.288731842Z","state":"SUCCEEDED","subtreeOperationCount":0,"suggestedPollingIntervalSeconds":2,"type":"task","updatedAt":"2024-11-18T13:45:48.024461169Z","userId":"stuart.mclaren@hpe.com"} + diff --git a/internal/simulator/hypervisorcluster.go b/internal/simulator/hypervisorcluster.go new file mode 100644 index 0000000..eb26bf0 --- /dev/null +++ b/internal/simulator/hypervisorcluster.go @@ -0,0 +1,8 @@ +// (C) Copyright 2024 Hewlett Packard Enterprise Development LP + +package simulator + +func HypervisorCluster() { + hypervisorClusterCreate() + hypervisorClusterDelete() +} diff --git a/internal/simulator/hypervisorcluster_create.go b/internal/simulator/hypervisorcluster_create.go index 86d0411..64a6d46 100644 --- a/internal/simulator/hypervisorcluster_create.go +++ b/internal/simulator/hypervisorcluster_create.go @@ -15,8 +15,6 @@ var clusterAsync string var clusterGet string func hypervisorClusterCreate() { - // TODO: (API) Replace manually create stubs when possible - taskID := "99992745-532b-404c-860c-20a6571b92c3" systemID := "126fd201-9e6e-5e31-9ffb-a766265b1fd3" clusterID := "298a299e-78f5-5acb-86ce-4e9fdc290ab7" @@ -38,7 +36,3 @@ func hypervisorClusterCreate() { SetHeader("Content-Type", "application/json"). BodyString(clusterGet) } - -func HypervisorCluster() { - hypervisorClusterCreate() -} diff --git a/internal/simulator/hypervisorcluster_delete.go b/internal/simulator/hypervisorcluster_delete.go new file mode 100644 index 0000000..a33ec5c --- /dev/null +++ b/internal/simulator/hypervisorcluster_delete.go @@ -0,0 +1,41 @@ +// (C) Copyright 2024 Hewlett Packard Enterprise Development LP + +package simulator + +import ( + _ "embed" + + "github.com/h2non/gock" +) + +//go:embed fixtures/hypervisorclusters/delete/async1.json +var deleteTaskOne string + +//go:embed fixtures/hypervisorclusters/delete/async2.json +var deleteTaskTwo string + +func hypervisorClusterDelete() { + taskID := "a73607cc-ae57-4efe-b573-615813e6c77d" + systemID := "126fd201-9e6e-5e31-9ffb-a766265b1fd3" + clusterID := "298a299e-78f5-5acb-86ce-4e9fdc290ab7" + + gock.New("http://localhost"). + Post("/private-cloud-business/v1beta1/systems/"+systemID+ + "/remove-hypervisor-clusters"). + MatchType("json"). + JSON(map[string][]string{"hypervisor_cluster_ids": {clusterID}}). + Reply(202). + SetHeader("Location", "/data-services/v1beta1/async-operations/"+taskID) + + gock.New("http://localhost"). + Get("/data-services/v1beta1/async-operations/"+taskID). + Reply(200). + SetHeader("Content-Type", "application/json"). + BodyString(deleteTaskOne) + + gock.New("http://localhost"). + Get("/data-services/v1beta1/async-operations/"+taskID). + Reply(200). + SetHeader("Content-Type", "application/json"). + BodyString(deleteTaskTwo) +} diff --git a/test/hypervisorcluster/hypervisorcluster_test.go b/test/hypervisorcluster/hypervisorcluster_test.go index 7f85e87..324ae3b 100644 --- a/test/hypervisorcluster/hypervisorcluster_test.go +++ b/test/hypervisorcluster/hypervisorcluster_test.go @@ -61,6 +61,17 @@ func checkUUIDAttr(resource string, attr string) func(*terraform.State) error { } } +func testAccCheckResourceDestroyed(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Check if the resource is in the state + if rs, ok := s.RootModule().Resources[resourceName]; ok { + return fmt.Errorf("Resource %s still exists: %v", resourceName, rs.Primary.ID) + } + + return nil + } +} + func TestAccHypervisorclusterResource(t *testing.T) { config1 := providerConfig + ` resource "hpegl_pc_hypervisor_cluster" "test" { @@ -102,7 +113,6 @@ func TestAccHypervisorclusterResource(t *testing.T) { } checkFn := resource.ComposeAggregateTestCheckFunc(checks...) - resource.Test(t, resource.TestCase{ ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, Steps: []resource.TestStep{ @@ -110,6 +120,13 @@ func TestAccHypervisorclusterResource(t *testing.T) { Config: config1, Check: checkFn, }, + { + // Remove hypervisor cluster from config to test delete + Config: providerConfig, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckResourceDestroyed("hpegl_pc_hypervisor_cluster.test"), + ), + }, }, }) }