diff --git a/alicloud/resource_alicloud_ess_notification.go b/alicloud/resource_alicloud_ess_notification.go index b353d9a76cb3..753f98514f83 100644 --- a/alicloud/resource_alicloud_ess_notification.go +++ b/alicloud/resource_alicloud_ess_notification.go @@ -2,6 +2,9 @@ package alicloud import ( "fmt" + "github.com/PaesslerAG/jsonpath" + util "github.com/alibabacloud-go/tea-utils/service" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "strings" "github.com/aliyun/alibaba-cloud-sdk-go/services/ess" @@ -35,17 +38,24 @@ func resourceAlicloudEssNotification() *schema.Resource { Required: true, ForceNew: true, }, + "time_zone": { + Type: schema.TypeString, + Optional: true, + }, }, } } func resourceAlicloudEssNotificationCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AliyunClient) - - request := ess.CreateCreateNotificationConfigurationRequest() - request.RegionId = client.RegionId - request.ScalingGroupId = d.Get("scaling_group_id").(string) - request.NotificationArn = d.Get("notification_arn").(string) + var response map[string]interface{} + action := "CreateNotificationConfiguration" + request := make(map[string]interface{}) + request["RegionId"] = client.RegionId + conn, err := client.NewEssClient() + request["ScalingGroupId"] = d.Get("scaling_group_id").(string) + request["NotificationArn"] = d.Get("notification_arn").(string) + request["TimeZone"] = d.Get("time_zone").(string) if v, ok := d.GetOk("notification_types"); ok { notificationTypes := make([]string, 0) notificationTypeList := v.(*schema.Set).List() @@ -55,18 +65,20 @@ func resourceAlicloudEssNotificationCreate(d *schema.ResourceData, meta interfac } } if len(notificationTypes) > 0 { - request.NotificationType = ¬ificationTypes + request["NotificationType"] = ¬ificationTypes } } - - raw, err := client.WithEssClient(func(essClient *ess.Client) (interface{}, error) { - return essClient.CreateNotificationConfiguration(request) + runtime := util.RuntimeOptions{} + runtime.SetAutoretry(true) + err = resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError { + response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2014-08-28"), StringPointer("AK"), nil, request, &runtime) + if err != nil { + return resource.RetryableError(err) + } + return nil }) - if err != nil { - return WrapErrorf(err, DefaultErrorMsg, "alicloud_ess_notification", request.GetActionName(), AlibabaCloudSdkGoERROR) - } - addDebug(request.GetActionName(), raw, request.RpcRequest, request) - d.SetId(fmt.Sprintf("%s:%s", request.ScalingGroupId, request.NotificationArn)) + addDebug(action, response, request) + d.SetId(fmt.Sprintf("%s:%s", request["ScalingGroupId"], request["NotificationArn"])) return resourceAlicloudEssNotificationRead(d, meta) } @@ -81,39 +93,50 @@ func resourceAlicloudEssNotificationRead(d *schema.ResourceData, meta interface{ } return WrapError(err) } - d.Set("scaling_group_id", object.ScalingGroupId) - d.Set("notification_arn", object.NotificationArn) - d.Set("notification_types", object.NotificationTypes.NotificationType) + d.Set("scaling_group_id", object["ScalingGroupId"]) + d.Set("notification_arn", object["NotificationArn"]) + d.Set("time_zone", object["TimeZone"]) + notificationTypes, _ := jsonpath.Get("$.NotificationTypes", object) + notificationType, _ := jsonpath.Get("$.NotificationType", notificationTypes) + d.Set("notification_types", notificationType) return nil } func resourceAlicloudEssNotificationUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AliyunClient) - request := ess.CreateModifyNotificationConfigurationRequest() - request.RegionId = client.RegionId + var response map[string]interface{} + action := "ModifyNotificationConfiguration" + request := make(map[string]interface{}) + request["RegionId"] = client.RegionId + conn, err := client.NewEssClient() + request["RegionId"] = client.RegionId parts := strings.SplitN(d.Id(), ":", 2) - request.ScalingGroupId = parts[0] - request.NotificationArn = parts[1] - if d.HasChange("notification_types") { - v := d.Get("notification_types") - notificationTypes := make([]string, 0) - notificationTypeList := v.(*schema.Set).List() - if len(notificationTypeList) > 0 { - for _, n := range notificationTypeList { - notificationTypes = append(notificationTypes, n.(string)) - } - } - if len(notificationTypes) > 0 { - request.NotificationType = ¬ificationTypes + request["ScalingGroupId"] = parts[0] + request["NotificationArn"] = parts[1] + v := d.Get("notification_types") + notificationTypes := make([]string, 0) + notificationTypeList := v.(*schema.Set).List() + if len(notificationTypeList) > 0 { + for _, n := range notificationTypeList { + notificationTypes = append(notificationTypes, n.(string)) } } - raw, err := client.WithEssClient(func(essClient *ess.Client) (interface{}, error) { - return essClient.ModifyNotificationConfiguration(request) - }) - if err != nil { - return WrapErrorf(err, DefaultErrorMsg, d.Id(), request.GetActionName(), AlibabaCloudSdkGoERROR) + if len(notificationTypes) > 0 { + request["NotificationType"] = ¬ificationTypes } - addDebug(request.GetActionName(), raw, request.RpcRequest, request) + if d.HasChange("time_zone") { + request["TimeZone"] = d.Get("time_zone").(string) + } + runtime := util.RuntimeOptions{} + runtime.SetAutoretry(true) + err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { + response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2014-08-28"), StringPointer("AK"), nil, request, &runtime) + if err != nil { + return resource.RetryableError(err) + } + return nil + }) + addDebug(action, response, request) return resourceAlicloudEssNotificationRead(d, meta) } diff --git a/alicloud/resource_alicloud_ess_notification_test.go b/alicloud/resource_alicloud_ess_notification_test.go index fb8edf9c81f5..05b042684f52 100644 --- a/alicloud/resource_alicloud_ess_notification_test.go +++ b/alicloud/resource_alicloud_ess_notification_test.go @@ -11,7 +11,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/terraform" ) -func TestAccAlicloudEssNotification_basic(t *testing.T) { +func TestAccAliCloudEssNotification_basic(t *testing.T) { rand := acctest.RandIntRange(1000, 999999) var v ess.NotificationConfigurationModel resourceId := "alicloud_ess_notification.default" @@ -27,7 +27,8 @@ func TestAccAlicloudEssNotification_basic(t *testing.T) { return &EssService{testAccProvider.Meta().(*connectivity.AliyunClient)} }) rac := resourceAttrCheckInit(rc, ra) - + name := fmt.Sprintf("tf-testAccEssNotificationBasic-%d", rand) + testAccConfig := resourceTestAccConfigFunc(resourceId, name, testAccEssNotification) testAccCheck := rac.resourceAttrMapUpdateSet() resource.Test(t, resource.TestCase{ PreCheck: func() { @@ -38,7 +39,11 @@ func TestAccAlicloudEssNotification_basic(t *testing.T) { CheckDestroy: testAccCheckEssNotificationDestroy, Steps: []resource.TestStep{ { - Config: testAccEssNotification(EcsInstanceCommonTestCase, rand), + Config: testAccConfig(map[string]interface{}{ + "scaling_group_id": "${alicloud_ess_scaling_group.default.id}", + "notification_types": []string{"AUTOSCALING:SCALE_OUT_SUCCESS", "AUTOSCALING:SCALE_OUT_ERROR"}, + "notification_arn": "acs:ess:${data.alicloud_regions.default.regions.0.id}:${data.alicloud_account.default.id}:queue/${alicloud_mns_queue.default.name}", + }), Check: resource.ComposeTestCheckFunc( testAccCheck(nil), ), @@ -49,7 +54,9 @@ func TestAccAlicloudEssNotification_basic(t *testing.T) { ImportStateVerify: true, }, { - Config: testAccEssNotification_update_notification_types(EcsInstanceCommonTestCase, rand), + Config: testAccConfig(map[string]interface{}{ + "notification_types": []string{"AUTOSCALING:SCALE_OUT_SUCCESS", "AUTOSCALING:SCALE_OUT_ERROR", "AUTOSCALING:SCALE_IN_SUCCESS", "AUTOSCALING:SCALE_IN_ERROR"}, + }), Check: resource.ComposeTestCheckFunc( testAccCheck(map[string]string{ "notification_types.#": "4", @@ -57,13 +64,17 @@ func TestAccAlicloudEssNotification_basic(t *testing.T) { ), }, { - Config: testAccEssNotification_update_scaling_group_id(EcsInstanceCommonTestCase, rand), + Config: testAccConfig(map[string]interface{}{ + "scaling_group_id": "${alicloud_ess_scaling_group.default1.id}", + }), Check: resource.ComposeTestCheckFunc( testAccCheck(nil), ), }, { - Config: testAccEssNotification_update_notification_arn(EcsInstanceCommonTestCase, rand), + Config: testAccConfig(map[string]interface{}{ + "notification_arn": "acs:ess:${data.alicloud_regions.default.regions.0.id}:${data.alicloud_account.default.id}:queue/${alicloud_mns_queue.default1.name}", + }), Check: resource.ComposeTestCheckFunc( testAccCheck(nil), ), @@ -73,6 +84,64 @@ func TestAccAlicloudEssNotification_basic(t *testing.T) { } +func TestAccAliCloudEssNotification_timeZone(t *testing.T) { + rand := acctest.RandIntRange(1000, 999999) + var v ess.NotificationConfigurationModel + resourceId := "alicloud_ess_notification.default" + + basicMap := map[string]string{ + "notification_types.#": "2", + "scaling_group_id": CHECKSET, + "notification_arn": CHECKSET, + } + + ra := resourceAttrInit(resourceId, basicMap) + rc := resourceCheckInit(resourceId, &v, func() interface{} { + return &EssService{testAccProvider.Meta().(*connectivity.AliyunClient)} + }) + rac := resourceAttrCheckInit(rc, ra) + name := fmt.Sprintf("tf-testAccEssNotificationTimeZone-%d", rand) + testAccConfig := resourceTestAccConfigFunc(resourceId, name, testAccEssNotification) + testAccCheck := rac.resourceAttrMapUpdateSet() + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + }, + IDRefreshName: resourceId, + Providers: testAccProviders, + CheckDestroy: testAccCheckEssNotificationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccConfig(map[string]interface{}{ + "scaling_group_id": "${alicloud_ess_scaling_group.default.id}", + "notification_types": []string{"AUTOSCALING:SCALE_OUT_SUCCESS", "AUTOSCALING:SCALE_OUT_ERROR"}, + "notification_arn": "acs:ess:${data.alicloud_regions.default.regions.0.id}:${data.alicloud_account.default.id}:queue/${alicloud_mns_queue.default.name}", + "time_zone": "UTC+8", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(nil), + ), + }, + { + ResourceName: resourceId, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccConfig(map[string]interface{}{ + "time_zone": "UTC-7", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "time_zone": "UTC-7", + }), + ), + }, + }, + }) + +} + func testAccCheckEssNotificationDestroy(s *terraform.State) error { client := testAccProvider.Meta().(*connectivity.AliyunClient) essService := EssService{client} @@ -94,53 +163,25 @@ func testAccCheckEssNotificationDestroy(s *terraform.State) error { return nil } -func testAccEssNotification(common string, rand int) string { +func testAccEssNotification(common string) string { return fmt.Sprintf(` %s variable "name" { - default = "tf-testAccEssNotification-%d" - } - - data "alicloud_regions" "default" { - current = true - } - - data "alicloud_account" "default" { - } - - resource "alicloud_ess_scaling_group" "default" { - min_size = 1 - max_size = 1 - scaling_group_name = "${var.name}" - removal_policies = ["OldestInstance", "NewestInstance"] - vswitch_ids = ["${alicloud_vswitch.default.id}"] - } - - resource "alicloud_mns_queue" "default"{ - name="${var.name}" + default = "%s" } - - resource "alicloud_ess_notification" "default" { - scaling_group_id = "${alicloud_ess_scaling_group.default.id}" - notification_types = ["AUTOSCALING:SCALE_OUT_SUCCESS","AUTOSCALING:SCALE_OUT_ERROR"] - notification_arn = "acs:ess:${data.alicloud_regions.default.regions.0.id}:${data.alicloud_account.default.id}:queue/${alicloud_mns_queue.default.name}" + variable "newname" { + default = "newnameN" } - `, common, rand) -} - -func testAccEssNotification_update_notification_types(common string, rand int) string { - return fmt.Sprintf(` - %s - variable "name" { - default = "tf-testAccEssNotification-%d" + resource "alicloud_mns_queue" "default1"{ + name="${var.newname}" } - data "alicloud_regions" "default" { current = true } data "alicloud_account" "default" { } + resource "alicloud_ess_scaling_group" "default" { min_size = 1 @@ -149,36 +190,6 @@ func testAccEssNotification_update_notification_types(common string, rand int) s removal_policies = ["OldestInstance", "NewestInstance"] vswitch_ids = ["${alicloud_vswitch.default.id}"] } - - resource "alicloud_mns_queue" "default"{ - name="${var.name}" - } - - resource "alicloud_ess_notification" "default" { - scaling_group_id = "${alicloud_ess_scaling_group.default.id}" - notification_types = ["AUTOSCALING:SCALE_OUT_SUCCESS","AUTOSCALING:SCALE_OUT_ERROR","AUTOSCALING:SCALE_IN_SUCCESS","AUTOSCALING:SCALE_IN_ERROR"] - notification_arn = "acs:ess:${data.alicloud_regions.default.regions.0.id}:${data.alicloud_account.default.id}:queue/${alicloud_mns_queue.default.name}" - } - `, common, rand) -} - -func testAccEssNotification_update_scaling_group_id(common string, rand int) string { - return fmt.Sprintf(` - %s - variable "name" { - default = "tf-testAccEssNotification-%d" - } - - variable "newname" { - default = "tf-testAccEssNotification_new-%d" - } - - data "alicloud_regions" "default" { - current = true - } - - data "alicloud_account" "default" { - } resource "alicloud_ess_scaling_group" "default1" { min_size = 1 @@ -188,52 +199,9 @@ func testAccEssNotification_update_scaling_group_id(common string, rand int) str vswitch_ids = ["${alicloud_vswitch.default.id}"] } + resource "alicloud_mns_queue" "default"{ name="${var.name}" } - - resource "alicloud_ess_notification" "default" { - scaling_group_id = "${alicloud_ess_scaling_group.default1.id}" - notification_types = ["AUTOSCALING:SCALE_OUT_SUCCESS","AUTOSCALING:SCALE_OUT_ERROR","AUTOSCALING:SCALE_IN_SUCCESS","AUTOSCALING:SCALE_IN_ERROR"] - notification_arn = "acs:ess:${data.alicloud_regions.default.regions.0.id}:${data.alicloud_account.default.id}:queue/${alicloud_mns_queue.default.name}" - } - `, common, rand, rand) -} - -func testAccEssNotification_update_notification_arn(common string, rand int) string { - return fmt.Sprintf(` - %s - variable "name" { - default = "tf-testAccEssNotification-%d" - } - - variable "newname" { - default = "tf-testAccEssNotification-new-%d" - } - - data "alicloud_regions" "default" { - current = true - } - - data "alicloud_account" "default" { - } - - resource "alicloud_ess_scaling_group" "default1" { - min_size = 1 - max_size = 1 - scaling_group_name = "${var.newname}" - removal_policies = ["OldestInstance", "NewestInstance"] - vswitch_ids = ["${alicloud_vswitch.default.id}"] - } - - resource "alicloud_mns_queue" "default1"{ - name="${var.newname}" - } - - resource "alicloud_ess_notification" "default" { - scaling_group_id = "${alicloud_ess_scaling_group.default1.id}" - notification_types = ["AUTOSCALING:SCALE_OUT_SUCCESS","AUTOSCALING:SCALE_OUT_ERROR","AUTOSCALING:SCALE_IN_SUCCESS","AUTOSCALING:SCALE_IN_ERROR"] - notification_arn = "acs:ess:${data.alicloud_regions.default.regions.0.id}:${data.alicloud_account.default.id}:queue/${alicloud_mns_queue.default1.name}" - } - `, common, rand, rand) + `, EcsInstanceCommonTestCase, common) } diff --git a/alicloud/service_alicloud_ess.go b/alicloud/service_alicloud_ess.go index 8f3474b9e3a4..d20c07e2f862 100644 --- a/alicloud/service_alicloud_ess.go +++ b/alicloud/service_alicloud_ess.go @@ -122,31 +122,54 @@ func (s *EssService) WaitForEssLifecycleHook(id string, status Status, timeout i } } -func (s *EssService) DescribeEssNotification(id string) (notification ess.NotificationConfigurationModel, err error) { +func (s *EssService) DescribeEssNotification(id string) (object map[string]interface{}, err error) { + var response map[string]interface{} + conn, err := s.client.NewEssClient() + if err != nil { + return nil, WrapError(err) + } parts := strings.SplitN(id, ":", 2) scalingGroupId, notificationArn := parts[0], parts[1] - request := ess.CreateDescribeNotificationConfigurationsRequest() - request.RegionId = s.client.RegionId - request.ScalingGroupId = scalingGroupId - raw, err := s.client.WithEssClient(func(essClient *ess.Client) (interface{}, error) { - return essClient.DescribeNotificationConfigurations(request) - }) + request := map[string]interface{}{ + "ScalingGroupId": scalingGroupId, + "RegionId": s.client.RegionId, + } + + runtime := util.RuntimeOptions{} + runtime.SetAutoretry(true) + response, err = conn.DoRequest(StringPointer("DescribeNotificationConfigurations"), nil, StringPointer("POST"), StringPointer("2014-08-28"), StringPointer("AK"), nil, request, &runtime) if err != nil { if IsExpectedErrors(err, []string{"NotificationConfigurationNotExist", "InvalidScalingGroupId.NotFound"}) { err = WrapErrorf(Error(GetNotFoundMessage("EssNotification", id)), NotFoundMsg, ProviderERROR) } - err = WrapErrorf(err, DefaultErrorMsg, id, request.GetActionName(), AlibabaCloudSdkGoERROR) + err = WrapErrorf(err, DefaultErrorMsg, id, "DescribeNotificationConfigurations", AlibabaCloudSdkGoERROR) return } - addDebug(request.GetActionName(), raw, request.RpcRequest, request) - response, _ := raw.(*ess.DescribeNotificationConfigurationsResponse) - for _, v := range response.NotificationConfigurationModels.NotificationConfigurationModel { - if v.NotificationArn == notificationArn { - return v, nil + + addDebug("DescribeNotificationConfigurations", response, request) + + v, err := jsonpath.Get("$.NotificationConfigurationModels", response) + + if err != nil { + return object, WrapErrorf(err, FailedGetAttributeMsg, id, "$.NotificationConfigurationModels", response) + } + + vv, err := jsonpath.Get("$.NotificationConfigurationModel", v) + + if err != nil { + return object, WrapErrorf(err, FailedGetAttributeMsg, id, "$.NotificationConfigurationModel", response) + } + + for _, w := range vv.([]interface{}) { + m := w.(map[string]interface{}) + if m["NotificationArn"] == notificationArn { + return m, nil } } + err = WrapErrorf(Error(GetNotFoundMessage("EssNotificationConfiguration", id)), NotFoundMsg, ProviderERROR) return + } func (s *EssService) WaitForEssNotification(id string, status Status, timeout int) error { @@ -162,7 +185,7 @@ func (s *EssService) WaitForEssNotification(id string, status Status, timeout in return WrapError(err) } } - resourceId := fmt.Sprintf("%s:%s", object.ScalingGroupId, object.NotificationArn) + resourceId := fmt.Sprintf("%s:%s", object["ScalingGroupId"], object["NotificationArn"]) if resourceId == id && status != Deleted { return nil } diff --git a/website/docs/r/ess_notification.html.markdown b/website/docs/r/ess_notification.html.markdown index 8b83202d843d..daee9a234146 100644 --- a/website/docs/r/ess_notification.html.markdown +++ b/website/docs/r/ess_notification.html.markdown @@ -87,6 +87,7 @@ The following arguments are supported: * account-id: the ID of your account. * resource-relative-id: the notification method. Valid values : `cloudmonitor`, MNS queue: `queue/{queuename}`, Replace the queuename with the specific MNS queue name, MNS topic: `topic/{topicname}`, Replace the topicname with the specific MNS topic name. * `notification_types` - (Required) The notification types of Auto Scaling events and resource changes. Supported notification types: 'AUTOSCALING:SCALE_OUT_SUCCESS', 'AUTOSCALING:SCALE_IN_SUCCESS', 'AUTOSCALING:SCALE_OUT_ERROR', 'AUTOSCALING:SCALE_IN_ERROR', 'AUTOSCALING:SCALE_REJECT', 'AUTOSCALING:SCALE_OUT_START', 'AUTOSCALING:SCALE_IN_START', 'AUTOSCALING:SCHEDULE_TASK_EXPIRING'. +* `time_zone` - (Optional, Available since v1.239.0) The time zone of the notification. Specify the value in UTC. For example, a value of UTC+8 specifies that the time is 8 hours ahead of Coordinated Universal Time, and a value of UTC-7 specifies that the time is 7 hours behind Coordinated Universal Time. ## Attribute Reference