From b586902742eb5be99bf70ab8b8e6fc2787795736 Mon Sep 17 00:00:00 2001 From: chenhanzhang Date: Wed, 15 Jan 2025 10:29:32 +0800 Subject: [PATCH] resource/alicloud_alb_load_balancer: add new attribute deletion_protection_config. --- .../resource_alicloud_alb_load_balancer.go | 1245 ++++++++--------- ...esource_alicloud_alb_load_balancer_test.go | 59 +- alicloud/service_alicloud_alb_v2.go | 192 +-- .../docs/r/alb_load_balancer.html.markdown | 114 +- 4 files changed, 821 insertions(+), 789 deletions(-) diff --git a/alicloud/resource_alicloud_alb_load_balancer.go b/alicloud/resource_alicloud_alb_load_balancer.go index e0d8e19b8d9f..4bb4ff8d7c7a 100644 --- a/alicloud/resource_alicloud_alb_load_balancer.go +++ b/alicloud/resource_alicloud_alb_load_balancer.go @@ -4,9 +4,9 @@ package alicloud import ( "fmt" "log" - "regexp" "time" + "github.com/PaesslerAG/jsonpath" util "github.com/alibabacloud-go/tea-utils/service" "github.com/aliyun/terraform-provider-alicloud/alicloud/connectivity" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" @@ -28,20 +28,24 @@ func resourceAliCloudAlbLoadBalancer() *schema.Resource { Delete: schema.DefaultTimeout(5 * time.Minute), }, Schema: map[string]*schema.Schema{ - "load_balancer_edition": { - Type: schema.TypeString, - Required: true, - ValidateFunc: StringInSlice([]string{"Basic", "Standard", "StandardWithWaf"}, false), - }, - "address_type": { - Type: schema.TypeString, - Required: true, - ValidateFunc: StringInSlice([]string{"Internet", "Intranet"}, false), - }, - "vpc_id": { - Type: schema.TypeString, - Required: true, - ForceNew: true, + "access_log_config": { + Type: schema.TypeSet, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "log_store": { + Optional: true, + Type: schema.TypeString, + Computed: true, + }, + "log_project": { + Optional: true, + Type: schema.TypeString, + Computed: true, + }, + }, + }, }, "address_allocated_mode": { Type: schema.TypeString, @@ -50,39 +54,59 @@ func resourceAliCloudAlbLoadBalancer() *schema.Resource { ValidateFunc: StringInSlice([]string{"Fixed", "Dynamic"}, false), }, "address_ip_version": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Computed: true, - ValidateFunc: StringInSlice([]string{"IPv4", "DualStack"}, false), + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, }, - "ipv6_address_type": { + "address_type": { Type: schema.TypeString, - Optional: true, - Computed: true, + Required: true, ValidateFunc: StringInSlice([]string{"Internet", "Intranet"}, false), }, "bandwidth_package_id": { Type: schema.TypeString, Optional: true, ForceNew: true, - Computed: true, }, - "resource_group_id": { + "create_time": { Type: schema.TypeString, + Computed: true, + }, + "deletion_protection_config": { + Type: schema.TypeList, Optional: true, Computed: true, + ForceNew: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Optional: true, + }, + "enabled_time": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, }, - "load_balancer_name": { + "dns_name": { Type: schema.TypeString, - Optional: true, + Computed: true, }, - "deletion_protection_enabled": { + "dry_run": { Type: schema.TypeBool, Optional: true, }, + "ipv6_address_type": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, "load_balancer_billing_config": { - Type: schema.TypeSet, + Type: schema.TypeList, Required: true, ForceNew: true, MaxItems: 1, @@ -97,56 +121,62 @@ func resourceAliCloudAlbLoadBalancer() *schema.Resource { }, }, }, + "load_balancer_edition": { + Type: schema.TypeString, + Required: true, + }, + "load_balancer_name": { + Type: schema.TypeString, + Optional: true, + }, "modification_protection_config": { - Type: schema.TypeSet, + Type: schema.TypeList, Optional: true, Computed: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "status": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ValidateFunc: StringInSlice([]string{"ConsoleProtection", "NonProtection"}, false), + Type: schema.TypeString, + Optional: true, }, "reason": { Type: schema.TypeString, Optional: true, - Computed: true, - ValidateFunc: StringMatch(regexp.MustCompile(`^[a-zA-Z][a-zA-Z0-9_\-.]{1,127}$`), "The reason must be 2 to 128 characters in length, and must start with a letter. It can contain digits, periods (.), underscores (_), and hyphens (-)."), DiffSuppressFunc: modificationProtectionConfigDiffSuppressFunc, }, }, }, }, - "access_log_config": { - Type: schema.TypeSet, + "region_id": { + Type: schema.TypeString, + Computed: true, + }, + "resource_group_id": { + Type: schema.TypeString, Optional: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "log_project": { - Type: schema.TypeString, - Required: true, - }, - "log_store": { - Type: schema.TypeString, - Required: true, - }, - }, - }, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tags": tagsSchema(), + "vpc_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, }, "zone_mappings": { Type: schema.TypeSet, Required: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "vswitch_id": { + "zone_id": { Type: schema.TypeString, Required: true, }, - "zone_id": { + "vswitch_id": { Type: schema.TypeString, Required: true, }, @@ -155,15 +185,15 @@ func resourceAliCloudAlbLoadBalancer() *schema.Resource { Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "allocation_id": { + "address": { Type: schema.TypeString, Computed: true, }, - "eip_type": { + "allocation_id": { Type: schema.TypeString, Computed: true, }, - "address": { + "eip_type": { Type: schema.TypeString, Computed: true, }, @@ -177,21 +207,9 @@ func resourceAliCloudAlbLoadBalancer() *schema.Resource { }, }, }, - "tags": tagsSchema(), - "dry_run": { + "deletion_protection_enabled": { Type: schema.TypeBool, Optional: true, - }, - "dns_name": { - Type: schema.TypeString, - Computed: true, - }, - "status": { - Type: schema.TypeString, - Computed: true, - }, - "create_time": { - Type: schema.TypeString, Computed: true, }, }, @@ -199,100 +217,98 @@ func resourceAliCloudAlbLoadBalancer() *schema.Resource { } func resourceAliCloudAlbLoadBalancerCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*connectivity.AliyunClient) - albServiceV2 := AlbServiceV2{client} - var response map[string]interface{} + action := "CreateLoadBalancer" - request := make(map[string]interface{}) + var request map[string]interface{} + var response map[string]interface{} + query := make(map[string]interface{}) conn, err := client.NewAlbClient() if err != nil { return WrapError(err) } + request = make(map[string]interface{}) - request["ClientToken"] = buildClientToken("CreateLoadBalancer") - request["LoadBalancerEdition"] = d.Get("load_balancer_edition") - request["AddressType"] = d.Get("address_type") - request["VpcId"] = d.Get("vpc_id") + request["ClientToken"] = buildClientToken(action) + if v, ok := d.GetOkExists("deletion_protection_enabled"); ok { + request["DeletionProtectionEnabled"] = v + } + request["VpcId"] = d.Get("vpc_id") + request["AddressType"] = d.Get("address_type") + if v, ok := d.GetOk("load_balancer_name"); ok { + request["LoadBalancerName"] = v + } if v, ok := d.GetOk("address_allocated_mode"); ok { request["AddressAllocatedMode"] = v } - - if v, ok := d.GetOk("address_ip_version"); ok { - request["AddressIpVersion"] = v - } - if v, ok := d.GetOk("resource_group_id"); ok { request["ResourceGroupId"] = v } - - if v, ok := d.GetOk("load_balancer_name"); ok { - request["LoadBalancerName"] = v - } - - if v, ok := d.GetOkExists("deletion_protection_enabled"); ok { - request["DeletionProtectionEnabled"] = v + request["LoadBalancerEdition"] = d.Get("load_balancer_edition") + if v, ok := d.GetOk("zone_mappings"); ok { + zoneMappingsMapsArray := make([]interface{}, 0) + for _, dataLoop := range v.(*schema.Set).List() { + dataLoopTmp := dataLoop.(map[string]interface{}) + dataLoopMap := make(map[string]interface{}) + dataLoopMap["ZoneId"] = dataLoopTmp["zone_id"] + dataLoopMap["VSwitchId"] = dataLoopTmp["vswitch_id"] + zoneMappingsMapsArray = append(zoneMappingsMapsArray, dataLoopMap) + } + request["ZoneMappings"] = zoneMappingsMapsArray } - loadBalancerBillingConfig := d.Get("load_balancer_billing_config") - loadBalancerBillingConfigMap := map[string]interface{}{} - for _, loadBalancerBillingConfigList := range loadBalancerBillingConfig.(*schema.Set).List() { - loadBalancerBillingConfigArg := loadBalancerBillingConfigList.(map[string]interface{}) + objectDataLocalMap := make(map[string]interface{}) - loadBalancerBillingConfigMap["PayType"] = convertAlbLoadBalancerBillingConfigPayTypeRequest(loadBalancerBillingConfigArg["pay_type"]) + if v, ok := d.GetOk("load_balancer_billing_config"); ok { + payType1, _ := jsonpath.Get("$[0].pay_type", v) + if payType1 != nil && payType1 != "" { + objectDataLocalMap["PayType"] = convertAlbLoadBalancerBillingConfigPayTypeRequest(payType1) + } } if v, ok := d.GetOk("bandwidth_package_id"); ok { - loadBalancerBillingConfigMap["BandwidthPackageId"] = v + objectDataLocalMap["BandwidthPackageId"] = v } - request["LoadBalancerBillingConfig"] = loadBalancerBillingConfigMap + request["LoadBalancerBillingConfig"] = objectDataLocalMap - if v, ok := d.GetOk("modification_protection_config"); ok { - modificationProtectionConfigMap := map[string]interface{}{} - for _, modificationProtectionConfigList := range v.(*schema.Set).List() { - modificationProtectionConfigArg := modificationProtectionConfigList.(map[string]interface{}) - - if status, ok := modificationProtectionConfigArg["status"]; ok { - modificationProtectionConfigMap["Status"] = status - } + objectDataLocalMap1 := make(map[string]interface{}) - if reason, ok := modificationProtectionConfigArg["reason"]; ok { - modificationProtectionConfigMap["Reason"] = reason - } + if v := d.Get("modification_protection_config"); !IsNil(v) { + reason1, _ := jsonpath.Get("$[0].reason", v) + if reason1 != nil && reason1 != "" { + objectDataLocalMap1["Reason"] = reason1 + } + status1, _ := jsonpath.Get("$[0].status", v) + if status1 != nil && status1 != "" { + objectDataLocalMap1["Status"] = status1 } - request["ModificationProtectionConfig"] = modificationProtectionConfigMap + request["ModificationProtectionConfig"] = objectDataLocalMap1 } - zoneMappings := d.Get("zone_mappings") - zoneMappingsMaps := make([]map[string]interface{}, 0) - for _, zoneMappingsList := range zoneMappings.(*schema.Set).List() { - zoneMappingsMap := make(map[string]interface{}) - zoneMappingsArg := zoneMappingsList.(map[string]interface{}) - - zoneMappingsMap["VSwitchId"] = zoneMappingsArg["vswitch_id"] - zoneMappingsMap["ZoneId"] = zoneMappingsArg["zone_id"] - - zoneMappingsMaps = append(zoneMappingsMaps, zoneMappingsMap) + if v, ok := d.GetOk("address_ip_version"); ok { + request["AddressIpVersion"] = v } - - request["ZoneMappings"] = zoneMappingsMaps - if v, ok := d.GetOk("tags"); ok { tagsMap := ConvertTags(v.(map[string]interface{})) - request["Tag"] = tagsMap + request["Tags"] = tagsMap } - if v, ok := d.GetOkExists("dry_run"); ok { - request["DryRun"] = v + if v, ok := d.GetOk("deletion_protection_config"); ok { + jsonPathResult7, err := jsonpath.Get("$[0].enabled", v) + if err == nil && jsonPathResult7 != "" { + request["DeletionProtectionEnabled"] = jsonPathResult7 + } } runtime := util.RuntimeOptions{} runtime.SetAutoretry(true) wait := incrementalWait(3*time.Second, 5*time.Second) - err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutCreate)), func() *resource.RetryError { - response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2020-06-16"), StringPointer("AK"), nil, request, &runtime) + err = resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError { + response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2020-06-16"), StringPointer("AK"), query, request, &runtime) if err != nil { if IsExpectedErrors(err, []string{"SystemBusy", "IdempotenceProcessing"}) || NeedRetry(err) { wait() @@ -310,6 +326,7 @@ func resourceAliCloudAlbLoadBalancerCreate(d *schema.ResourceData, meta interfac d.SetId(fmt.Sprint(response["LoadBalancerId"])) + albServiceV2 := AlbServiceV2{client} stateConf := BuildStateConf([]string{}, []string{"Active"}, d.Timeout(schema.TimeoutCreate), 5*time.Second, albServiceV2.AlbLoadBalancerStateRefreshFunc(d.Id(), "LoadBalancerStatus", []string{"CreateFailed"})) if _, err := stateConf.WaitForState(); err != nil { return WrapErrorf(err, IdMsg, d.Id()) @@ -322,459 +339,201 @@ func resourceAliCloudAlbLoadBalancerRead(d *schema.ResourceData, meta interface{ client := meta.(*connectivity.AliyunClient) albServiceV2 := AlbServiceV2{client} - object, err := albServiceV2.DescribeAlbLoadBalancer(d.Id()) + objectRaw, err := albServiceV2.DescribeAlbLoadBalancer(d.Id()) if err != nil { if !d.IsNewResource() && NotFoundError(err) { - log.Printf("[DEBUG] Resource alicloud_alb_load_balancer albServiceV2.DescribeAlbLoadBalancer Failed!!! %s", err) + log.Printf("[DEBUG] Resource alicloud_alb_load_balancer DescribeAlbLoadBalancer Failed!!! %s", err) d.SetId("") return nil } return WrapError(err) } - d.Set("load_balancer_edition", object["LoadBalancerEdition"]) - d.Set("address_type", object["AddressType"]) - d.Set("vpc_id", object["VpcId"]) - d.Set("address_allocated_mode", object["AddressAllocatedMode"]) - d.Set("address_ip_version", convertAlbLoadBalancerAddressIpVersionResponse(object["AddressIpVersion"])) - d.Set("ipv6_address_type", object["Ipv6AddressType"]) - d.Set("bandwidth_package_id", object["BandwidthPackageId"]) - d.Set("resource_group_id", object["ResourceGroupId"]) - d.Set("load_balancer_name", object["LoadBalancerName"]) - d.Set("tags", tagsToMap(object["Tags"])) - d.Set("dns_name", object["DNSName"]) - d.Set("status", object["LoadBalancerStatus"]) - d.Set("create_time", object["CreateTime"]) - - if deletionProtectionConfig, ok := object["DeletionProtectionConfig"]; ok { - deletionProtectionConfigArg := deletionProtectionConfig.(map[string]interface{}) - - if enabled, ok := deletionProtectionConfigArg["Enabled"]; ok { - d.Set("deletion_protection_enabled", enabled) - } + if objectRaw["AddressAllocatedMode"] != nil { + d.Set("address_allocated_mode", objectRaw["AddressAllocatedMode"]) } - - if loadBalancerBillingConfig, ok := object["LoadBalancerBillingConfig"]; ok { - loadBalancerBillingConfigMaps := make([]map[string]interface{}, 0) - loadBalancerBillingConfigArg := loadBalancerBillingConfig.(map[string]interface{}) - loadBalancerBillingConfigMap := make(map[string]interface{}) - - if payType, ok := loadBalancerBillingConfigArg["PayType"]; ok { - loadBalancerBillingConfigMap["pay_type"] = convertAlbLoadBalancerBillingConfigPayTypeResponse(payType) - } - - loadBalancerBillingConfigMaps = append(loadBalancerBillingConfigMaps, loadBalancerBillingConfigMap) - - d.Set("load_balancer_billing_config", loadBalancerBillingConfigMaps) + if objectRaw["AddressIpVersion"] != nil { + d.Set("address_ip_version", convertAlbLoadBalancerAddressIpVersionResponse(objectRaw["AddressIpVersion"])) } - - if modificationProtectionConfig, ok := object["ModificationProtectionConfig"]; ok { - modificationProtectionConfigMaps := make([]map[string]interface{}, 0) - modificationProtectionConfigArg := modificationProtectionConfig.(map[string]interface{}) - modificationProtectionConfigMap := make(map[string]interface{}) - - if status, ok := modificationProtectionConfigArg["Status"]; ok { - modificationProtectionConfigMap["status"] = status - } - - if reason, ok := modificationProtectionConfigArg["Reason"]; ok { - modificationProtectionConfigMap["reason"] = reason - } - - modificationProtectionConfigMaps = append(modificationProtectionConfigMaps, modificationProtectionConfigMap) - - d.Set("modification_protection_config", modificationProtectionConfigMaps) + if objectRaw["AddressType"] != nil { + d.Set("address_type", objectRaw["AddressType"]) } - - if accessLogConfig, ok := object["AccessLogConfig"]; ok { - accessLogConfigMaps := make([]map[string]interface{}, 0) - accessLogConfigArg := accessLogConfig.(map[string]interface{}) - accessLogConfigMap := make(map[string]interface{}) - - if logProject, ok := accessLogConfigArg["LogProject"]; ok { - accessLogConfigMap["log_project"] = logProject - } - - if logStore, ok := accessLogConfigArg["LogStore"]; ok { - accessLogConfigMap["log_store"] = logStore - } - - accessLogConfigMaps = append(accessLogConfigMaps, accessLogConfigMap) - - d.Set("access_log_config", accessLogConfigMaps) + if objectRaw["BandwidthPackageId"] != nil { + d.Set("bandwidth_package_id", objectRaw["BandwidthPackageId"]) } - - if zoneMappings, ok := object["ZoneMappings"]; ok { - zoneMappingsMaps := make([]map[string]interface{}, 0) - for _, zoneMappingsList := range zoneMappings.([]interface{}) { - zoneMappingsArg := zoneMappingsList.(map[string]interface{}) - zoneMappingsMap := map[string]interface{}{} - - if vSwitchId, ok := zoneMappingsArg["VSwitchId"]; ok { - zoneMappingsMap["vswitch_id"] = vSwitchId - } - - if zoneId, ok := zoneMappingsArg["ZoneId"]; ok { - zoneMappingsMap["zone_id"] = zoneId - } - - if loadBalancerAddresses, ok := zoneMappingsArg["LoadBalancerAddresses"]; ok { - loadBalancerAddressesMaps := make([]map[string]interface{}, 0) - for _, loadBalancerAddressesList := range loadBalancerAddresses.([]interface{}) { - loadBalancerAddressesArg := loadBalancerAddressesList.(map[string]interface{}) - loadBalancerAddressesMap := make(map[string]interface{}) - - if allocationId, ok := loadBalancerAddressesArg["AllocationId"]; ok { - loadBalancerAddressesMap["allocation_id"] = allocationId - } - - if eipType, ok := loadBalancerAddressesArg["EipType"]; ok { - loadBalancerAddressesMap["eip_type"] = eipType - } - - if address, ok := loadBalancerAddressesArg["Address"]; ok { - loadBalancerAddressesMap["address"] = address - } - - if ipv6Address, ok := loadBalancerAddressesArg["Ipv6Address"]; ok { - loadBalancerAddressesMap["ipv6_address"] = ipv6Address - } - - loadBalancerAddressesMaps = append(loadBalancerAddressesMaps, loadBalancerAddressesMap) - } - - zoneMappingsMap["load_balancer_addresses"] = loadBalancerAddressesMaps - } - - zoneMappingsMaps = append(zoneMappingsMaps, zoneMappingsMap) - } - - d.Set("zone_mappings", zoneMappingsMaps) + if objectRaw["CreateTime"] != nil { + d.Set("create_time", objectRaw["CreateTime"]) } - - return nil -} - -func resourceAliCloudAlbLoadBalancerUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*connectivity.AliyunClient) - albServiceV2 := AlbServiceV2{client} - var response map[string]interface{} - d.Partial(true) - - update := false - updateLoadBalancerEditionReq := map[string]interface{}{ - "ClientToken": buildClientToken("UpdateLoadBalancerEdition"), - "LoadBalancerId": d.Id(), + if objectRaw["DNSName"] != nil { + d.Set("dns_name", objectRaw["DNSName"]) } - - if !d.IsNewResource() && d.HasChange("load_balancer_edition") { - update = true + if objectRaw["Ipv6AddressType"] != nil { + d.Set("ipv6_address_type", objectRaw["Ipv6AddressType"]) } - updateLoadBalancerEditionReq["LoadBalancerEdition"] = d.Get("load_balancer_edition") - - if v, ok := d.GetOkExists("dry_run"); ok { - updateLoadBalancerEditionReq["DryRun"] = v + if objectRaw["LoadBalancerEdition"] != nil { + d.Set("load_balancer_edition", objectRaw["LoadBalancerEdition"]) } - - if update { - action := "UpdateLoadBalancerEdition" - conn, err := client.NewAlbClient() - if err != nil { - return WrapError(err) - } - - runtime := util.RuntimeOptions{} - runtime.SetAutoretry(true) - wait := incrementalWait(3*time.Second, 5*time.Second) - err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError { - response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2020-06-16"), StringPointer("AK"), nil, updateLoadBalancerEditionReq, &runtime) - if err != nil { - if IsExpectedErrors(err, []string{"SystemBusy", "IdempotenceProcessing"}) || NeedRetry(err) { - wait() - return resource.RetryableError(err) - } - return resource.NonRetryableError(err) - } - return nil - }) - addDebug(action, response, updateLoadBalancerEditionReq) - - if err != nil { - return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) - } - - stateConf := BuildStateConf([]string{}, []string{fmt.Sprint(d.Get("load_balancer_edition"))}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albServiceV2.AlbLoadBalancerStateRefreshFunc(d.Id(), "LoadBalancerEdition", []string{})) - if _, err := stateConf.WaitForState(); err != nil { - return WrapErrorf(err, IdMsg, d.Id()) - } - - d.SetPartial("load_balancer_edition") + if objectRaw["LoadBalancerName"] != nil { + d.Set("load_balancer_name", objectRaw["LoadBalancerName"]) } - - update = false - updateLoadBalancerAddressTypeConfigReq := map[string]interface{}{ - "ClientToken": buildClientToken("UpdateLoadBalancerAddressTypeConfig"), - "LoadBalancerId": d.Id(), + if objectRaw["RegionId"] != nil { + d.Set("region_id", convertAlbLoadBalancerRegionIdResponse(objectRaw["RegionId"])) } - - if !d.IsNewResource() && d.HasChange("address_type") { - update = true + if objectRaw["ResourceGroupId"] != nil { + d.Set("resource_group_id", objectRaw["ResourceGroupId"]) } - updateLoadBalancerAddressTypeConfigReq["AddressType"] = d.Get("address_type") - - if v, ok := d.GetOkExists("dry_run"); ok { - updateLoadBalancerAddressTypeConfigReq["DryRun"] = v + if objectRaw["LoadBalancerStatus"] != nil { + d.Set("status", objectRaw["LoadBalancerStatus"]) } - - if update { - action := "UpdateLoadBalancerAddressTypeConfig" - conn, err := client.NewAlbClient() - if err != nil { - return WrapError(err) - } - - runtime := util.RuntimeOptions{} - runtime.SetAutoretry(true) - wait := incrementalWait(3*time.Second, 5*time.Second) - err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError { - response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2020-06-16"), StringPointer("AK"), nil, updateLoadBalancerAddressTypeConfigReq, &runtime) - if err != nil { - if NeedRetry(err) { - wait() - return resource.RetryableError(err) - } - return resource.NonRetryableError(err) - } - return nil - }) - addDebug(action, response, updateLoadBalancerAddressTypeConfigReq) - - if err != nil { - return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) - } - - stateConf := BuildStateConf([]string{}, []string{"Active"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albServiceV2.AlbLoadBalancerStateRefreshFunc(d.Id(), "LoadBalancerStatus", []string{})) - if _, err := stateConf.WaitForState(); err != nil { - return WrapErrorf(err, IdMsg, d.Id()) - } - - d.SetPartial("address_type") + if objectRaw["VpcId"] != nil { + d.Set("vpc_id", objectRaw["VpcId"]) } - update = false - moveResourceGroupReq := map[string]interface{}{ - "ResourceType": "loadbalancer", - "ResourceId": d.Id(), + accessLogConfigMaps := make([]map[string]interface{}, 0) + accessLogConfigMap := make(map[string]interface{}) + accessLogConfig1Raw := make(map[string]interface{}) + if objectRaw["AccessLogConfig"] != nil { + accessLogConfig1Raw = objectRaw["AccessLogConfig"].(map[string]interface{}) } + if len(accessLogConfig1Raw) > 0 { + accessLogConfigMap["log_project"] = accessLogConfig1Raw["LogProject"] + accessLogConfigMap["log_store"] = accessLogConfig1Raw["LogStore"] - if !d.IsNewResource() && d.HasChange("resource_group_id") { - update = true + accessLogConfigMaps = append(accessLogConfigMaps, accessLogConfigMap) } - if v, ok := d.GetOk("resource_group_id"); ok { - moveResourceGroupReq["NewResourceGroupId"] = v + if err := d.Set("access_log_config", accessLogConfigMaps); err != nil { + return err } - if update { - action := "MoveResourceGroup" - conn, err := client.NewAlbClient() - if err != nil { - return WrapError(err) - } - - runtime := util.RuntimeOptions{} - runtime.SetAutoretry(true) - wait := incrementalWait(3*time.Second, 5*time.Second) - err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError { - response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2020-06-16"), StringPointer("AK"), nil, moveResourceGroupReq, &runtime) - if err != nil { - if IsExpectedErrors(err, []string{"undefined"}) || NeedRetry(err) { - wait() - return resource.RetryableError(err) - } - return resource.NonRetryableError(err) - } - return nil - }) - addDebug(action, response, moveResourceGroupReq) - - if err != nil { - return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) - } - - stateConf := BuildStateConf([]string{}, []string{"Active"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albServiceV2.AlbLoadBalancerStateRefreshFunc(d.Id(), "LoadBalancerStatus", []string{})) - if _, err := stateConf.WaitForState(); err != nil { - return WrapErrorf(err, IdMsg, d.Id()) - } - - d.SetPartial("resource_group_id") + deletionProtectionConfigMaps := make([]map[string]interface{}, 0) + deletionProtectionConfigMap := make(map[string]interface{}) + deletionProtectionConfig1Raw := make(map[string]interface{}) + if objectRaw["DeletionProtectionConfig"] != nil { + deletionProtectionConfig1Raw = objectRaw["DeletionProtectionConfig"].(map[string]interface{}) } + if len(deletionProtectionConfig1Raw) > 0 { + d.Set("deletion_protection_enabled", deletionProtectionConfig1Raw["Enabled"]) + deletionProtectionConfigMap["enabled"] = deletionProtectionConfig1Raw["Enabled"] + deletionProtectionConfigMap["enabled_time"] = deletionProtectionConfig1Raw["EnabledTime"] - update = false - updateLoadBalancerAttributeReq := map[string]interface{}{ - "ClientToken": buildClientToken("UpdateLoadBalancerAttribute"), - "LoadBalancerId": d.Id(), + deletionProtectionConfigMaps = append(deletionProtectionConfigMaps, deletionProtectionConfigMap) } - - if !d.IsNewResource() && d.HasChange("load_balancer_name") { - update = true + if objectRaw["DeletionProtectionConfig"] != nil { + if err := d.Set("deletion_protection_config", deletionProtectionConfigMaps); err != nil { + return err + } } - if v, ok := d.GetOk("load_balancer_name"); ok { - updateLoadBalancerAttributeReq["LoadBalancerName"] = v + loadBalancerBillingConfigMaps := make([]map[string]interface{}, 0) + loadBalancerBillingConfigMap := make(map[string]interface{}) + loadBalancerBillingConfig1Raw := make(map[string]interface{}) + if objectRaw["LoadBalancerBillingConfig"] != nil { + loadBalancerBillingConfig1Raw = objectRaw["LoadBalancerBillingConfig"].(map[string]interface{}) } + if len(loadBalancerBillingConfig1Raw) > 0 { + loadBalancerBillingConfigMap["pay_type"] = convertAlbLoadBalancerLoadBalancerBillingConfigPayTypeResponse(loadBalancerBillingConfig1Raw["PayType"]) - if !d.IsNewResource() && d.HasChange("modification_protection_config") { - update = true + loadBalancerBillingConfigMaps = append(loadBalancerBillingConfigMaps, loadBalancerBillingConfigMap) } - if v, ok := d.GetOk("modification_protection_config"); ok { - modificationProtectionConfigMap := map[string]interface{}{} - for _, modificationProtectionConfigList := range v.(*schema.Set).List() { - modificationProtectionConfigArg := modificationProtectionConfigList.(map[string]interface{}) - - if status, ok := modificationProtectionConfigArg["status"]; ok { - modificationProtectionConfigMap["Status"] = status - } - - if reason, ok := modificationProtectionConfigArg["reason"]; ok { - modificationProtectionConfigMap["Reason"] = reason - } + if objectRaw["LoadBalancerBillingConfig"] != nil { + if err := d.Set("load_balancer_billing_config", loadBalancerBillingConfigMaps); err != nil { + return err } - - updateLoadBalancerAttributeReq["ModificationProtectionConfig"] = modificationProtectionConfigMap - } - - if v, ok := d.GetOkExists("dry_run"); ok { - updateLoadBalancerAttributeReq["DryRun"] = v } - - if update { - action := "UpdateLoadBalancerAttribute" - conn, err := client.NewAlbClient() - if err != nil { - return WrapError(err) - } - - runtime := util.RuntimeOptions{} - runtime.SetAutoretry(true) - wait := incrementalWait(3*time.Second, 5*time.Second) - err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError { - response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2020-06-16"), StringPointer("AK"), nil, updateLoadBalancerAttributeReq, &runtime) - if err != nil { - if IsExpectedErrors(err, []string{"SystemBusy", "IdempotenceProcessing"}) || NeedRetry(err) { - wait() - return resource.RetryableError(err) - } - return resource.NonRetryableError(err) - } - return nil - }) - addDebug(action, response, updateLoadBalancerAttributeReq) - - if err != nil { - return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) - } - - stateConf := BuildStateConf([]string{}, []string{"Active"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albServiceV2.AlbLoadBalancerStateRefreshFunc(d.Id(), "LoadBalancerStatus", []string{})) - if _, err := stateConf.WaitForState(); err != nil { - return WrapErrorf(err, IdMsg, d.Id()) - } - - d.SetPartial("load_balancer_name") - d.SetPartial("modification_protection_config") + modificationProtectionConfigMaps := make([]map[string]interface{}, 0) + modificationProtectionConfigMap := make(map[string]interface{}) + modificationProtectionConfig1Raw := make(map[string]interface{}) + if objectRaw["ModificationProtectionConfig"] != nil { + modificationProtectionConfig1Raw = objectRaw["ModificationProtectionConfig"].(map[string]interface{}) } + if len(modificationProtectionConfig1Raw) > 0 { + modificationProtectionConfigMap["reason"] = modificationProtectionConfig1Raw["Reason"] + modificationProtectionConfigMap["status"] = modificationProtectionConfig1Raw["Status"] - update = false - updateLoadBalancerZonesReq := map[string]interface{}{ - "ClientToken": buildClientToken("UpdateLoadBalancerZones"), - "LoadBalancerId": d.Id(), + modificationProtectionConfigMaps = append(modificationProtectionConfigMaps, modificationProtectionConfigMap) } - - if !d.IsNewResource() && d.HasChange("zone_mappings") { - update = true + if objectRaw["ModificationProtectionConfig"] != nil { + if err := d.Set("modification_protection_config", modificationProtectionConfigMaps); err != nil { + return err + } } - zoneMappings := d.Get("zone_mappings") + tagsMaps := objectRaw["Tags"] + d.Set("tags", tagsToMap(tagsMaps)) + zoneMappings1Raw := objectRaw["ZoneMappings"] zoneMappingsMaps := make([]map[string]interface{}, 0) - for _, zoneMappingsList := range zoneMappings.(*schema.Set).List() { - zoneMappingsMap := make(map[string]interface{}) - zoneMappingsArg := zoneMappingsList.(map[string]interface{}) - - zoneMappingsMap["VSwitchId"] = zoneMappingsArg["vswitch_id"] - zoneMappingsMap["ZoneId"] = zoneMappingsArg["zone_id"] - - zoneMappingsMaps = append(zoneMappingsMaps, zoneMappingsMap) - } - - updateLoadBalancerZonesReq["ZoneMappings"] = zoneMappingsMaps - - if v, ok := d.GetOkExists("dry_run"); ok { - updateLoadBalancerZonesReq["DryRun"] = v - } - - if update { - action := "UpdateLoadBalancerZones" - conn, err := client.NewAlbClient() - if err != nil { - return WrapError(err) - } + if zoneMappings1Raw != nil { + for _, zoneMappingsChild1Raw := range zoneMappings1Raw.([]interface{}) { + zoneMappingsMap := make(map[string]interface{}) + zoneMappingsChild1Raw := zoneMappingsChild1Raw.(map[string]interface{}) + zoneMappingsMap["vswitch_id"] = zoneMappingsChild1Raw["VSwitchId"] + zoneMappingsMap["zone_id"] = zoneMappingsChild1Raw["ZoneId"] + + loadBalancerAddresses1Raw := zoneMappingsChild1Raw["LoadBalancerAddresses"] + loadBalancerAddressesMaps := make([]map[string]interface{}, 0) + if loadBalancerAddresses1Raw != nil { + for _, loadBalancerAddressesChild1Raw := range loadBalancerAddresses1Raw.([]interface{}) { + loadBalancerAddressesMap := make(map[string]interface{}) + loadBalancerAddressesChild1Raw := loadBalancerAddressesChild1Raw.(map[string]interface{}) + loadBalancerAddressesMap["address"] = loadBalancerAddressesChild1Raw["Address"] + loadBalancerAddressesMap["allocation_id"] = loadBalancerAddressesChild1Raw["AllocationId"] + loadBalancerAddressesMap["eip_type"] = loadBalancerAddressesChild1Raw["EipType"] + loadBalancerAddressesMap["ipv6_address"] = loadBalancerAddressesChild1Raw["Ipv6Address"] - runtime := util.RuntimeOptions{} - runtime.SetAutoretry(true) - wait := incrementalWait(3*time.Second, 5*time.Second) - err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError { - response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2020-06-16"), StringPointer("AK"), nil, updateLoadBalancerZonesReq, &runtime) - if err != nil { - if NeedRetry(err) { - wait() - return resource.RetryableError(err) + loadBalancerAddressesMaps = append(loadBalancerAddressesMaps, loadBalancerAddressesMap) } - return resource.NonRetryableError(err) } - return nil - }) - addDebug(action, response, updateLoadBalancerZonesReq) - - if err != nil { - return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) + zoneMappingsMap["load_balancer_addresses"] = loadBalancerAddressesMaps + zoneMappingsMaps = append(zoneMappingsMaps, zoneMappingsMap) } - - stateConf := BuildStateConf([]string{}, []string{"Active"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albServiceV2.AlbLoadBalancerStateRefreshFunc(d.Id(), "LoadBalancerStatus", []string{})) - if _, err := stateConf.WaitForState(); err != nil { - return WrapErrorf(err, IdMsg, d.Id()) + } + if objectRaw["ZoneMappings"] != nil { + if err := d.Set("zone_mappings", zoneMappingsMaps); err != nil { + return err } - - d.SetPartial("zone_mappings") } - if d.HasChange("ipv6_address_type") { + return nil +} + +func resourceAliCloudAlbLoadBalancerUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*connectivity.AliyunClient) + var request map[string]interface{} + var response map[string]interface{} + var query map[string]interface{} + update := false + d.Partial(true) + + if !d.IsNewResource() && d.HasChanges("deletion_protection_config.0.enabled", "deletion_protection_enabled") { + albServiceV2 := AlbServiceV2{client} object, err := albServiceV2.DescribeAlbLoadBalancer(d.Id()) if err != nil { return WrapError(err) } - target := d.Get("ipv6_address_type").(string) - if object["Ipv6AddressType"] != nil && object["Ipv6AddressType"].(string) != target { - if target == "Intranet" { - request := map[string]interface{}{ - "ClientToken": buildClientToken("DisableLoadBalancerIpv6Internet"), - "LoadBalancerId": d.Id(), - } - - if v, ok := d.GetOkExists("dry_run"); ok { - request["DryRun"] = v - } + target := d.Get("deletion_protection_config.0.enabled").(bool) + if d.HasChange("deletion_protection_enabled") { + target = d.Get("deletion_protection_enabled").(bool) + } - action := "DisableLoadBalancerIpv6Internet" + currentValue, err := jsonpath.Get("$.DeletionProtectionConfig.Enabled", object) + if currentValue != nil && currentValue.(bool) != target { + if target == true { + action := "EnableDeletionProtection" conn, err := client.NewAlbClient() if err != nil { return WrapError(err) } + request = make(map[string]interface{}) + query = make(map[string]interface{}) + request["ResourceId"] = d.Id() + request["ClientToken"] = buildClientToken(action) runtime := util.RuntimeOptions{} runtime.SetAutoretry(true) wait := incrementalWait(3*time.Second, 5*time.Second) - err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError { - response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2020-06-16"), StringPointer("AK"), nil, request, &runtime) + err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { + response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2020-06-16"), StringPointer("AK"), query, request, &runtime) if err != nil { - if NeedRetry(err) { + if IsExpectedErrors(err, []string{"IdempotenceProcessing", "SystemBusy", "undefined", "IncorrectStatus.LoadBalancer"}) || NeedRetry(err) { wait() return resource.RetryableError(err) } @@ -783,40 +542,35 @@ func resourceAliCloudAlbLoadBalancerUpdate(d *schema.ResourceData, meta interfac return nil }) addDebug(action, response, request) - if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) } - - stateConf := BuildStateConf([]string{}, []string{"Intranet"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albServiceV2.AlbLoadBalancerStateRefreshFunc(d.Id(), "Ipv6AddressType", []string{})) + albServiceV2 := AlbServiceV2{client} + stateConf := BuildStateConf([]string{}, []string{"Active"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albServiceV2.AlbLoadBalancerStateRefreshFunc(d.Id(), "LoadBalancerStatus", []string{})) if _, err := stateConf.WaitForState(); err != nil { return WrapErrorf(err, IdMsg, d.Id()) } - } - - if target == "Internet" { - request := map[string]interface{}{ - "ClientToken": buildClientToken("EnableLoadBalancerIpv6Internet"), - "LoadBalancerId": d.Id(), - } - if v, ok := d.GetOkExists("dry_run"); ok { - request["DryRun"] = v - } - - action := "EnableLoadBalancerIpv6Internet" + } + if target == false { + action := "DisableDeletionProtection" conn, err := client.NewAlbClient() if err != nil { return WrapError(err) } + request = make(map[string]interface{}) + query = make(map[string]interface{}) + request["ResourceId"] = d.Id() + request["RegionId"] = client.RegionId + request["ClientToken"] = buildClientToken(action) runtime := util.RuntimeOptions{} runtime.SetAutoretry(true) wait := incrementalWait(3*time.Second, 5*time.Second) - err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError { - response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2020-06-16"), StringPointer("AK"), nil, request, &runtime) + err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { + response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2020-06-16"), StringPointer("AK"), query, request, &runtime) if err != nil { - if NeedRetry(err) { + if IsExpectedErrors(err, []string{"IdempotenceProcessing", "SystemBusy", "undefined", "IncorrectStatus.LoadBalancer"}) || NeedRetry(err) { wait() return resource.RetryableError(err) } @@ -825,62 +579,49 @@ func resourceAliCloudAlbLoadBalancerUpdate(d *schema.ResourceData, meta interfac return nil }) addDebug(action, response, request) - if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) } - - stateConf := BuildStateConf([]string{}, []string{"Internet"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albServiceV2.AlbLoadBalancerStateRefreshFunc(d.Id(), "Ipv6AddressType", []string{})) + albServiceV2 := AlbServiceV2{client} + stateConf := BuildStateConf([]string{}, []string{"Active"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albServiceV2.AlbLoadBalancerStateRefreshFunc(d.Id(), "LoadBalancerStatus", []string{})) if _, err := stateConf.WaitForState(); err != nil { return WrapErrorf(err, IdMsg, d.Id()) } - } - d.SetPartial("ipv6_address_type") + } } } - - if !d.IsNewResource() && d.HasChange("deletion_protection_enabled") { - current := false - + if d.HasChange("ipv6_address_type") { + albServiceV2 := AlbServiceV2{client} object, err := albServiceV2.DescribeAlbLoadBalancer(d.Id()) if err != nil { return WrapError(err) - } - - if deletionProtectionConfig, ok := object["DeletionProtectionConfig"]; ok { - deletionProtectionConfigArg := deletionProtectionConfig.(map[string]interface{}) - - if enabled, ok := deletionProtectionConfigArg["Enabled"]; ok { - current = enabled.(bool) - } - } - - target := d.Get("deletion_protection_enabled").(bool) - if current != target { - if target == false { - request := map[string]interface{}{ - "ClientToken": buildClientToken("DisableDeletionProtection"), - "ResourceId": d.Id(), - } - - if v, ok := d.GetOkExists("dry_run"); ok { - request["DryRun"] = v - } + } - action := "DisableDeletionProtection" + target := d.Get("ipv6_address_type").(string) + if object["Ipv6AddressType"].(string) != target { + if target == "Internet" { + action := "EnableLoadBalancerIpv6Internet" conn, err := client.NewAlbClient() if err != nil { return WrapError(err) } + request = make(map[string]interface{}) + query = make(map[string]interface{}) + request["LoadBalancerId"] = d.Id() + + request["ClientToken"] = buildClientToken(action) + if v, ok := d.GetOkExists("dry_run"); ok { + request["DryRun"] = v + } runtime := util.RuntimeOptions{} runtime.SetAutoretry(true) wait := incrementalWait(3*time.Second, 5*time.Second) - err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError { - response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2020-06-16"), StringPointer("AK"), nil, request, &runtime) + err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { + response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2020-06-16"), StringPointer("AK"), query, request, &runtime) if err != nil { - if IsExpectedErrors(err, []string{"SystemBusy", "IdempotenceProcessing"}) || NeedRetry(err) { + if IsExpectedErrors(err, []string{"IncorrectStatus.LoadBalancer"}) || NeedRetry(err) { wait() return resource.RetryableError(err) } @@ -889,40 +630,38 @@ func resourceAliCloudAlbLoadBalancerUpdate(d *schema.ResourceData, meta interfac return nil }) addDebug(action, response, request) - if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) } - - stateConf := BuildStateConf([]string{}, []string{"Active"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albServiceV2.AlbLoadBalancerStateRefreshFunc(d.Id(), "LoadBalancerStatus", []string{})) + albServiceV2 := AlbServiceV2{client} + stateConf := BuildStateConf([]string{}, []string{"Internet"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albServiceV2.AlbLoadBalancerStateRefreshFunc(d.Id(), "Ipv6AddressType", []string{})) if _, err := stateConf.WaitForState(); err != nil { return WrapErrorf(err, IdMsg, d.Id()) } - } - if target == true { - request := map[string]interface{}{ - "ClientToken": buildClientToken("EnableDeletionProtection"), - "ResourceId": d.Id(), + } + if target == "Intranet" { + action := "DisableLoadBalancerIpv6Internet" + conn, err := client.NewAlbClient() + if err != nil { + return WrapError(err) } + request = make(map[string]interface{}) + query = make(map[string]interface{}) + request["LoadBalancerId"] = d.Id() + request["ClientToken"] = buildClientToken(action) if v, ok := d.GetOkExists("dry_run"); ok { request["DryRun"] = v } - action := "EnableDeletionProtection" - conn, err := client.NewAlbClient() - if err != nil { - return WrapError(err) - } - runtime := util.RuntimeOptions{} runtime.SetAutoretry(true) wait := incrementalWait(3*time.Second, 5*time.Second) - err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutUpdate)), func() *resource.RetryError { - response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2020-06-16"), StringPointer("AK"), nil, request, &runtime) + err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { + response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2020-06-16"), StringPointer("AK"), query, request, &runtime) if err != nil { - if IsExpectedErrors(err, []string{"SystemBusy", "IdempotenceProcessing"}) || NeedRetry(err) { + if IsExpectedErrors(err, []string{"IncorrectStatus.LoadBalancer"}) || NeedRetry(err) { wait() return resource.RetryableError(err) } @@ -931,21 +670,265 @@ func resourceAliCloudAlbLoadBalancerUpdate(d *schema.ResourceData, meta interfac return nil }) addDebug(action, response, request) - if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) } - - stateConf := BuildStateConf([]string{}, []string{"Active"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albServiceV2.AlbLoadBalancerStateRefreshFunc(d.Id(), "LoadBalancerStatus", []string{})) + albServiceV2 := AlbServiceV2{client} + stateConf := BuildStateConf([]string{}, []string{"Intranet"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albServiceV2.AlbLoadBalancerStateRefreshFunc(d.Id(), "Ipv6AddressType", []string{})) if _, err := stateConf.WaitForState(); err != nil { return WrapErrorf(err, IdMsg, d.Id()) } + + } + } + } + + action := "UpdateLoadBalancerAttribute" + conn, err := client.NewAlbClient() + if err != nil { + return WrapError(err) + } + request = make(map[string]interface{}) + query = make(map[string]interface{}) + request["LoadBalancerId"] = d.Id() + + request["ClientToken"] = buildClientToken(action) + if !d.IsNewResource() && d.HasChange("load_balancer_name") { + update = true + request["LoadBalancerName"] = d.Get("load_balancer_name") + } + + if !d.IsNewResource() && d.HasChange("modification_protection_config") { + update = true + objectDataLocalMap := make(map[string]interface{}) + + if v := d.Get("modification_protection_config"); v != nil { + reason1, _ := jsonpath.Get("$[0].reason", v) + if reason1 != nil && (d.HasChange("modification_protection_config.0.reason") || reason1 != "") { + objectDataLocalMap["Reason"] = reason1 + } + status1, _ := jsonpath.Get("$[0].status", v) + if status1 != nil && (d.HasChange("modification_protection_config.0.status") || status1 != "") { + objectDataLocalMap["Status"] = status1 + } + + request["ModificationProtectionConfig"] = objectDataLocalMap + } + } + + if v, ok := d.GetOkExists("dry_run"); ok { + request["DryRun"] = v + } + + if update { + runtime := util.RuntimeOptions{} + runtime.SetAutoretry(true) + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { + response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2020-06-16"), StringPointer("AK"), query, request, &runtime) + if err != nil { + if IsExpectedErrors(err, []string{"ResourceNotFound.LoadBalancer", "SystemBusy", "IdempotenceProcessing", "IncorrectStatus.LoadBalancer"}) || NeedRetry(err) { + wait() + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) + addDebug(action, response, request) + if err != nil { + return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) + } + albServiceV2 := AlbServiceV2{client} + stateConf := BuildStateConf([]string{}, []string{"Active"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albServiceV2.AlbLoadBalancerStateRefreshFunc(d.Id(), "LoadBalancerStatus", []string{})) + if _, err := stateConf.WaitForState(); err != nil { + return WrapErrorf(err, IdMsg, d.Id()) + } + } + update = false + action = "UpdateLoadBalancerEdition" + conn, err = client.NewAlbClient() + if err != nil { + return WrapError(err) + } + request = make(map[string]interface{}) + query = make(map[string]interface{}) + request["LoadBalancerId"] = d.Id() + + request["ClientToken"] = buildClientToken(action) + if !d.IsNewResource() && d.HasChange("load_balancer_edition") { + update = true + } + request["LoadBalancerEdition"] = d.Get("load_balancer_edition") + if v, ok := d.GetOkExists("dry_run"); ok { + request["DryRun"] = v + } + + if update { + runtime := util.RuntimeOptions{} + runtime.SetAutoretry(true) + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { + response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2020-06-16"), StringPointer("AK"), query, request, &runtime) + if err != nil { + if IsExpectedErrors(err, []string{"SystemBusy", "IdempotenceProcessing", "IncorrectStatus.LoadBalancer"}) || NeedRetry(err) { + wait() + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) + addDebug(action, response, request) + if err != nil { + return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) + } + albServiceV2 := AlbServiceV2{client} + stateConf := BuildStateConf([]string{}, []string{fmt.Sprint(d.Get("load_balancer_edition"))}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albServiceV2.AlbLoadBalancerStateRefreshFunc(d.Id(), "LoadBalancerEdition", []string{})) + if _, err := stateConf.WaitForState(); err != nil { + return WrapErrorf(err, IdMsg, d.Id()) + } + } + update = false + action = "MoveResourceGroup" + conn, err = client.NewAlbClient() + if err != nil { + return WrapError(err) + } + request = make(map[string]interface{}) + query = make(map[string]interface{}) + request["ResourceId"] = d.Id() + + if _, ok := d.GetOk("resource_group_id"); ok && !d.IsNewResource() && d.HasChange("resource_group_id") { + update = true + } + request["NewResourceGroupId"] = d.Get("resource_group_id") + request["ResourceType"] = "loadbalancer" + + if update { + runtime := util.RuntimeOptions{} + runtime.SetAutoretry(true) + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { + response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2020-06-16"), StringPointer("AK"), query, request, &runtime) + if err != nil { + if IsExpectedErrors(err, []string{"undefined", "IncorrectStatus.LoadBalancer"}) || NeedRetry(err) { + wait() + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) + addDebug(action, response, request) + if err != nil { + return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) + } + albServiceV2 := AlbServiceV2{client} + stateConf := BuildStateConf([]string{}, []string{"Active"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albServiceV2.AlbLoadBalancerStateRefreshFunc(d.Id(), "LoadBalancerStatus", []string{})) + if _, err := stateConf.WaitForState(); err != nil { + return WrapErrorf(err, IdMsg, d.Id()) + } + } + update = false + action = "UpdateLoadBalancerZones" + conn, err = client.NewAlbClient() + if err != nil { + return WrapError(err) + } + request = make(map[string]interface{}) + query = make(map[string]interface{}) + request["LoadBalancerId"] = d.Id() + + request["ClientToken"] = buildClientToken(action) + if !d.IsNewResource() && d.HasChange("zone_mappings") { + update = true + } + if v, ok := d.GetOk("zone_mappings"); ok || d.HasChange("zone_mappings") { + zoneMappingsMapsArray := make([]interface{}, 0) + for _, dataLoop := range v.(*schema.Set).List() { + dataLoopTmp := dataLoop.(map[string]interface{}) + dataLoopMap := make(map[string]interface{}) + dataLoopMap["ZoneId"] = dataLoopTmp["zone_id"] + dataLoopMap["VSwitchId"] = dataLoopTmp["vswitch_id"] + zoneMappingsMapsArray = append(zoneMappingsMapsArray, dataLoopMap) + } + request["ZoneMappings"] = zoneMappingsMapsArray + } + + if update { + runtime := util.RuntimeOptions{} + runtime.SetAutoretry(true) + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { + response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2020-06-16"), StringPointer("AK"), query, request, &runtime) + if err != nil { + if IsExpectedErrors(err, []string{"IncorrectStatus.LoadBalancer"}) || NeedRetry(err) { + wait() + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) } + return nil + }) + addDebug(action, response, request) + if err != nil { + return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) + } + albServiceV2 := AlbServiceV2{client} + stateConf := BuildStateConf([]string{}, []string{"Active"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albServiceV2.AlbLoadBalancerStateRefreshFunc(d.Id(), "LoadBalancerStatus", []string{})) + if _, err := stateConf.WaitForState(); err != nil { + return WrapErrorf(err, IdMsg, d.Id()) + } + } + update = false + action = "UpdateLoadBalancerAddressTypeConfig" + conn, err = client.NewAlbClient() + if err != nil { + return WrapError(err) + } + request = make(map[string]interface{}) + query = make(map[string]interface{}) + request["LoadBalancerId"] = d.Id() + + request["ClientToken"] = buildClientToken(action) + if !d.IsNewResource() && d.HasChange("address_type") { + update = true + } + request["AddressType"] = d.Get("address_type") - d.SetPartial("deletion_protection_enabled") + if update { + runtime := util.RuntimeOptions{} + runtime.SetAutoretry(true) + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { + response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2020-06-16"), StringPointer("AK"), query, request, &runtime) + if err != nil { + if IsExpectedErrors(err, []string{"IncorrectStatus.LoadBalancer"}) || NeedRetry(err) { + wait() + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) + addDebug(action, response, request) + if err != nil { + return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) + } + albServiceV2 := AlbServiceV2{client} + stateConf := BuildStateConf([]string{}, []string{"Active"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albServiceV2.AlbLoadBalancerStateRefreshFunc(d.Id(), "LoadBalancerStatus", []string{})) + if _, err := stateConf.WaitForState(); err != nil { + return WrapErrorf(err, IdMsg, d.Id()) } } + if d.HasChange("tags") { + albServiceV2 := AlbServiceV2{client} + if err := albServiceV2.SetResourceTags(d, "loadbalancer"); err != nil { + return WrapError(err) + } + } if d.HasChange("access_log_config") { oldAccessLogConfig, newAccessLogConfig := d.GetChange("access_log_config") removed := oldAccessLogConfig.(*schema.Set) @@ -987,6 +970,7 @@ func resourceAliCloudAlbLoadBalancerUpdate(d *schema.ResourceData, meta interfac return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) } + albServiceV2 := AlbServiceV2{client} stateConf := BuildStateConf([]string{}, []string{"Active"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albServiceV2.AlbLoadBalancerStateRefreshFunc(d.Id(), "LoadBalancerStatus", []string{})) if _, err := stateConf.WaitForState(); err != nil { return WrapErrorf(err, IdMsg, d.Id()) @@ -1038,6 +1022,7 @@ func resourceAliCloudAlbLoadBalancerUpdate(d *schema.ResourceData, meta interfac return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) } + albServiceV2 := AlbServiceV2{client} stateConf := BuildStateConf([]string{}, []string{"Active"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albServiceV2.AlbLoadBalancerStateRefreshFunc(d.Id(), "LoadBalancerStatus", []string{})) if _, err := stateConf.WaitForState(); err != nil { return WrapErrorf(err, IdMsg, d.Id()) @@ -1047,42 +1032,35 @@ func resourceAliCloudAlbLoadBalancerUpdate(d *schema.ResourceData, meta interfac d.SetPartial("access_log_config") } - if !d.IsNewResource() && d.HasChange("tags") { - if err := albServiceV2.SetResourceTags(d, "loadbalancer"); err != nil { - return WrapError(err) - } - - d.SetPartial("tags") - } - d.Partial(false) - return resourceAliCloudAlbLoadBalancerRead(d, meta) } func resourceAliCloudAlbLoadBalancerDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*connectivity.AliyunClient) - albServiceV2 := AlbServiceV2{client} action := "DeleteLoadBalancer" + var request map[string]interface{} var response map[string]interface{} - + query := make(map[string]interface{}) conn, err := client.NewAlbClient() if err != nil { return WrapError(err) } + request = make(map[string]interface{}) + request["LoadBalancerId"] = d.Id() - request := map[string]interface{}{ - "ClientToken": buildClientToken("DeleteLoadBalancer"), - "LoadBalancerId": d.Id(), - } + request["ClientToken"] = buildClientToken(action) runtime := util.RuntimeOptions{} runtime.SetAutoretry(true) wait := incrementalWait(3*time.Second, 5*time.Second) - err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutDelete)), func() *resource.RetryError { - response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2020-06-16"), StringPointer("AK"), nil, request, &runtime) + err = resource.Retry(d.Timeout(schema.TimeoutDelete), func() *resource.RetryError { + response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2020-06-16"), StringPointer("AK"), query, request, &runtime) + request["ClientToken"] = buildClientToken(action) + if err != nil { - if IsExpectedErrors(err, []string{"SystemBusy", "IdempotenceProcessing"}) || NeedRetry(err) { + if IsExpectedErrors(err, []string{"ResourceNotFound.LoadBalancer", "SystemBusy", "IdempotenceProcessing"}) || NeedRetry(err) { wait() return resource.RetryableError(err) } @@ -1099,45 +1077,27 @@ func resourceAliCloudAlbLoadBalancerDelete(d *schema.ResourceData, meta interfac return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) } - stateConf := BuildStateConf([]string{}, []string{"Succeeded"}, d.Timeout(schema.TimeoutDelete), 5*time.Second, albServiceV2.AlbJobStateRefreshFunc(d.Id(), "loadbalancer", response["JobId"].(string), []string{})) - if _, err := stateConf.WaitForState(); err != nil { - return WrapErrorf(err, IdMsg, d.Id()) + albServiceV2 := AlbServiceV2{client} + stateConf := BuildStateConf([]string{}, []string{"[Succeeded]"}, d.Timeout(schema.TimeoutDelete), 5*time.Second, albServiceV2.DescribeAsyncAlbLoadBalancerStateRefreshFunc(d, response, "$.Jobs[*].Status", []string{})) + if jobDetail, err := stateConf.WaitForState(); err != nil { + return WrapErrorf(err, IdMsg, d.Id(), jobDetail) } return nil } -func convertAlbLoadBalancerBillingConfigPayTypeRequest(source interface{}) interface{} { - switch source { - case "PayAsYouGo": - return "PostPay" - } - - return source -} - -func convertAlbLoadBalancerBillingConfigPayTypeResponse(source interface{}) interface{} { - switch source { - case "PostPay": - return "PayAsYouGo" - } - - return source -} - func convertAlbLoadBalancerPaymentTypeResponse(source interface{}) interface{} { switch source { case "PostPay": return "PayAsYouGo" } - return source } -func convertAlbLoadBalancerAddressIpVersionResponse(source interface{}) interface{} { +func convertAlbLoadBalancerBillingConfigPayTypeRequest(source interface{}) interface{} { switch source { - case "Ipv4": - return "IPv4" + case "PayAsYouGo": + return "PostPay" } return source @@ -1145,26 +1105,41 @@ func convertAlbLoadBalancerAddressIpVersionResponse(source interface{}) interfac func modificationProtectionConfigDiffSuppressFunc(k, old, new string, d *schema.ResourceData) bool { if v, ok := d.GetOk("modification_protection_config"); ok { - val := v.(*schema.Set).List() + val := v.([]interface{}) if len(val) > 2 { // modification_protection_config 为 Object 类型 return true } - for _, modificationProtectionConfigs := range val { modificationProtectionConfigArg := modificationProtectionConfigs.(map[string]interface{}) return fmt.Sprintf(modificationProtectionConfigArg["status"].(string)) != "ConsoleProtection" } } - return true } -func convertAlbRegionIdResponse(source interface{}) interface{} { +func convertAlbLoadBalancerLoadBalancerBillingConfigPayTypeResponse(source interface{}) interface{} { + source = fmt.Sprint(source) + switch source { + case "PostPay": + return "PayAsYouGo" + } + return source +} +func convertAlbLoadBalancerRegionIdResponse(source interface{}) interface{} { + source = fmt.Sprint(source) switch source { case "cn-hangzhou-onebox-nebula": return "cn-hangzhou" } + return source +} + +func convertAlbLoadBalancerAddressIpVersionResponse(source interface{}) interface{} { + switch source { + case "Ipv4": + return "IPv4" + } return source } diff --git a/alicloud/resource_alicloud_alb_load_balancer_test.go b/alicloud/resource_alicloud_alb_load_balancer_test.go index 426c537a15a9..15e4f3af247b 100644 --- a/alicloud/resource_alicloud_alb_load_balancer_test.go +++ b/alicloud/resource_alicloud_alb_load_balancer_test.go @@ -153,6 +153,26 @@ func TestAccAliCloudAlbLoadBalancer_basic0(t *testing.T) { }), ), }, + { + Config: testAccConfig(map[string]interface{}{ + "deletion_protection_enabled": "true", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "deletion_protection_enabled": "true", + }), + ), + }, + { + Config: testAccConfig(map[string]interface{}{ + "deletion_protection_enabled": "false", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "deletion_protection_enabled": "false", + }), + ), + }, { Config: testAccConfig(map[string]interface{}{ "load_balancer_edition": "Standard", @@ -475,6 +495,11 @@ func TestAccAliCloudAlbLoadBalancer_basic1(t *testing.T) { "zone_id": "${alicloud_vswitch.zone_b.zone_id}", }, }, + "deletion_protection_config": []map[string]interface{}{ + { + "enabled": "true", + }, + }, }), Check: resource.ComposeTestCheckFunc( testAccCheck(map[string]string{ @@ -488,6 +513,20 @@ func TestAccAliCloudAlbLoadBalancer_basic1(t *testing.T) { }), ), }, + { + Config: testAccConfig(map[string]interface{}{ + "deletion_protection_config": []map[string]interface{}{ + { + "enabled": "false", + }, + }, + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "deletion_protection_config.#": "1", + }), + ), + }, { Config: testAccConfig(map[string]interface{}{ "load_balancer_edition": "Standard", @@ -548,26 +587,6 @@ func TestAccAliCloudAlbLoadBalancer_basic1(t *testing.T) { }), ), }, - { - Config: testAccConfig(map[string]interface{}{ - "deletion_protection_enabled": "true", - }), - Check: resource.ComposeTestCheckFunc( - testAccCheck(map[string]string{ - "deletion_protection_enabled": "true", - }), - ), - }, - { - Config: testAccConfig(map[string]interface{}{ - "deletion_protection_enabled": "false", - }), - Check: resource.ComposeTestCheckFunc( - testAccCheck(map[string]string{ - "deletion_protection_enabled": "false", - }), - ), - }, { Config: testAccConfig(map[string]interface{}{ "modification_protection_config": []map[string]interface{}{ diff --git a/alicloud/service_alicloud_alb_v2.go b/alicloud/service_alicloud_alb_v2.go index e0f620fc58a5..7368c283c737 100644 --- a/alicloud/service_alicloud_alb_v2.go +++ b/alicloud/service_alicloud_alb_v2.go @@ -18,6 +18,73 @@ type AlbServiceV2 struct { client *connectivity.AliyunClient } +func (s *AlbServiceV2) DescribeAlbListAsynJobs(id, resourceType, jobId string) (object map[string]interface{}, err error) { + + client := s.client + var request map[string]interface{} + var response map[string]interface{} + var query map[string]interface{} + action := "ListAsynJobs" + conn, err := client.NewAlbClient() + if err != nil { + return object, WrapError(err) + } + request = make(map[string]interface{}) + query = make(map[string]interface{}) + + query["JobIds.1"] = jobId + query["ResourceType"] = resourceType + query["ResourceIds.1"] = id + + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(1*time.Minute, func() *resource.RetryError { + response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2020-06-16"), StringPointer("AK"), query, request, &util.RuntimeOptions{}) + + if err != nil { + if NeedRetry(err) { + wait() + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + addDebug(action, response, request) + return nil + }) + if err != nil { + return object, WrapErrorf(err, DefaultErrorMsg, id, action, AlibabaCloudSdkGoERROR) + } + + v, err := jsonpath.Get("$.Jobs[*]", response) + if err != nil { + return object, WrapErrorf(err, FailedGetAttributeMsg, id, "$.Jobs[*]", response) + } + if len(v.([]interface{})) == 0 { + return object, nil + } + + return v.([]interface{})[0].(map[string]interface{}), nil +} + +func (s *AlbServiceV2) AlbJobStateRefreshFunc(id string, resourceType string, jobId string, failStates []string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + object, err := s.DescribeAlbListAsynJobs(id, resourceType, jobId) + if err != nil { + if NotFoundError(err) { + return object, "", nil + } + return nil, "", WrapError(err) + } + + currentStatus := fmt.Sprint(object["Status"]) + for _, failState := range failStates { + if currentStatus == failState { + return object, currentStatus, WrapError(Error(FailedToReachTargetStatus, currentStatus)) + } + } + return object, currentStatus, nil + } +} + // DescribeAlbListenerAclAttachment <<< Encapsulated get interface for Alb ListenerAclAttachment. func (s *AlbServiceV2) DescribeAlbListenerAclAttachment(id string) (object map[string]interface{}, err error) { @@ -108,72 +175,24 @@ func (s *AlbServiceV2) AlbListenerAclAttachmentStateRefreshFunc(id string, field // DescribeAlbLoadBalancer <<< Encapsulated get interface for Alb LoadBalancer. func (s *AlbServiceV2) DescribeAlbLoadBalancer(id string) (object map[string]interface{}, err error) { - var response map[string]interface{} - action := "GetLoadBalancerAttribute" - - conn, err := s.client.NewAlbClient() - if err != nil { - return object, WrapError(err) - } - - request := map[string]interface{}{ - "LoadBalancerId": id, - } - - runtime := util.RuntimeOptions{} - runtime.SetAutoretry(true) - wait := incrementalWait(3*time.Second, 5*time.Second) - err = resource.Retry(1*time.Minute, func() *resource.RetryError { - response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2020-06-16"), StringPointer("AK"), nil, request, &runtime) - if err != nil { - if NeedRetry(err) { - wait() - return resource.RetryableError(err) - } - return resource.NonRetryableError(err) - } - return nil - }) - addDebug(action, response, request) - - if err != nil { - if IsExpectedErrors(err, []string{"ResourceNotFound.LoadBalancer"}) { - return object, WrapErrorf(Error(GetNotFoundMessage("Alb:LoadBalancer", id)), NotFoundWithResponse, response) - } - return object, WrapErrorf(err, DefaultErrorMsg, id, action, AlibabaCloudSdkGoERROR) - } - - v, err := jsonpath.Get("$", response) - if err != nil { - return object, WrapErrorf(err, FailedGetAttributeMsg, id, "$", response) - } - - object = v.(map[string]interface{}) - - return object, nil -} - -func (s *AlbServiceV2) DescribeAlbListAsynJobs(id, resourceType, jobId string) (object map[string]interface{}, err error) { - client := s.client var request map[string]interface{} var response map[string]interface{} var query map[string]interface{} - action := "ListAsynJobs" + action := "GetLoadBalancerAttribute" conn, err := client.NewAlbClient() if err != nil { return object, WrapError(err) } request = make(map[string]interface{}) query = make(map[string]interface{}) + request["LoadBalancerId"] = id - query["JobIds.1"] = jobId - query["ResourceType"] = resourceType - query["ResourceIds.1"] = id - + runtime := util.RuntimeOptions{} + runtime.SetAutoretry(true) wait := incrementalWait(3*time.Second, 5*time.Second) err = resource.Retry(1*time.Minute, func() *resource.RetryError { - response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2020-06-16"), StringPointer("AK"), query, request, &util.RuntimeOptions{}) + response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2020-06-16"), StringPointer("AK"), query, request, &runtime) if err != nil { if NeedRetry(err) { @@ -182,27 +201,22 @@ func (s *AlbServiceV2) DescribeAlbListAsynJobs(id, resourceType, jobId string) ( } return resource.NonRetryableError(err) } - addDebug(action, response, request) return nil }) + addDebug(action, response, request) if err != nil { + if IsExpectedErrors(err, []string{"ResourceNotFound.LoadBalancer", "-735"}) { + return object, WrapErrorf(Error(GetNotFoundMessage("LoadBalancer", id)), NotFoundMsg, response) + } return object, WrapErrorf(err, DefaultErrorMsg, id, action, AlibabaCloudSdkGoERROR) } - v, err := jsonpath.Get("$.Jobs[*]", response) - if err != nil { - return object, WrapErrorf(err, FailedGetAttributeMsg, id, "$.Jobs[*]", response) - } - if len(v.([]interface{})) == 0 { - return object, nil - } - - return v.([]interface{})[0].(map[string]interface{}), nil + return response, nil } -func (s *AlbServiceV2) AlbJobStateRefreshFunc(id string, resourceType string, jobId string, failStates []string) resource.StateRefreshFunc { +func (s *AlbServiceV2) AlbLoadBalancerStateRefreshFunc(id string, field string, failStates []string) resource.StateRefreshFunc { return func() (interface{}, string, error) { - object, err := s.DescribeAlbListAsynJobs(id, resourceType, jobId) + object, err := s.DescribeAlbLoadBalancer(id) if err != nil { if NotFoundError(err) { return object, "", nil @@ -210,7 +224,16 @@ func (s *AlbServiceV2) AlbJobStateRefreshFunc(id string, resourceType string, jo return nil, "", WrapError(err) } - currentStatus := fmt.Sprint(object["Status"]) + v, err := jsonpath.Get(field, object) + currentStatus := fmt.Sprint(v) + + if strings.HasPrefix(field, "#") { + v, _ := jsonpath.Get(strings.TrimPrefix(field, "#"), object) + if v != nil { + currentStatus = "#CHECKSET" + } + } + for _, failState := range failStates { if currentStatus == failState { return object, currentStatus, WrapError(Error(FailedToReachTargetStatus, currentStatus)) @@ -220,24 +243,33 @@ func (s *AlbServiceV2) AlbJobStateRefreshFunc(id string, resourceType string, jo } } -func (s *AlbServiceV2) AlbLoadBalancerStateRefreshFunc(id string, field string, failStates []string) resource.StateRefreshFunc { +func (s *AlbServiceV2) DescribeAsyncAlbLoadBalancerStateRefreshFunc(d *schema.ResourceData, res map[string]interface{}, field string, failStates []string) resource.StateRefreshFunc { return func() (interface{}, string, error) { - object, err := s.DescribeAlbLoadBalancer(id) + object, err := s.DescribeAsyncListAsynJobs(d, res) if err != nil { if NotFoundError(err) { return object, "", nil } - return nil, "", WrapError(err) } v, err := jsonpath.Get(field, object) currentStatus := fmt.Sprint(v) + + if strings.HasPrefix(field, "#") { + v, _ := jsonpath.Get(strings.TrimPrefix(field, "#"), object) + if v != nil { + currentStatus = "#CHECKSET" + } + } + for _, failState := range failStates { if currentStatus == failState { + if _err, ok := object["error"]; ok { + return _err, currentStatus, WrapError(Error(FailedToReachTargetStatus, currentStatus)) + } return object, currentStatus, WrapError(Error(FailedToReachTargetStatus, currentStatus)) } } - return object, currentStatus, nil } } @@ -253,6 +285,7 @@ func (s *AlbServiceV2) SetResourceTags(d *schema.ResourceData, resourceType stri client := s.client var request map[string]interface{} var response map[string]interface{} + query := make(map[string]interface{}) added, removed := parsingTags(d) removedTagKeys := make([]string, 0) @@ -268,7 +301,9 @@ func (s *AlbServiceV2) SetResourceTags(d *schema.ResourceData, resourceType stri return WrapError(err) } request = make(map[string]interface{}) + query = make(map[string]interface{}) request["ResourceId.1"] = d.Id() + request["ResourceType"] = resourceType for i, key := range removedTagKeys { request[fmt.Sprintf("TagKey.%d", i+1)] = key @@ -278,18 +313,17 @@ func (s *AlbServiceV2) SetResourceTags(d *schema.ResourceData, resourceType stri runtime.SetAutoretry(true) wait := incrementalWait(3*time.Second, 5*time.Second) err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { - response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2020-06-16"), StringPointer("AK"), nil, request, &runtime) - + response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2020-06-16"), StringPointer("AK"), query, request, &runtime) if err != nil { - if IsExpectedErrors(err, []string{"SystemBusy", "IdempotenceProcessing"}) || NeedRetry(err) { + if IsExpectedErrors(err, []string{"SystemBusy", "IdempotenceProcessing", "IncorrectStatus.LoadBalancer"}) || NeedRetry(err) { wait() return resource.RetryableError(err) } return resource.NonRetryableError(err) } - addDebug(action, response, request) return nil }) + addDebug(action, response, request) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) } @@ -303,7 +337,9 @@ func (s *AlbServiceV2) SetResourceTags(d *schema.ResourceData, resourceType stri return WrapError(err) } request = make(map[string]interface{}) + query = make(map[string]interface{}) request["ResourceId.1"] = d.Id() + count := 1 for key, value := range added { request[fmt.Sprintf("Tag.%d.Key", count)] = key @@ -316,24 +352,22 @@ func (s *AlbServiceV2) SetResourceTags(d *schema.ResourceData, resourceType stri runtime.SetAutoretry(true) wait := incrementalWait(3*time.Second, 5*time.Second) err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { - response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2020-06-16"), StringPointer("AK"), nil, request, &runtime) - + response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2020-06-16"), StringPointer("AK"), query, request, &runtime) if err != nil { - if IsExpectedErrors(err, []string{"SystemBusy", "IdempotenceProcessing"}) || NeedRetry(err) { + if IsExpectedErrors(err, []string{"SystemBusy", "IdempotenceProcessing", "IncorrectStatus.LoadBalancer"}) || NeedRetry(err) { wait() return resource.RetryableError(err) } return resource.NonRetryableError(err) } - addDebug(action, response, request) return nil }) + addDebug(action, response, request) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) } } - d.SetPartial("tags") } return nil diff --git a/website/docs/r/alb_load_balancer.html.markdown b/website/docs/r/alb_load_balancer.html.markdown index 79db211dd188..523bcf9cf4b7 100644 --- a/website/docs/r/alb_load_balancer.html.markdown +++ b/website/docs/r/alb_load_balancer.html.markdown @@ -3,14 +3,16 @@ subcategory: "Application Load Balancer (ALB)" layout: "alicloud" page_title: "Alicloud: alicloud_alb_load_balancer" description: |- - Provides a Alicloud ALB Load Balancer resource. + Provides a Alicloud Application Load Balancer (ALB) Load Balancer resource. --- # alicloud_alb_load_balancer -Provides a ALB Load Balancer resource. +Provides a Application Load Balancer (ALB) Load Balancer resource. -For information about ALB Load Balancer and how to use it, see [What is Load Balancer](https://www.alibabacloud.com/help/en/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-createloadbalancer). +Load Balancer Instance. + +For information about Application Load Balancer (ALB) Load Balancer and how to use it, see [What is Load Balancer](https://www.alibabacloud.com/help/en/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-createloadbalancer). -> **NOTE:** Available since v1.132.0. @@ -18,12 +20,6 @@ For information about ALB Load Balancer and how to use it, see [What is Load Bal Basic Usage -
- ```terraform variable "name" { default = "terraform-example" @@ -78,81 +74,89 @@ resource "alicloud_alb_load_balancer" "default" { ## Argument Reference The following arguments are supported: - -* `load_balancer_edition` - (Required) The edition of the ALB instance. The features and billing rules vary based on the edition of the ALB instance. Valid values: `Basic`, `Standard`, `StandardWithWaf`. -* `address_type` - (Required) The type of the address of the ALB instance. Valid values: `Internet`, `Intranet`. -* `vpc_id` - (Required, ForceNew) The ID of the VPC. -* `address_allocated_mode` - (Optional, ForceNew) The mode in which IP addresses are allocated. Valid values: `Fixed`, `Dynamic`. -* `address_ip_version` - (Optional, ForceNew) The protocol version. Valid values: `IPv4`, `DualStack`. -* `ipv6_address_type` - (Optional, Available since v1.211.2) The address type of the Ipv6 address. Valid values: `Internet`, `Intranet`. -* `bandwidth_package_id` - (Optional, ForceNew, Available since v1.211.2) The ID of the Internet Shared Bandwidth instance that is associated with the Internet-facing ALB instance. -* `resource_group_id` - (Optional) The ID of the resource group. -* `load_balancer_name` - (Optional) The name of the ALB instance. +* `address_allocated_mode` - (Optional, ForceNew) The method in which IP addresses are assigned. Valid values: Fixed: The ALB instance uses a fixed IP address. Dynamic (default): An IP address is dynamically assigned to each zone of the ALB instance. +* `address_ip_version` - (Optional, ForceNew, Computed) The protocol version. Value: + - `IPv4`:IPv4 type. + - `DualStack`: the dual-stack type. +* `address_type` - (Required) The type of IP address that the SLB instance uses to provide services. +* `bandwidth_package_id` - (Optional, ForceNew, Available since v1.211.2) The ID of the EIP bandwidth plan which is associated with an ALB instance that uses a public IP address. +* `deletion_protection_config` - (Optional, ForceNew, Computed, List, Available since v1.242.0) Remove the Protection Configuration See [`deletion_protection_config`](#deletion_protection_config) below. +* `dry_run` - (Optional) Whether to PreCheck only this request, value: + + true: sends a check request and does not create a resource. Check items include whether required parameters are filled in, request format, and business restrictions. If the check fails, the corresponding error is returned. If the check passes, the error code DryRunOperation is returned. + + false (default): Sends a normal request, returns the HTTP_2xx status code after the check, and directly performs the operation. +* `ipv6_address_type` - (Optional, Available since v1.211.2) The address type of Ipv6 +* `load_balancer_billing_config` - (Required, ForceNew, List) The configuration of the billing method. See [`load_balancer_billing_config`](#load_balancer_billing_config) below. +* `load_balancer_edition` - (Required) The edition of the ALB instance. +* `load_balancer_name` - (Optional) The name of the resource +* `modification_protection_config` - (Optional, Computed, List) Modify the Protection Configuration See [`modification_protection_config`](#modification_protection_config) below. +* `resource_group_id` - (Optional, Computed) The ID of the resource group +* `tags` - (Optional, Map) The tag of the resource +* `vpc_id` - (Required, ForceNew) The ID of the virtual private cloud (VPC) where the SLB instance is deployed. +* `zone_mappings` - (Required, Set) The zones and vSwitches. You must specify at least two zones. See [`zone_mappings`](#zone_mappings) below. +* `access_log_config` - (Optional, Set) The configuration of the access log. See [`access_log_config`](#access_log_config) below. * `deletion_protection_enabled` - (Optional, Bool) Specifies whether to enable deletion protection. Default value: `false`. Valid values: - `true`: Enables deletion protection. - `false`: Disables deletion protection. -* `load_balancer_billing_config` - (Required, ForceNew, Set) The billing method of the ALB instance. See [`load_balancer_billing_config`](#load_balancer_billing_config) below. -* `modification_protection_config` - (Optional, Set) The configuration of the read-only mode. See [`modification_protection_config`](#modification_protection_config) below. -* `access_log_config` - (Optional, Set) The configuration of the access log. See [`access_log_config`](#access_log_config) below. -* `zone_mappings` - (Required, Set) The list of zones and vSwitch mappings. You must specify at least two zones. See [`zone_mappings`](#zone_mappings) below. -* `tags` - (Optional) A mapping of tags to assign to the resource. -* `dry_run` - (Optional, Bool) Specifies whether to perform a dry run. Default value: `false`. Valid values: `true`, `false`. -### `load_balancer_billing_config` +### `access_log_config` -The load_balancer_billing_config supports the following: +The access_log_config supports the following: -* `pay_type` - (Required, ForceNew) The billing method of the ALB instance. Valid values: `PayAsYouGo`. +* `log_project` - (Optional) The project to which the access log is shipped. +* `log_store` - (Optional) The Logstore to which the access log is shipped. -### `modification_protection_config` +### `deletion_protection_config` -The modification_protection_config supports the following: +The deletion_protection_config supports the following: +* `enabled` - (Optional, Available since v1.242.0) Remove the Protection Status -* `status` - (Optional) Specifies whether to enable the configuration read-only mode. Valid values: `ConsoleProtection`, `NonProtection`. -* `reason` - (Optional) The reason for enabling the configuration read-only mode. **NOTE:** `reason` takes effect only if `status` is set to `ConsoleProtection`. +### `load_balancer_billing_config` -### `access_log_config` +The load_balancer_billing_config supports the following: +* `pay_type` - (Required, ForceNew) Pay Type -The access_log_config supports the following: +### `modification_protection_config` -* `log_project` - (Required) The project to which the access log is shipped. -* `log_store` - (Required) The Logstore to which the access log is shipped. +The modification_protection_config supports the following: +* `reason` - (Optional) Managed Instance +* `status` - (Optional) Load Balancing Modify the Protection Status ### `zone_mappings` The zone_mappings supports the following: - -* `vswitch_id` - (Required) The ID of the VSwitch. -* `zone_id` - (Required) The zone ID of the ALB instance. +* `vswitch_id` - (Required) The ID of the vSwitch that corresponds to the zone. Each zone can use only one vSwitch and subnet. +* `zone_id` - (Required) The ID of the zone to which the SLB instance belongs. ## Attributes Reference The following attributes are exported: - -* `id` - The resource ID in terraform of Load Balancer. -* `dns_name` - (Available since v1.158.0) The domain name of the ALB instance. -* `status` - The status of the Load Balancer. -* `create_time` - The time when the resource was created. -* `zone_mappings` - The list of zones and vSwitch mappings. - * `load_balancer_addresses` - The IP address of the ALB instance. - * `allocation_id` - The ID of the EIP. - * `eip_type` - The type of the EIP. - * `address` - IP address. The Public IP Address, and Private IP Address from the Address Type. - * `ipv6_address` - Ipv6 address. +* `id` - The ID of the resource supplied above. +* `create_time` - The creation time of the resource +* `deletion_protection_config` - Remove the Protection Configuration + * `enabled_time` - Deletion Protection Turn-on Time Use Greenwich Mean Time, in the Format of Yyyy-MM-ddTHH: mm: SSZ +* `dns_name` - DNS Domain Name +* `region_id` - The region ID of the resource +* `status` - Server Load Balancer Instance Status:, indicating that the instance listener will no longer forward traffic.(default). +* `zone_mappings` - The zones and vSwitches. You must specify at least two zones. + * `load_balancer_addresses` - The SLB Instance Address + * `address` - IP Address. The Public IP Address, and Private IP Address from the Address Type + * `allocation_id` - The ID of the EIP instance. + * `eip_type` - The type of the EIP instance. + * `ipv6_address` - Ipv6 address ## Timeouts The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration-0-11/resources.html#timeouts) for certain actions: - * `create` - (Defaults to 5 mins) Used when create the Load Balancer. -* `update` - (Defaults to 5 mins) Used when update the Load Balancer. * `delete` - (Defaults to 5 mins) Used when delete the Load Balancer. - +* `update` - (Defaults to 5 mins) Used when update the Load Balancer. ## Import -Alb Load Balancer can be imported using the id, e.g. +Application Load Balancer (ALB) Load Balancer can be imported using the id, e.g. ```shell $ terraform import alicloud_alb_load_balancer.example -``` +``` \ No newline at end of file