Skip to content

Commit

Permalink
feat(CodeArts/Deploy): support to copy host
Browse files Browse the repository at this point in the history
  • Loading branch information
saf3dfsa committed Dec 24, 2024
1 parent 1172c45 commit 6c7ced0
Show file tree
Hide file tree
Showing 4 changed files with 312 additions and 0 deletions.
48 changes: 48 additions & 0 deletions docs/resources/codearts_deploy_hosts_copy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
subcategory: "CodeArts Deploy"
layout: "huaweicloud"
page_title: "HuaweiCloud: huaweicloud_codearts_deploy_hosts_copy"
description: |-
Manages a CodeArts deploy hosts copy resource within HuaweiCloud.
---

# huaweicloud_codearts_deploy_hosts_copy

Manages a CodeArts deploy hosts copy resource within HuaweiCloud.

## Example Usage

```hcl
variable "source_group_id" {}
variable "host_uuids" {}
variable "target_group_id" {}
resource "huaweicloud_codearts_deploy_hosts_copy" "test" {
source_group_id = var.source_group_id
host_uuids = var.host_uuids
target_group_id = var.target_group_id
}
```

## Argument Reference

The following arguments are supported:

* `region` - (Optional, String, ForceNew) Specifies the region in which to create the resource.
If omitted, the provider-level region will be used.
Changing this creates a new resource.

* `source_group_id` - (Required, String, ForceNew) Specifies the source group ID.
Changing this creates a new resource.

* `host_uuids` - (Required, List, ForceNew) Specifies the host IDs list.
Changing this creates a new resource.

* `target_group_id` - (Required, String, ForceNew) Specifies the target group ID.
Changing this creates a new resource.

## Attribute Reference

In addition to all arguments above, the following attributes are exported:

* `id` - The resource ID.
1 change: 1 addition & 0 deletions huaweicloud/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -2212,6 +2212,7 @@ func Provider() *schema.Provider {
"huaweicloud_codearts_deploy_application_group": codeartsdeploy.ResourceDeployApplicationGroup(),
"huaweicloud_codearts_deploy_group": codeartsdeploy.ResourceDeployGroup(),
"huaweicloud_codearts_deploy_host": codeartsdeploy.ResourceDeployHost(),
"huaweicloud_codearts_deploy_hosts_copy": codeartsdeploy.ResourceCodeArtsDeployHostsCopy(),

"huaweicloud_codearts_inspector_website": codeartsinspector.ResourceInspectorWebsite(),
"huaweicloud_codearts_inspector_website_scan": codeartsinspector.ResourceInspectorWebsiteScan(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
package codeartsdeploy

import (
"fmt"
"strings"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"

"github.com/chnsz/golangsdk"

"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config"
"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance"
"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance/common"
"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/utils"
)

func TestAccCodeArtsDeployHostsCopy_basic(t *testing.T) {
name := acceptance.RandomAccResourceName()

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acceptance.TestAccPreCheck(t) },
ProviderFactories: acceptance.TestAccProviderFactories,
CheckDestroy: nil,
Steps: []resource.TestStep{
{
Config: testCodeArtsDeployHostsCopy_basic(name),
Check: resource.ComposeTestCheckFunc(
removeTheCopyHost("huaweicloud_codearts_deploy_group.test.1"),
),
},
},
})
}

func testCodeArtsDeployHostsCopy_base(name string) string {
return fmt.Sprintf(`
%[1]s
%[2]s
resource "huaweicloud_compute_instance" "test" {
name = "%[3]s"
image_id = data.huaweicloud_images_image.test.id
flavor_id = data.huaweicloud_compute_flavors.test.ids[0]
security_group_ids = [huaweicloud_networking_secgroup.test.id]
availability_zone = data.huaweicloud_availability_zones.test.names[0]
admin_pass = "Test@123"
delete_disks_on_termination = true
network {
uuid = huaweicloud_vpc_subnet.test.id
}
eip_type = "5_bgp"
bandwidth {
share_type = "PER"
size = 5
charge_mode = "bandwidth"
}
}
resource "huaweicloud_codearts_deploy_group" "test" {
count = 2
project_id = huaweicloud_codearts_project.test.id
name = "%[3]s-${count.index}"
os_type = "linux"
description = "test"
}
resource "huaweicloud_codearts_deploy_host" "test" {
group_id = huaweicloud_codearts_deploy_group.test[0].id
ip_address = huaweicloud_compute_instance.test.public_ip
port = 22
username = "root"
password = "Test@123"
os_type = "linux"
name = "%[3]s"
as_proxy = true
}
`, common.TestBaseComputeResources(name), testProject_basic(name), name)
}

func testCodeArtsDeployHostsCopy_basic(name string) string {
return fmt.Sprintf(`
%[1]s
resource "huaweicloud_codearts_deploy_hosts_copy" "test" {
source_group_id = huaweicloud_codearts_deploy_group.test[0].id
host_uuids = [huaweicloud_codearts_deploy_host.test.id]
target_group_id = huaweicloud_codearts_deploy_group.test[1].id
}
`, testCodeArtsDeployHostsCopy_base(name))
}

// Can not delete group when group having a host, delete host before destroy
func removeTheCopyHost(resourceName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
// get group ID
rs, ok := s.RootModule().Resources[resourceName]
if !ok {
return fmt.Errorf("resource (%s) not found", resourceName)
}
groupId := rs.Primary.ID
if groupId == "" {
return fmt.Errorf("attribute ID of Resource (%s) not found: %s", resourceName, rs)
}

cfg := acceptance.TestAccProvider.Meta().(*config.Config)
client, err := cfg.NewServiceClient("codearts_deploy", acceptance.HW_REGION_NAME)
if err != nil {
return fmt.Errorf("error creating CodeArts Deploy client, err: %s", err)
}

// get host ID from host list
gethttpUrl := "v1/resources/host-groups/{group_id}/hosts"
getPath := client.Endpoint + gethttpUrl
getPath = strings.ReplaceAll(getPath, "{group_id}", groupId)
getOpt := golangsdk.RequestOpts{
KeepResponseBody: true,
}

getResp, err := client.Request("GET", getPath, &getOpt)
if err != nil {
return fmt.Errorf("error retrieving CodeArts deploy hosts: %s", err)
}
getRespBody, err := utils.FlattenResponse(getResp)
if err != nil {
return err
}

hostId := utils.PathSearch("result[0].uuid", getRespBody, "").(string)
if hostId == "" {
return fmt.Errorf("unable to find host ID from API response")
}

// delete host
deletehttpUrl := "v1/resources/host-groups/{group_id}/hosts/{host_id}"
deletePath := client.Endpoint + deletehttpUrl
deletePath = strings.ReplaceAll(deletePath, "{group_id}", groupId)
deletePath = strings.ReplaceAll(deletePath, "{host_id}", hostId)
deleteOpt := golangsdk.RequestOpts{
KeepResponseBody: true,
MoreHeaders: map[string]string{
"Content-Type": "application/json;charset=utf-8",
},
}

_, err = client.Request("DELETE", deletePath, &deleteOpt)
if err != nil {
return fmt.Errorf("error deleting CodeArts deploy host: %s", err)
}

return nil
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package codeartsdeploy

import (
"context"
"strings"

"github.com/hashicorp/go-uuid"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"

"github.com/chnsz/golangsdk"

"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config"
)

// @API CodeArtsDeploy POST /v1/resources/host-groups/{group_id}/hosts/replication
func ResourceCodeArtsDeployHostsCopy() *schema.Resource {
return &schema.Resource{
CreateContext: resourceCodeArtsDeployHostsCopyCreate,
ReadContext: resourceCodeArtsDeployHostsCopyRead,
DeleteContext: resourceCodeArtsDeployHostsCopyDelete,

Schema: map[string]*schema.Schema{
"region": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"source_group_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: `Specifies the source group ID.`,
},
"host_uuids": {
Type: schema.TypeList,
Required: true,
ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString},
Description: `Specifies the host ID list.`,
},
"target_group_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: `Specifies the target group ID.`,
},
},
}
}

func resourceCodeArtsDeployHostsCopyCreate(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
cfg := meta.(*config.Config)
region := cfg.GetRegion(d)
client, err := cfg.NewServiceClient("codearts_deploy", region)
if err != nil {
return diag.Errorf("error creating CodeArts deploy client: %s", err)
}

httpUrl := "v1/resources/host-groups/{group_id}/hosts/replication"
createPath := client.Endpoint + httpUrl
createPath = strings.ReplaceAll(createPath, "{group_id}", d.Get("source_group_id").(string))
createOpt := golangsdk.RequestOpts{
KeepResponseBody: true,
JSONBody: buildCreateCodeArtsDeployHostsCopyBodyParams(d),
}

_, err = client.Request("POST", createPath, &createOpt)
if err != nil {
return diag.Errorf("error copying CodeArts deploy hosts: %s", err)
}

id, err := uuid.GenerateUUID()
if err != nil {
return diag.Errorf("unable to generate ID: %s", err)
}
d.SetId(id)

return nil
}

func buildCreateCodeArtsDeployHostsCopyBodyParams(d *schema.ResourceData) map[string]interface{} {
bodyParams := map[string]interface{}{
"host_uuids": d.Get("host_uuids"),
"target_group_id": d.Get("target_group_id"),
}
return bodyParams
}

func resourceCodeArtsDeployHostsCopyRead(_ context.Context, _ *schema.ResourceData, _ interface{}) diag.Diagnostics {
return nil
}

func resourceCodeArtsDeployHostsCopyDelete(_ context.Context, _ *schema.ResourceData, _ interface{}) diag.Diagnostics {
errorMsg := "Deleting hosts copy resource is not supported. The resource is only removed from the" +
"state, the hosts remain in the cloud."
return diag.Diagnostics{
diag.Diagnostic{
Severity: diag.Warning,
Summary: errorMsg,
},
}
}

0 comments on commit 6c7ced0

Please sign in to comment.