Skip to content

Commit

Permalink
feat(as): support lifecycle hook callback resource (#5053)
Browse files Browse the repository at this point in the history
  • Loading branch information
jinyangyang222 authored Jun 21, 2024
1 parent a49c4d4 commit 01cf612
Show file tree
Hide file tree
Showing 11 changed files with 318 additions and 15 deletions.
67 changes: 67 additions & 0 deletions docs/resources/as_lifecycle_hook_callback.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
---
subcategory: "Auto Scaling"
layout: "huaweicloud"
page_title: "HuaweiCloud: huaweicloud_as_lifecycle_hook_callback"
description: |-
Manages an AS lifecycle hook callback resource within HuaweiCloud.
---

# huaweicloud_as_lifecycle_hook_callback

Manages an AS lifecycle hook callback resource within HuaweiCloud.

-> 1. Callback action can only be performed when the instance lifecycle hook state is **HANGING**.
<br/>2. The lifecycle hook callback is a one-time action.
<br/>3. Destroying resources does not change the current state of the instance lifecycle hook.

## Example Usage

```hcl
variable "as_group_id" {}
variable "lifecycle_action_result" {}
variable "instance_id" {}
variable "hook_name" {}
resource "huaweicloud_as_lifecycle_hook_callback" "test" {
scaling_group_id = var.as_group_id
lifecycle_action_result = var.lifecycle_action_result
instance_id = var.instance_id
lifecycle_hook_name = var.hook_name
}
```

## Argument Reference

The following arguments are supported:

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

* `scaling_group_id` - (Required, String, ForceNew) Specifies the ID of the AS group.
Changing this will create a new resource.

* `lifecycle_action_result` - (Required, String, ForceNew) Specifies the lifecycle hook callback operation.
The valid values are as follows:
+ **ABANDON**
+ **CONTINUE**
+ **EXTEND**: Extend the timeout by `1` hour each time.

Changing this will create a new resource.

* `lifecycle_action_key` - (Optional, String, ForceNew) Specifies the lifecycle hook callback operation token.
Changing this will create a new resource.

* `instance_id` - (Optional, String, ForceNew) Specifies the instance ID for the lifecycle callback.
Changing this will create a new resource.

* `lifecycle_hook_name` - (Optional, String, ForceNew) Specifies the lifecycle hook name.
Changing this will create a new resource.

-> The parameters `instance_id` and `lifecycle_hook_name` must be used together, and they are mutually exclusive with
the parameter `lifecycle_action_key`.

## Attribute Reference

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

* `id` - The resource ID in UUID format.
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-20240618022207-775fb17e64e9
github.com/chnsz/golangsdk v0.0.0-20240621021004-a551a04f344b
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-20240618022207-775fb17e64e9 h1:8HfuICiNSdlWJVe+jFFuXXSDMQHYH8cW8NltZKqKVuY=
github.com/chnsz/golangsdk v0.0.0-20240618022207-775fb17e64e9/go.mod h1:Erm4hDWxXgAdbkG3+hhJFgRzEL1TvvcroWzw2Gax4uI=
github.com/chnsz/golangsdk v0.0.0-20240621021004-a551a04f344b h1:W5102qXKU2A+g8zVhuc3a3MnUHD1NLrEQ9Dfv2mSk5A=
github.com/chnsz/golangsdk v0.0.0-20240621021004-a551a04f344b/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
17 changes: 9 additions & 8 deletions huaweicloud/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -1046,14 +1046,15 @@ func Provider() *schema.Provider {
"huaweicloud_apig_throttling_policy": apig.ResourceApigThrottlingPolicyV2(),
"huaweicloud_apig_endpoint_whitelist": apig.ResourceEndpointWhiteList(),

"huaweicloud_as_configuration": as.ResourceASConfiguration(),
"huaweicloud_as_group": as.ResourceASGroup(),
"huaweicloud_as_lifecycle_hook": as.ResourceASLifecycleHook(),
"huaweicloud_as_instance_attach": as.ResourceASInstanceAttach(),
"huaweicloud_as_notification": as.ResourceAsNotification(),
"huaweicloud_as_policy": as.ResourceASPolicy(),
"huaweicloud_as_bandwidth_policy": as.ResourceASBandWidthPolicy(),
"huaweicloud_as_planned_task": as.ResourcePlannedTask(),
"huaweicloud_as_configuration": as.ResourceASConfiguration(),
"huaweicloud_as_group": as.ResourceASGroup(),
"huaweicloud_as_lifecycle_hook": as.ResourceASLifecycleHook(),
"huaweicloud_as_instance_attach": as.ResourceASInstanceAttach(),
"huaweicloud_as_notification": as.ResourceAsNotification(),
"huaweicloud_as_policy": as.ResourceASPolicy(),
"huaweicloud_as_bandwidth_policy": as.ResourceASBandWidthPolicy(),
"huaweicloud_as_planned_task": as.ResourcePlannedTask(),
"huaweicloud_as_lifecycle_hook_callback": as.ResourceLifecycleHookCallBack(),

"huaweicloud_bms_instance": bms.ResourceBmsInstance(),
"huaweicloud_bcs_instance": bcs.ResourceInstance(),
Expand Down
28 changes: 26 additions & 2 deletions huaweicloud/services/acceptance/acceptance.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,11 @@ var (
HW_CERT_BATCH_PUSH_ID = os.Getenv("HW_CERT_BATCH_PUSH_ID")
HW_CERT_BATCH_PUSH_WAF_ID = os.Getenv("HW_CERT_BATCH_PUSH_WAF_ID")

HW_AS_SCALING_GROUP_ID = os.Getenv("HW_AS_SCALING_GROUP_ID")
HW_AS_SCALING_POLICY_ID = os.Getenv("HW_AS_SCALING_POLICY_ID")
HW_AS_SCALING_GROUP_ID = os.Getenv("HW_AS_SCALING_GROUP_ID")
HW_AS_SCALING_POLICY_ID = os.Getenv("HW_AS_SCALING_POLICY_ID")
HW_AS_LIFECYCLE_ACTION_KEY = os.Getenv("HW_AS_LIFECYCLE_ACTION_KEY")
HW_AS_INSTANCE_ID = os.Getenv("HW_AS_INSTANCE_ID")
HW_AS_LIFECYCLE_HOOK_NAME = os.Getenv("HW_AS_LIFECYCLE_HOOK_NAME")

HW_DATAARTS_WORKSPACE_ID = os.Getenv("HW_DATAARTS_WORKSPACE_ID")
HW_DATAARTS_CDM_NAME = os.Getenv("HW_DATAARTS_CDM_NAME")
Expand Down Expand Up @@ -1572,6 +1575,27 @@ func TestAccPreCheckASScalingPolicyID(t *testing.T) {
}
}

// lintignore:AT003
func TestAccPreCheckASLifecycleActionKey(t *testing.T) {
if HW_AS_LIFECYCLE_ACTION_KEY == "" {
t.Skip("HW_AS_LIFECYCLE_ACTION_KEY must be set for the acceptance test")
}
}

// lintignore:AT003
func TestAccPreCheckASINSTANCEID(t *testing.T) {
if HW_AS_INSTANCE_ID == "" {
t.Skip("HW_AS_INSTANCE_ID must be set for the acceptance test")
}
}

// lintignore:AT003
func TestAccPreCheckASLifecycleHookName(t *testing.T) {
if HW_AS_LIFECYCLE_HOOK_NAME == "" {
t.Skip("HW_AS_LIFECYCLE_HOOK_NAME must be set for the acceptance test")
}
}

// lintignore:AT003
func TestAccPreCheckDataArtsWorkSpaceID(t *testing.T) {
if HW_DATAARTS_WORKSPACE_ID == "" {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package as

import (
"fmt"
"testing"

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

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

// Because an instance with a status of **HANGING** cannot be obtained through resources and datasource.
// So using environment variables to inject parameters for testing.
func TestAccLifecycleHookCallBack_basic(t *testing.T) {
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
acceptance.TestAccPreCheck(t)
acceptance.TestAccPreCheckASLifecycleActionKey(t)
},
ProviderFactories: acceptance.TestAccProviderFactories,
CheckDestroy: nil,
Steps: []resource.TestStep{
{
Config: testAccLifecycleHookCallBack_withActionKey("ABANDON"),
},
},
})
}

func testAccLifecycleHookCallBack_withActionKey(action string) string {
return fmt.Sprintf(`
resource "huaweicloud_as_lifecycle_hook_callback" "test" {
scaling_group_id = "%[1]s"
lifecycle_action_result = "%[2]s"
lifecycle_action_key = "%[3]s"
}
`, acceptance.HW_AS_SCALING_GROUP_ID, action, acceptance.HW_AS_LIFECYCLE_ACTION_KEY)
}

func TestAccLifecycleHookCallBack_withInstanceIdAndHookName(t *testing.T) {
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
acceptance.TestAccPreCheck(t)
acceptance.TestAccPreCheckASINSTANCEID(t)
acceptance.TestAccPreCheckASLifecycleHookName(t)
},
ProviderFactories: acceptance.TestAccProviderFactories,
CheckDestroy: nil,
Steps: []resource.TestStep{
{
Config: testAccLifecycleHookCallBack_withInstanceIdAndHookName("CONTINUE"),
},
},
})
}

func testAccLifecycleHookCallBack_withInstanceIdAndHookName(action string) string {
return fmt.Sprintf(`
resource "huaweicloud_as_lifecycle_hook_callback" "test" {
scaling_group_id = "%[1]s"
lifecycle_action_result = "%[2]s"
instance_id = "%[3]s"
lifecycle_hook_name = "%[4]s"
}
`, acceptance.HW_AS_SCALING_GROUP_ID, action, acceptance.HW_AS_INSTANCE_ID, acceptance.HW_AS_LIFECYCLE_HOOK_NAME)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package as

import (
"context"

"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/openstack/autoscaling/v1/lifecyclehooks"

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

// @API AS PUT /autoscaling-api/v1/{project_id}/scaling_instance_hook/{scaling_group_id}/callback
func ResourceLifecycleHookCallBack() *schema.Resource {
return &schema.Resource{
CreateContext: resourceLifecycleHookCallBackCreate,
ReadContext: resourceLifecycleHookCallBackRead,
DeleteContext: resourceLifecycleHookCallBackDelete,

Schema: map[string]*schema.Schema{
"region": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"scaling_group_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"lifecycle_action_result": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"lifecycle_action_key": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"instance_id": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ConflictsWith: []string{"lifecycle_action_key"},
},
"lifecycle_hook_name": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ConflictsWith: []string{"lifecycle_action_key"},
},
},
}
}

func resourceLifecycleHookCallBackCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var (
conf = meta.(*config.Config)
region = conf.GetRegion(d)
)
client, err := conf.AutoscalingV1Client(region)
if err != nil {
return diag.Errorf("error creating autoscaling client: %s", err)
}

callBackOpts := lifecyclehooks.CallBackOpts{
LifecycleActionResult: d.Get("lifecycle_action_result").(string),
LifecycleActionKey: d.Get("lifecycle_action_key").(string),
InstanceId: d.Get("instance_id").(string),
LifecycleHookName: d.Get("lifecycle_hook_name").(string),
}

err = lifecyclehooks.CallBack(client, callBackOpts, d.Get("scaling_group_id").(string)).ExtractErr()
if err != nil {
return diag.Errorf("callback the AS lifecycle hook failed: %s", err)
}

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

d.SetId(uuId)

return resourceLifecycleHookCallBackRead(ctx, d, meta)
}

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

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

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion vendor/modules.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ github.com/apparentlymart/go-cidr/cidr
# github.com/apparentlymart/go-textseg/v13 v13.0.0
## explicit; go 1.16
github.com/apparentlymart/go-textseg/v13/textseg
# github.com/chnsz/golangsdk v0.0.0-20240618022207-775fb17e64e9
# github.com/chnsz/golangsdk v0.0.0-20240621021004-a551a04f344b
## explicit; go 1.14
github.com/chnsz/golangsdk
github.com/chnsz/golangsdk/auth
Expand Down

0 comments on commit 01cf612

Please sign in to comment.