Skip to content

Commit

Permalink
feat(workspace): support the terminal bindings resource (#3773)
Browse files Browse the repository at this point in the history
  • Loading branch information
Lance52259 authored Nov 30, 2023
1 parent 16be556 commit 2ff57ae
Show file tree
Hide file tree
Showing 11 changed files with 817 additions and 10 deletions.
80 changes: 80 additions & 0 deletions docs/resources/workspace_terminal_bindings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
subcategory: "Workspace"
---

# huaweicloud_workspace_terminal_bindings

Manages the terminal bindings between MAC addresses and desktops within HuaweiCloud.

-> Only one resource can be created in a region.

## Example Usage

### Allow a machine to remote the desktops

```hcl
variable "desktop_name" {}
resource "huaweicloud_workspace_terminal_bindings" "test" {
enabled = true
disabled_after_delete = true
bindings {
desktop_name = var.desktop_name
mac = "FA-16-3E-E2-3A-1D"
}
}
```

## Argument Reference

The following arguments are supported:

* `region` - (Optional, String, ForceNew) Specifies the region where the desktops (to be bound to the MAC address) are located.
If omitted, the provider-level region will be used. Changing this will create a new resource.

* `bindings` - (Required, List) Specifies the terminal bindings configuration between MAC addresses and desktops.
The [blacklist](#terminal_bindings_args) structure is documented below.

* `enabled` - (Optional, Bool) Specifies whether bindings are available.

* `disabled_after_delete` - (Optional, Bool) Specifies whether disabled the binding function before destroy resource.
Defaults to **true**.

<a name="terminal_bindings_args"></a>
The `bindings` block supports:

* `mac` - (Required, String) Specifies the MAC address.

* `desktop_name` - (Required, String) Specifies the desktop name.

* `description` - (Optional, String) Specifies the binding description.

## Attribute Reference

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

* `id` - The resource ID in UUID format.

* `bindings` - The terminal bindings configuration between MAC addresses and desktops.
The [blacklist](#terminal_bindings_attr) structure is documented below.

<a name="terminal_bindings_attr"></a>
The `bindings` block supports:

* `id` - The ID of the binding policy.

## Import

Bindings can be imported using the resource `id`, e.g.

```
$ terraform import huaweicloud_workspace_terminal_bindings.test <id>
```

Also you can using any UUID string to replace this ID in the import phase.

Note that the imported state may not be identical to your resource definition, because of parameter
`disabled_after_delete` is not a remote parameter.
It is generally recommended running `terraform plan` after importing resource.
You can then decide if changes should be applied to the resource, or the resource definition should be updated.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.18

require (
github.com/GehirnInc/crypt v0.0.0-20200316065508-bb7000b8a962
github.com/chnsz/golangsdk v0.0.0-20231130090402-a3fcc7889fa9
github.com/chnsz/golangsdk v0.0.0-20231130115815-5d9e3e666b0b
github.com/hashicorp/go-cleanhttp v0.5.2
github.com/hashicorp/go-multierror v1.1.1
github.com/hashicorp/go-uuid v1.0.3
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/chnsz/golangsdk v0.0.0-20231130090402-a3fcc7889fa9 h1:L7RB7A6iuw9MPCp7vY9d1jZvIXiu/tqszG8b6Cy7jnA=
github.com/chnsz/golangsdk v0.0.0-20231130090402-a3fcc7889fa9/go.mod h1:Erm4hDWxXgAdbkG3+hhJFgRzEL1TvvcroWzw2Gax4uI=
github.com/chnsz/golangsdk v0.0.0-20231130115815-5d9e3e666b0b h1:HdQqladAqLkzzRkx435FF5LhmTN6fepC5OwOqHmta00=
github.com/chnsz/golangsdk v0.0.0-20231130115815-5d9e3e666b0b/go.mod h1:Erm4hDWxXgAdbkG3+hhJFgRzEL1TvvcroWzw2Gax4uI=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
Expand Down
11 changes: 6 additions & 5 deletions huaweicloud/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -1244,11 +1244,12 @@ func Provider() *schema.Provider {
"huaweicloud_waf_instance_group_associate": waf.ResourceWafInstGroupAssociate(),
"huaweicloud_waf_reference_table": waf.ResourceWafReferenceTableV1(),

"huaweicloud_workspace_access_policy": workspace.ResourceAccessPolicy(),
"huaweicloud_workspace_desktop": workspace.ResourceDesktop(),
"huaweicloud_workspace_policy_group": workspace.ResourcePolicyGroup(),
"huaweicloud_workspace_service": workspace.ResourceService(),
"huaweicloud_workspace_user": workspace.ResourceUser(),
"huaweicloud_workspace_access_policy": workspace.ResourceAccessPolicy(),
"huaweicloud_workspace_desktop": workspace.ResourceDesktop(),
"huaweicloud_workspace_policy_group": workspace.ResourcePolicyGroup(),
"huaweicloud_workspace_service": workspace.ResourceService(),
"huaweicloud_workspace_terminal_binding": workspace.ResourceTerminalBinding(),
"huaweicloud_workspace_user": workspace.ResourceUser(),

"huaweicloud_cpts_project": cpts.ResourceProject(),
"huaweicloud_cpts_task": cpts.ResourceTask(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
package workspace

import (
"fmt"
"testing"

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

"github.com/chnsz/golangsdk"
"github.com/chnsz/golangsdk/openstack/workspace/v2/terminals"

"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 getTerminalBindingsFunc(conf *config.Config, _ *terraform.ResourceState) (interface{}, error) {
client, err := conf.WorkspaceV2Client(acceptance.HW_REGION_NAME)
if err != nil {
return nil, fmt.Errorf("Error creating Workspace v2 client: %s", err)
}
opts := terminals.ListOpts{
Offset: utils.Int(0), // Offset is the required query parameter.
Limit: 1000, // Limit is the required query parameter.
}
resp, err := terminals.List(client, opts)
if len(resp) > 0 || err != nil {
return resp, err
}
return nil, golangsdk.ErrDefault404{}
}

func TestAccTerminalBindings_basic(t *testing.T) {
var (
bindings []terminals.TerminalBindingResp
resourceName = "huaweicloud_workspace_terminal_binding.test"
name = acceptance.RandomAccResourceNameWithDash()
rc = acceptance.InitResourceCheck(resourceName, &bindings, getTerminalBindingsFunc)
)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acceptance.TestAccPreCheck(t) },
ProviderFactories: acceptance.TestAccProviderFactories,
CheckDestroy: rc.CheckResourceDestroy(),
Steps: []resource.TestStep{
{
Config: testAccTerminalBindings_basic_step1(name),
Check: resource.ComposeTestCheckFunc(
rc.CheckResourceExists(),
resource.TestCheckResourceAttr(resourceName, "enabled", "false"),
resource.TestCheckResourceAttr(resourceName, "disabled_after_delete", "false"),
resource.TestCheckResourceAttr(resourceName, "bindings.#", "1"),
resource.TestCheckResourceAttr(resourceName, "bindings.0.mac", "FA-16-3E-E2-3A-1D"),
resource.TestCheckResourceAttrPair(resourceName, "bindings.0.desktop_name", "huaweicloud_workspace_desktop.test1", "name"),
),
},
{
Config: testAccTerminalBindings_basic_step2(name),
Check: resource.ComposeTestCheckFunc(
rc.CheckResourceExists(),
resource.TestCheckResourceAttr(resourceName, "enabled", "true"),
resource.TestCheckResourceAttr(resourceName, "disabled_after_delete", "true"),
resource.TestCheckResourceAttr(resourceName, "bindings.#", "1"),
resource.TestCheckResourceAttr(resourceName, "bindings.0.mac", "FA-16-3E-E2-3A-1D"),
resource.TestCheckResourceAttrPair(resourceName, "bindings.0.desktop_name", "huaweicloud_workspace_desktop.test1", "name"),
),
},
{
Config: testAccTerminalBindings_basic_step3(name),
Check: resource.ComposeTestCheckFunc(
rc.CheckResourceExists(),
resource.TestCheckResourceAttr(resourceName, "enabled", "true"),
resource.TestCheckResourceAttr(resourceName, "disabled_after_delete", "true"),
resource.TestCheckResourceAttr(resourceName, "bindings.#", "1"),
resource.TestCheckResourceAttr(resourceName, "bindings.0.mac", "FA-16-3E-E2-3A-1E"),
resource.TestCheckResourceAttrPair(resourceName, "bindings.0.desktop_name", "huaweicloud_workspace_desktop.test2", "name"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"disabled_after_delete"},
},
},
})
}

func testAccTerminalBindings_base(name string) string {
return fmt.Sprintf(`
%s
data "huaweicloud_availability_zones" "test" {}
resource "huaweicloud_workspace_service" "test" {
access_mode = "INTERNET"
vpc_id = huaweicloud_vpc.test.id
network_ids = [
huaweicloud_vpc_subnet.test.id,
]
}
resource "huaweicloud_workspace_desktop" "test1" {
flavor_id = "workspace.x86.ultimate.large2"
image_type = "market"
image_id = "8451dedf-b353-43aa-b5fb-5bccadda2207"
availability_zone = data.huaweicloud_availability_zones.test.names[0]
vpc_id = huaweicloud_vpc.test.id
security_groups = [
huaweicloud_workspace_service.test.desktop_security_group.0.id,
huaweicloud_networking_secgroup.test.id,
]
nic {
network_id = huaweicloud_vpc_subnet.test.id
}
name = "%[2]s-1"
user_name = "%[2]s-user-1" // The user_name cannot be same as the desktop_name
user_email = "[email protected]"
user_group = "administrators"
delete_user = true
root_volume {
type = "SAS"
size = 80
}
data_volume {
type = "SAS"
size = 50
}
}
resource "huaweicloud_workspace_desktop" "test2" {
// Concurrent creation crashes the service, making it impossible to delete cloud desktops.
depends_on = [huaweicloud_workspace_desktop.test1]
flavor_id = "workspace.x86.ultimate.large2"
image_type = "market"
image_id = "8451dedf-b353-43aa-b5fb-5bccadda2207"
availability_zone = data.huaweicloud_availability_zones.test.names[0]
vpc_id = huaweicloud_vpc.test.id
security_groups = [
huaweicloud_workspace_service.test.desktop_security_group.0.id,
huaweicloud_networking_secgroup.test.id,
]
nic {
network_id = huaweicloud_vpc_subnet.test.id
}
name = "%[2]s-2"
user_name = "%[2]s-user-2" // The user_name cannot be same as the desktop_name
user_email = "[email protected]"
user_group = "administrators"
delete_user = true
root_volume {
type = "SAS"
size = 80
}
data_volume {
type = "SAS"
size = 50
}
}
`, common.TestBaseNetwork(name), name)
}

func testAccTerminalBindings_basic_step1(name string) string {
return fmt.Sprintf(`
%[1]s
resource "huaweicloud_workspace_terminal_binding" "test" {
enabled = false
disabled_after_delete = false
bindings {
desktop_name = huaweicloud_workspace_desktop.test1.name
mac = "FA-16-3E-E2-3A-1D"
}
}
`, testAccTerminalBindings_base(name))
}

func testAccTerminalBindings_basic_step2(name string) string {
return fmt.Sprintf(`
%[1]s
resource "huaweicloud_workspace_terminal_binding" "test" {
enabled = true
disabled_after_delete = true
bindings {
desktop_name = huaweicloud_workspace_desktop.test1.name
mac = "FA-16-3E-E2-3A-1D"
}
}
`, testAccTerminalBindings_base(name))
}

func testAccTerminalBindings_basic_step3(name string) string {
return fmt.Sprintf(`
%[1]s
resource "huaweicloud_workspace_terminal_binding" "test" {
enabled = true
disabled_after_delete = true
bindings {
desktop_name = huaweicloud_workspace_desktop.test2.name
mac = "FA-16-3E-E2-3A-1E"
}
}
`, testAccTerminalBindings_base(name))
}
Loading

0 comments on commit 2ff57ae

Please sign in to comment.