diff --git a/alicloud/resource_alicloud_alb_listener.go b/alicloud/resource_alicloud_alb_listener.go index aa64bd5d7f28..2889401342d8 100644 --- a/alicloud/resource_alicloud_alb_listener.go +++ b/alicloud/resource_alicloud_alb_listener.go @@ -1,3 +1,4 @@ +// Package alicloud. This file is generated automatically. Please do not modify it manually, thank you! package alicloud import ( @@ -6,6 +7,7 @@ import ( "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" @@ -22,102 +24,84 @@ func resourceAliCloudAlbListener() *schema.Resource { State: schema.ImportStatePassthrough, }, Timeouts: &schema.ResourceTimeout{ - Create: schema.DefaultTimeout(2 * time.Minute), - Update: schema.DefaultTimeout(2 * time.Minute), - Delete: schema.DefaultTimeout(2 * time.Minute), + Create: schema.DefaultTimeout(5 * time.Minute), + Update: schema.DefaultTimeout(5 * time.Minute), + Delete: schema.DefaultTimeout(5 * time.Minute), }, Schema: map[string]*schema.Schema{ "access_log_record_customized_headers_enabled": { Type: schema.TypeBool, Optional: true, - Computed: true, }, - "certificates": { - Type: schema.TypeSet, + "access_log_tracing_config": { + Type: schema.TypeList, Optional: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "certificate_id": { - Type: schema.TypeString, - Optional: true, + "tracing_type": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: StringInSlice([]string{"Zipkin"}, false), + }, + "tracing_sample": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: IntBetween(0, 10000), + }, + "tracing_enabled": { + Type: schema.TypeBool, + Required: true, }, }, }, }, - "access_log_tracing_config": { - Type: schema.TypeSet, + "ca_certificates": { + Type: schema.TypeList, Optional: true, - MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "tracing_enabled": { - Type: schema.TypeBool, - Optional: true, - }, - "tracing_sample": { - Type: schema.TypeInt, - Optional: true, - ValidateFunc: IntBetween(1, 10000), - }, - "tracing_type": { + "certificate_id": { Type: schema.TypeString, Optional: true, }, }, }, }, - "acl_config": { - Type: schema.TypeSet, - Optional: true, - Computed: true, - MaxItems: 1, - Deprecated: "Field 'acl_config' has been deprecated from provider version 1.163.0 and it will be removed in the future version. Please use the new resource 'alicloud_alb_listener_acl_attachment'.", + "ca_enabled": { + Type: schema.TypeBool, + Optional: true, + }, + "certificates": { + Type: schema.TypeList, + Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "acl_relations": { - Type: schema.TypeSet, + "certificate_id": { + Type: schema.TypeString, Optional: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "acl_id": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "status": { - Type: schema.TypeString, - Computed: true, - }, - }, - }, - }, - "acl_type": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ValidateFunc: StringInSlice([]string{"White", "Black"}, false), }, }, }, }, "default_actions": { - Type: schema.TypeSet, - Optional: true, + Type: schema.TypeList, + Required: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "type": { Type: schema.TypeString, Required: true, + ForceNew: true, }, "forward_group_config": { - Type: schema.TypeSet, - Required: true, + Type: schema.TypeList, + Optional: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "server_group_tuples": { - Type: schema.TypeSet, + Type: schema.TypeList, Required: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -147,28 +131,22 @@ func resourceAliCloudAlbListener() *schema.Resource { Type: schema.TypeBool, Optional: true, Computed: true, - DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { - if v, ok := d.GetOk("listener_protocol"); ok && v.(string) == "HTTPS" { - return false - } - return true - }, }, "idle_timeout": { - Type: schema.TypeInt, - Optional: true, - Computed: true, + Type: schema.TypeInt, + Optional: true, + Computed: true, + ValidateFunc: IntBetween(0, 60), }, "listener_description": { - Type: schema.TypeString, - Optional: true, - ValidateFunc: StringMatch(regexp.MustCompile(`^([^\x00-\xff]|[\w.,;/@-]){2,256}$`), "\t\nThe description of the listener.\n\nThe description must be 2 to 256 characters in length. The name can contain only the characters in the following string: /^([^\\x00-\\xff]|[\\w.,;/@-]){2,256}$/."), + Type: schema.TypeString, + Optional: true, }, "listener_port": { Type: schema.TypeInt, Required: true, ForceNew: true, - ValidateFunc: IntBetween(1, 65535), + ValidateFunc: IntBetween(0, 65535), }, "listener_protocol": { Type: schema.TypeString, @@ -182,7 +160,7 @@ func resourceAliCloudAlbListener() *schema.Resource { ForceNew: true, }, "quic_config": { - Type: schema.TypeSet, + Type: schema.TypeList, Optional: true, Computed: true, MaxItems: 1, @@ -196,118 +174,112 @@ func resourceAliCloudAlbListener() *schema.Resource { Type: schema.TypeBool, Optional: true, Computed: true, - DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { - if v, ok := d.GetOk("listener_protocol"); ok && v.(string) == "HTTPS" { - return false - } - return true - }, }, }, }, }, "request_timeout": { - Type: schema.TypeInt, - Optional: true, - Computed: true, + Type: schema.TypeInt, + Optional: true, + Computed: true, + ValidateFunc: IntBetween(0, 180), }, "security_policy_id": { Type: schema.TypeString, Optional: true, Computed: true, - DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { - if v, ok := d.GetOk("listener_protocol"); ok && v.(string) == "HTTPS" { - return false - } - return true - }, }, - "tags": tagsSchema(), "status": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ValidateFunc: StringInSlice([]string{"Running", "Stopped"}, false), + Type: schema.TypeString, + Optional: true, + Computed: true, }, + "tags": tagsSchema(), "x_forwarded_for_config": { - Type: schema.TypeSet, - Optional: true, - Computed: true, - MaxItems: 1, - ConflictsWith: []string{"xforwarded_for_config"}, - DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { - if v, ok := d.GetOk("listener_protocol"); ok && v.(string) == "HTTPS" { - return false - } - return true - }, + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "x_forwarded_for_client_cert_issuer_dn_alias": { - Type: schema.TypeString, + "x_forwarded_for_client_source_ips_enabled": { + Type: schema.TypeBool, Optional: true, }, - "x_forwarded_for_client_cert_issuer_dn_enabled": { + "x_forwarded_for_host_enabled": { Type: schema.TypeBool, Optional: true, - Computed: true, }, - "x_forwarded_for_client_cert_client_verify_alias": { + "x_forwarded_for_client_source_ips_trusted": { Type: schema.TypeString, Optional: true, }, - "x_forwarded_for_client_cert_client_verify_enabled": { + "x_forwarded_for_client_cert_subject_dn_alias": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: StringMatch(regexp.MustCompile("^[0-9a-z-_]{1,40}"), "The Custom Header Field Name,"), + }, + "x_forwarded_for_slb_id_enabled": { Type: schema.TypeBool, Optional: true, Computed: true, }, + "x_forwarded_for_client_cert_issuer_dn_alias": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: StringMatch(regexp.MustCompile("^[0-9a-z-_]{1,40}"), "The Custom Header Field Names Only When xforwardedforclientcertsubjectdnenabled, Which Evaluates to True When the Entry into Force of."), + }, + "x_forwarded_for_client_cert_client_verify_alias": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: StringMatch(regexp.MustCompile("^[0-9a-z-_]{1,40}"), "The Custom Header Field Names Only When xforwardedforclientcertclientverifyenabled Has a Value of True, this Value Will Not Take Effect until."), + }, "x_forwarded_for_client_cert_finger_print_alias": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + ValidateFunc: StringMatch(regexp.MustCompile("^[0-9a-z-_]{1,40}"), "The Custom Header Field Names Only When xforwardedforclientcertfingerprintenabled, Which Evaluates to True When the Entry into Force of."), }, - "x_forwarded_for_client_cert_finger_print_enabled": { + "x_forwarded_for_proto_enabled": { Type: schema.TypeBool, Optional: true, Computed: true, }, - "x_forwarded_for_client_source_ips_enabled": { + "x_forwarded_for_slb_port_enabled": { Type: schema.TypeBool, Optional: true, + Computed: true, }, - "x_forwarded_for_client_source_ips_trusted": { - Type: schema.TypeString, - Optional: true, - }, - "x_forwarded_for_client_cert_subject_dn_alias": { - Type: schema.TypeString, + "x_forwarded_for_client_src_port_enabled": { + Type: schema.TypeBool, Optional: true, + Computed: true, }, - "x_forwarded_for_client_cert_subject_dn_enabled": { + "x_forwarded_for_enabled": { Type: schema.TypeBool, Optional: true, Computed: true, }, - "x_forwarded_for_client_src_port_enabled": { - Type: schema.TypeBool, + "x_forwarded_for_processing_mode": { + Type: schema.TypeString, Optional: true, Computed: true, }, - "x_forwarded_for_enabled": { + "x_forwarded_for_client_cert_client_verify_enabled": { Type: schema.TypeBool, Optional: true, Computed: true, }, - "x_forwarded_for_proto_enabled": { + "x_forwarded_for_client_cert_subject_dn_enabled": { Type: schema.TypeBool, Optional: true, Computed: true, }, - "x_forwarded_for_slb_id_enabled": { + "x_forwarded_for_client_cert_finger_print_enabled": { Type: schema.TypeBool, Optional: true, Computed: true, }, - "x_forwarded_for_slb_port_enabled": { + "x_forwarded_for_client_cert_issuer_dn_enabled": { Type: schema.TypeBool, Optional: true, Computed: true, @@ -394,54 +366,76 @@ func resourceAliCloudAlbListener() *schema.Resource { }, }, }, + "acl_config": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + MaxItems: 1, + Deprecated: "Field 'acl_config' has been deprecated from provider version 1.163.0 and it will be removed in the future version. Please use the new resource 'alicloud_alb_listener_acl_attachment'.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "acl_relations": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "acl_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "acl_type": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: StringInSlice([]string{"White", "Black"}, false), + }, + }, + }, + }, }, } } func resourceAliCloudAlbListenerCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*connectivity.AliyunClient) - var response map[string]interface{} + action := "CreateListener" - 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(action) + if v, ok := d.GetOk("certificates"); ok { - certificatesMaps := make([]map[string]interface{}, 0) - for _, certificates := range v.(*schema.Set).List() { - certificatesArg := certificates.(map[string]interface{}) - certificatesMap := map[string]interface{}{} - certificatesMap["CertificateId"] = certificatesArg["certificate_id"] - certificatesMaps = append(certificatesMaps, certificatesMap) - } - request["Certificates"] = certificatesMaps - } - defaultActionsMaps := make([]map[string]interface{}, 0) - for _, defaultActions := range d.Get("default_actions").(*schema.Set).List() { - defaultActionsArg := defaultActions.(map[string]interface{}) - defaultActionsMap := map[string]interface{}{} - defaultActionsMap["Type"] = defaultActionsArg["type"] - forwardGroupConfigMap := map[string]interface{}{} - for _, forwardGroupConfig := range defaultActionsArg["forward_group_config"].(*schema.Set).List() { - forwardGroupConfigArg := forwardGroupConfig.(map[string]interface{}) - serverGroupTuplesMaps := make([]map[string]interface{}, 0) - for _, serverGroupTuples := range forwardGroupConfigArg["server_group_tuples"].(*schema.Set).List() { - serverGroupTuplesArg := serverGroupTuples.(map[string]interface{}) - serverGroupTuplesMap := map[string]interface{}{} - serverGroupTuplesMap["ServerGroupId"] = serverGroupTuplesArg["server_group_id"] - serverGroupTuplesMaps = append(serverGroupTuplesMaps, serverGroupTuplesMap) - } - forwardGroupConfigMap["ServerGroupTuples"] = serverGroupTuplesMaps + certificatesMapsArray := make([]interface{}, 0) + for _, dataLoop := range v.([]interface{}) { + dataLoopTmp := dataLoop.(map[string]interface{}) + dataLoopMap := make(map[string]interface{}) + dataLoopMap["CertificateId"] = dataLoopTmp["certificate_id"] + certificatesMapsArray = append(certificatesMapsArray, dataLoopMap) } - - defaultActionsMap["ForwardGroupConfig"] = forwardGroupConfigMap - defaultActionsMaps = append(defaultActionsMaps, defaultActionsMap) + request["Certificates"] = certificatesMapsArray } - request["DefaultActions"] = defaultActionsMaps - if v, ok := d.GetOkExists("dry_run"); ok { - request["DryRun"] = v + request["LoadBalancerId"] = d.Get("load_balancer_id") + request["ListenerProtocol"] = d.Get("listener_protocol") + request["ListenerPort"] = d.Get("listener_port") + if v, ok := d.GetOkExists("request_timeout"); ok && v.(int) > 0 { + request["RequestTimeout"] = v } if v, ok := d.GetOkExists("gzip_enabled"); ok { request["GzipEnabled"] = v @@ -449,75 +443,186 @@ func resourceAliCloudAlbListenerCreate(d *schema.ResourceData, meta interface{}) if v, ok := d.GetOkExists("http2_enabled"); ok { request["Http2Enabled"] = v } - if v, ok := d.GetOk("idle_timeout"); ok { - request["IdleTimeout"] = v - } - if v, ok := d.GetOk("listener_description"); ok { - request["ListenerDescription"] = v - } - request["ListenerPort"] = d.Get("listener_port") - request["ListenerProtocol"] = d.Get("listener_protocol") - request["LoadBalancerId"] = d.Get("load_balancer_id") - if v, ok := d.GetOk("request_timeout"); ok { - request["RequestTimeout"] = v - } if v, ok := d.GetOk("security_policy_id"); ok { request["SecurityPolicyId"] = v } - if v, ok := d.GetOk("xforwarded_for_config"); ok { - xforwardedForConfigMap := map[string]interface{}{} - for _, xforwardedForConfig := range v.(*schema.Set).List() { - xforwardedForConfigArg := xforwardedForConfig.(map[string]interface{}) - xforwardedForConfigMap["XForwardedForClientCertIssuerDNAlias"] = xforwardedForConfigArg["xforwardedforclientcert_issuerdnalias"] - xforwardedForConfigMap["XForwardedForClientCertIssuerDNEnabled"] = xforwardedForConfigArg["xforwardedforclientcert_issuerdnenabled"] - xforwardedForConfigMap["XForwardedForClientCertClientVerifyAlias"] = xforwardedForConfigArg["xforwardedforclientcertclientverifyalias"] - xforwardedForConfigMap["XForwardedForClientCertClientVerifyEnabled"] = xforwardedForConfigArg["xforwardedforclientcertclientverifyenabled"] - xforwardedForConfigMap["XForwardedForClientCertFingerprintAlias"] = xforwardedForConfigArg["xforwardedforclientcertfingerprintalias"] - xforwardedForConfigMap["XForwardedForClientCertFingerprintEnabled"] = xforwardedForConfigArg["xforwardedforclientcertfingerprintenabled"] - xforwardedForConfigMap["XForwardedForClientCertSubjectDNAlias"] = xforwardedForConfigArg["xforwardedforclientcertsubjectdnalias"] - xforwardedForConfigMap["XForwardedForClientCertSubjectDNEnabled"] = xforwardedForConfigArg["xforwardedforclientcertsubjectdnenabled"] - xforwardedForConfigMap["XForwardedForClientSrcPortEnabled"] = xforwardedForConfigArg["xforwardedforclientsrcportenabled"] - xforwardedForConfigMap["XForwardedForEnabled"] = xforwardedForConfigArg["xforwardedforenabled"] - xforwardedForConfigMap["XForwardedForProtoEnabled"] = xforwardedForConfigArg["xforwardedforprotoenabled"] - xforwardedForConfigMap["XForwardedForSLBIdEnabled"] = xforwardedForConfigArg["xforwardedforslbidenabled"] - xforwardedForConfigMap["XForwardedForSLBPortEnabled"] = xforwardedForConfigArg["xforwardedforslbportenabled"] + objectDataLocalMap := make(map[string]interface{}) + + if v := d.Get("quic_config"); !IsNil(v) { + quicListenerId1, _ := jsonpath.Get("$[0].quic_listener_id", v) + if quicListenerId1 != nil && quicListenerId1 != "" { + objectDataLocalMap["QuicListenerId"] = quicListenerId1 + } + quicUpgradeEnabled1, _ := jsonpath.Get("$[0].quic_upgrade_enabled", v) + if quicUpgradeEnabled1 != nil && quicUpgradeEnabled1 != "" { + objectDataLocalMap["QuicUpgradeEnabled"] = quicUpgradeEnabled1 } - request["XForwardedForConfig"] = xforwardedForConfigMap + request["QuicConfig"] = objectDataLocalMap } - if v, ok := d.GetOk("x_forwarded_for_config"); ok { - xforwardedForConfigMap := map[string]interface{}{} - for _, xforwardedForConfig := range v.(*schema.Set).List() { - xforwardedForConfigArg := xforwardedForConfig.(map[string]interface{}) - xforwardedForConfigMap["XForwardedForClientCertIssuerDNAlias"] = xforwardedForConfigArg["x_forwarded_for_client_cert_issuer_dn_alias"] - xforwardedForConfigMap["XForwardedForClientCertIssuerDNEnabled"] = xforwardedForConfigArg["x_forwarded_for_client_cert_issuer_dn_enabled"] - xforwardedForConfigMap["XForwardedForClientCertClientVerifyAlias"] = xforwardedForConfigArg["x_forwarded_for_client_cert_client_verify_alias"] - xforwardedForConfigMap["XForwardedForClientCertClientVerifyEnabled"] = xforwardedForConfigArg["x_forwarded_for_client_cert_client_verify_enabled"] - xforwardedForConfigMap["XForwardedForClientCertFingerprintAlias"] = xforwardedForConfigArg["x_forwarded_for_client_cert_finger_print_alias"] - xforwardedForConfigMap["XForwardedForClientCertFingerprintEnabled"] = xforwardedForConfigArg["x_forwarded_for_client_cert_finger_print_enabled"] - xforwardedForConfigMap["XForwardedForClientCertSubjectDNAlias"] = xforwardedForConfigArg["x_forwarded_for_client_cert_subject_dn_alias"] - xforwardedForConfigMap["XForwardedForClientCertSubjectDNEnabled"] = xforwardedForConfigArg["x_forwarded_for_client_cert_subject_dn_enabled"] - xforwardedForConfigMap["XForwardedForClientSourceIpsEnabled"] = xforwardedForConfigArg["x_forwarded_for_client_source_ips_enabled"] - xforwardedForConfigMap["XForwardedForClientSourceIpsTrusted"] = xforwardedForConfigArg["x_forwarded_for_client_source_ips_trusted"] - xforwardedForConfigMap["XForwardedForClientSrcPortEnabled"] = xforwardedForConfigArg["x_forwarded_for_client_src_port_enabled"] - xforwardedForConfigMap["XForwardedForEnabled"] = xforwardedForConfigArg["x_forwarded_for_enabled"] - xforwardedForConfigMap["XForwardedForProtoEnabled"] = xforwardedForConfigArg["x_forwarded_for_proto_enabled"] - xforwardedForConfigMap["XForwardedForSLBIdEnabled"] = xforwardedForConfigArg["x_forwarded_for_slb_id_enabled"] - xforwardedForConfigMap["XForwardedForSLBPortEnabled"] = xforwardedForConfigArg["x_forwarded_for_slb_port_enabled"] - } + if v, ok := d.GetOkExists("idle_timeout"); ok && v.(int) > 0 { + request["IdleTimeout"] = v + } + if v, ok := d.GetOk("default_actions"); ok { + defaultActionsMapsArray := make([]interface{}, 0) + for _, dataLoop1 := range v.([]interface{}) { + dataLoop1Tmp := dataLoop1.(map[string]interface{}) + dataLoop1Map := make(map[string]interface{}) + dataLoop1Map["Type"] = dataLoop1Tmp["type"] + localData2 := make(map[string]interface{}) + if v, ok := dataLoop1Tmp["forward_group_config"]; ok { + localData3, err := jsonpath.Get("$[0].server_group_tuples", v) + if err != nil { + localData3 = make([]interface{}, 0) + } + localMaps1 := make([]interface{}, 0) + for _, dataLoop3 := range localData3.([]interface{}) { + dataLoop3Tmp := make(map[string]interface{}) + if dataLoop3 != nil { + dataLoop3Tmp = dataLoop3.(map[string]interface{}) + } + dataLoop3Map := make(map[string]interface{}) + dataLoop3Map["ServerGroupId"] = dataLoop3Tmp["server_group_id"] + localMaps1 = append(localMaps1, dataLoop3Map) + } + localData2["ServerGroupTuples"] = localMaps1 + } - request["XForwardedForConfig"] = xforwardedForConfigMap + dataLoop1Map["ForwardGroupConfig"] = localData2 + defaultActionsMapsArray = append(defaultActionsMapsArray, dataLoop1Map) + } + request["DefaultActions"] = defaultActionsMapsArray + } + + if v, ok := d.GetOkExists("ca_enabled"); ok { + request["CaEnabled"] = v + } + if v, ok := d.GetOk("ca_certificates"); ok { + caCertificatesMapsArray := make([]interface{}, 0) + for _, dataLoop4 := range v.([]interface{}) { + dataLoop4Tmp := dataLoop4.(map[string]interface{}) + dataLoop4Map := make(map[string]interface{}) + dataLoop4Map["CertificateId"] = dataLoop4Tmp["certificate_id"] + caCertificatesMapsArray = append(caCertificatesMapsArray, dataLoop4Map) + } + request["CaCertificates"] = caCertificatesMapsArray + } + + if v, ok := d.GetOk("tags"); ok { + tagsMap := ConvertTags(v.(map[string]interface{})) + request["Tags"] = tagsMap + } + + if v, ok := d.GetOk("listener_description"); ok { + request["ListenerDescription"] = v + } + objectDataLocalMap1 := make(map[string]interface{}) + + if v := d.Get("x_forwarded_for_config"); !IsNil(v) { + xForwardedForClientCertClientVerifyAlias1, _ := jsonpath.Get("$[0].x_forwarded_for_client_cert_client_verify_alias", v) + if xForwardedForClientCertClientVerifyAlias1 != nil && xForwardedForClientCertClientVerifyAlias1 != "" { + objectDataLocalMap1["XForwardedForClientCertClientVerifyAlias"] = xForwardedForClientCertClientVerifyAlias1 + } + xForwardedForClientCertClientVerifyEnabled1, _ := jsonpath.Get("$[0].x_forwarded_for_client_cert_client_verify_enabled", v) + if xForwardedForClientCertClientVerifyEnabled1 != nil && xForwardedForClientCertClientVerifyEnabled1 != "" { + objectDataLocalMap1["XForwardedForClientCertClientVerifyEnabled"] = xForwardedForClientCertClientVerifyEnabled1 + } + xForwardedForClientCertFingerPrintAlias, _ := jsonpath.Get("$[0].x_forwarded_for_client_cert_finger_print_alias", v) + if xForwardedForClientCertFingerPrintAlias != nil && xForwardedForClientCertFingerPrintAlias != "" { + objectDataLocalMap1["XForwardedForClientCertFingerprintAlias"] = xForwardedForClientCertFingerPrintAlias + } + xForwardedForClientCertFingerPrintEnabled, _ := jsonpath.Get("$[0].x_forwarded_for_client_cert_finger_print_enabled", v) + if xForwardedForClientCertFingerPrintEnabled != nil && xForwardedForClientCertFingerPrintEnabled != "" { + objectDataLocalMap1["XForwardedForClientCertFingerprintEnabled"] = xForwardedForClientCertFingerPrintEnabled + } + xForwardedForClientCertIssuerDnAlias, _ := jsonpath.Get("$[0].x_forwarded_for_client_cert_issuer_dn_alias", v) + if xForwardedForClientCertIssuerDnAlias != nil && xForwardedForClientCertIssuerDnAlias != "" { + objectDataLocalMap1["XForwardedForClientCertIssuerDNAlias"] = xForwardedForClientCertIssuerDnAlias + } + xForwardedForClientCertIssuerDnEnabled, _ := jsonpath.Get("$[0].x_forwarded_for_client_cert_issuer_dn_enabled", v) + if xForwardedForClientCertIssuerDnEnabled != nil && xForwardedForClientCertIssuerDnEnabled != "" { + objectDataLocalMap1["XForwardedForClientCertIssuerDNEnabled"] = xForwardedForClientCertIssuerDnEnabled + } + xForwardedForClientCertSubjectDnAlias, _ := jsonpath.Get("$[0].x_forwarded_for_client_cert_subject_dn_alias", v) + if xForwardedForClientCertSubjectDnAlias != nil && xForwardedForClientCertSubjectDnAlias != "" { + objectDataLocalMap1["XForwardedForClientCertSubjectDNAlias"] = xForwardedForClientCertSubjectDnAlias + } + xForwardedForClientCertSubjectDnEnabled, _ := jsonpath.Get("$[0].x_forwarded_for_client_cert_subject_dn_enabled", v) + if xForwardedForClientCertSubjectDnEnabled != nil && xForwardedForClientCertSubjectDnEnabled != "" { + objectDataLocalMap1["XForwardedForClientCertSubjectDNEnabled"] = xForwardedForClientCertSubjectDnEnabled + } + xForwardedForClientSrcPortEnabled1, _ := jsonpath.Get("$[0].x_forwarded_for_client_src_port_enabled", v) + if xForwardedForClientSrcPortEnabled1 != nil && xForwardedForClientSrcPortEnabled1 != "" { + objectDataLocalMap1["XForwardedForClientSrcPortEnabled"] = xForwardedForClientSrcPortEnabled1 + } + xForwardedForEnabled1, _ := jsonpath.Get("$[0].x_forwarded_for_enabled", v) + if xForwardedForEnabled1 != nil && xForwardedForEnabled1 != "" { + objectDataLocalMap1["XForwardedForEnabled"] = xForwardedForEnabled1 + } + xForwardedForProtoEnabled1, _ := jsonpath.Get("$[0].x_forwarded_for_proto_enabled", v) + if xForwardedForProtoEnabled1 != nil && xForwardedForProtoEnabled1 != "" { + objectDataLocalMap1["XForwardedForProtoEnabled"] = xForwardedForProtoEnabled1 + } + xForwardedForSlbIdEnabled, _ := jsonpath.Get("$[0].x_forwarded_for_slb_id_enabled", v) + if xForwardedForSlbIdEnabled != nil && xForwardedForSlbIdEnabled != "" { + objectDataLocalMap1["XForwardedForSLBIdEnabled"] = xForwardedForSlbIdEnabled + } + xForwardedForSlbPortEnabled, _ := jsonpath.Get("$[0].x_forwarded_for_slb_port_enabled", v) + if xForwardedForSlbPortEnabled != nil && xForwardedForSlbPortEnabled != "" { + objectDataLocalMap1["XForwardedForSLBPortEnabled"] = xForwardedForSlbPortEnabled + } + xForwardedForClientSourceIpsEnabled1, _ := jsonpath.Get("$[0].x_forwarded_for_client_source_ips_enabled", v) + if xForwardedForClientSourceIpsEnabled1 != nil && xForwardedForClientSourceIpsEnabled1 != "" { + objectDataLocalMap1["XForwardedForClientSourceIpsEnabled"] = xForwardedForClientSourceIpsEnabled1 + } + xForwardedForProcessingMode1, _ := jsonpath.Get("$[0].x_forwarded_for_processing_mode", v) + if xForwardedForProcessingMode1 != nil && xForwardedForProcessingMode1 != "" { + objectDataLocalMap1["XForwardedForProcessingMode"] = xForwardedForProcessingMode1 + } + xForwardedForClientSourceIpsTrusted1, _ := jsonpath.Get("$[0].x_forwarded_for_client_source_ips_trusted", v) + if xForwardedForClientSourceIpsTrusted1 != nil && xForwardedForClientSourceIpsTrusted1 != "" { + objectDataLocalMap1["XForwardedForClientSourceIpsTrusted"] = xForwardedForClientSourceIpsTrusted1 + } + xForwardedForHostEnabled1, _ := jsonpath.Get("$[0].x_forwarded_for_host_enabled", v) + if xForwardedForHostEnabled1 != nil && xForwardedForHostEnabled1 != "" { + objectDataLocalMap1["XForwardedForHostEnabled"] = xForwardedForHostEnabled1 + } + + request["XForwardedForConfig"] = objectDataLocalMap1 } - request["ClientToken"] = buildClientToken("CreateListener") + if v, ok := d.GetOkExists("dry_run"); ok { + request["DryRun"] = v + } + if v, ok := d.GetOk("xforwarded_for_config"); ok { + xforwardedForConfigMap := map[string]interface{}{} + for _, xforwardedForConfig := range v.(*schema.Set).List() { + xforwardedForConfigArg := xforwardedForConfig.(map[string]interface{}) + xforwardedForConfigMap["XForwardedForClientCertIssuerDNAlias"] = xforwardedForConfigArg["xforwardedforclientcert_issuerdnalias"] + xforwardedForConfigMap["XForwardedForClientCertIssuerDNEnabled"] = xforwardedForConfigArg["xforwardedforclientcert_issuerdnenabled"] + xforwardedForConfigMap["XForwardedForClientCertClientVerifyAlias"] = xforwardedForConfigArg["xforwardedforclientcertclientverifyalias"] + xforwardedForConfigMap["XForwardedForClientCertClientVerifyEnabled"] = xforwardedForConfigArg["xforwardedforclientcertclientverifyenabled"] + xforwardedForConfigMap["XForwardedForClientCertFingerprintAlias"] = xforwardedForConfigArg["xforwardedforclientcertfingerprintalias"] + xforwardedForConfigMap["XForwardedForClientCertFingerprintEnabled"] = xforwardedForConfigArg["xforwardedforclientcertfingerprintenabled"] + xforwardedForConfigMap["XForwardedForClientCertSubjectDNAlias"] = xforwardedForConfigArg["xforwardedforclientcertsubjectdnalias"] + xforwardedForConfigMap["XForwardedForClientCertSubjectDNEnabled"] = xforwardedForConfigArg["xforwardedforclientcertsubjectdnenabled"] + xforwardedForConfigMap["XForwardedForClientSrcPortEnabled"] = xforwardedForConfigArg["xforwardedforclientsrcportenabled"] + xforwardedForConfigMap["XForwardedForEnabled"] = xforwardedForConfigArg["xforwardedforenabled"] + xforwardedForConfigMap["XForwardedForProtoEnabled"] = xforwardedForConfigArg["xforwardedforprotoenabled"] + xforwardedForConfigMap["XForwardedForSLBIdEnabled"] = xforwardedForConfigArg["xforwardedforslbidenabled"] + xforwardedForConfigMap["XForwardedForSLBPortEnabled"] = xforwardedForConfigArg["xforwardedforslbportenabled"] + } + + request["XForwardedForConfig"] = xforwardedForConfigMap + } 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{"IdempotenceProcessing", "IncorrectBusinessStatus.LoadBalancer", "SystemBusy", "-21020"}) || NeedRetry(err) { + if IsExpectedErrors(err, []string{"SystemBusy", "IdempotenceProcessing", "IncorrectBusinessStatus.LoadBalancer", "-21020"}) || NeedRetry(err) { wait() return resource.RetryableError(err) } @@ -526,15 +631,17 @@ func resourceAliCloudAlbListenerCreate(d *schema.ResourceData, meta interface{}) return nil }) addDebug(action, response, request) + if err != nil { return WrapErrorf(err, DefaultErrorMsg, "alicloud_alb_listener", action, AlibabaCloudSdkGoERROR) } d.SetId(fmt.Sprint(response["ListenerId"])) - albService := AlbService{client} - stateConf := BuildStateConf([]string{}, []string{"Running"}, d.Timeout(schema.TimeoutCreate), 5*time.Second, albService.AlbListenerStateRefreshFunc(d.Id(), []string{})) - if _, err := stateConf.WaitForState(); err != nil { - return WrapErrorf(err, IdMsg, d.Id()) + + albServiceV2 := AlbServiceV2{client} + stateConf := BuildStateConf([]string{}, []string{"[Succeeded]"}, d.Timeout(schema.TimeoutCreate), 5*time.Second, albServiceV2.DescribeAsyncAlbListenerStateRefreshFunc(d, response, "$.Jobs[*].Status", []string{})) + if jobDetail, err := stateConf.WaitForState(); err != nil { + return WrapErrorf(err, IdMsg, d.Id(), jobDetail) } return resourceAliCloudAlbListenerUpdate(d, meta) @@ -542,116 +649,198 @@ func resourceAliCloudAlbListenerCreate(d *schema.ResourceData, meta interface{}) func resourceAliCloudAlbListenerRead(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AliyunClient) - albService := AlbService{client} - object, err := albService.DescribeAlbListener(d.Id()) + albServiceV2 := AlbServiceV2{client} + + objectRaw, err := albServiceV2.DescribeAlbListener(d.Id()) if err != nil { if !d.IsNewResource() && NotFoundError(err) { - log.Printf("[DEBUG] Resource alicloud_alb_listener albService.DescribeAlbListener Failed!!! %s", err) + log.Printf("[DEBUG] Resource alicloud_alb_listener DescribeAlbListener Failed!!! %s", err) d.SetId("") return nil } return WrapError(err) } - d.Set("access_log_record_customized_headers_enabled", object["LogConfig"].(map[string]interface{})["AccessLogRecordCustomizedHeadersEnabled"]) + if objectRaw["CaEnabled"] != nil { + d.Set("ca_enabled", objectRaw["CaEnabled"]) + } + if objectRaw["GzipEnabled"] != nil { + d.Set("gzip_enabled", objectRaw["GzipEnabled"]) + } + if objectRaw["Http2Enabled"] != nil { + d.Set("http2_enabled", objectRaw["Http2Enabled"]) + } + if objectRaw["IdleTimeout"] != nil { + d.Set("idle_timeout", objectRaw["IdleTimeout"]) + } + if objectRaw["ListenerDescription"] != nil { + d.Set("listener_description", objectRaw["ListenerDescription"]) + } + if objectRaw["ListenerPort"] != nil { + d.Set("listener_port", objectRaw["ListenerPort"]) + } + if objectRaw["ListenerProtocol"] != nil { + d.Set("listener_protocol", objectRaw["ListenerProtocol"]) + } + if objectRaw["LoadBalancerId"] != nil { + d.Set("load_balancer_id", objectRaw["LoadBalancerId"]) + } + if objectRaw["RequestTimeout"] != nil { + d.Set("request_timeout", objectRaw["RequestTimeout"]) + } + if objectRaw["SecurityPolicyId"] != nil { + d.Set("security_policy_id", objectRaw["SecurityPolicyId"]) + } + if objectRaw["ListenerStatus"] != nil { + d.Set("status", objectRaw["ListenerStatus"]) + } - accessLogTracingConfigSli := make([]map[string]interface{}, 0) - if accessLogTracingConfig, ok := object["LogConfig"].(map[string]interface{})["AccessLogTracingConfig"]; ok && len(accessLogTracingConfig.(map[string]interface{})) > 0 { - accessLogTracingConfigMap := make(map[string]interface{}) - accessLogTracingConfigMap["tracing_enabled"] = accessLogTracingConfig.(map[string]interface{})["TracingEnabled"] - accessLogTracingConfigMap["tracing_sample"] = accessLogTracingConfig.(map[string]interface{})["TracingSample"] - accessLogTracingConfigMap["tracing_type"] = accessLogTracingConfig.(map[string]interface{})["TracingType"] - accessLogTracingConfigSli = append(accessLogTracingConfigSli, accessLogTracingConfigMap) + logConfig1RawObj, _ := jsonpath.Get("$.LogConfig", objectRaw) + logConfig1Raw := make(map[string]interface{}) + if logConfig1RawObj != nil { + logConfig1Raw = logConfig1RawObj.(map[string]interface{}) + } + if logConfig1Raw["AccessLogRecordCustomizedHeadersEnabled"] != nil { + d.Set("access_log_record_customized_headers_enabled", logConfig1Raw["AccessLogRecordCustomizedHeadersEnabled"]) } - d.Set("access_log_tracing_config", accessLogTracingConfigSli) - aclConfigSli := make([]map[string]interface{}, 0) - if aclConfig, ok := object["AclConfig"]; ok && len(aclConfig.(map[string]interface{})) > 0 { - aclConfigMap := make(map[string]interface{}) + accessLogTracingConfigMaps := make([]map[string]interface{}, 0) + accessLogTracingConfigMap := make(map[string]interface{}) + accessLogTracingConfig1RawObj, _ := jsonpath.Get("$.LogConfig.AccessLogTracingConfig", objectRaw) + accessLogTracingConfig1Raw := make(map[string]interface{}) + if accessLogTracingConfig1RawObj != nil { + accessLogTracingConfig1Raw = accessLogTracingConfig1RawObj.(map[string]interface{}) + } + if len(accessLogTracingConfig1Raw) > 0 { + accessLogTracingConfigMap["tracing_enabled"] = accessLogTracingConfig1Raw["TracingEnabled"] + accessLogTracingConfigMap["tracing_sample"] = accessLogTracingConfig1Raw["TracingSample"] + accessLogTracingConfigMap["tracing_type"] = accessLogTracingConfig1Raw["TracingType"] - aclRelationsSli := make([]map[string]interface{}, 0) - if v, ok := aclConfig.(map[string]interface{})["AclRelations"]; ok && len(v.([]interface{})) > 0 { - for _, aclRelations := range v.([]interface{}) { - aclRelationsMap := make(map[string]interface{}) - aclRelationsMap["acl_id"] = aclRelations.(map[string]interface{})["AclId"] - aclRelationsMap["status"] = aclRelations.(map[string]interface{})["Status"] - aclRelationsSli = append(aclRelationsSli, aclRelationsMap) - } + accessLogTracingConfigMaps = append(accessLogTracingConfigMaps, accessLogTracingConfigMap) + } + if accessLogTracingConfig1RawObj != nil { + if err := d.Set("access_log_tracing_config", accessLogTracingConfigMaps); err != nil { + return err } - aclConfigMap["acl_relations"] = aclRelationsSli - aclConfigMap["acl_type"] = aclConfig.(map[string]interface{})["AclType"] - aclConfigSli = append(aclConfigSli, aclConfigMap) } - d.Set("acl_config", aclConfigSli) - if certificatesList, ok := object["Certificates"]; ok && certificatesList != nil { - certificatesMaps := make([]map[string]interface{}, 0) - for _, certificatesListItem := range certificatesList.([]interface{}) { - if certificatesListItemArg, ok := certificatesListItem.(map[string]interface{}); ok { - certificatesListItemMap := map[string]interface{}{} - certificatesListItemMap["certificate_id"] = certificatesListItemArg["CertificateId"] - certificatesMaps = append(certificatesMaps, certificatesListItemMap) - } + caCertificates1Raw := objectRaw["CaCertificates"] + caCertificatesMaps := make([]map[string]interface{}, 0) + if caCertificates1Raw != nil { + for _, caCertificatesChild1Raw := range caCertificates1Raw.([]interface{}) { + caCertificatesMap := make(map[string]interface{}) + caCertificatesChild1Raw := caCertificatesChild1Raw.(map[string]interface{}) + caCertificatesMap["certificate_id"] = caCertificatesChild1Raw["CertificateId"] + + caCertificatesMaps = append(caCertificatesMaps, caCertificatesMap) + } + } + if objectRaw["CaCertificates"] != nil { + if err := d.Set("ca_certificates", caCertificatesMaps); err != nil { + return err } + } + certificates1Raw := objectRaw["Certificates"] + certificatesMaps := make([]map[string]interface{}, 0) + if certificates1Raw != nil { + for _, certificatesChild1Raw := range certificates1Raw.([]interface{}) { + certificatesMap := make(map[string]interface{}) + certificatesChild1Raw := certificatesChild1Raw.(map[string]interface{}) + certificatesMap["certificate_id"] = certificatesChild1Raw["CertificateId"] - d.Set("certificates", certificatesMaps) + certificatesMaps = append(certificatesMaps, certificatesMap) + } } + if objectRaw["Certificates"] != nil { + if err := d.Set("certificates", certificatesMaps); err != nil { + return err + } + } + defaultActions1Raw := objectRaw["DefaultActions"] + defaultActionsMaps := make([]map[string]interface{}, 0) + if defaultActions1Raw != nil { + for _, defaultActionsChild1Raw := range defaultActions1Raw.([]interface{}) { + defaultActionsMap := make(map[string]interface{}) + defaultActionsChild1Raw := defaultActionsChild1Raw.(map[string]interface{}) + defaultActionsMap["type"] = defaultActionsChild1Raw["Type"] + + forwardGroupConfigMaps := make([]map[string]interface{}, 0) + forwardGroupConfigMap := make(map[string]interface{}) + serverGroupTuples1Raw, _ := jsonpath.Get("$.ForwardGroupConfig.ServerGroupTuples", defaultActionsChild1Raw) - if defaultActionsList, ok := object["DefaultActions"]; ok && defaultActionsList != nil { - defaultActionsMaps := make([]map[string]interface{}, 0) - for _, defaultActions := range defaultActionsList.([]interface{}) { - defaultActionsArg := defaultActions.(map[string]interface{}) - defaultActionsMap := map[string]interface{}{} - defaultActionsMap["type"] = defaultActionsArg["Type"] - forwardGroupConfig := defaultActionsArg["ForwardGroupConfig"] - forwardGroupConfigArg := forwardGroupConfig.(map[string]interface{}) serverGroupTuplesMaps := make([]map[string]interface{}, 0) - for _, serverGroupTuples := range forwardGroupConfigArg["ServerGroupTuples"].([]interface{}) { - serverGroupTuplesArg := serverGroupTuples.(map[string]interface{}) - serverGroupTuplesMap := map[string]interface{}{} - serverGroupTuplesMap["server_group_id"] = serverGroupTuplesArg["ServerGroupId"] - serverGroupTuplesMaps = append(serverGroupTuplesMaps, serverGroupTuplesMap) + if serverGroupTuples1Raw != nil { + for _, serverGroupTuplesChild1Raw := range serverGroupTuples1Raw.([]interface{}) { + serverGroupTuplesMap := make(map[string]interface{}) + serverGroupTuplesChild1Raw := serverGroupTuplesChild1Raw.(map[string]interface{}) + serverGroupTuplesMap["server_group_id"] = serverGroupTuplesChild1Raw["ServerGroupId"] + + serverGroupTuplesMaps = append(serverGroupTuplesMaps, serverGroupTuplesMap) + } } - forwardGroupConfigMaps := make([]map[string]interface{}, 0) - forwardGroupConfigMap := map[string]interface{}{} forwardGroupConfigMap["server_group_tuples"] = serverGroupTuplesMaps forwardGroupConfigMaps = append(forwardGroupConfigMaps, forwardGroupConfigMap) defaultActionsMap["forward_group_config"] = forwardGroupConfigMaps defaultActionsMaps = append(defaultActionsMaps, defaultActionsMap) } - - d.Set("default_actions", defaultActionsMaps) } - - d.Set("gzip_enabled", object["GzipEnabled"]) - d.Set("http2_enabled", object["Http2Enabled"]) - if v, ok := object["IdleTimeout"]; ok && fmt.Sprint(v) != "0" { - d.Set("idle_timeout", formatInt(v)) + if objectRaw["DefaultActions"] != nil { + if err := d.Set("default_actions", defaultActionsMaps); err != nil { + return err + } } - d.Set("listener_description", object["ListenerDescription"]) - if v, ok := object["ListenerPort"]; ok && fmt.Sprint(v) != "0" { - d.Set("listener_port", formatInt(v)) + quicConfigMaps := make([]map[string]interface{}, 0) + quicConfigMap := make(map[string]interface{}) + quicConfig1Raw := make(map[string]interface{}) + if objectRaw["QuicConfig"] != nil { + quicConfig1Raw = objectRaw["QuicConfig"].(map[string]interface{}) } - d.Set("listener_protocol", object["ListenerProtocol"]) - d.Set("load_balancer_id", object["LoadBalancerId"]) - d.Set("status", object["ListenerStatus"]) + if len(quicConfig1Raw) > 0 { + quicConfigMap["quic_listener_id"] = quicConfig1Raw["QuicListenerId"] + quicConfigMap["quic_upgrade_enabled"] = quicConfig1Raw["QuicUpgradeEnabled"] - if quicConfig, ok := object["QuicConfig"]; ok { - quicConfigSli := make([]map[string]interface{}, 0) - if len(quicConfig.(map[string]interface{})) > 0 { - quicConfigMap := make(map[string]interface{}) - quicConfigMap["quic_listener_id"] = quicConfig.(map[string]interface{})["QuicListenerId"] - quicConfigMap["quic_upgrade_enabled"] = quicConfig.(map[string]interface{})["QuicUpgradeEnabled"] - quicConfigSli = append(quicConfigSli, quicConfigMap) + quicConfigMaps = append(quicConfigMaps, quicConfigMap) + } + if objectRaw["QuicConfig"] != nil { + if err := d.Set("quic_config", quicConfigMaps); err != nil { + return err } - d.Set("quic_config", quicConfigSli) } - - if v, ok := object["RequestTimeout"]; ok && fmt.Sprint(v) != "0" { - d.Set("request_timeout", formatInt(v)) + tagsMaps := objectRaw["Tags"] + d.Set("tags", tagsToMap(tagsMaps)) + xForwardedForConfigMaps := make([]map[string]interface{}, 0) + xForwardedForConfigMap := make(map[string]interface{}) + xForwardedForConfig1Raw := make(map[string]interface{}) + if objectRaw["XForwardedForConfig"] != nil { + xForwardedForConfig1Raw = objectRaw["XForwardedForConfig"].(map[string]interface{}) + } + if len(xForwardedForConfig1Raw) > 0 { + xForwardedForConfigMap["x_forwarded_for_client_cert_client_verify_alias"] = xForwardedForConfig1Raw["XForwardedForClientCertClientVerifyAlias"] + xForwardedForConfigMap["x_forwarded_for_client_cert_client_verify_enabled"] = xForwardedForConfig1Raw["XForwardedForClientCertClientVerifyEnabled"] + xForwardedForConfigMap["x_forwarded_for_client_cert_finger_print_alias"] = xForwardedForConfig1Raw["XForwardedForClientCertFingerprintAlias"] + xForwardedForConfigMap["x_forwarded_for_client_cert_finger_print_enabled"] = xForwardedForConfig1Raw["XForwardedForClientCertFingerprintEnabled"] + xForwardedForConfigMap["x_forwarded_for_client_cert_issuer_dn_alias"] = xForwardedForConfig1Raw["XForwardedForClientCertIssuerDNAlias"] + xForwardedForConfigMap["x_forwarded_for_client_cert_issuer_dn_enabled"] = xForwardedForConfig1Raw["XForwardedForClientCertIssuerDNEnabled"] + xForwardedForConfigMap["x_forwarded_for_client_cert_subject_dn_alias"] = xForwardedForConfig1Raw["XForwardedForClientCertSubjectDNAlias"] + xForwardedForConfigMap["x_forwarded_for_client_cert_subject_dn_enabled"] = xForwardedForConfig1Raw["XForwardedForClientCertSubjectDNEnabled"] + xForwardedForConfigMap["x_forwarded_for_client_source_ips_enabled"] = xForwardedForConfig1Raw["XForwardedForClientSourceIpsEnabled"] + xForwardedForConfigMap["x_forwarded_for_client_source_ips_trusted"] = xForwardedForConfig1Raw["XForwardedForClientSourceIpsTrusted"] + xForwardedForConfigMap["x_forwarded_for_client_src_port_enabled"] = xForwardedForConfig1Raw["XForwardedForClientSrcPortEnabled"] + xForwardedForConfigMap["x_forwarded_for_enabled"] = xForwardedForConfig1Raw["XForwardedForEnabled"] + xForwardedForConfigMap["x_forwarded_for_host_enabled"] = xForwardedForConfig1Raw["XForwardedForHostEnabled"] + xForwardedForConfigMap["x_forwarded_for_processing_mode"] = xForwardedForConfig1Raw["XForwardedForProcessingMode"] + xForwardedForConfigMap["x_forwarded_for_proto_enabled"] = xForwardedForConfig1Raw["XForwardedForProtoEnabled"] + xForwardedForConfigMap["x_forwarded_for_slb_id_enabled"] = xForwardedForConfig1Raw["XForwardedForSLBIdEnabled"] + xForwardedForConfigMap["x_forwarded_for_slb_port_enabled"] = xForwardedForConfig1Raw["XForwardedForSLBPortEnabled"] + + xForwardedForConfigMaps = append(xForwardedForConfigMaps, xForwardedForConfigMap) + } + if objectRaw["XForwardedForConfig"] != nil { + if err := d.Set("x_forwarded_for_config", xForwardedForConfigMaps); err != nil { + return err + } } - d.Set("security_policy_id", object["SecurityPolicyId"]) - if xforwardedForConfig, ok := object["XForwardedForConfig"]; ok && len(xforwardedForConfig.(map[string]interface{})) > 0 { + if xforwardedForConfig, ok := objectRaw["XForwardedForConfig"]; ok && len(xforwardedForConfig.(map[string]interface{})) > 0 { xforwardedForConfigSli := make([]map[string]interface{}, 0) xforwardedForConfigMap := make(map[string]interface{}) xforwardedForConfigMap["xforwardedforclientcert_issuerdnalias"] = xforwardedForConfig.(map[string]interface{})["XForwardedForClientCertIssuerDNAlias"] @@ -671,250 +860,335 @@ func resourceAliCloudAlbListenerRead(d *schema.ResourceData, meta interface{}) e d.Set("xforwarded_for_config", xforwardedForConfigSli) } - if xforwardedForConfig, ok := object["XForwardedForConfig"]; ok && len(xforwardedForConfig.(map[string]interface{})) > 0 { - xforwardedForConfigSli := make([]map[string]interface{}, 0) - xforwardedForConfigMap := make(map[string]interface{}) - xforwardedForConfigMap["x_forwarded_for_client_cert_issuer_dn_alias"] = xforwardedForConfig.(map[string]interface{})["XForwardedForClientCertIssuerDNAlias"] - xforwardedForConfigMap["x_forwarded_for_client_cert_issuer_dn_enabled"] = xforwardedForConfig.(map[string]interface{})["XForwardedForClientCertIssuerDNEnabled"] - xforwardedForConfigMap["x_forwarded_for_client_cert_client_verify_alias"] = xforwardedForConfig.(map[string]interface{})["XForwardedForClientCertClientVerifyAlias"] - xforwardedForConfigMap["x_forwarded_for_client_cert_client_verify_enabled"] = xforwardedForConfig.(map[string]interface{})["XForwardedForClientCertClientVerifyEnabled"] - xforwardedForConfigMap["x_forwarded_for_client_cert_finger_print_alias"] = xforwardedForConfig.(map[string]interface{})["XForwardedForClientCertFingerprintAlias"] - xforwardedForConfigMap["x_forwarded_for_client_cert_finger_print_enabled"] = xforwardedForConfig.(map[string]interface{})["XForwardedForClientCertFingerprintEnabled"] - xforwardedForConfigMap["x_forwarded_for_client_cert_subject_dn_alias"] = xforwardedForConfig.(map[string]interface{})["XForwardedForClientCertSubjectDNAlias"] - xforwardedForConfigMap["x_forwarded_for_client_cert_subject_dn_enabled"] = xforwardedForConfig.(map[string]interface{})["XForwardedForClientCertSubjectDNEnabled"] - xforwardedForConfigMap["x_forwarded_for_client_source_ips_enabled"] = xforwardedForConfig.(map[string]interface{})["XForwardedForClientSourceIpsEnabled"] - xforwardedForConfigMap["x_forwarded_for_client_source_ips_trusted"] = xforwardedForConfig.(map[string]interface{})["XForwardedForClientSourceIpsTrusted"] - xforwardedForConfigMap["x_forwarded_for_client_src_port_enabled"] = xforwardedForConfig.(map[string]interface{})["XForwardedForClientSrcPortEnabled"] - xforwardedForConfigMap["x_forwarded_for_enabled"] = xforwardedForConfig.(map[string]interface{})["XForwardedForEnabled"] - xforwardedForConfigMap["x_forwarded_for_proto_enabled"] = xforwardedForConfig.(map[string]interface{})["XForwardedForProtoEnabled"] - xforwardedForConfigMap["x_forwarded_for_slb_id_enabled"] = xforwardedForConfig.(map[string]interface{})["XForwardedForSLBIdEnabled"] - xforwardedForConfigMap["x_forwarded_for_slb_port_enabled"] = xforwardedForConfig.(map[string]interface{})["XForwardedForSLBPortEnabled"] - xforwardedForConfigSli = append(xforwardedForConfigSli, xforwardedForConfigMap) - d.Set("x_forwarded_for_config", xforwardedForConfigSli) - } + aclConfigSli := make([]map[string]interface{}, 0) + if aclConfig, ok := objectRaw["AclConfig"]; ok && len(aclConfig.(map[string]interface{})) > 0 { + aclConfigMap := make(map[string]interface{}) - listTagResourcesObject, err := albService.ListTagResources(d.Id(), "listener") - if err != nil { - return WrapError(err) + aclRelationsSli := make([]map[string]interface{}, 0) + if v, ok := aclConfig.(map[string]interface{})["AclRelations"]; ok && len(v.([]interface{})) > 0 { + for _, aclRelations := range v.([]interface{}) { + aclRelationsMap := make(map[string]interface{}) + aclRelationsMap["acl_id"] = aclRelations.(map[string]interface{})["AclId"] + aclRelationsMap["status"] = aclRelations.(map[string]interface{})["Status"] + aclRelationsSli = append(aclRelationsSli, aclRelationsMap) + } + } + aclConfigMap["acl_relations"] = aclRelationsSli + aclConfigMap["acl_type"] = aclConfig.(map[string]interface{})["AclType"] + aclConfigSli = append(aclConfigSli, aclConfigMap) } - - d.Set("tags", tagsToMap(listTagResourcesObject)) - + d.Set("acl_config", aclConfigSli) return nil } func resourceAliCloudAlbListenerUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AliyunClient) - albService := AlbService{client} - albServiceV2 := AlbServiceV2{client} + var request map[string]interface{} var response map[string]interface{} + var query map[string]interface{} + update := false d.Partial(true) - if d.HasChange("tags") { - if err := albService.SetResourceTags(d, "listener"); err != nil { + if d.HasChange("status") { + albServiceV2 := AlbServiceV2{client} + object, err := albServiceV2.DescribeAlbListener(d.Id()) + if err != nil { return WrapError(err) } - d.SetPartial("tags") - } + target := d.Get("status").(string) + if object["ListenerStatus"].(string) != target { + if target == "Running" { + action := "StartListener" + conn, err := client.NewAlbClient() + if err != nil { + return WrapError(err) + } + request = make(map[string]interface{}) + query = make(map[string]interface{}) + request["ListenerId"] = d.Id() - update := false - request := map[string]interface{}{ - "ListenerId": d.Id(), - } + request["ClientToken"] = buildClientToken(action) + if v, ok := d.GetOkExists("dry_run"); ok { + request["DryRun"] = v + } - if d.HasChange("access_log_record_customized_headers_enabled") { - if v, ok := d.GetOkExists("access_log_record_customized_headers_enabled"); ok { - update = true - request["AccessLogRecordCustomizedHeadersEnabled"] = v - } - } + 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{"IncorrectBusinessStatus.LoadBalancer", "SystemBusy", "IdempotenceProcessing", "IncorrectStatus.Listener", "VipStatusNotSupport", "-22001"}) || 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{"Running"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albServiceV2.AlbListenerStateRefreshFunc(d.Id(), "ListenerStatus", []string{})) + if _, err := stateConf.WaitForState(); err != nil { + return WrapErrorf(err, IdMsg, d.Id()) + } - if d.HasChange("access_log_tracing_config") { - if v, ok := d.GetOk("access_log_tracing_config"); ok { - update = true - accessLogTracingConfigMap := map[string]interface{}{} - for _, certificates := range v.(*schema.Set).List() { - certificatesArg := certificates.(map[string]interface{}) - accessLogTracingConfigMap["TracingEnabled"] = certificatesArg["tracing_enabled"] - accessLogTracingConfigMap["TracingSample"] = certificatesArg["tracing_sample"] - accessLogTracingConfigMap["TracingType"] = certificatesArg["tracing_type"] } - request["AccessLogTracingConfig"] = accessLogTracingConfigMap - } - } + if target == "Stopped" { + action := "StopListener" + conn, err := client.NewAlbClient() + if err != nil { + return WrapError(err) + } + request = make(map[string]interface{}) + query = make(map[string]interface{}) + request["ListenerId"] = d.Id() - if update { - if v, ok := d.GetOkExists("dry_run"); ok { - request["DryRun"] = v - } - action := "UpdateListenerLogConfig" - conn, err := client.NewAlbClient() - if err != nil { - return WrapError(err) - } - request["ClientToken"] = buildClientToken("UpdateListenerLogConfig") - 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) - if err != nil { - if IsExpectedErrors(err, []string{"IdempotenceProcessing", "IncorrectBusinessStatus.LoadBalancer", "SystemBusy"}) || NeedRetry(err) { - wait() - return resource.RetryableError(err) + request["ClientToken"] = buildClientToken(action) + if v, ok := d.GetOkExists("dry_run"); ok { + request["DryRun"] = v } - return resource.NonRetryableError(err) + + 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{"IncorrectBusinessStatus.LoadBalancer", "SystemBusy", "IdempotenceProcessing", "IncorrectStatus.Listener", "-22001", "VipStatusNotSupport"}) || 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{"Stopped"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albServiceV2.AlbListenerStateRefreshFunc(d.Id(), "ListenerStatus", []string{})) + if _, err := stateConf.WaitForState(); err != nil { + return WrapErrorf(err, IdMsg, d.Id()) + } + } - return nil - }) - addDebug(action, response, request) - if err != nil { - return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) } - stateConf := BuildStateConf([]string{}, []string{"Running"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albService.AlbListenerStateRefreshFunc(d.Id(), []string{})) - if _, err := stateConf.WaitForState(); err != nil { - return WrapErrorf(err, IdMsg, d.Id()) - } - d.SetPartial("access_log_record_customized_headers_enabled") - d.SetPartial("access_log_tracing_config") } - update = false - updateListenerAttributeReq := map[string]interface{}{ - "ListenerId": d.Id(), + action := "UpdateListenerAttribute" + conn, err := client.NewAlbClient() + if err != nil { + return WrapError(err) } + request = make(map[string]interface{}) + query = make(map[string]interface{}) + request["ListenerId"] = d.Id() - if d.HasChange("certificates") { + request["ClientToken"] = buildClientToken(action) + if !d.IsNewResource() && d.HasChange("certificates") { update = true - } - if v, ok := d.GetOk("certificates"); ok { - certificatesMaps := make([]map[string]interface{}, 0) - for _, certificates := range v.(*schema.Set).List() { - certificatesArg := certificates.(map[string]interface{}) - certificatesMap := map[string]interface{}{} - certificatesMap["CertificateId"] = certificatesArg["certificate_id"] - certificatesMaps = append(certificatesMaps, certificatesMap) + if v, ok := d.GetOk("certificates"); ok || d.HasChange("certificates") { + certificatesMapsArray := make([]interface{}, 0) + for _, dataLoop := range v.([]interface{}) { + dataLoopTmp := dataLoop.(map[string]interface{}) + dataLoopMap := make(map[string]interface{}) + dataLoopMap["CertificateId"] = dataLoopTmp["certificate_id"] + certificatesMapsArray = append(certificatesMapsArray, dataLoopMap) + } + request["Certificates"] = certificatesMapsArray } - updateListenerAttributeReq["Certificates"] = certificatesMaps } - if d.HasChange("quic_config") { - if v, ok := d.GetOk("quic_config"); ok { - update = true - quicConfigMap := map[string]interface{}{} - - for _, quicConfig := range v.(*schema.Set).List() { - quicConfigArg := quicConfig.(map[string]interface{}) - quicConfigMap["QuicListenerId"] = quicConfigArg["quic_listener_id"] - quicConfigMap["QuicUpgradeEnabled"] = quicConfigArg["quic_upgrade_enabled"] - } - - updateListenerAttributeReq["QuicConfig"] = quicConfigMap - } + if !d.IsNewResource() && d.HasChange("request_timeout") { + update = true + request["RequestTimeout"] = d.Get("request_timeout") } - if !d.IsNewResource() && d.HasChange("default_actions") { + if !d.IsNewResource() && d.HasChange("gzip_enabled") { update = true + request["GzipEnabled"] = d.Get("gzip_enabled") } - defaultActionsMaps := make([]map[string]interface{}, 0) - for _, defaultActions := range d.Get("default_actions").(*schema.Set).List() { - defaultActionsArg := defaultActions.(map[string]interface{}) - defaultActionsMap := map[string]interface{}{} - defaultActionsMap["Type"] = defaultActionsArg["type"] - forwardGroupConfigMap := map[string]interface{}{} - for _, forwardGroupConfig := range defaultActionsArg["forward_group_config"].(*schema.Set).List() { - forwardGroupConfigArg := forwardGroupConfig.(map[string]interface{}) - serverGroupTuplesMaps := make([]map[string]interface{}, 0) - for _, serverGroupTuples := range forwardGroupConfigArg["server_group_tuples"].(*schema.Set).List() { - serverGroupTuplesArg := serverGroupTuples.(map[string]interface{}) - serverGroupTuplesMap := map[string]interface{}{} - serverGroupTuplesMap["ServerGroupId"] = serverGroupTuplesArg["server_group_id"] - serverGroupTuplesMaps = append(serverGroupTuplesMaps, serverGroupTuplesMap) - } - forwardGroupConfigMap["ServerGroupTuples"] = serverGroupTuplesMaps - } - defaultActionsMap["ForwardGroupConfig"] = forwardGroupConfigMap - defaultActionsMaps = append(defaultActionsMaps, defaultActionsMap) + if !d.IsNewResource() && d.HasChange("http2_enabled") { + update = true + request["Http2Enabled"] = d.Get("http2_enabled") } - updateListenerAttributeReq["DefaultActions"] = defaultActionsMaps + if !d.IsNewResource() && d.HasChange("security_policy_id") { + update = true + request["SecurityPolicyId"] = d.Get("security_policy_id") + } - if !d.IsNewResource() && d.HasChange("gzip_enabled") { + if !d.IsNewResource() && d.HasChange("quic_config") { update = true + objectDataLocalMap := make(map[string]interface{}) - if v, ok := d.GetOkExists("gzip_enabled"); ok { - updateListenerAttributeReq["GzipEnabled"] = v + if v := d.Get("quic_config"); v != nil { + quicUpgradeEnabled1, _ := jsonpath.Get("$[0].quic_upgrade_enabled", v) + if quicUpgradeEnabled1 != nil && (d.HasChange("quic_config.0.quic_upgrade_enabled") || quicUpgradeEnabled1 != "") { + objectDataLocalMap["QuicUpgradeEnabled"] = quicUpgradeEnabled1 + } + quicListenerId1, _ := jsonpath.Get("$[0].quic_listener_id", v) + if quicListenerId1 != nil && (d.HasChange("quic_config.0.quic_listener_id") || quicListenerId1 != "") { + objectDataLocalMap["QuicListenerId"] = quicListenerId1 + } + + request["QuicConfig"] = objectDataLocalMap } } - if !d.IsNewResource() && d.HasChange("http2_enabled") { + if !d.IsNewResource() && d.HasChange("default_actions") { update = true + } + if v, ok := d.GetOk("default_actions"); ok || d.HasChange("default_actions") { + defaultActionsMapsArray := make([]interface{}, 0) + for _, dataLoop1 := range v.([]interface{}) { + dataLoop1Tmp := dataLoop1.(map[string]interface{}) + dataLoop1Map := make(map[string]interface{}) + if !IsNil(dataLoop1Tmp["forward_group_config"]) { + localData2 := make(map[string]interface{}) + if v, ok := dataLoop1Tmp["forward_group_config"]; ok { + localData3, err := jsonpath.Get("$[0].server_group_tuples", v) + if err != nil { + localData3 = make([]interface{}, 0) + } + localMaps1 := make([]interface{}, 0) + for _, dataLoop3 := range localData3.([]interface{}) { + dataLoop3Tmp := make(map[string]interface{}) + if dataLoop3 != nil { + dataLoop3Tmp = dataLoop3.(map[string]interface{}) + } + dataLoop3Map := make(map[string]interface{}) + dataLoop3Map["ServerGroupId"] = dataLoop3Tmp["server_group_id"] + localMaps1 = append(localMaps1, dataLoop3Map) + } + localData2["ServerGroupTuples"] = localMaps1 + } - if v, ok := d.GetOkExists("http2_enabled"); ok { - updateListenerAttributeReq["Http2Enabled"] = v + dataLoop1Map["ForwardGroupConfig"] = localData2 + } + dataLoop1Map["Type"] = dataLoop1Tmp["type"] + defaultActionsMapsArray = append(defaultActionsMapsArray, dataLoop1Map) } + request["DefaultActions"] = defaultActionsMapsArray } if !d.IsNewResource() && d.HasChange("idle_timeout") { update = true - - if v, ok := d.GetOk("idle_timeout"); ok { - updateListenerAttributeReq["IdleTimeout"] = v - } + request["IdleTimeout"] = d.Get("idle_timeout") } - if !d.IsNewResource() && d.HasChange("listener_description") { + if !d.IsNewResource() && d.HasChange("ca_enabled") { update = true - } - if v, ok := d.GetOk("listener_description"); ok { - updateListenerAttributeReq["ListenerDescription"] = v + request["CaEnabled"] = d.Get("ca_enabled") } - if !d.IsNewResource() && d.HasChange("request_timeout") { + if !d.IsNewResource() && d.HasChange("ca_certificates") { update = true - - if v, ok := d.GetOk("request_timeout"); ok { - updateListenerAttributeReq["RequestTimeout"] = v + if v, ok := d.GetOk("ca_certificates"); ok || d.HasChange("ca_certificates") { + caCertificatesMapsArray := make([]interface{}, 0) + for _, dataLoop4 := range v.([]interface{}) { + dataLoop4Tmp := dataLoop4.(map[string]interface{}) + dataLoop4Map := make(map[string]interface{}) + dataLoop4Map["CertificateId"] = dataLoop4Tmp["certificate_id"] + caCertificatesMapsArray = append(caCertificatesMapsArray, dataLoop4Map) + } + request["CaCertificates"] = caCertificatesMapsArray } } - if !d.IsNewResource() && d.HasChange("security_policy_id") { + if !d.IsNewResource() && d.HasChange("listener_description") { update = true - } - if v, ok := d.GetOk("security_policy_id"); ok { - updateListenerAttributeReq["SecurityPolicyId"] = v + request["ListenerDescription"] = d.Get("listener_description") } if !d.IsNewResource() && d.HasChange("x_forwarded_for_config") { update = true + objectDataLocalMap1 := make(map[string]interface{}) - if v, ok := d.GetOk("x_forwarded_for_config"); ok { - xforwardedForConfigMap := map[string]interface{}{} - for _, xforwardedForConfig := range v.(*schema.Set).List() { - xforwardedForConfigArg := xforwardedForConfig.(map[string]interface{}) - xforwardedForConfigMap["XForwardedForClientCertIssuerDNAlias"] = xforwardedForConfigArg["x_forwarded_for_client_cert_issuer_dn_alias"] - xforwardedForConfigMap["XForwardedForClientCertIssuerDNEnabled"] = xforwardedForConfigArg["x_forwarded_for_client_cert_issuer_dn_enabled"] - xforwardedForConfigMap["XForwardedForClientCertClientVerifyAlias"] = xforwardedForConfigArg["x_forwarded_for_client_cert_client_verify_alias"] - xforwardedForConfigMap["XForwardedForClientCertClientVerifyEnabled"] = xforwardedForConfigArg["x_forwarded_for_client_cert_client_verify_enabled"] - xforwardedForConfigMap["XForwardedForClientCertFingerprintAlias"] = xforwardedForConfigArg["x_forwarded_for_client_cert_finger_print_alias"] - xforwardedForConfigMap["XForwardedForClientCertFingerprintEnabled"] = xforwardedForConfigArg["x_forwarded_for_client_cert_finger_print_enabled"] - xforwardedForConfigMap["XForwardedForClientCertSubjectDNAlias"] = xforwardedForConfigArg["x_forwarded_for_client_cert_subject_dn_alias"] - xforwardedForConfigMap["XForwardedForClientCertSubjectDNEnabled"] = xforwardedForConfigArg["x_forwarded_for_client_cert_subject_dn_enabled"] - xforwardedForConfigMap["XForwardedForClientSourceIpsEnabled"] = xforwardedForConfigArg["x_forwarded_for_client_source_ips_enabled"] - xforwardedForConfigMap["XForwardedForClientSourceIpsTrusted"] = xforwardedForConfigArg["x_forwarded_for_client_source_ips_trusted"] - xforwardedForConfigMap["XForwardedForClientSrcPortEnabled"] = xforwardedForConfigArg["x_forwarded_for_client_src_port_enabled"] - xforwardedForConfigMap["XForwardedForEnabled"] = xforwardedForConfigArg["x_forwarded_for_enabled"] - xforwardedForConfigMap["XForwardedForProtoEnabled"] = xforwardedForConfigArg["x_forwarded_for_proto_enabled"] - xforwardedForConfigMap["XForwardedForSLBIdEnabled"] = xforwardedForConfigArg["x_forwarded_for_slb_id_enabled"] - xforwardedForConfigMap["XForwardedForSLBPortEnabled"] = xforwardedForConfigArg["x_forwarded_for_slb_port_enabled"] + if v := d.Get("x_forwarded_for_config"); v != nil { + xForwardedForClientCertClientVerifyAlias1, _ := jsonpath.Get("$[0].x_forwarded_for_client_cert_client_verify_alias", v) + if xForwardedForClientCertClientVerifyAlias1 != nil && (d.HasChange("x_forwarded_for_config.0.x_forwarded_for_client_cert_client_verify_alias") || xForwardedForClientCertClientVerifyAlias1 != "") { + objectDataLocalMap1["XForwardedForClientCertClientVerifyAlias"] = xForwardedForClientCertClientVerifyAlias1 + } + xForwardedForClientCertClientVerifyEnabled1, _ := jsonpath.Get("$[0].x_forwarded_for_client_cert_client_verify_enabled", v) + if xForwardedForClientCertClientVerifyEnabled1 != nil && (d.HasChange("x_forwarded_for_config.0.x_forwarded_for_client_cert_client_verify_enabled") || xForwardedForClientCertClientVerifyEnabled1 != "") { + objectDataLocalMap1["XForwardedForClientCertClientVerifyEnabled"] = xForwardedForClientCertClientVerifyEnabled1 + } + xForwardedForClientCertFingerPrintAlias, _ := jsonpath.Get("$[0].x_forwarded_for_client_cert_finger_print_alias", v) + if xForwardedForClientCertFingerPrintAlias != nil && (d.HasChange("x_forwarded_for_config.0.x_forwarded_for_client_cert_finger_print_alias") || xForwardedForClientCertFingerPrintAlias != "") { + objectDataLocalMap1["XForwardedForClientCertFingerprintAlias"] = xForwardedForClientCertFingerPrintAlias + } + xForwardedForClientCertFingerPrintEnabled, _ := jsonpath.Get("$[0].x_forwarded_for_client_cert_finger_print_enabled", v) + if xForwardedForClientCertFingerPrintEnabled != nil && (d.HasChange("x_forwarded_for_config.0.x_forwarded_for_client_cert_finger_print_enabled") || xForwardedForClientCertFingerPrintEnabled != "") { + objectDataLocalMap1["XForwardedForClientCertFingerprintEnabled"] = xForwardedForClientCertFingerPrintEnabled + } + xForwardedForClientCertIssuerDnAlias, _ := jsonpath.Get("$[0].x_forwarded_for_client_cert_issuer_dn_alias", v) + if xForwardedForClientCertIssuerDnAlias != nil && (d.HasChange("x_forwarded_for_config.0.x_forwarded_for_client_cert_issuer_dn_alias") || xForwardedForClientCertIssuerDnAlias != "") { + objectDataLocalMap1["XForwardedForClientCertIssuerDNAlias"] = xForwardedForClientCertIssuerDnAlias + } + xForwardedForClientCertIssuerDnEnabled, _ := jsonpath.Get("$[0].x_forwarded_for_client_cert_issuer_dn_enabled", v) + if xForwardedForClientCertIssuerDnEnabled != nil && (d.HasChange("x_forwarded_for_config.0.x_forwarded_for_client_cert_issuer_dn_enabled") || xForwardedForClientCertIssuerDnEnabled != "") { + objectDataLocalMap1["XForwardedForClientCertIssuerDNEnabled"] = xForwardedForClientCertIssuerDnEnabled + } + xForwardedForClientCertSubjectDnAlias, _ := jsonpath.Get("$[0].x_forwarded_for_client_cert_subject_dn_alias", v) + if xForwardedForClientCertSubjectDnAlias != nil && (d.HasChange("x_forwarded_for_config.0.x_forwarded_for_client_cert_subject_dn_alias") || xForwardedForClientCertSubjectDnAlias != "") { + objectDataLocalMap1["XForwardedForClientCertSubjectDNAlias"] = xForwardedForClientCertSubjectDnAlias + } + xForwardedForClientCertSubjectDnEnabled, _ := jsonpath.Get("$[0].x_forwarded_for_client_cert_subject_dn_enabled", v) + if xForwardedForClientCertSubjectDnEnabled != nil && (d.HasChange("x_forwarded_for_config.0.x_forwarded_for_client_cert_subject_dn_enabled") || xForwardedForClientCertSubjectDnEnabled != "") { + objectDataLocalMap1["XForwardedForClientCertSubjectDNEnabled"] = xForwardedForClientCertSubjectDnEnabled + } + xForwardedForClientSrcPortEnabled1, _ := jsonpath.Get("$[0].x_forwarded_for_client_src_port_enabled", v) + if xForwardedForClientSrcPortEnabled1 != nil && (d.HasChange("x_forwarded_for_config.0.x_forwarded_for_client_src_port_enabled") || xForwardedForClientSrcPortEnabled1 != "") { + objectDataLocalMap1["XForwardedForClientSrcPortEnabled"] = xForwardedForClientSrcPortEnabled1 + } + xForwardedForEnabled1, _ := jsonpath.Get("$[0].x_forwarded_for_enabled", v) + if xForwardedForEnabled1 != nil && (d.HasChange("x_forwarded_for_config.0.x_forwarded_for_enabled") || xForwardedForEnabled1 != "") { + objectDataLocalMap1["XForwardedForEnabled"] = xForwardedForEnabled1 + } + xForwardedForProtoEnabled1, _ := jsonpath.Get("$[0].x_forwarded_for_proto_enabled", v) + if xForwardedForProtoEnabled1 != nil && (d.HasChange("x_forwarded_for_config.0.x_forwarded_for_proto_enabled") || xForwardedForProtoEnabled1 != "") { + objectDataLocalMap1["XForwardedForProtoEnabled"] = xForwardedForProtoEnabled1 + } + xForwardedForSlbIdEnabled, _ := jsonpath.Get("$[0].x_forwarded_for_slb_id_enabled", v) + if xForwardedForSlbIdEnabled != nil && (d.HasChange("x_forwarded_for_config.0.x_forwarded_for_slb_id_enabled") || xForwardedForSlbIdEnabled != "") { + objectDataLocalMap1["XForwardedForSLBIdEnabled"] = xForwardedForSlbIdEnabled + } + xForwardedForSlbPortEnabled, _ := jsonpath.Get("$[0].x_forwarded_for_slb_port_enabled", v) + if xForwardedForSlbPortEnabled != nil && (d.HasChange("x_forwarded_for_config.0.x_forwarded_for_slb_port_enabled") || xForwardedForSlbPortEnabled != "") { + objectDataLocalMap1["XForwardedForSLBPortEnabled"] = xForwardedForSlbPortEnabled + } + xForwardedForClientSourceIpsEnabled1, _ := jsonpath.Get("$[0].x_forwarded_for_client_source_ips_enabled", v) + if xForwardedForClientSourceIpsEnabled1 != nil && (d.HasChange("x_forwarded_for_config.0.x_forwarded_for_client_source_ips_enabled") || xForwardedForClientSourceIpsEnabled1 != "") { + objectDataLocalMap1["XForwardedForClientSourceIpsEnabled"] = xForwardedForClientSourceIpsEnabled1 + } + xForwardedForProcessingMode1, _ := jsonpath.Get("$[0].x_forwarded_for_processing_mode", v) + if xForwardedForProcessingMode1 != nil && (d.HasChange("x_forwarded_for_config.0.x_forwarded_for_processing_mode") || xForwardedForProcessingMode1 != "") { + objectDataLocalMap1["XForwardedForProcessingMode"] = xForwardedForProcessingMode1 + } + xForwardedForClientSourceIpsTrusted1, _ := jsonpath.Get("$[0].x_forwarded_for_client_source_ips_trusted", v) + if xForwardedForClientSourceIpsTrusted1 != nil && (d.HasChange("x_forwarded_for_config.0.x_forwarded_for_client_source_ips_trusted") || xForwardedForClientSourceIpsTrusted1 != "") { + objectDataLocalMap1["XForwardedForClientSourceIpsTrusted"] = xForwardedForClientSourceIpsTrusted1 + } + xForwardedForHostEnabled1, _ := jsonpath.Get("$[0].x_forwarded_for_host_enabled", v) + if xForwardedForHostEnabled1 != nil && (d.HasChange("x_forwarded_for_config.0.x_forwarded_for_host_enabled") || xForwardedForHostEnabled1 != "") { + objectDataLocalMap1["XForwardedForHostEnabled"] = xForwardedForHostEnabled1 } - updateListenerAttributeReq["XForwardedForConfig"] = xforwardedForConfigMap + request["XForwardedForConfig"] = objectDataLocalMap1 } } + if v, ok := d.GetOkExists("dry_run"); ok { + request["DryRun"] = v + } if !d.IsNewResource() && d.HasChange("xforwarded_for_config") { update = true @@ -937,27 +1211,84 @@ func resourceAliCloudAlbListenerUpdate(d *schema.ResourceData, meta interface{}) xforwardedForConfigMap["XForwardedForSLBPortEnabled"] = xforwardedForConfigArg["xforwardedforslbportenabled"] } - updateListenerAttributeReq["XForwardedForConfig"] = xforwardedForConfigMap + request["XForwardedForConfig"] = xforwardedForConfigMap } } - if update { - if v, ok := d.GetOkExists("dry_run"); ok { - updateListenerAttributeReq["DryRun"] = v - } - action := "UpdateListenerAttribute" - conn, err := client.NewAlbClient() + 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{"IncorrectBusinessStatus.LoadBalancer", "SystemBusy", "IdempotenceProcessing", "IncorrectStatus.Listener", "VipStatusNotSupport", "-22001"}) || NeedRetry(err) { + wait() + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) + addDebug(action, response, request) if err != nil { - return WrapError(err) + return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) + } + albServiceV2 := AlbServiceV2{client} + stateConf := BuildStateConf([]string{}, []string{"[Succeeded]"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albServiceV2.DescribeAsyncAlbListenerStateRefreshFunc(d, response, "$.Jobs[*].Status", []string{})) + if jobDetail, err := stateConf.WaitForState(); err != nil { + return WrapErrorf(err, IdMsg, d.Id(), jobDetail) + } + } + update = false + action = "UpdateListenerLogConfig" + conn, err = client.NewAlbClient() + if err != nil { + return WrapError(err) + } + request = make(map[string]interface{}) + query = make(map[string]interface{}) + request["ListenerId"] = d.Id() + + request["ClientToken"] = buildClientToken(action) + if d.HasChange("access_log_record_customized_headers_enabled") { + update = true + request["AccessLogRecordCustomizedHeadersEnabled"] = d.Get("access_log_record_customized_headers_enabled") + } + + if d.HasChange("access_log_tracing_config") { + update = true + objectDataLocalMap := make(map[string]interface{}) + + if v := d.Get("access_log_tracing_config"); v != nil { + tracingSample1, _ := jsonpath.Get("$[0].tracing_sample", v) + if tracingSample1 != nil && (d.HasChange("access_log_tracing_config.0.tracing_sample") || tracingSample1 != "") && tracingSample1.(int) > 0 { + objectDataLocalMap["TracingSample"] = tracingSample1 + } + tracingType1, _ := jsonpath.Get("$[0].tracing_type", v) + if tracingType1 != nil && (d.HasChange("access_log_tracing_config.0.tracing_type") || tracingType1 != "") { + objectDataLocalMap["TracingType"] = tracingType1 + } + tracingEnabled1, _ := jsonpath.Get("$[0].tracing_enabled", v) + if tracingEnabled1 != nil && (d.HasChange("access_log_tracing_config.0.tracing_enabled") || tracingEnabled1 != "") { + objectDataLocalMap["TracingEnabled"] = tracingEnabled1 + } + + request["AccessLogTracingConfig"] = objectDataLocalMap } - updateListenerAttributeReq["ClientToken"] = buildClientToken("UpdateListenerAttribute") + } + + 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(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, updateListenerAttributeReq, &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{"IdempotenceProcessing", "IncorrectBusinessStatus.LoadBalancer", "SystemBusy"}) || NeedRetry(err) { + if IsExpectedErrors(err, []string{"IncorrectBusinessStatus.LoadBalancer", "SystemBusy", "IdempotenceProcessing", "IncorrectStatus.Listener", "-22001", "VipStatusNotSupport"}) || NeedRetry(err) { wait() return resource.RetryableError(err) } @@ -965,30 +1296,26 @@ func resourceAliCloudAlbListenerUpdate(d *schema.ResourceData, meta interface{}) } return nil }) - addDebug(action, response, updateListenerAttributeReq) + addDebug(action, response, request) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) } - stateConf := BuildStateConf([]string{}, []string{"Running", "Stopped"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albService.AlbListenerStateRefreshFunc(d.Id(), []string{})) - if _, err := stateConf.WaitForState(); err != nil { - return WrapErrorf(err, IdMsg, d.Id()) + albServiceV2 := AlbServiceV2{client} + stateConf := BuildStateConf([]string{}, []string{"[Succeeded]"}, d.Timeout(schema.TimeoutUpdate), 0, albServiceV2.DescribeAsyncAlbListenerStateRefreshFunc(d, response, "$.Jobs[*].Status", []string{})) + if jobDetail, err := stateConf.WaitForState(); err != nil { + return WrapErrorf(err, IdMsg, d.Id(), jobDetail) } - d.SetPartial("certificates") - d.SetPartial("default_actions") - d.SetPartial("server_group_id") - d.SetPartial("type") - d.SetPartial("gzip_enabled") - d.SetPartial("http2_enabled") - d.SetPartial("idle_timeout") - d.SetPartial("listener_description") - d.SetPartial("quic_config") - d.SetPartial("request_timeout") - d.SetPartial("security_policy_id") - d.SetPartial("xforwarded_for_config") - d.SetPartial("x_forwarded_for_config") } + if d.HasChange("tags") { + albServiceV2 := AlbServiceV2{client} + if err := albServiceV2.SetResourceTags(d, "listener"); err != nil { + return WrapError(err) + } + } if d.HasChange("acl_config") { + albService := AlbService{client} + albServiceV2 := AlbServiceV2{client} oldAssociateAcls, newAssociateVpcs := d.GetChange("acl_config") oldAssociateAclsSet := oldAssociateAcls.(*schema.Set) newAssociateAclsSet := newAssociateVpcs.(*schema.Set) @@ -1096,118 +1423,35 @@ func resourceAliCloudAlbListenerUpdate(d *schema.ResourceData, meta interface{}) } } } - - if d.HasChange("status") { - object, err := albService.DescribeAlbListener(d.Id()) - if err != nil { - return WrapError(err) - } - target := d.Get("status").(string) - if object["ListenerStatus"].(string) != target { - if target == "Running" { - request := map[string]interface{}{ - "ListenerId": d.Id(), - } - if v, ok := d.GetOkExists("dry_run"); ok { - request["DryRun"] = v - } - action := "StartListener" - conn, err := client.NewAlbClient() - if err != nil { - return WrapError(err) - } - request["ClientToken"] = buildClientToken("StartListener") - 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) - if err != nil { - if IsExpectedErrors(err, []string{"IdempotenceProcessing", "IncorrectBusinessStatus.LoadBalancer", "SystemBusy"}) || 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) - } - stateConf := BuildStateConf([]string{}, []string{"Running"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albService.AlbListenerStateRefreshFunc(d.Id(), []string{})) - if _, err := stateConf.WaitForState(); err != nil { - return WrapErrorf(err, IdMsg, d.Id()) - } - } - if target == "Stopped" { - request := map[string]interface{}{ - "ListenerId": d.Id(), - } - if v, ok := d.GetOkExists("dry_run"); ok { - request["DryRun"] = v - } - action := "StopListener" - conn, err := client.NewAlbClient() - if err != nil { - return WrapError(err) - } - request["ClientToken"] = buildClientToken("StopListener") - 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) - if err != nil { - if IsExpectedErrors(err, []string{"IdempotenceProcessing", "IncorrectBusinessStatus.LoadBalancer", "SystemBusy"}) || 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) - } - stateConf := BuildStateConf([]string{}, []string{"Stopped"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albService.AlbListenerStateRefreshFunc(d.Id(), []string{})) - if _, err := stateConf.WaitForState(); err != nil { - return WrapErrorf(err, IdMsg, d.Id()) - } - } - d.SetPartial("status") - } - } - d.Partial(false) - return resourceAliCloudAlbListenerRead(d, meta) } func resourceAliCloudAlbListenerDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*connectivity.AliyunClient) action := "DeleteListener" + 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 := map[string]interface{}{ - "ListenerId": d.Id(), - } + request = make(map[string]interface{}) + request["ListenerId"] = d.Id() + + request["ClientToken"] = buildClientToken(action) - if v, ok := d.GetOkExists("dry_run"); ok { - request["DryRun"] = v - } - request["ClientToken"] = buildClientToken("DeleteListener") 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{"IdempotenceProcessing", "ResourceInConfiguring.Listener", "IncorrectBusinessStatus.LoadBalancer", "IncorrectStatus.LoadBalancer", "SystemBusy", "-22031"}) || NeedRetry(err) { + if IsExpectedErrors(err, []string{"IncorrectBusinessStatus.LoadBalancer", "SystemBusy", "IdempotenceProcessing", "ResourceInConfiguring.Listener", "IncorrectStatus.LoadBalancer", "-22031"}) || NeedRetry(err) { wait() return resource.RetryableError(err) } @@ -1216,12 +1460,19 @@ func resourceAliCloudAlbListenerDelete(d *schema.ResourceData, meta interface{}) return nil }) addDebug(action, response, request) + if err != nil { - if IsExpectedErrors(err, []string{"ResourceNotFound.Listener", "ResourceNotFound.LoadBalancer"}) { + if NotFoundError(err) { return nil } return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) } + albServiceV2 := AlbServiceV2{client} + stateConf := BuildStateConf([]string{}, []string{"[Succeeded]"}, d.Timeout(schema.TimeoutDelete), 5*time.Second, albServiceV2.DescribeAsyncAlbListenerStateRefreshFunc(d, response, "$.Jobs[*].Status", []string{})) + if jobDetail, err := stateConf.WaitForState(); err != nil { + return WrapErrorf(err, IdMsg, d.Id(), jobDetail) + } + return nil } diff --git a/alicloud/resource_alicloud_alb_listener_test.go b/alicloud/resource_alicloud_alb_listener_test.go index dc3dc9ccc4c4..2f3551037fbc 100644 --- a/alicloud/resource_alicloud_alb_listener_test.go +++ b/alicloud/resource_alicloud_alb_listener_test.go @@ -163,6 +163,32 @@ func TestAccAliCloudALBListener_basic0(t *testing.T) { }), ), }, + { + Config: testAccConfig(map[string]interface{}{ + "xforwarded_for_config": []map[string]interface{}{ + { + "xforwardedforclientcertclientverifyalias": "test_client-verify-alias_123451", + "xforwardedforclientcertclientverifyenabled": "true", + "xforwardedforclientcertfingerprintalias": "test_client-verify-alias_123452", + "xforwardedforclientcertfingerprintenabled": "true", + "xforwardedforclientcert_issuerdnalias": "test_client-verify-alias_123453", + "xforwardedforclientcert_issuerdnenabled": "true", + "xforwardedforclientcertsubjectdnalias": "test_client-verify-alias_123454", + "xforwardedforclientcertsubjectdnenabled": "true", + "xforwardedforclientsrcportenabled": "true", + "xforwardedforenabled": "true", + "xforwardedforprotoenabled": "true", + "xforwardedforslbidenabled": "true", + "xforwardedforslbportenabled": "true", + }, + }, + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "xforwarded_for_config.#": "1", + }), + ), + }, { Config: testAccConfig(map[string]interface{}{ "status": "Stopped", @@ -296,32 +322,6 @@ func TestAccAliCloudALBListener_basic0(t *testing.T) { }), ), }, - { - Config: testAccConfig(map[string]interface{}{ - "xforwarded_for_config": []map[string]interface{}{ - { - "xforwardedforclientcertclientverifyalias": "test_client-verify-alias_123451", - "xforwardedforclientcertclientverifyenabled": "true", - "xforwardedforclientcertfingerprintalias": "test_client-verify-alias_123452", - "xforwardedforclientcertfingerprintenabled": "true", - "xforwardedforclientcert_issuerdnalias": "test_client-verify-alias_123453", - "xforwardedforclientcert_issuerdnenabled": "true", - "xforwardedforclientcertsubjectdnalias": "test_client-verify-alias_123454", - "xforwardedforclientcertsubjectdnenabled": "true", - "xforwardedforclientsrcportenabled": "true", - "xforwardedforenabled": "true", - "xforwardedforprotoenabled": "true", - "xforwardedforslbidenabled": "true", - "xforwardedforslbportenabled": "true", - }, - }, - }), - Check: resource.ComposeTestCheckFunc( - testAccCheck(map[string]string{ - "xforwarded_for_config.#": "1", - }), - ), - }, { Config: testAccConfig(map[string]interface{}{ "access_log_record_customized_headers_enabled": "false", @@ -730,6 +730,12 @@ func TestAccAliCloudALBListener_basic3(t *testing.T) { }, }, }, + "ca_enabled": "true", + "ca_certificates": []map[string]interface{}{ + { + "certificate_id": "${var.ca_certificate_id}", + }, + }, "gzip_enabled": "true", "http2_enabled": "true", "idle_timeout": "20", @@ -752,6 +758,8 @@ func TestAccAliCloudALBListener_basic3(t *testing.T) { "x_forwarded_for_slb_port_enabled": "true", "x_forwarded_for_client_source_ips_enabled": "true", "x_forwarded_for_client_source_ips_trusted": "192.168.1.0/24", + "x_forwarded_for_host_enabled": "true", + "x_forwarded_for_processing_mode": "append", }, }, }), @@ -792,6 +800,8 @@ func TestAccAliCloudALBListener_basic3(t *testing.T) { "x_forwarded_for_slb_port_enabled": "true", "x_forwarded_for_client_source_ips_enabled": "false", "x_forwarded_for_client_source_ips_trusted": "192.168.1.0/24", + "x_forwarded_for_host_enabled": "true", + "x_forwarded_for_processing_mode": "remove", }, }, }), @@ -802,34 +812,36 @@ func TestAccAliCloudALBListener_basic3(t *testing.T) { ), }, //x_forwarded_for_enabled cannot be set to false - //{ - // Config: testAccConfig(map[string]interface{}{ - // "x_forwarded_for_config": []map[string]interface{}{ - // { - // "x_forwarded_for_client_cert_client_verify_alias": "test_client-verify-alias_123451", - // "x_forwarded_for_client_cert_client_verify_enabled": "false", - // "x_forwarded_for_client_cert_finger_print_alias": "test_client-verify-alias_123452", - // "x_forwarded_for_client_cert_finger_print_enabled": "false", - // "x_forwarded_for_client_cert_issuer_dn_alias": "test_client-verify-alias_123453", - // "x_forwarded_for_client_cert_issuer_dn_enabled": "false", - // "x_forwarded_for_client_cert_subject_dn_alias": "test_client-verify-alias_123454", - // "x_forwarded_for_client_cert_subject_dn_enabled": "false", - // "x_forwarded_for_client_src_port_enabled": "false", - // "x_forwarded_for_enabled": "false", - // "x_forwarded_for_proto_enabled": "false", - // "x_forwarded_for_slb_id_enabled": "false", - // "x_forwarded_for_slb_port_enabled": "false", - // "x_forwarded_for_client_source_ips_enabled": "true", - // "x_forwarded_for_client_source_ips_trusted": "192.168.2.0/24", - // }, - // }, - // }), - // Check: resource.ComposeTestCheckFunc( - // testAccCheck(map[string]string{ - // "x_forwarded_for_config.#": "1", - // }), - // ), - //}, + { + Config: testAccConfig(map[string]interface{}{ + "x_forwarded_for_config": []map[string]interface{}{ + { + "x_forwarded_for_client_cert_client_verify_alias": "test_client-verify-alias_123451", + "x_forwarded_for_client_cert_client_verify_enabled": "false", + "x_forwarded_for_client_cert_finger_print_alias": "test_client-verify-alias_123452", + "x_forwarded_for_client_cert_finger_print_enabled": "false", + "x_forwarded_for_client_cert_issuer_dn_alias": "test_client-verify-alias_123453", + "x_forwarded_for_client_cert_issuer_dn_enabled": "false", + "x_forwarded_for_client_cert_subject_dn_alias": "test_client-verify-alias_123454", + "x_forwarded_for_client_cert_subject_dn_enabled": "false", + "x_forwarded_for_client_src_port_enabled": "false", + "x_forwarded_for_enabled": "false", + "x_forwarded_for_proto_enabled": "false", + "x_forwarded_for_slb_id_enabled": "false", + "x_forwarded_for_slb_port_enabled": "false", + "x_forwarded_for_client_source_ips_enabled": "true", + "x_forwarded_for_client_source_ips_trusted": "192.168.2.0/24", + "x_forwarded_for_host_enabled": "false", + "x_forwarded_for_processing_mode": "remove", + }, + }, + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "x_forwarded_for_config.#": "1", + }), + ), + }, { ResourceName: resourceId, ImportState: true, @@ -1011,6 +1023,21 @@ func TestAccAliCloudALBListener_basic4(t *testing.T) { }), ), }, + { + Config: testAccConfig(map[string]interface{}{ + "quic_config": []map[string]interface{}{ + { + "quic_upgrade_enabled": "false", + "quic_listener_id": "", + }, + }, + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "quic_config.#": "1", + }), + ), + }, { ResourceName: resourceId, ImportState: true, @@ -1036,6 +1063,10 @@ func AliCloudALBListenerBasicDependence0(name string) string { default = "%s" } + variable "ca_certificate_id" { + default = "1efd3cac-e8c1-611d-b971-f96e5e432aba" + } + data "alicloud_resource_manager_resource_groups" "default" { } diff --git a/alicloud/resource_alicloud_alb_server_group.go b/alicloud/resource_alicloud_alb_server_group.go index e5e6637e213c..86fc7c9fced7 100644 --- a/alicloud/resource_alicloud_alb_server_group.go +++ b/alicloud/resource_alicloud_alb_server_group.go @@ -1,3 +1,4 @@ +// Package alicloud. This file is generated automatically. Please do not modify it manually, thank you! package alicloud import ( @@ -5,11 +6,11 @@ import ( "log" "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" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/helper/validation" ) func resourceAliCloudAlbServerGroup() *schema.Resource { @@ -22,86 +23,50 @@ func resourceAliCloudAlbServerGroup() *schema.Resource { State: schema.ImportStatePassthrough, }, Timeouts: &schema.ResourceTimeout{ - Create: schema.DefaultTimeout(6 * time.Minute), - Delete: schema.DefaultTimeout(6 * time.Minute), - Update: schema.DefaultTimeout(6 * time.Minute), + Create: schema.DefaultTimeout(5 * time.Minute), + Update: schema.DefaultTimeout(5 * time.Minute), + Delete: schema.DefaultTimeout(5 * time.Minute), }, - CustomizeDiff: resourceAlbServerGroupCustomizeDiff, Schema: map[string]*schema.Schema{ - "server_group_name": { - Type: schema.TypeString, - Required: true, - }, - "server_group_type": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Computed: true, - ValidateFunc: StringInSlice([]string{"Instance", "Ip", "Fc"}, false), - }, - "protocol": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Computed: true, - ValidateFunc: StringInSlice([]string{"HTTP", "HTTPS", "gRPC"}, false), - }, - "vpc_id": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - }, - "scheduler": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ValidateFunc: StringInSlice([]string{"Sch", "Wlc", "Wrr"}, false), - }, - "resource_group_id": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "sticky_session_config": { - Type: schema.TypeSet, + "connection_drain_config": { + Type: schema.TypeList, Optional: true, - Computed: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "sticky_session_enabled": { + "connection_drain_enabled": { Type: schema.TypeBool, Optional: true, + Computed: true, }, - "sticky_session_type": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ValidateFunc: StringInSlice([]string{"Server", "Insert"}, false), - }, - "cookie": { - Type: schema.TypeString, + "connection_drain_timeout": { + Type: schema.TypeInt, Optional: true, Computed: true, }, - "cookie_timeout": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - ValidateFunc: validation.Any(validation.IntInSlice([]int{0}), validation.IntBetween(1, 86400)), - }, }, }, }, + "create_time": { + Type: schema.TypeString, + Computed: true, + }, + "cross_zone_enabled": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, "health_check_config": { Type: schema.TypeList, Required: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "health_check_enabled": { - Type: schema.TypeBool, - Required: true, + "health_check_interval": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + ValidateFunc: IntBetween(0, 50), }, "health_check_connect_port": { Type: schema.TypeInt, @@ -109,22 +74,17 @@ func resourceAliCloudAlbServerGroup() *schema.Resource { Computed: true, ValidateFunc: IntBetween(0, 65535), }, - "health_check_host": { - Type: schema.TypeString, + "health_check_codes": { + Type: schema.TypeList, Optional: true, Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, - "health_check_http_version": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ValidateFunc: StringInSlice([]string{"HTTP1.0", "HTTP1.1"}, false), - }, - "health_check_interval": { + "unhealthy_threshold": { Type: schema.TypeInt, Optional: true, Computed: true, - ValidateFunc: IntBetween(1, 50), + ValidateFunc: IntBetween(2, 10), }, "health_check_method": { Type: schema.TypeString, @@ -132,233 +92,383 @@ func resourceAliCloudAlbServerGroup() *schema.Resource { Computed: true, ValidateFunc: StringInSlice([]string{"GET", "POST", "HEAD"}, false), }, - "health_check_path": { + "health_check_host": { Type: schema.TypeString, Optional: true, Computed: true, }, - "health_check_protocol": { + "health_check_path": { Type: schema.TypeString, Optional: true, Computed: true, }, - "health_check_timeout": { + "healthy_threshold": { Type: schema.TypeInt, Optional: true, Computed: true, - ValidateFunc: IntBetween(1, 300), + ValidateFunc: IntBetween(2, 10), }, - "healthy_threshold": { - Type: schema.TypeInt, + "health_check_protocol": { + Type: schema.TypeString, Optional: true, Computed: true, - ValidateFunc: IntBetween(2, 10), + ValidateFunc: StringInSlice([]string{"HTTP", "HTTPS", "TCP", "GRPC"}, false), }, - "unhealthy_threshold": { - Type: schema.TypeInt, + "health_check_http_version": { + Type: schema.TypeString, Optional: true, Computed: true, - ValidateFunc: IntBetween(2, 10), + ValidateFunc: StringInSlice([]string{"HTTP1.0", "HTTP1.1"}, false), }, - "health_check_codes": { - Type: schema.TypeList, - Optional: true, - Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, + "health_check_enabled": { + Type: schema.TypeBool, + Required: true, + }, + "health_check_timeout": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + ValidateFunc: IntBetween(0, 300), }, }, }, }, + "health_check_template_id": { + Type: schema.TypeString, + Optional: true, + }, + "protocol": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + ValidateFunc: StringInSlice([]string{"HTTP", "HTTPS", "GRPC"}, false), + }, + "resource_group_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "scheduler": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: StringInSlice([]string{"Wrr", "Wlc", "Sch", "Uch"}, false), + }, + "server_group_name": { + Type: schema.TypeString, + Required: true, + }, + "server_group_type": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, "servers": { Type: schema.TypeSet, Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "server_id": { + "status": { Type: schema.TypeString, - Required: true, + Computed: true, }, "server_type": { - Type: schema.TypeString, - Required: true, - ValidateFunc: StringInSlice([]string{"Ecs", "Eni", "Eci", "Ip", "Fc"}, false), + Type: schema.TypeString, + Required: true, }, - "server_ip": { + "description": { Type: schema.TypeString, Optional: true, - Computed: true, + }, + "server_id": { + Type: schema.TypeString, + Required: true, }, "port": { Type: schema.TypeInt, Optional: true, ValidateFunc: IntBetween(0, 65535), }, + "server_ip": { + Type: schema.TypeString, + Optional: true, + }, "remote_ip_enabled": { Type: schema.TypeBool, Optional: true, + }, + "server_group_id": { + Type: schema.TypeString, Computed: true, }, "weight": { - Type: schema.TypeInt, - Optional: true, - Default: 100, - ValidateFunc: IntBetween(0, 100), + Type: schema.TypeInt, + Optional: true, + Computed: true, }, - "description": { - Type: schema.TypeString, + }, + }, + }, + "slow_start_config": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "slow_start_enabled": { + Type: schema.TypeBool, Optional: true, + Computed: true, }, - "status": { + "slow_start_duration": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + }, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "sticky_session_config": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cookie": { Type: schema.TypeString, + Optional: true, Computed: true, }, + "cookie_timeout": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + ValidateFunc: IntBetween(0, 86400), + }, + "sticky_session_type": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: StringInSlice([]string{"Insert", "Server"}, false), + }, + "sticky_session_enabled": { + Type: schema.TypeBool, + Optional: true, + }, }, }, }, "tags": tagsSchema(), - "dry_run": { + "uch_config": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: StringInSlice([]string{"QueryString"}, false), + }, + "value": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + "upstream_keepalive_enabled": { Type: schema.TypeBool, Optional: true, }, - "status": { + "vpc_id": { Type: schema.TypeString, - Computed: true, + Optional: true, + ForceNew: true, }, }, } } func resourceAliCloudAlbServerGroupCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*connectivity.AliyunClient) - albService := AlbService{client} - var response map[string]interface{} + action := "CreateServerGroup" - 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("CreateServerGroup") - request["ServerGroupName"] = d.Get("server_group_name") - - if v, ok := d.GetOk("server_group_type"); ok { - request["ServerGroupType"] = v - } - - if v, ok := d.GetOk("protocol"); ok { - request["Protocol"] = v - } + request["ClientToken"] = buildClientToken(action) + request["ServerGroupName"] = d.Get("server_group_name") if v, ok := d.GetOk("vpc_id"); ok { request["VpcId"] = v } - if v, ok := d.GetOk("scheduler"); ok { request["Scheduler"] = v } - + if v, ok := d.GetOk("protocol"); ok { + request["Protocol"] = v + } if v, ok := d.GetOk("resource_group_id"); ok { request["ResourceGroupId"] = v } + objectDataLocalMap := make(map[string]interface{}) - if v, ok := d.GetOk("sticky_session_config"); ok { - stickySessionConfigMap := make(map[string]interface{}) - for _, stickySessionConfigList := range v.(*schema.Set).List() { - stickySessionConfigArg := stickySessionConfigList.(map[string]interface{}) - - if stickySessionEnabled, ok := stickySessionConfigArg["sticky_session_enabled"]; ok { - stickySessionConfigMap["StickySessionEnabled"] = stickySessionEnabled - } - - if stickySessionConfigMap["StickySessionEnabled"] == true { - if stickySessionType, ok := stickySessionConfigArg["sticky_session_type"]; ok { - stickySessionConfigMap["StickySessionType"] = stickySessionType - } - - if stickySessionConfigMap["StickySessionType"] == "Server" { - if cookie, ok := stickySessionConfigArg["cookie"]; ok { - stickySessionConfigMap["Cookie"] = cookie - } - } - - if stickySessionConfigMap["StickySessionType"] == "Insert" { - if cookieTimeout, ok := stickySessionConfigArg["cookie_timeout"]; ok { - stickySessionConfigMap["CookieTimeout"] = cookieTimeout - } - } - } + if v := d.Get("health_check_config"); v != nil { + healthCheckConnectPort1, _ := jsonpath.Get("$[0].health_check_connect_port", v) + if healthCheckConnectPort1 != nil && healthCheckConnectPort1 != "" { + objectDataLocalMap["HealthCheckConnectPort"] = healthCheckConnectPort1 + } + healthCheckEnabled1, _ := jsonpath.Get("$[0].health_check_enabled", v) + if healthCheckEnabled1 != nil && healthCheckEnabled1 != "" { + objectDataLocalMap["HealthCheckEnabled"] = healthCheckEnabled1 + } + healthCheckHost1, _ := jsonpath.Get("$[0].health_check_host", v) + if healthCheckHost1 != nil && healthCheckHost1 != "" { + objectDataLocalMap["HealthCheckHost"] = healthCheckHost1 + } + healthCheckHttpVersion1, _ := jsonpath.Get("$[0].health_check_http_version", v) + if healthCheckHttpVersion1 != nil && healthCheckHttpVersion1 != "" { + objectDataLocalMap["HealthCheckHttpVersion"] = healthCheckHttpVersion1 + } + healthCheckInterval1, _ := jsonpath.Get("$[0].health_check_interval", v) + if healthCheckInterval1 != nil && healthCheckInterval1 != "" && healthCheckInterval1.(int) > 0 { + objectDataLocalMap["HealthCheckInterval"] = healthCheckInterval1 + } + healthCheckMethod1, _ := jsonpath.Get("$[0].health_check_method", v) + if healthCheckMethod1 != nil && healthCheckMethod1 != "" { + objectDataLocalMap["HealthCheckMethod"] = healthCheckMethod1 + } + healthCheckPath1, _ := jsonpath.Get("$[0].health_check_path", v) + if healthCheckPath1 != nil && healthCheckPath1 != "" { + objectDataLocalMap["HealthCheckPath"] = healthCheckPath1 + } + healthCheckProtocol1, _ := jsonpath.Get("$[0].health_check_protocol", v) + if healthCheckProtocol1 != nil && healthCheckProtocol1 != "" { + objectDataLocalMap["HealthCheckProtocol"] = healthCheckProtocol1 + } + healthCheckTimeout1, _ := jsonpath.Get("$[0].health_check_timeout", v) + if healthCheckTimeout1 != nil && healthCheckTimeout1 != "" && healthCheckTimeout1.(int) > 0 { + objectDataLocalMap["HealthCheckTimeout"] = healthCheckTimeout1 + } + healthyThreshold1, _ := jsonpath.Get("$[0].healthy_threshold", v) + if healthyThreshold1 != nil && healthyThreshold1 != "" && healthyThreshold1.(int) > 0 { + objectDataLocalMap["HealthyThreshold"] = healthyThreshold1 + } + unhealthyThreshold1, _ := jsonpath.Get("$[0].unhealthy_threshold", v) + if unhealthyThreshold1 != nil && unhealthyThreshold1 != "" && unhealthyThreshold1.(int) > 0 { + objectDataLocalMap["UnhealthyThreshold"] = unhealthyThreshold1 + } + healthCheckCodes1, _ := jsonpath.Get("$[0].health_check_codes", v) + if healthCheckCodes1 != nil && healthCheckCodes1 != "" { + objectDataLocalMap["HealthCheckCodes"] = healthCheckCodes1 } - request["StickySessionConfig"] = stickySessionConfigMap + request["HealthCheckConfig"] = objectDataLocalMap } - healthCheckConfig := d.Get("health_check_config") - healthCheckConfigMap := make(map[string]interface{}) - for _, healthCheckConfigList := range healthCheckConfig.([]interface{}) { - healthCheckConfigArg := healthCheckConfigList.(map[string]interface{}) + objectDataLocalMap1 := make(map[string]interface{}) - healthCheckConfigMap["HealthCheckEnabled"] = healthCheckConfigArg["health_check_enabled"] - if healthCheckConfigMap["HealthCheckEnabled"] == true { - if healthCheckConnectPort, ok := d.GetOkExists("health_check_config.0.health_check_connect_port"); ok { - healthCheckConfigMap["HealthCheckConnectPort"] = healthCheckConnectPort - } - - if healthCheckHost, ok := d.GetOk("health_check_config.0.health_check_host"); ok { - healthCheckConfigMap["HealthCheckHost"] = healthCheckHost - } - - if healthCheckHttpVersion, ok := d.GetOk("health_check_config.0.health_check_http_version"); ok { - healthCheckConfigMap["HealthCheckHttpVersion"] = healthCheckHttpVersion - } - - if healthCheckInterval, ok := d.GetOkExists("health_check_config.0.health_check_interval"); ok { - healthCheckConfigMap["HealthCheckInterval"] = healthCheckInterval - } + if v := d.Get("sticky_session_config"); !IsNil(v) { + cookie1, _ := jsonpath.Get("$[0].cookie", v) + if cookie1 != nil && cookie1 != "" { + objectDataLocalMap1["Cookie"] = cookie1 + } + cookieTimeout1, _ := jsonpath.Get("$[0].cookie_timeout", v) + if cookieTimeout1 != nil && cookieTimeout1 != "" && cookieTimeout1.(int) > 0 { + objectDataLocalMap1["CookieTimeout"] = cookieTimeout1 + } + stickySessionEnabled1, _ := jsonpath.Get("$[0].sticky_session_enabled", v) + if stickySessionEnabled1 != nil && stickySessionEnabled1 != "" { + objectDataLocalMap1["StickySessionEnabled"] = stickySessionEnabled1 + } + stickySessionType1, _ := jsonpath.Get("$[0].sticky_session_type", v) + if stickySessionType1 != nil && stickySessionType1 != "" { + objectDataLocalMap1["StickySessionType"] = stickySessionType1 + } - if healthCheckMethod, ok := d.GetOk("health_check_config.0.health_check_method"); ok { - healthCheckConfigMap["HealthCheckMethod"] = healthCheckMethod - } + request["StickySessionConfig"] = objectDataLocalMap1 + } - if healthCheckPath, ok := d.GetOk("health_check_config.0.health_check_path"); ok { - healthCheckConfigMap["HealthCheckPath"] = healthCheckPath - } + if v, ok := d.GetOk("server_group_type"); ok { + request["ServerGroupType"] = v + } + objectDataLocalMap2 := make(map[string]interface{}) - if healthCheckProtocol, ok := d.GetOk("health_check_config.0.health_check_protocol"); ok { - healthCheckConfigMap["HealthCheckProtocol"] = healthCheckProtocol - } + if v := d.Get("uch_config"); !IsNil(v) { + type1, _ := jsonpath.Get("$[0].type", v) + if type1 != nil && type1 != "" { + objectDataLocalMap2["Type"] = type1 + } + value1, _ := jsonpath.Get("$[0].value", v) + if value1 != nil && value1 != "" { + objectDataLocalMap2["Value"] = value1 + } - if healthCheckTimeout, ok := d.GetOkExists("health_check_config.0.health_check_timeout"); ok { - healthCheckConfigMap["HealthCheckTimeout"] = healthCheckTimeout - } + request["UchConfig"] = objectDataLocalMap2 + } - if healthyThreshold, ok := d.GetOkExists("health_check_config.0.healthy_threshold"); ok { - healthCheckConfigMap["HealthyThreshold"] = healthyThreshold - } + if v, ok := d.GetOk("tags"); ok { + tagsMap := ConvertTags(v.(map[string]interface{})) + request["Tags"] = tagsMap + } - if unhealthyThreshold, ok := d.GetOkExists("health_check_config.0.unhealthy_threshold"); ok { - healthCheckConfigMap["UnhealthyThreshold"] = unhealthyThreshold - } + objectDataLocalMap3 := make(map[string]interface{}) - if healthCheckCodes, ok := d.GetOk("health_check_config.0.health_check_codes"); ok { - healthCheckConfigMap["HealthCheckCodes"] = healthCheckCodes - } + if v := d.Get("connection_drain_config"); !IsNil(v) { + connectionDrainEnabled1, _ := jsonpath.Get("$[0].connection_drain_enabled", v) + if connectionDrainEnabled1 != nil && connectionDrainEnabled1 != "" { + objectDataLocalMap3["ConnectionDrainEnabled"] = connectionDrainEnabled1 + } + connectionDrainTimeout1, _ := jsonpath.Get("$[0].connection_drain_timeout", v) + if connectionDrainTimeout1 != nil && connectionDrainTimeout1 != "" { + objectDataLocalMap3["ConnectionDrainTimeout"] = connectionDrainTimeout1 } + + request["ConnectionDrainConfig"] = objectDataLocalMap3 } - request["HealthCheckConfig"] = healthCheckConfigMap + objectDataLocalMap4 := make(map[string]interface{}) + + if v := d.Get("slow_start_config"); !IsNil(v) { + slowStartEnabled1, _ := jsonpath.Get("$[0].slow_start_enabled", v) + if slowStartEnabled1 != nil && slowStartEnabled1 != "" { + objectDataLocalMap4["SlowStartEnabled"] = slowStartEnabled1 + } + slowStartDuration1, _ := jsonpath.Get("$[0].slow_start_duration", v) + if slowStartDuration1 != nil && slowStartDuration1 != "" && slowStartDuration1.(int) > 0 { + objectDataLocalMap4["SlowStartDuration"] = slowStartDuration1 + } - if v, ok := d.GetOkExists("dry_run"); ok { - request["DryRun"] = v + request["SlowStartConfig"] = objectDataLocalMap4 } + if v, ok := d.GetOkExists("upstream_keepalive_enabled"); ok { + request["UpstreamKeepaliveEnabled"] = v + } + if v, ok := d.GetOkExists("cross_zone_enabled"); ok { + request["CrossZoneEnabled"] = v + } runtime := util.RuntimeOptions{} runtime.SetAutoretry(true) - wait := incrementalWait(3*time.Second, 3*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) + wait := incrementalWait(3*time.Second, 5*time.Second) + 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 NeedRetry(err) { + if IsExpectedErrors(err, []string{"SystemBusy", "IdempotenceProcessing", "OperationFailed.ResourceGroupStatusCheckFail"}) || NeedRetry(err) { wait() return resource.RetryableError(err) } @@ -374,7 +484,8 @@ func resourceAliCloudAlbServerGroupCreate(d *schema.ResourceData, meta interface d.SetId(fmt.Sprint(response["ServerGroupId"])) - stateConf := BuildStateConf([]string{}, []string{"Available"}, d.Timeout(schema.TimeoutCreate), 5*time.Second, albService.AlbServerGroupStateRefreshFunc(d.Id(), []string{})) + albServiceV2 := AlbServiceV2{client} + stateConf := BuildStateConf([]string{}, []string{"Available"}, d.Timeout(schema.TimeoutCreate), 0, albServiceV2.AlbServerGroupStateRefreshFunc(d.Id(), "ServerGroupStatus", []string{})) if _, err := stateConf.WaitForState(); err != nil { return WrapErrorf(err, IdMsg, d.Id()) } @@ -384,312 +495,371 @@ func resourceAliCloudAlbServerGroupCreate(d *schema.ResourceData, meta interface func resourceAliCloudAlbServerGroupRead(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AliyunClient) - albService := AlbService{client} + albServiceV2 := AlbServiceV2{client} - object, err := albService.DescribeAlbServerGroup(d.Id()) + objectRaw, err := albServiceV2.DescribeAlbServerGroup(d.Id()) if err != nil { if !d.IsNewResource() && NotFoundError(err) { - log.Printf("[DEBUG] Resource alicloud_alb_server_group albService.DescribeAlbServerGroup Failed!!! %s", err) + log.Printf("[DEBUG] Resource alicloud_alb_server_group DescribeAlbServerGroup Failed!!! %s", err) d.SetId("") return nil } return WrapError(err) } - d.Set("server_group_name", object["ServerGroupName"]) - d.Set("server_group_type", object["ServerGroupType"]) - d.Set("protocol", object["Protocol"]) - d.Set("vpc_id", object["VpcId"]) - d.Set("scheduler", object["Scheduler"]) - d.Set("resource_group_id", object["ResourceGroupId"]) - - if stickySessionConfig, ok := object["StickySessionConfig"]; ok { - stickySessionConfigMaps := make([]map[string]interface{}, 0) - stickySessionConfigArg := stickySessionConfig.(map[string]interface{}) - stickySessionConfigMap := make(map[string]interface{}) - - if stickySessionEnabled, ok := stickySessionConfigArg["StickySessionEnabled"]; ok { - stickySessionConfigMap["sticky_session_enabled"] = stickySessionEnabled - } - - if stickySessionType, ok := stickySessionConfigArg["StickySessionType"]; ok { - stickySessionConfigMap["sticky_session_type"] = stickySessionType - } - - if cookie, ok := stickySessionConfigArg["Cookie"]; ok { - stickySessionConfigMap["cookie"] = cookie - } - - if cookieTimeout, ok := stickySessionConfigArg["CookieTimeout"]; ok { - stickySessionConfigMap["cookie_timeout"] = cookieTimeout - } - - if len(stickySessionConfigMap) > 0 { - stickySessionConfigMaps = append(stickySessionConfigMaps, stickySessionConfigMap) - } - - d.Set("sticky_session_config", stickySessionConfigMaps) + if objectRaw["CreateTime"] != nil { + d.Set("create_time", objectRaw["CreateTime"]) + } + if objectRaw["CrossZoneEnabled"] != nil { + d.Set("cross_zone_enabled", objectRaw["CrossZoneEnabled"]) + } + if objectRaw["Protocol"] != nil { + d.Set("protocol", objectRaw["Protocol"]) + } + if objectRaw["ResourceGroupId"] != nil { + d.Set("resource_group_id", objectRaw["ResourceGroupId"]) + } + if objectRaw["Scheduler"] != nil { + d.Set("scheduler", objectRaw["Scheduler"]) + } + if objectRaw["ServerGroupName"] != nil { + d.Set("server_group_name", objectRaw["ServerGroupName"]) + } + if objectRaw["ServerGroupType"] != nil { + d.Set("server_group_type", objectRaw["ServerGroupType"]) + } + if objectRaw["ServerGroupStatus"] != nil { + d.Set("status", objectRaw["ServerGroupStatus"]) + } + if objectRaw["UpstreamKeepaliveEnabled"] != nil { + d.Set("upstream_keepalive_enabled", objectRaw["UpstreamKeepaliveEnabled"]) + } + if objectRaw["VpcId"] != nil { + d.Set("vpc_id", objectRaw["VpcId"]) } - if healthCheckConfig, ok := object["HealthCheckConfig"]; ok { - healthCheckConfigMaps := make([]map[string]interface{}, 0) - healthCheckConfigArg := healthCheckConfig.(map[string]interface{}) - healthCheckConfigMap := make(map[string]interface{}) - - if healthCheckEnabled, ok := healthCheckConfigArg["HealthCheckEnabled"]; ok { - healthCheckConfigMap["health_check_enabled"] = healthCheckEnabled - } - - if healthCheckConnectPort, ok := healthCheckConfigArg["HealthCheckConnectPort"]; ok { - healthCheckConfigMap["health_check_connect_port"] = formatInt(healthCheckConnectPort) - } - - if healthCheckHost, ok := healthCheckConfigArg["HealthCheckHost"]; ok { - healthCheckConfigMap["health_check_host"] = healthCheckHost - } - - if healthCheckHttpVersion, ok := healthCheckConfigArg["HealthCheckHttpVersion"]; ok { - healthCheckConfigMap["health_check_http_version"] = healthCheckHttpVersion - } - - if healthCheckInterval, ok := healthCheckConfigArg["HealthCheckInterval"]; ok { - healthCheckConfigMap["health_check_interval"] = formatInt(healthCheckInterval) - } - - if healthCheckMethod, ok := healthCheckConfigArg["HealthCheckMethod"]; ok { - healthCheckConfigMap["health_check_method"] = healthCheckMethod - } + connectionDrainConfigMaps := make([]map[string]interface{}, 0) + connectionDrainConfigMap := make(map[string]interface{}) + connectionDrainConfig1Raw := make(map[string]interface{}) + if objectRaw["ConnectionDrainConfig"] != nil { + connectionDrainConfig1Raw = objectRaw["ConnectionDrainConfig"].(map[string]interface{}) + } + if len(connectionDrainConfig1Raw) > 0 { + connectionDrainConfigMap["connection_drain_enabled"] = connectionDrainConfig1Raw["ConnectionDrainEnabled"] + connectionDrainConfigMap["connection_drain_timeout"] = connectionDrainConfig1Raw["ConnectionDrainTimeout"] - if healthCheckPath, ok := healthCheckConfigArg["HealthCheckPath"]; ok { - healthCheckConfigMap["health_check_path"] = healthCheckPath + connectionDrainConfigMaps = append(connectionDrainConfigMaps, connectionDrainConfigMap) + } + if objectRaw["ConnectionDrainConfig"] != nil { + if err := d.Set("connection_drain_config", connectionDrainConfigMaps); err != nil { + return err } - - if healthCheckProtocol, ok := healthCheckConfigArg["HealthCheckProtocol"]; ok { - healthCheckConfigMap["health_check_protocol"] = healthCheckProtocol + } + healthCheckConfigMaps := make([]map[string]interface{}, 0) + healthCheckConfigMap := make(map[string]interface{}) + healthCheckConfig1Raw := make(map[string]interface{}) + if objectRaw["HealthCheckConfig"] != nil { + healthCheckConfig1Raw = objectRaw["HealthCheckConfig"].(map[string]interface{}) + } + if len(healthCheckConfig1Raw) > 0 { + healthCheckConfigMap["health_check_connect_port"] = healthCheckConfig1Raw["HealthCheckConnectPort"] + healthCheckConfigMap["health_check_enabled"] = healthCheckConfig1Raw["HealthCheckEnabled"] + healthCheckConfigMap["health_check_host"] = healthCheckConfig1Raw["HealthCheckHost"] + healthCheckConfigMap["health_check_http_version"] = healthCheckConfig1Raw["HealthCheckHttpVersion"] + healthCheckConfigMap["health_check_interval"] = healthCheckConfig1Raw["HealthCheckInterval"] + healthCheckConfigMap["health_check_method"] = healthCheckConfig1Raw["HealthCheckMethod"] + healthCheckConfigMap["health_check_path"] = healthCheckConfig1Raw["HealthCheckPath"] + healthCheckConfigMap["health_check_protocol"] = healthCheckConfig1Raw["HealthCheckProtocol"] + healthCheckConfigMap["health_check_timeout"] = healthCheckConfig1Raw["HealthCheckTimeout"] + healthCheckConfigMap["healthy_threshold"] = healthCheckConfig1Raw["HealthyThreshold"] + healthCheckConfigMap["unhealthy_threshold"] = healthCheckConfig1Raw["UnhealthyThreshold"] + + healthCheckCodes1Raw := make([]interface{}, 0) + if healthCheckConfig1Raw["HealthCheckCodes"] != nil { + healthCheckCodes1Raw = healthCheckConfig1Raw["HealthCheckCodes"].([]interface{}) } - if healthCheckTimeout, ok := healthCheckConfigArg["HealthCheckTimeout"]; ok { - healthCheckConfigMap["health_check_timeout"] = formatInt(healthCheckTimeout) + healthCheckConfigMap["health_check_codes"] = healthCheckCodes1Raw + healthCheckConfigMaps = append(healthCheckConfigMaps, healthCheckConfigMap) + } + if objectRaw["HealthCheckConfig"] != nil { + if err := d.Set("health_check_config", healthCheckConfigMaps); err != nil { + return err } + } + slowStartConfigMaps := make([]map[string]interface{}, 0) + slowStartConfigMap := make(map[string]interface{}) + slowStartConfig1Raw := make(map[string]interface{}) + if objectRaw["SlowStartConfig"] != nil { + slowStartConfig1Raw = objectRaw["SlowStartConfig"].(map[string]interface{}) + } + if len(slowStartConfig1Raw) > 0 { + slowStartConfigMap["slow_start_duration"] = slowStartConfig1Raw["SlowStartDuration"] + slowStartConfigMap["slow_start_enabled"] = slowStartConfig1Raw["SlowStartEnabled"] - if healthyThreshold, ok := healthCheckConfigArg["HealthyThreshold"]; ok { - healthCheckConfigMap["healthy_threshold"] = formatInt(healthyThreshold) + slowStartConfigMaps = append(slowStartConfigMaps, slowStartConfigMap) + } + if objectRaw["SlowStartConfig"] != nil { + if err := d.Set("slow_start_config", slowStartConfigMaps); err != nil { + return err } + } + stickySessionConfigMaps := make([]map[string]interface{}, 0) + stickySessionConfigMap := make(map[string]interface{}) + stickySessionConfig1Raw := make(map[string]interface{}) + if objectRaw["StickySessionConfig"] != nil { + stickySessionConfig1Raw = objectRaw["StickySessionConfig"].(map[string]interface{}) + } + if len(stickySessionConfig1Raw) > 0 { + stickySessionConfigMap["cookie"] = stickySessionConfig1Raw["Cookie"] + stickySessionConfigMap["cookie_timeout"] = stickySessionConfig1Raw["CookieTimeout"] + stickySessionConfigMap["sticky_session_enabled"] = stickySessionConfig1Raw["StickySessionEnabled"] + stickySessionConfigMap["sticky_session_type"] = stickySessionConfig1Raw["StickySessionType"] - if unhealthyThreshold, ok := healthCheckConfigArg["UnhealthyThreshold"]; ok { - healthCheckConfigMap["unhealthy_threshold"] = formatInt(unhealthyThreshold) + stickySessionConfigMaps = append(stickySessionConfigMaps, stickySessionConfigMap) + } + if objectRaw["StickySessionConfig"] != nil { + if err := d.Set("sticky_session_config", stickySessionConfigMaps); err != nil { + return err } + } + tagsMaps := objectRaw["Tags"] + d.Set("tags", tagsToMap(tagsMaps)) + uchConfigMaps := make([]map[string]interface{}, 0) + uchConfigMap := make(map[string]interface{}) + uchConfig1Raw := make(map[string]interface{}) + if objectRaw["UchConfig"] != nil { + uchConfig1Raw = objectRaw["UchConfig"].(map[string]interface{}) + } + if len(uchConfig1Raw) > 0 { + uchConfigMap["type"] = uchConfig1Raw["Type"] + uchConfigMap["value"] = uchConfig1Raw["Value"] - if healthCheckCodes, ok := healthCheckConfigArg["HealthCheckCodes"]; ok { - healthCheckConfigMap["health_check_codes"] = healthCheckCodes + uchConfigMaps = append(uchConfigMaps, uchConfigMap) + } + if objectRaw["UchConfig"] != nil { + if err := d.Set("uch_config", uchConfigMaps); err != nil { + return err } - - healthCheckConfigMaps = append(healthCheckConfigMaps, healthCheckConfigMap) - - d.Set("health_check_config", healthCheckConfigMaps) } - serversList, err := albService.ListServerGroupServers(d.Id()) - if err != nil { + objectRaw, err = albServiceV2.DescribeServerGroupListServerGroupServers(d.Id()) + if err != nil && !NotFoundError(err) { return WrapError(err) } - if len(serversList) > 0 { - serversMaps := make([]map[string]interface{}, 0) - for _, servers := range serversList { - serversArg := servers.(map[string]interface{}) - serversMap := map[string]interface{}{} - - serversMap["server_id"] = serversArg["ServerId"] - serversMap["server_type"] = serversArg["ServerType"] - - if serverIp, ok := serversArg["ServerIp"]; ok { - serversMap["server_ip"] = serverIp - } - - if port, ok := serversArg["Port"]; ok { - serversMap["port"] = port - } - - if remoteIpEnabled, ok := serversArg["RemoteIpEnabled"]; ok { - serversMap["remote_ip_enabled"] = remoteIpEnabled - } - - if weight, ok := serversArg["Weight"]; ok { - serversMap["weight"] = weight - } - - if description, ok := serversArg["Description"]; ok { - serversMap["description"] = description - } - - if status, ok := serversArg["Status"]; ok { - serversMap["status"] = status - } + servers1Raw, _ := jsonpath.Get("$.Servers", objectRaw) + + serversMaps := make([]map[string]interface{}, 0) + if servers1Raw != nil { + for _, serversChild1Raw := range servers1Raw.([]interface{}) { + serversMap := make(map[string]interface{}) + serversChild1Raw := serversChild1Raw.(map[string]interface{}) + serversMap["description"] = serversChild1Raw["Description"] + serversMap["port"] = serversChild1Raw["Port"] + serversMap["remote_ip_enabled"] = serversChild1Raw["RemoteIpEnabled"] + serversMap["server_group_id"] = serversChild1Raw["ServerGroupId"] + serversMap["server_id"] = serversChild1Raw["ServerId"] + serversMap["server_ip"] = serversChild1Raw["ServerIp"] + serversMap["server_type"] = serversChild1Raw["ServerType"] + serversMap["status"] = serversChild1Raw["Status"] + serversMap["weight"] = serversChild1Raw["Weight"] serversMaps = append(serversMaps, serversMap) } - - d.Set("servers", serversMaps) } - - d.Set("status", object["ServerGroupStatus"]) - - listTagResourcesObject, err := albService.ListTagResources(d.Id(), "servergroup") - if err != nil { - return WrapError(err) + if objectRaw["Servers"] != nil { + if err := d.Set("servers", serversMaps); err != nil { + return err + } } - d.Set("tags", tagsToMap(listTagResourcesObject)) - return nil } func resourceAliCloudAlbServerGroupUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AliyunClient) - albService := AlbService{client} + var request map[string]interface{} var response map[string]interface{} + var query map[string]interface{} + update := false d.Partial(true) - if d.HasChange("tags") { - if err := albService.SetResourceTags(d, "servergroup"); err != nil { - return WrapError(err) - } - - d.SetPartial("tags") - } - - update := false - updateServerGroupAttributeReq := map[string]interface{}{ - "ClientToken": buildClientToken("UpdateServerGroupAttribute"), - "ServerGroupId": d.Id(), + action := "UpdateServerGroupAttribute" + conn, err := client.NewAlbClient() + if err != nil { + return WrapError(err) } + request = make(map[string]interface{}) + query = make(map[string]interface{}) + request["ServerGroupId"] = d.Id() + request["ClientToken"] = buildClientToken(action) if !d.IsNewResource() && d.HasChange("server_group_name") { update = true } - if v, ok := d.GetOk("server_group_name"); ok { - updateServerGroupAttributeReq["ServerGroupName"] = v - } - + request["ServerGroupName"] = d.Get("server_group_name") if !d.IsNewResource() && d.HasChange("scheduler") { update = true - } - if v, ok := d.GetOk("scheduler"); ok { - updateServerGroupAttributeReq["Scheduler"] = v + request["Scheduler"] = d.Get("scheduler") } - if !d.IsNewResource() && d.HasChange("sticky_session_config") { + if !d.IsNewResource() && d.HasChange("health_check_config") { update = true } - if v, ok := d.GetOk("sticky_session_config"); ok { - stickySessionConfigMap := make(map[string]interface{}) - for _, stickySessionConfigList := range v.(*schema.Set).List() { - stickySessionConfigArg := stickySessionConfigList.(map[string]interface{}) + objectDataLocalMap := make(map[string]interface{}) - if stickySessionEnabled, ok := stickySessionConfigArg["sticky_session_enabled"]; ok { - stickySessionConfigMap["StickySessionEnabled"] = stickySessionEnabled - } + if v := d.Get("health_check_config"); v != nil { + healthCheckConnectPort1, _ := jsonpath.Get("$[0].health_check_connect_port", v) + if healthCheckConnectPort1 != nil && (d.HasChange("health_check_config.0.health_check_connect_port") || healthCheckConnectPort1 != "") { + objectDataLocalMap["HealthCheckConnectPort"] = healthCheckConnectPort1 + } + healthCheckEnabled1, _ := jsonpath.Get("$[0].health_check_enabled", v) + if healthCheckEnabled1 != nil && (d.HasChange("health_check_config.0.health_check_enabled") || healthCheckEnabled1 != "") { + objectDataLocalMap["HealthCheckEnabled"] = healthCheckEnabled1 + } + healthCheckHost1, _ := jsonpath.Get("$[0].health_check_host", v) + if healthCheckHost1 != nil && (d.HasChange("health_check_config.0.health_check_host") || healthCheckHost1 != "") { + objectDataLocalMap["HealthCheckHost"] = healthCheckHost1 + } + healthCheckHttpVersion1, _ := jsonpath.Get("$[0].health_check_http_version", v) + if healthCheckHttpVersion1 != nil && (d.HasChange("health_check_config.0.health_check_http_version") || healthCheckHttpVersion1 != "") { + objectDataLocalMap["HealthCheckHttpVersion"] = healthCheckHttpVersion1 + } + healthCheckInterval1, _ := jsonpath.Get("$[0].health_check_interval", v) + if healthCheckInterval1 != nil && (d.HasChange("health_check_config.0.health_check_interval") || healthCheckInterval1 != "") && healthCheckInterval1.(int) > 0 { + objectDataLocalMap["HealthCheckInterval"] = healthCheckInterval1 + } + healthCheckMethod1, _ := jsonpath.Get("$[0].health_check_method", v) + if healthCheckMethod1 != nil && (d.HasChange("health_check_config.0.health_check_method") || healthCheckMethod1 != "") { + objectDataLocalMap["HealthCheckMethod"] = healthCheckMethod1 + } + healthCheckPath1, _ := jsonpath.Get("$[0].health_check_path", v) + if healthCheckPath1 != nil && (d.HasChange("health_check_config.0.health_check_path") || healthCheckPath1 != "") { + objectDataLocalMap["HealthCheckPath"] = healthCheckPath1 + } + healthCheckProtocol1, _ := jsonpath.Get("$[0].health_check_protocol", v) + if healthCheckProtocol1 != nil && (d.HasChange("health_check_config.0.health_check_protocol") || healthCheckProtocol1 != "") { + objectDataLocalMap["HealthCheckProtocol"] = healthCheckProtocol1 + } + healthCheckTimeout1, _ := jsonpath.Get("$[0].health_check_timeout", v) + if healthCheckTimeout1 != nil && (d.HasChange("health_check_config.0.health_check_timeout") || healthCheckTimeout1 != "") && healthCheckTimeout1.(int) > 0 { + objectDataLocalMap["HealthCheckTimeout"] = healthCheckTimeout1 + } + healthyThreshold1, _ := jsonpath.Get("$[0].healthy_threshold", v) + if healthyThreshold1 != nil && (d.HasChange("health_check_config.0.healthy_threshold") || healthyThreshold1 != "") && healthyThreshold1.(int) > 0 { + objectDataLocalMap["HealthyThreshold"] = healthyThreshold1 + } + unhealthyThreshold1, _ := jsonpath.Get("$[0].unhealthy_threshold", v) + if unhealthyThreshold1 != nil && (d.HasChange("health_check_config.0.unhealthy_threshold") || unhealthyThreshold1 != "") && unhealthyThreshold1.(int) > 0 { + objectDataLocalMap["UnhealthyThreshold"] = unhealthyThreshold1 + } + healthCheckCodes1, _ := jsonpath.Get("$[0].health_check_codes", d.Get("health_check_config")) + if healthCheckCodes1 != nil && (d.HasChange("health_check_config.0.health_check_codes") || healthCheckCodes1 != "") { + objectDataLocalMap["HealthCheckCodes"] = healthCheckCodes1 + } - if stickySessionConfigMap["StickySessionEnabled"] == true { - if stickySessionType, ok := stickySessionConfigArg["sticky_session_type"]; ok { - stickySessionConfigMap["StickySessionType"] = stickySessionType - } + request["HealthCheckConfig"] = objectDataLocalMap + } - if stickySessionConfigMap["StickySessionType"] == "Server" { - if cookie, ok := stickySessionConfigArg["cookie"]; ok { - stickySessionConfigMap["Cookie"] = cookie - } - } + if !d.IsNewResource() && d.HasChange("sticky_session_config") { + update = true + objectDataLocalMap1 := make(map[string]interface{}) - if stickySessionConfigMap["StickySessionType"] == "Insert" { - if cookieTimeout, ok := stickySessionConfigArg["cookie_timeout"]; ok { - stickySessionConfigMap["CookieTimeout"] = cookieTimeout - } - } + if v := d.Get("sticky_session_config"); v != nil { + cookie1, _ := jsonpath.Get("$[0].cookie", v) + if cookie1 != nil && (d.HasChange("sticky_session_config.0.cookie") || cookie1 != "") { + objectDataLocalMap1["Cookie"] = cookie1 + } + cookieTimeout1, _ := jsonpath.Get("$[0].cookie_timeout", v) + if cookieTimeout1 != nil && (d.HasChange("sticky_session_config.0.cookie_timeout") || cookieTimeout1 != "") && cookieTimeout1.(int) > 0 { + objectDataLocalMap1["CookieTimeout"] = cookieTimeout1 + } + stickySessionEnabled1, _ := jsonpath.Get("$[0].sticky_session_enabled", v) + if stickySessionEnabled1 != nil && (d.HasChange("sticky_session_config.0.sticky_session_enabled") || stickySessionEnabled1 != "") { + objectDataLocalMap1["StickySessionEnabled"] = stickySessionEnabled1 + } + stickySessionType1, _ := jsonpath.Get("$[0].sticky_session_type", v) + if stickySessionType1 != nil && (d.HasChange("sticky_session_config.0.sticky_session_type") || stickySessionType1 != "") { + objectDataLocalMap1["StickySessionType"] = stickySessionType1 } - } - updateServerGroupAttributeReq["StickySessionConfig"] = stickySessionConfigMap + request["StickySessionConfig"] = objectDataLocalMap1 + } } - if !d.IsNewResource() && d.HasChange("health_check_config") { + if !d.IsNewResource() && d.HasChange("uch_config") { update = true - } - healthCheckConfig := d.Get("health_check_config") - healthCheckConfigMap := make(map[string]interface{}) - for _, healthCheckConfigList := range healthCheckConfig.([]interface{}) { - healthCheckConfigArg := healthCheckConfigList.(map[string]interface{}) + objectDataLocalMap2 := make(map[string]interface{}) - healthCheckConfigMap["HealthCheckEnabled"] = healthCheckConfigArg["health_check_enabled"] - - if healthCheckConfigMap["HealthCheckEnabled"] == true { - if healthCheckConnectPort, ok := d.GetOkExists("health_check_config.0.health_check_connect_port"); ok { - healthCheckConfigMap["HealthCheckConnectPort"] = healthCheckConnectPort + if v := d.Get("uch_config"); v != nil { + type1, _ := jsonpath.Get("$[0].type", v) + if type1 != nil && (d.HasChange("uch_config.0.type") || type1 != "") { + objectDataLocalMap2["Type"] = type1 } - - if healthCheckHost, ok := d.GetOk("health_check_config.0.health_check_host"); ok { - healthCheckConfigMap["HealthCheckHost"] = healthCheckHost + value1, _ := jsonpath.Get("$[0].value", v) + if value1 != nil && (d.HasChange("uch_config.0.value") || value1 != "") { + objectDataLocalMap2["Value"] = value1 } - if healthCheckHttpVersion, ok := d.GetOk("health_check_config.0.health_check_http_version"); ok { - healthCheckConfigMap["HealthCheckHttpVersion"] = healthCheckHttpVersion - } + request["UchConfig"] = objectDataLocalMap2 + } + } - if healthCheckInterval, ok := d.GetOkExists("health_check_config.0.health_check_interval"); ok { - healthCheckConfigMap["HealthCheckInterval"] = healthCheckInterval - } + if !d.IsNewResource() && d.HasChange("connection_drain_config") { + update = true + objectDataLocalMap3 := make(map[string]interface{}) - if healthCheckMethod, ok := d.GetOk("health_check_config.0.health_check_method"); ok { - healthCheckConfigMap["HealthCheckMethod"] = healthCheckMethod + if v := d.Get("connection_drain_config"); v != nil { + connectionDrainEnabled1, _ := jsonpath.Get("$[0].connection_drain_enabled", v) + if connectionDrainEnabled1 != nil && (d.HasChange("connection_drain_config.0.connection_drain_enabled") || connectionDrainEnabled1 != "") { + objectDataLocalMap3["ConnectionDrainEnabled"] = connectionDrainEnabled1 } - - if healthCheckPath, ok := d.GetOk("health_check_config.0.health_check_path"); ok { - healthCheckConfigMap["HealthCheckPath"] = healthCheckPath + connectionDrainTimeout1, _ := jsonpath.Get("$[0].connection_drain_timeout", v) + if connectionDrainTimeout1 != nil && (d.HasChange("connection_drain_config.0.connection_drain_timeout") || connectionDrainTimeout1 != "") { + objectDataLocalMap3["ConnectionDrainTimeout"] = connectionDrainTimeout1 } - if healthCheckProtocol, ok := d.GetOk("health_check_config.0.health_check_protocol"); ok { - healthCheckConfigMap["HealthCheckProtocol"] = healthCheckProtocol - } + request["ConnectionDrainConfig"] = objectDataLocalMap3 + } + } - if healthCheckTimeout, ok := d.GetOkExists("health_check_config.0.health_check_timeout"); ok { - healthCheckConfigMap["HealthCheckTimeout"] = healthCheckTimeout - } + if !d.IsNewResource() && d.HasChange("slow_start_config") { + update = true + objectDataLocalMap4 := make(map[string]interface{}) - if healthyThreshold, ok := d.GetOkExists("health_check_config.0.healthy_threshold"); ok { - healthCheckConfigMap["HealthyThreshold"] = healthyThreshold + if v := d.Get("slow_start_config"); v != nil { + slowStartEnabled1, _ := jsonpath.Get("$[0].slow_start_enabled", v) + if slowStartEnabled1 != nil && (d.HasChange("slow_start_config.0.slow_start_enabled") || slowStartEnabled1 != "") { + objectDataLocalMap4["SlowStartEnabled"] = slowStartEnabled1 } - - if unhealthyThreshold, ok := d.GetOkExists("health_check_config.0.unhealthy_threshold"); ok { - healthCheckConfigMap["UnhealthyThreshold"] = unhealthyThreshold + slowStartDuration1, _ := jsonpath.Get("$[0].slow_start_duration", v) + if slowStartDuration1 != nil && (d.HasChange("slow_start_config.0.slow_start_duration") || slowStartDuration1 != "") { + objectDataLocalMap4["SlowStartDuration"] = slowStartDuration1 } - if healthCheckCodes, ok := d.GetOk("health_check_config.0.health_check_codes"); ok { - healthCheckConfigMap["HealthCheckCodes"] = healthCheckCodes - } + request["SlowStartConfig"] = objectDataLocalMap4 } } - updateServerGroupAttributeReq["HealthCheckConfig"] = healthCheckConfigMap + if !d.IsNewResource() && d.HasChange("upstream_keepalive_enabled") { + update = true + request["UpstreamKeepaliveEnabled"] = d.Get("upstream_keepalive_enabled") + } - if v, ok := d.GetOkExists("dry_run"); ok { - updateServerGroupAttributeReq["DryRun"] = v + if !d.IsNewResource() && d.HasChange("cross_zone_enabled") { + update = true + request["CrossZoneEnabled"] = d.Get("cross_zone_enabled") } if update { - action := "UpdateServerGroupAttribute" - 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, updateServerGroupAttributeReq, &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{"IncorrectStatus.ServerGroup", "ResourceNotFound.ServerGroup"}) || NeedRetry(err) { + if IsExpectedErrors(err, []string{"SystemBusy", "IdempotenceProcessing", "IncorrectStatus.ServerGroup"}) || NeedRetry(err) { wait() return resource.RetryableError(err) } @@ -697,48 +867,72 @@ func resourceAliCloudAlbServerGroupUpdate(d *schema.ResourceData, meta interface } return nil }) - addDebug(action, response, updateServerGroupAttributeReq) - + addDebug(action, response, request) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) } - - stateConf := BuildStateConf([]string{}, []string{"Available"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albService.AlbServerGroupStateRefreshFunc(d.Id(), []string{})) + albServiceV2 := AlbServiceV2{client} + stateConf := BuildStateConf([]string{}, []string{"Available"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albServiceV2.AlbServerGroupStateRefreshFunc(d.Id(), "ServerGroupStatus", []string{})) if _, err := stateConf.WaitForState(); err != nil { return WrapErrorf(err, IdMsg, d.Id()) } - - d.SetPartial("server_group_name") - d.SetPartial("scheduler") - d.SetPartial("sticky_session_config") - d.SetPartial("health_check_config") } - update = false - moveResourceGroup := map[string]interface{}{ - "ResourceType": "servergroup", - "ResourceId": d.Id(), + 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 !d.IsNewResource() && d.HasChange("resource_group_id") { + if _, ok := d.GetOk("resource_group_id"); ok && !d.IsNewResource() && d.HasChange("resource_group_id") { update = true } - if v, ok := d.GetOk("resource_group_id"); ok { - moveResourceGroup["NewResourceGroupId"] = v - } - + request["NewResourceGroupId"] = d.Get("resource_group_id") + request["ResourceType"] = "servergroup" if update { - action := "MoveResourceGroup" - conn, err := client.NewAlbClient() + 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{"NotExist.ResourceGroup"}) || NeedRetry(err) { + wait() + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) + addDebug(action, response, request) if err != nil { - return WrapError(err) + return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) } + } + update = false + action = "ApplyHealthCheckTemplateToServerGroup" + conn, err = client.NewAlbClient() + if err != nil { + return WrapError(err) + } + request = make(map[string]interface{}) + query = make(map[string]interface{}) + request["ServerGroupId"] = d.Id() + request["ClientToken"] = buildClientToken(action) + if d.HasChange("health_check_template_id") { + update = true + } + request["HealthCheckTemplateId"] = d.Get("health_check_template_id") + if update { runtime := util.RuntimeOptions{} runtime.SetAutoretry(true) - wait := incrementalWait(3*time.Second, 3*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, moveResourceGroup, &runtime) + 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 NeedRetry(err) { wait() @@ -748,59 +942,52 @@ func resourceAliCloudAlbServerGroupUpdate(d *schema.ResourceData, meta interface } return nil }) - addDebug(action, response, moveResourceGroup) - + addDebug(action, response, request) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) } - - d.SetPartial("resource_group_id") } - update = false if d.HasChange("servers") { - removed, added := d.GetChange("servers") - removeServersFromServerGroupReq := map[string]interface{}{ - "ClientToken": buildClientToken("RemoveServersFromServerGroup"), - "ServerGroupId": d.Id(), - } - - removeServersMaps := make([]map[string]interface{}, 0) - for _, servers := range removed.(*schema.Set).List() { - update = true - serversMap := map[string]interface{}{} - serversArg := servers.(map[string]interface{}) - - serversMap["ServerId"] = serversArg["server_id"] - serversMap["ServerType"] = serversArg["server_type"] - - if serverIp, ok := serversArg["server_ip"]; ok { - serversMap["ServerIp"] = serverIp - } - - if port, ok := serversArg["port"]; ok { - serversMap["Port"] = port - } - - removeServersMaps = append(removeServersMaps, serversMap) - } - - removeServersFromServerGroupReq["Servers"] = removeServersMaps + oldEntry, newEntry := d.GetChange("servers") + oldEntrySet := oldEntry.(*schema.Set) + newEntrySet := newEntry.(*schema.Set) + removed := oldEntrySet.Difference(newEntrySet) + added := newEntrySet.Difference(oldEntrySet) - if update { + if removed.Len() > 0 { action := "RemoveServersFromServerGroup" conn, err := client.NewAlbClient() if err != nil { return WrapError(err) } + request = make(map[string]interface{}) + query = make(map[string]interface{}) + request["ServerGroupId"] = d.Id() + + request["ClientToken"] = buildClientToken(action) + localData := removed.List() + serversMapsArray := make([]interface{}, 0) + for _, dataLoop := range localData { + dataLoopTmp := dataLoop.(map[string]interface{}) + dataLoopMap := make(map[string]interface{}) + if dataLoopTmp["port"].(int) > 0 { + dataLoopMap["Port"] = dataLoopTmp["port"] + } + dataLoopMap["ServerId"] = dataLoopTmp["server_id"] + dataLoopMap["ServerIp"] = dataLoopTmp["server_ip"] + dataLoopMap["ServerType"] = dataLoopTmp["server_type"] + serversMapsArray = append(serversMapsArray, dataLoopMap) + } + request["Servers"] = serversMapsArray runtime := util.RuntimeOptions{} runtime.SetAutoretry(true) - wait := incrementalWait(3*time.Second, 3*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, removeServersFromServerGroupReq, &runtime) + 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.ServerGroup"}) || NeedRetry(err) { + if IsExpectedErrors(err, []string{"SystemBusy", "IdempotenceProcessing", "IncorrectStatus.ServerGroup"}) || NeedRetry(err) { wait() return resource.RetryableError(err) } @@ -808,68 +995,54 @@ func resourceAliCloudAlbServerGroupUpdate(d *schema.ResourceData, meta interface } return nil }) - addDebug(action, response, removeServersFromServerGroupReq) - - stateConf := BuildStateConf([]string{}, []string{"Available"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albService.AlbServerGroupStateRefreshFunc(d.Id(), []string{})) + addDebug(action, response, request) + if err != nil { + return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) + } + albServiceV2 := AlbServiceV2{client} + stateConf := BuildStateConf([]string{}, []string{"Available"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albServiceV2.AlbServerGroupStateRefreshFunc(d.Id(), "ServerGroupStatus", []string{})) if _, err := stateConf.WaitForState(); err != nil { return WrapErrorf(err, IdMsg, d.Id()) } - } - - update = false - addServersToServerGroupReq := map[string]interface{}{ - "ClientToken": buildClientToken("AddServersToServerGroup"), - "ServerGroupId": d.Id(), - } - - addServersMaps := make([]map[string]interface{}, 0) - for _, servers := range added.(*schema.Set).List() { - update = true - serversArg := servers.(map[string]interface{}) - serversMap := map[string]interface{}{} - - serversMap["ServerId"] = serversArg["server_id"] - serversMap["ServerType"] = serversArg["server_type"] - - if serverIp, ok := serversArg["server_ip"]; ok { - serversMap["ServerIp"] = serverIp - } - - if port, ok := serversArg["port"]; ok { - serversMap["Port"] = port - } - if remoteIpEnabled, ok := serversArg["remote_ip_enabled"]; ok { - serversMap["RemoteIpEnabled"] = remoteIpEnabled - } - - if weight, ok := serversArg["weight"]; ok { - serversMap["Weight"] = weight - } - - if description, ok := serversArg["description"]; ok && fmt.Sprint(description) != "" { - serversMap["Description"] = description - } - - addServersMaps = append(addServersMaps, serversMap) } - addServersToServerGroupReq["Servers"] = addServersMaps - - if update { + if added.Len() > 0 { action := "AddServersToServerGroup" conn, err := client.NewAlbClient() if err != nil { return WrapError(err) } + request = make(map[string]interface{}) + query = make(map[string]interface{}) + request["ServerGroupId"] = d.Id() + + request["ClientToken"] = buildClientToken(action) + localData := added.List() + serversMapsArray := make([]interface{}, 0) + for _, dataLoop := range localData { + dataLoopTmp := dataLoop.(map[string]interface{}) + dataLoopMap := make(map[string]interface{}) + dataLoopMap["Description"] = dataLoopTmp["description"] + if dataLoopTmp["port"].(int) > 0 { + dataLoopMap["Port"] = dataLoopTmp["port"] + } + dataLoopMap["ServerId"] = dataLoopTmp["server_id"] + dataLoopMap["ServerIp"] = dataLoopTmp["server_ip"] + dataLoopMap["ServerType"] = dataLoopTmp["server_type"] + dataLoopMap["Weight"] = dataLoopTmp["weight"] + dataLoopMap["RemoteIpEnabled"] = dataLoopTmp["remote_ip_enabled"] + serversMapsArray = append(serversMapsArray, dataLoopMap) + } + request["Servers"] = serversMapsArray 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, addServersToServerGroupReq, &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{"IncorrectStatus.ServerGroup"}) || NeedRetry(err) { + if IsExpectedErrors(err, []string{"SystemBusy", "IdempotenceProcessing", "IncorrectStatus.ServerGroup"}) || NeedRetry(err) { wait() return resource.RetryableError(err) } @@ -877,53 +1050,54 @@ func resourceAliCloudAlbServerGroupUpdate(d *schema.ResourceData, meta interface } return nil }) - addDebug(action, response, addServersToServerGroupReq) - + addDebug(action, response, request) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) } - - stateConf := BuildStateConf([]string{}, []string{"Available"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albService.AlbServerGroupStateRefreshFunc(d.Id(), []string{})) + albServiceV2 := AlbServiceV2{client} + stateConf := BuildStateConf([]string{}, []string{"Available"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, albServiceV2.AlbServerGroupStateRefreshFunc(d.Id(), "ServerGroupStatus", []string{})) if _, err := stateConf.WaitForState(); err != nil { return WrapErrorf(err, IdMsg, d.Id()) } + } - d.SetPartial("servers") } - + if d.HasChange("tags") { + albServiceV2 := AlbServiceV2{client} + if err := albServiceV2.SetResourceTags(d, "servergroup"); err != nil { + return WrapError(err) + } + } d.Partial(false) - return resourceAliCloudAlbServerGroupRead(d, meta) } func resourceAliCloudAlbServerGroupDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*connectivity.AliyunClient) - albService := AlbService{client} action := "DeleteServerGroup" + 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["ServerGroupId"] = d.Id() - request := map[string]interface{}{ - "ClientToken": buildClientToken("DeleteServerGroup"), - "ServerGroupId": d.Id(), - } - - if v, ok := d.GetOkExists("dry_run"); ok { - request["DryRun"] = v - } + 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{"IncorrectStatus.ServerGroup", "ResourceInUse.ServerGroup"}) || NeedRetry(err) { + if IsExpectedErrors(err, []string{"IncorrectStatus.ServerGroup", "SystemBusy", "IdempotenceProcessing", "ResourceInUse.ServerGroup"}) || NeedRetry(err) { wait() return resource.RetryableError(err) } @@ -940,26 +1114,11 @@ func resourceAliCloudAlbServerGroupDelete(d *schema.ResourceData, meta interface return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) } - stateConf := BuildStateConf([]string{}, []string{}, d.Timeout(schema.TimeoutDelete), 5*time.Second, albService.AlbServerGroupStateRefreshFunc(d.Id(), []string{})) + albServiceV2 := AlbServiceV2{client} + stateConf := BuildStateConf([]string{}, []string{}, d.Timeout(schema.TimeoutDelete), 5*time.Second, albServiceV2.AlbServerGroupStateRefreshFunc(d.Id(), "ServerGroupStatus", []string{})) if _, err := stateConf.WaitForState(); err != nil { return WrapErrorf(err, IdMsg, d.Id()) } return nil } - -func resourceAlbServerGroupCustomizeDiff(diff *schema.ResourceDiff, v interface{}) error { - groupType := diff.Get("server_group_type").(string) - if groupType == "Fc" { - // Fc load balancers do not support vpc_id, protocol - if diff.Get("vpc_id") != "" { - return fmt.Errorf("fc server group type do not support vpc_id") - } - - if diff.Get("protocol") != "" { - return fmt.Errorf("fc server group type do not support protocol") - } - } - - return nil -} diff --git a/alicloud/resource_alicloud_alb_server_group_test.go b/alicloud/resource_alicloud_alb_server_group_test.go index 20f5865fff17..d4ec0ed5ec2f 100644 --- a/alicloud/resource_alicloud_alb_server_group_test.go +++ b/alicloud/resource_alicloud_alb_server_group_test.go @@ -110,7 +110,6 @@ func testSweepAlbServerGroup(region string) error { func TestAccAliCloudALBServerGroup_basic0(t *testing.T) { var v map[string]interface{} - checkoutSupportedRegions(t, true, connectivity.AlbSupportRegions) resourceId := "alicloud_alb_server_group.default" ra := resourceAttrInit(resourceId, AliCloudALBServerGroupMap0) rc := resourceCheckInitWithDescribeMethod(resourceId, &v, func() interface{} { @@ -143,6 +142,13 @@ func TestAccAliCloudALBServerGroup_basic0(t *testing.T) { "health_check_enabled": "true", }, }, + "slow_start_config": []map[string]interface{}{ + { + "slow_start_enabled": "true", + "slow_start_duration": "30", + }, + }, + "cross_zone_enabled": "true", }), Check: resource.ComposeTestCheckFunc( testAccCheck(map[string]string{ @@ -150,9 +156,38 @@ func TestAccAliCloudALBServerGroup_basic0(t *testing.T) { "vpc_id": CHECKSET, "sticky_session_config.#": "1", "health_check_config.#": "1", + "cross_zone_enabled": "true", }), ), }, + { + Config: testAccConfig(map[string]interface{}{ + "cross_zone_enabled": "false", + "slow_start_config": []map[string]interface{}{ + { + "slow_start_enabled": "true", + "slow_start_duration": "40", + }, + }, + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "cross_zone_enabled": "false", + }), + ), + }, + { + Config: testAccConfig(map[string]interface{}{ + "slow_start_config": []map[string]interface{}{ + { + "slow_start_enabled": "false", + }, + }, + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{}), + ), + }, { Config: testAccConfig(map[string]interface{}{ "server_group_name": name + "-update", @@ -163,6 +198,52 @@ func TestAccAliCloudALBServerGroup_basic0(t *testing.T) { }), ), }, + { + Config: testAccConfig(map[string]interface{}{ + "connection_drain_config": []map[string]interface{}{ + { + "connection_drain_enabled": "true", + "connection_drain_timeout": "300", + }, + }, + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{}), + ), + }, + { + Config: testAccConfig(map[string]interface{}{ + "connection_drain_config": []map[string]interface{}{ + { + "connection_drain_enabled": "false", + "connection_drain_timeout": "0", + }, + }, + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{}), + ), + }, + { + Config: testAccConfig(map[string]interface{}{ + "upstream_keepalive_enabled": "true", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "upstream_keepalive_enabled": "true", + }), + ), + }, + { + Config: testAccConfig(map[string]interface{}{ + "upstream_keepalive_enabled": "false", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "upstream_keepalive_enabled": "false", + }), + ), + }, { Config: testAccConfig(map[string]interface{}{ "scheduler": "Wlc", @@ -173,6 +254,32 @@ func TestAccAliCloudALBServerGroup_basic0(t *testing.T) { }), ), }, + { + Config: testAccConfig(map[string]interface{}{ + "scheduler": "Uch", + "uch_config": []map[string]interface{}{ + { + "type": "QueryString", + "value": "abc", + }, + }, + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "scheduler": "Uch", + }), + ), + }, + { + Config: testAccConfig(map[string]interface{}{ + "health_check_template_id": "${alicloud_alb_health_check_template.default.id}", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "health_check_template_id": CHECKSET, + }), + ), + }, { Config: testAccConfig(map[string]interface{}{ "resource_group_id": "${data.alicloud_resource_manager_resource_groups.default.groups.1.id}", @@ -288,9 +395,10 @@ func TestAccAliCloudALBServerGroup_basic0(t *testing.T) { ), }, { - ResourceName: resourceId, - ImportState: true, - ImportStateVerify: true, + ResourceName: resourceId, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"health_check_template_id"}, }, }, }) @@ -298,7 +406,6 @@ func TestAccAliCloudALBServerGroup_basic0(t *testing.T) { func TestAccAliCloudALBServerGroup_basic0_twin(t *testing.T) { var v map[string]interface{} - checkoutSupportedRegions(t, true, connectivity.AlbSupportRegions) resourceId := "alicloud_alb_server_group.default" ra := resourceAttrInit(resourceId, AliCloudALBServerGroupMap0) rc := resourceCheckInitWithDescribeMethod(resourceId, &v, func() interface{} { @@ -392,7 +499,6 @@ func TestAccAliCloudALBServerGroup_basic0_twin(t *testing.T) { func TestAccAliCloudALBServerGroup_basic1(t *testing.T) { var v map[string]interface{} - checkoutSupportedRegions(t, true, connectivity.AlbSupportRegions) resourceId := "alicloud_alb_server_group.default" ra := resourceAttrInit(resourceId, AliCloudALBServerGroupMap0) rc := resourceCheckInitWithDescribeMethod(resourceId, &v, func() interface{} { @@ -582,7 +688,6 @@ func TestAccAliCloudALBServerGroup_basic1(t *testing.T) { func TestAccAliCloudALBServerGroup_basic1_twin(t *testing.T) { var v map[string]interface{} - checkoutSupportedRegions(t, true, connectivity.AlbSupportRegions) resourceId := "alicloud_alb_server_group.default" ra := resourceAttrInit(resourceId, AliCloudALBServerGroupMap0) rc := resourceCheckInitWithDescribeMethod(resourceId, &v, func() interface{} { @@ -676,7 +781,6 @@ func TestAccAliCloudALBServerGroup_basic1_twin(t *testing.T) { func TestAccAliCloudALBServerGroup_basic2(t *testing.T) { var v map[string]interface{} - checkoutSupportedRegions(t, true, connectivity.AlbSupportRegions) resourceId := "alicloud_alb_server_group.default" ra := resourceAttrInit(resourceId, AliCloudALBServerGroupMap0) rc := resourceCheckInitWithDescribeMethod(resourceId, &v, func() interface{} { @@ -796,7 +900,6 @@ func TestAccAliCloudALBServerGroup_basic2(t *testing.T) { func TestAccAliCloudALBServerGroup_basic2_twin(t *testing.T) { var v map[string]interface{} - checkoutSupportedRegions(t, true, connectivity.AlbSupportRegions) resourceId := "alicloud_alb_server_group.default" ra := resourceAttrInit(resourceId, AliCloudALBServerGroupMap0) rc := resourceCheckInitWithDescribeMethod(resourceId, &v, func() interface{} { @@ -921,5 +1024,9 @@ func AliCloudALBServerGroupBasicDependence0(name string) string { system_disk_category = "cloud_efficiency" vswitch_id = data.alicloud_vswitches.default.ids.0 } + + resource "alicloud_alb_health_check_template" "default" { + health_check_template_name = var.name + } `, name) } diff --git a/alicloud/service_alicloud_alb_v2.go b/alicloud/service_alicloud_alb_v2.go index 19527a3f9e56..6dcc67cd2cce 100644 --- a/alicloud/service_alicloud_alb_v2.go +++ b/alicloud/service_alicloud_alb_v2.go @@ -304,18 +304,18 @@ func (s *AlbServiceV2) SetResourceTags(d *schema.ResourceData, resourceType stri 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 } + request["ResourceType"] = resourceType 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) { + if IsExpectedErrors(err, []string{"SystemBusy", "IdempotenceProcessing", "OperationFailed.ResourceGroupStatusCheckFail"}) || NeedRetry(err) { wait() return resource.RetryableError(err) } @@ -354,7 +354,7 @@ func (s *AlbServiceV2) SetResourceTags(d *schema.ResourceData, resourceType stri 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) { + if IsExpectedErrors(err, []string{"SystemBusy", "IdempotenceProcessing", "OperationFailed.ResourceGroupStatusCheckFail"}) || NeedRetry(err) { wait() return resource.RetryableError(err) } @@ -692,6 +692,235 @@ func (s *AlbServiceV2) DescribeAsyncAlbLoadBalancerAccessLogConfigAttachmentStat // DescribeAlbLoadBalancerAccessLogConfigAttachment >>> Encapsulated. +// DescribeAlbServerGroup <<< Encapsulated get interface for Alb ServerGroup. + +func (s *AlbServiceV2) DescribeAlbServerGroup(id 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{} + conn, err := client.NewAlbClient() + if err != nil { + return object, WrapError(err) + } + request = make(map[string]interface{}) + query = make(map[string]interface{}) + request["ServerGroupIds.1"] = id + + action := "ListServerGroups" + + 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, &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 { + return object, WrapErrorf(err, DefaultErrorMsg, id, action, AlibabaCloudSdkGoERROR) + } + + v, err := jsonpath.Get("$.ServerGroups[*]", response) + if err != nil { + return object, WrapErrorf(Error(GetNotFoundMessage("ServerGroup", id)), NotFoundMsg, response) + } + + if len(v.([]interface{})) == 0 { + return object, WrapErrorf(Error(GetNotFoundMessage("ServerGroup", id)), NotFoundMsg, response) + } + + currentStatus := v.([]interface{})[0].(map[string]interface{})["ServerGroupId"] + if currentStatus == nil { + return object, WrapErrorf(Error(GetNotFoundMessage("ServerGroup", id)), NotFoundMsg, response) + } + + return v.([]interface{})[0].(map[string]interface{}), nil +} +func (s *AlbServiceV2) DescribeServerGroupListServerGroupServers(id 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{} + conn, err := client.NewAlbClient() + if err != nil { + return object, WrapError(err) + } + request = make(map[string]interface{}) + query = make(map[string]interface{}) + request["ServerGroupId"] = id + + action := "ListServerGroupServers" + + 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, &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.ServerGroup"}) { + return object, WrapErrorf(Error(GetNotFoundMessage("ServerGroup", id)), NotFoundMsg, response) + } + return object, WrapErrorf(err, DefaultErrorMsg, id, action, AlibabaCloudSdkGoERROR) + } + + return response, nil +} + +func (s *AlbServiceV2) AlbServerGroupStateRefreshFunc(id string, field string, failStates []string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + object, err := s.DescribeAlbServerGroup(id) + if err != nil { + if NotFoundError(err) { + return nil, "", 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 { + return object, currentStatus, WrapError(Error(FailedToReachTargetStatus, currentStatus)) + } + } + return object, currentStatus, nil + } +} + +// DescribeAlbServerGroup >>> Encapsulated. + +// DescribeAlbListener <<< Encapsulated get interface for Alb Listener. + +func (s *AlbServiceV2) DescribeAlbListener(id 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 := "GetListenerAttribute" + conn, err := client.NewAlbClient() + if err != nil { + return object, WrapError(err) + } + request = make(map[string]interface{}) + query = make(map[string]interface{}) + request["ListenerId"] = 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, &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.Listener"}) { + return object, WrapErrorf(Error(GetNotFoundMessage("Listener", id)), NotFoundMsg, response) + } + return object, WrapErrorf(err, DefaultErrorMsg, id, action, AlibabaCloudSdkGoERROR) + } + + return response, nil +} + +func (s *AlbServiceV2) AlbListenerStateRefreshFunc(id string, field string, failStates []string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + object, err := s.DescribeAlbListener(id) + 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 { + return object, currentStatus, WrapError(Error(FailedToReachTargetStatus, currentStatus)) + } + } + return object, currentStatus, nil + } +} + +func (s *AlbServiceV2) DescribeAsyncAlbListenerStateRefreshFunc(d *schema.ResourceData, res map[string]interface{}, field string, failStates []string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + object, err := s.DescribeAsyncListAsynJobs(d, res) + if err != nil { + if NotFoundError(err) { + return object, "", nil + } + } + + 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 + } +} + +// DescribeAlbListener >>> Encapsulated. + // DescribeAlbLoadBalancerZoneShiftedAttachment <<< Encapsulated get interface for Alb LoadBalancerZoneShiftedAttachment. func (s *AlbServiceV2) DescribeAlbLoadBalancerZoneShiftedAttachment(id string) (object map[string]interface{}, err error) { diff --git a/website/docs/r/alb_listener.html.markdown b/website/docs/r/alb_listener.html.markdown index 6fe0d2396eca..aabe5fab76c4 100644 --- a/website/docs/r/alb_listener.html.markdown +++ b/website/docs/r/alb_listener.html.markdown @@ -2,7 +2,6 @@ subcategory: "Application Load Balancer (ALB)" layout: "alicloud" page_title: "Alicloud: alicloud_alb_listener" -sidebar_current: "docs-alicloud-resource-alb-listener" description: |- Provides a Alicloud Application Load Balancer (ALB) Listener resource. --- @@ -11,6 +10,8 @@ description: |- Provides a Application Load Balancer (ALB) Listener resource. + + For information about Application Load Balancer (ALB) Listener and how to use it, see [What is Listener](https://www.alibabacloud.com/help/en/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-createlistener). -> **NOTE:** Available since v1.133.0. @@ -19,12 +20,6 @@ For information about Application Load Balancer (ALB) Listener and how to use it Basic Usage -
- - Open in AliCloud - -
- ```terraform variable "name" { default = "tf_example" @@ -154,149 +149,177 @@ resource "alicloud_alb_listener" "default" { ## Argument Reference The following arguments are supported: - -* `access_log_record_customized_headers_enabled` - (Optional)Indicates whether the access log has a custom header field. Valid values: true and false. Default value: false. - --> **NOTE:** Only Instances outside the Security Group to Access the Log Switch **accesslogenabled** Open, in Order to Set This Parameter to the **True**. -* `access_log_tracing_config` - (Optional) Xtrace Configuration Information. See [`access_log_tracing_config`](#access_log_tracing_config) below for details. -* `certificates` - (Optional) The default certificate of the Listener. See [`certificates`](#certificates) below for details. **NOTE:** When `listener_protocol` is `HTTPS`, The default certificate must be set one。 -* `default_actions` - (Optional) The Default Rule Action List. See [`default_actions`](#default_actions) below for details. -* `dry_run` - (Optional) The dry run. -* `gzip_enabled` - (Optional) Whether to Enable Gzip Compression, as a Specific File Type on a Compression. Valid values: `false`, `true`. Default Value: `true`. . -* `http2_enabled` - (Optional) Whether to Enable HTTP/2 Features. Valid Values: `True` Or `False`. Default Value: `True`. - --> **NOTE:** The attribute is valid when the attribute `listener_protocol` is `HTTPS`. -* `idle_timeout` - (Optional) Specify the Connection Idle Timeout Value: `1` to `60`. Unit: Seconds. -* `listener_description` - (Optional)The description of the listener. The description must be 2 to 256 characters in length. The name can contain only the characters in the following string: `/^([^\x00-\xff]|[\w.,;/@-]){2,256}$/`. -* `listener_port` - (Required, ForceNew) The ALB Instance Front-End, and Those of the Ports Used. Value: `1` to `65535`. -* `listener_protocol` - (Required, ForceNew) Snooping Protocols. Valid Values: `HTTP`, `HTTPS` Or `QUIC`. -* `load_balancer_id` - (Required, ForceNew) The ALB Instance Id. -* `quic_config` - (Optional) Configuration Associated with the QuIC Listening. See [`quic_config`](#quic_config) below for details. -* `request_timeout` - (Optional) The Specified Request Timeout Time. Value: `1` to `180`. Unit: Seconds. Default Value: `60`. If the Timeout Time Within the Back-End Server Has Not Answered the ALB Will Give up Waiting, the Client Returns the HTTP 504 Error Code. -* `security_policy_id` - (Optional) Security Policy. - --> **NOTE:** The attribute is valid when the attribute `listener_protocol` is `HTTPS`. - -* `status` - (Optional, Available since v1.133.0) The state of the listener. Valid Values: `Running` Or `Stopped`. Valid values: `Running`: The listener is running. `Stopped`: The listener is stopped. +* `access_log_record_customized_headers_enabled` - (Optional) Access Log Whether to Enable Carry Custom Header Field. + + Value: True **** Or False * *. + + Default Value: False * *. + +-> **NOTE:** Only Instances outside the Security Group to Access the Log Switch `accesslogenabled` Open, in Order to Set This Parameter to the **True * *. + +* `access_log_tracing_config` - (Optional, List) Xtrace Configuration Information. See [`access_log_tracing_config`](#access_log_tracing_config) below. +* `ca_certificates` - (Optional, List, Available since v1.242.0) The list of certificates. See [`ca_certificates`](#ca_certificates) below. +* `ca_enabled` - (Optional, Available since v1.242.0) Whether to turn on two-way authentication. Value: + - `true`: on. + - `false` (default): not enabled. +* `certificates` - (Optional, List) The list of certificates. See [`certificates`](#certificates) below. +* `default_actions` - (Required, List) The Default Rule Action List See [`default_actions`](#default_actions) below. +* `dry_run` - (Optional) Whether to PreCheck only this request. Value: + - `true`: The check request is sent and the listener configuration is not updated. Check items include whether required parameters, request format, and business restrictions are filled in. If the check does not pass, 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 passing the check, and performs the operation directly. +* `gzip_enabled` - (Optional, Computed) Whether to Enable Gzip Compression, as a Specific File Type on a Compression. Valid Values: True Or False. Default Value: TRUE. +* `http2_enabled` - (Optional, Computed) Whether to Enable HTTP/2 Features. Valid Values: True Or False. Default Value: TRUE. +* `idle_timeout` - (Optional, Computed, Int) Specify the Connection Idle Timeout Value: 1 to 60 miao. +* `listener_description` - (Optional) Set the IP Address of the Listened Description. Length Is from 2 to 256 Characters. +* `listener_port` - (Required, ForceNew, Int) The SLB Instance Front-End, and Those of the Ports Used. Value: 1~65535. +* `listener_protocol` - (Required, ForceNew) Snooping Protocols. Valid Values: HTTP, HTTPS Or QuIC. +* `load_balancer_id` - (Required, ForceNew) The SLB Instance Id. +* `quic_config` - (Optional, Computed, List) Configuration Associated with the QuIC Listening See [`quic_config`](#quic_config) below. +* `request_timeout` - (Optional, Computed, Int) The Specified Request Timeout Time. Value: 1~180 Seconds. Default Value: 60 miao. If the Timeout Time Within the Back-End Server Has Not Answered the SLB Will Give up Waiting, the Client Returns the HTTP 504 Error Code. +* `security_policy_id` - (Optional, Computed) Security Policy +* `status` - (Optional, Computed) The Current IP Address of the Listened State +* `tags` - (Optional, Map, Available since v1.215.0) The tag of the resource +* `x_forwarded_for_config` - (Optional, Computed, List, Available since v1.161.0) xforwardfor Related Attribute Configuration See [`x_forwarded_for_config`](#x_forwarded_for_config) below. * `xforwarded_for_config` - (Optional, Deprecated since v1.161.0) xforwardfor Related Attribute Configuration. See [`xforwarded_for_config`](#xforwarded_for_config) below for details. **NOTE:** 'xforwarded_for_config' has been deprecated since provider version 1.161.0. Use 'x_forwarded_for_config' instead.", -* `x_forwarded_for_config` - (Optional, Available since v1.161.0) The `x_forward_for` Related Attribute Configuration. See [`x_forwarded_for_config`](#x_forwarded_for_config) below for details. **NOTE:** The attribute is valid when the attribute `listener_protocol` is `HTTPS`. -* `tags` - (Optional, Available since v1.215.0) A mapping of tags to assign to the resource. * `acl_config` - (Optional, Deprecated since v1.163.0)The configurations of the access control lists (ACLs). See [`acl_config`](#acl_config) below for details. **NOTE:** Field `acl_config` has been deprecated from provider version 1.163.0, and it will be removed in the future version. Please use the new resource `alicloud_alb_listener_acl_attachment`., -### `x_forwarded_for_config` +### `access_log_tracing_config` -The x_forwarded_for_config supports the following: +The access_log_tracing_config supports the following: +* `tracing_enabled` - (Required) Xtrace Function. -* `x_forwarded_for_client_cert_issuer_dn_enabled` - (Optional) Indicates Whether the `X-Forwarded-Clientcert-issuerdn` Header Field Is Used to Obtain Access to the Server Load Balancer Instance of the Client Certificate after the Manifests Are Signed, the Publisher Information. -* `x_forwarded_for_client_cert_client_verify_alias` - (Optional) The Custom Header Field Names Only When `x_forwarded_for_client_cert_client_verify_enabled` Has a Value of True, this Value Will Not Take Effect until.The name must be 1 to 40 characters in length, and can contain letters, hyphens (-), underscores (_), and digits. -* `x_forwarded_for_client_cert_client_verify_enabled` - (Optional) Indicates Whether the `X-Forwarded-Clientcert-clientverify` Header Field Is Used to Obtain Access to the Server Load Balancer Instance of the Client Certificate to Verify the Results. -* `x_forwarded_for_client_cert_finger_print_alias` - (Optional) The Custom Header Field Names Only When `x_forwarded_for_client_certfingerprint_enabled`, Which Evaluates to True When the Entry into Force of.The name must be 1 to 40 characters in length, and can contain letters, hyphens (-), underscores (_), and digits. -* `x_forwarded_for_client_cert_finger_print_enabled` - (Optional) Indicates Whether the `X-Forwarded-client_cert-fingerprint` Header Field Is Used to Obtain Access to the Server Load Balancer Instance of the Client Certificate Fingerprint Value. -* `x_forwarded_for_client_cert_subject_dn_alias` - (Optional) The name of the custom header. This parameter is valid only if `x_forwarded_for_client_certsubjectdn_enabled` is set to true. The name must be 1 to 40 characters in length, and can contain letters, hyphens (-), underscores (_), and digits. -* `x_forwarded_for_client_cert_subject_dn_enabled` - (Optional) Specifies whether to use the `X-Forwarded-client_cert-subjectdn` header field to obtain information about the owner of the ALB client certificate. Valid values: true and false. Default value: false. -* `x_forwarded_for_client_cert_issuer_dn_alias` - (Optional) The Custom Header Field Names Only When `x_forwarded_for_client_cert_issuer_dn_enabled`, Which Evaluates to True When the Entry into Force of. -* `x_forwarded_for_client_src_port_enabled` - (Optional) Indicates Whether the X-Forwarded-Client-Port Header Field Is Used to Obtain Access to Server Load Balancer Instances to the Client, and Those of the Ports. -* `x_forwarded_for_enabled` - (Optional) Whether to Enable by X-Forwarded-For Header Field Is Used to Obtain the Client IP Addresses. -* `x_forwarded_for_proto_enabled` - (Optional) Indicates Whether the X-Forwarded-Proto Header Field Is Used to Obtain the Server Load Balancer Instance Snooping Protocols. -* `x_forwarded_for_slb_id_enabled` - (Optional) Indicates Whether the SLB-ID Header Field Is Used to Obtain the Load Balancing Instance Id. -* `x_forwarded_for_slb_port_enabled` - (Optional) Indicates Whether the X-Forwarded-Port Header Field Is Used to Obtain the Server Load Balancer Instance Listening Port. -* `x_forwarded_for_client_source_ips_enabled` - (Optional) Whether to use the X-Forwarded-Client-Ip header to obtain the source IP address of the server load balancer instance. Value: true, false. Note HTTP, HTTPS, and QUIC listeners support this parameter. The function corresponding to this parameter is not open by default. Please contact the account manager if you need to use it. -* `x_forwarded_for_client_source_ips_trusted` - (Optional) Specify the trusted proxy IP. Application-oriented load balancing ALB will traverse the X-Forwarded-For from back to front, and select the first IP that is not in the trusted IP list as the real client IP, which will be used for the source IP speed limit. + Value: True **** Or False * *. -### `xforwarded_for_config` + Default Value: False * *. -The xforwarded_for_config supports the following: +-> **NOTE:** Only Instances outside the Security Group to Access the Log Switch `accesslogenabled` Open, in Order to Set This Parameter to the **True * *. -* `xforwardedforclientcert_issuerdnenabled` - (Optional) Indicates Whether the `X-Forwarded-Clientcert-issuerdn` Header Field Is Used to Obtain Access to the Server Load Balancer Instance of the Client Certificate after the Manifests Are Signed, the Publisher Information. -* `xforwardedforclientcertclientverifyalias` - (Optional) The Custom Header Field Names Only When `xforwardedforclientcertclientverifyenabled` Has a Value of True, this Value Will Not Take Effect until.The name must be 1 to 40 characters in length, and can contain letters, hyphens (-), underscores (_), and digits. -* `xforwardedforclientcertclientverifyenabled` - (Optional) Indicates Whether the `X-Forwarded-Clientcert-clientverify` Header Field Is Used to Obtain Access to the Server Load Balancer Instance of the Client Certificate to Verify the Results. -* `xforwardedforclientcertfingerprintalias` - (Optional) The Custom Header Field Names Only When `xforwardedforclientcertfingerprintenabled`, Which Evaluates to True When the Entry into Force of.The name must be 1 to 40 characters in length, and can contain letters, hyphens (-), underscores (_), and digits. -* `xforwardedforclientcertfingerprintenabled` - (Optional) Indicates Whether the `X-Forwarded-Clientcert-fingerprint` Header Field Is Used to Obtain Access to the Server Load Balancer Instance of the Client Certificate Fingerprint Value. -* `xforwardedforclientcertsubjectdnalias` - (Optional) The name of the custom header. This parameter is valid only if `xforwardedforclientcertsubjectdnenabled` is set to true. The name must be 1 to 40 characters in length, and can contain letters, hyphens (-), underscores (_), and digits. -* `xforwardedforclientcertsubjectdnenabled` - (Optional) Specifies whether to use the `X-Forwarded-Clientcert-subjectdn` header field to obtain information about the owner of the ALB client certificate. Valid values: true and false. Default value: false. -* `xforwardedforclientcert_issuerdnalias` - (Optional) The Custom Header Field Names Only When `xforwardedforclientcert_issuerdnenabled`, Which Evaluates to True When the Entry into Force of. -* `xforwardedforclientsrcportenabled` - (Optional) Indicates Whether the X-Forwarded-Client-Port Header Field Is Used to Obtain Access to Server Load Balancer Instances to the Client, and Those of the Ports. -* `xforwardedforenabled` - (Optional) Whether to Enable by X-Forwarded-For Header Field Is Used to Obtain the Client IP Addresses. -* `xforwardedforprotoenabled` - (Optional) Indicates Whether the X-Forwarded-Proto Header Field Is Used to Obtain the Server Load Balancer Instance Snooping Protocols. -* `xforwardedforslbidenabled` - (Optional) Indicates Whether the SLB-ID Header Field Is Used to Obtain the Load Balancing Instance Id. -* `xforwardedforslbportenabled` - (Optional) Indicates Whether the X-Forwarded-Port Header Field Is Used to Obtain the Server Load Balancer Instance Listening Port. +* `tracing_sample` - (Optional, Int) Xtrace Sampling Rate. Value: 1~10000 **.> `tracingenabled` **True When Effective. +* `tracing_type` - (Optional) Xtrace Type Value Is **Zipkin * *. -### `quic_config` +-> **NOTE:** `tracingenabled` **True When Effective. -The quic_config supports the following: -* `quic_listener_id` - (Optional) There Is a Need to Correlate the QuIC Listener ID. The Https Listener, in Effect at the Time. quicupgradeenabled True When Required. -* `quic_upgrade_enabled` - (Optional) Indicates Whether to Enable the QuIC Upgrade. +### `ca_certificates` --> **NOTE:** The attribute is valid when the attribute `ListenerProtocol` is `HTTPS`. +The ca_certificates supports the following: +* `certificate_id` - (Optional, Available since v1.242.0) The ID of the certificate. Currently, only server certificates are supported. + +### `certificates` + +The certificates supports the following: +* `certificate_id` - (Optional) The ID of the certificate. Currently, only server certificates are supported. ### `default_actions` The default_actions supports the following: - -* `type` - (Required) Action Type. -* `forward_group_config` - (Required) The configurations of the actions. This parameter is required if Type is set to FowardGroup. See [`forward_group_config`](#default_actions-forward_group_config) below for details. +* `forward_group_config` - (Optional, List) Forwarding Action Configurations See [`forward_group_config`](#default_actions-forward_group_config) below. +* `type` - (Required, ForceNew) Action Type ### `default_actions-forward_group_config` -The forward_group_config supports the following: - -* `server_group_tuples` - (Required) The destination server group to which requests are forwarded. See [`server_group_tuples`](#default_actions-forward_group_config-server_group_tuples) below for details. +The default_actions-forward_group_config supports the following: +* `server_group_tuples` - (Required, List) The Forwarding Destination Server Group See [`server_group_tuples`](#default_actions-forward_group_config-server_group_tuples) below. ### `default_actions-forward_group_config-server_group_tuples` -The server_group_tuples supports the following: +The default_actions-forward_group_config-server_group_tuples supports the following: +* `server_group_id` - (Required) Forwarded to the Destination Server Group ID -* `server_group_id` - (Required) The ID of the destination server group to which requests are forwarded. +### `quic_config` -### `acl_config` +The quic_config supports the following: +* `quic_listener_id` - (Optional) There Is a Need to Correlate the QuIC Listener ID. The Https Listener, in Effect at the Time. quicupgradeenabled True When Required. +* `quic_upgrade_enabled` - (Optional, Computed) Indicates Whether to Enable the QuIC Upgrade -The acl_config supports the following: +### `x_forwarded_for_config` -* `acl_relations` - (Optional, Available since v1.136.0) The ACLs that are associated with the listener. See [`acl_relations`](#acl_config-acl_relations) below for details. -* `acl_type` - (Optional, Available since v1.136.0) The type of the ACL. Valid values: `White` Or `Black`. `White`: specifies the ACL as a whitelist. Only requests from the IP addresses or CIDR blocks in the ACL are forwarded. Whitelists apply to scenarios where only specific IP addresses are allowed to access an application. Risks may occur if the whitelist is improperly set. After you set a whitelist for an Application Load Balancer (ALB) listener, only requests from IP addresses that are added to the whitelist are distributed by the listener. If the whitelist is enabled without IP addresses specified, the ALB listener does not forward requests. `Black`: All requests from the IP addresses or CIDR blocks in the ACL are denied. The blacklist is used to prevent specified IP addresses from accessing an application. If the blacklist is enabled but the corresponding ACL does not contain IP addresses, the ALB listener forwards all requests. +The x_forwarded_for_config supports the following: +* `x_forwarded_for_client_cert_client_verify_alias` - (Optional) The Custom Header Field Names Only When xforwardedforclientcertclientverifyenabled Has a Value of True, this Value Will Not Take Effect until. +* `x_forwarded_for_client_cert_client_verify_enabled` - (Optional, Computed) Indicates Whether the X-Forwarded-Clientcert-clientverify Header Field Is Used to Obtain Access to the Server Load Balancer Instance of the Client Certificate to Verify the Results. +* `x_forwarded_for_client_cert_finger_print_alias` - (Optional) The Custom Header Field Names Only When xforwardedforclientcertfingerprintenabled, Which Evaluates to True When the Entry into Force of. +* `x_forwarded_for_client_cert_finger_print_enabled` - (Optional, Computed) Indicates Whether the X-Forwarded-Clientcert-fingerprint Header Field Is Used to Obtain Access to the Server Load Balancer Instance of the Client Certificate Fingerprint Value. +* `x_forwarded_for_client_cert_issuer_dn_alias` - (Optional) The Custom Header Field Names Only When xforwardedforclientcertsubjectdnenabled, Which Evaluates to True When the Entry into Force of. +* `x_forwarded_for_client_cert_issuer_dn_enabled` - (Optional, Computed) Indicates Whether the X-Forwarded-Clientcert-issuerdn Header Field Is Used to Obtain Access to the Server Load Balancer Instance of the Client Certificate after the Manifests Are Signed, the Publisher Information. +* `x_forwarded_for_client_cert_subject_dn_alias` - (Optional) The Custom Header Field Name, +* `x_forwarded_for_client_cert_subject_dn_enabled` - (Optional, Computed) Indicates Whether the X-Forwarded-Clientcert-subjectdn Header Field Is Used to Obtain Access to the Server Load Balancer Instance of the Client Certificate Owner Information. +* `x_forwarded_for_client_source_ips_enabled` - (Optional) Whether to use the X-Forwarded-Client-Ip header to obtain the source IP address of the server load balancer instance. Value: -### `acl_config-acl_relations` + true: Yes. -The acl_relations supports the following: + false (default): No. -* `acl_id` - (Optional, Available since v1.136.0) Snooping Binding of the Access Policy Group ID List. -* `status` - (Optional) The status of the ACL relation. + Note HTTP, HTTPS, and QUIC listeners support this parameter. The function corresponding to this parameter is not open by default. Please contact the account manager if you need to use it. +* `x_forwarded_for_client_source_ips_trusted` - (Optional) Specify the trusted proxy IP. -### `access_log_tracing_config` + Application-oriented load balancing ALB will traverse the X-Forwarded-For from back to front, and select the first IP that is not in the trusted IP list as the real client IP, which will be used for the source IP speed limit. +* `x_forwarded_for_client_src_port_enabled` - (Optional, Computed) Indicates Whether the X-Forwarded-Client-Port Header Field Is Used to Obtain Access to Server Load Balancer Instances to the Client, and Those of the Ports. +* `x_forwarded_for_enabled` - (Optional, Computed) Whether to Enable by X-Forwarded-For Header Field Is Used to Obtain the Client IP Addresses. +* `x_forwarded_for_host_enabled` - (Optional, Available since v1.242.0) Whether to enable the X-Forwarded-Host header field to obtain the domain name of the client accessing the Application Load Balancer. Value: -The access_log_tracing_config supports the following: + true: Yes. -* `tracing_enabled` - (Optional) Xtrace Function. Value: `True` Or `False` . Default Value: `False`. + false (default): No. --> **NOTE:** Only Instances outside the Security Group to Access the Log Switch `accesslogenabled` Open, in Order to Set This Parameter to the `True`. -* `tracing_sample` - (Optional) Xtrace Sampling Rate. Value: `1` to `10000`. + HTTP, HTTPS, and QUIC listeners support this parameter. +* `x_forwarded_for_processing_mode` - (Optional, Computed, Available since v1.242.0) Schema for processing X-Forwarded-For header fields. This value takes effect only when XForwardedForEnabled is true. Value: --> **NOTE:** This attribute is valid when `tracingenabled` is `true`. -* `tracing_type` - (Optional) Xtrace Type Value Is `Zipkin`. + append (default): append. --> **NOTE:** This attribute is valid when `tracingenabled` is `true`. + remove: Delete. + Configure append to add the last hop IP address to the X-Forwarded-For header field before sending the request to the backend service. -### `certificates` + Configure remove to delete the X-Forwarded-For header before the request is sent to the backend service, regardless of whether the request carries X-Forwarded-For header fields. -The certificates supports the following: + HTTP and HTTPS listeners support this parameter. +* `x_forwarded_for_proto_enabled` - (Optional, Computed) Indicates Whether the X-Forwarded-Proto Header Field Is Used to Obtain the Server Load Balancer Instance Snooping Protocols. +* `x_forwarded_for_slb_id_enabled` - (Optional, Computed) Indicates Whether the SLB-ID Header Field Is Used to Obtain the Load Balancing Instance Id +* `x_forwarded_for_slb_port_enabled` - (Optional, Computed) Indicates Whether the X-Forwarded-Port Header Field Is Used to Obtain the Server Load Balancer Instance Listening Port -* `certificate_id` - (Optional) The ID of the Certificate. +### `xforwarded_for_config` + +The xforwarded_for_config supports the following: + +* `xforwardedforclientcert_issuerdnenabled` - (Optional) Indicates Whether the `X-Forwarded-Clientcert-issuerdn` Header Field Is Used to Obtain Access to the Server Load Balancer Instance of the Client Certificate after the Manifests Are Signed, the Publisher Information. +* `xforwardedforclientcertclientverifyalias` - (Optional) The Custom Header Field Names Only When `xforwardedforclientcertclientverifyenabled` Has a Value of True, this Value Will Not Take Effect until.The name must be 1 to 40 characters in length, and can contain letters, hyphens (-), underscores (_), and digits. +* `xforwardedforclientcertclientverifyenabled` - (Optional) Indicates Whether the `X-Forwarded-Clientcert-clientverify` Header Field Is Used to Obtain Access to the Server Load Balancer Instance of the Client Certificate to Verify the Results. +* `xforwardedforclientcertfingerprintalias` - (Optional) The Custom Header Field Names Only When `xforwardedforclientcertfingerprintenabled`, Which Evaluates to True When the Entry into Force of.The name must be 1 to 40 characters in length, and can contain letters, hyphens (-), underscores (_), and digits. +* `xforwardedforclientcertfingerprintenabled` - (Optional) Indicates Whether the `X-Forwarded-Clientcert-fingerprint` Header Field Is Used to Obtain Access to the Server Load Balancer Instance of the Client Certificate Fingerprint Value. +* `xforwardedforclientcertsubjectdnalias` - (Optional) The name of the custom header. This parameter is valid only if `xforwardedforclientcertsubjectdnenabled` is set to true. The name must be 1 to 40 characters in length, and can contain letters, hyphens (-), underscores (_), and digits. +* `xforwardedforclientcertsubjectdnenabled` - (Optional) Specifies whether to use the `X-Forwarded-Clientcert-subjectdn` header field to obtain information about the owner of the ALB client certificate. Valid values: true and false. Default value: false. +* `xforwardedforclientcert_issuerdnalias` - (Optional) The Custom Header Field Names Only When `xforwardedforclientcert_issuerdnenabled`, Which Evaluates to True When the Entry into Force of. +* `xforwardedforclientsrcportenabled` - (Optional) Indicates Whether the X-Forwarded-Client-Port Header Field Is Used to Obtain Access to Server Load Balancer Instances to the Client, and Those of the Ports. +* `xforwardedforenabled` - (Optional) Whether to Enable by X-Forwarded-For Header Field Is Used to Obtain the Client IP Addresses. +* `xforwardedforprotoenabled` - (Optional) Indicates Whether the X-Forwarded-Proto Header Field Is Used to Obtain the Server Load Balancer Instance Snooping Protocols. +* `xforwardedforslbidenabled` - (Optional) Indicates Whether the SLB-ID Header Field Is Used to Obtain the Load Balancing Instance Id. +* `xforwardedforslbportenabled` - (Optional) Indicates Whether the X-Forwarded-Port Header Field Is Used to Obtain the Server Load Balancer Instance Listening Port. + +### `acl_config` + +The acl_config supports the following: + +* `acl_relations` - (Optional, Available since v1.136.0) The ACLs that are associated with the listener. See [`acl_relations`](#acl_config-acl_relations) below for details. +* `acl_type` - (Optional, Available since v1.136.0) The type of the ACL. Valid values: `White` Or `Black`. `White`: specifies the ACL as a whitelist. Only requests from the IP addresses or CIDR blocks in the ACL are forwarded. Whitelists apply to scenarios where only specific IP addresses are allowed to access an application. Risks may occur if the whitelist is improperly set. After you set a whitelist for an Application Load Balancer (ALB) listener, only requests from IP addresses that are added to the whitelist are distributed by the listener. If the whitelist is enabled without IP addresses specified, the ALB listener does not forward requests. `Black`: All requests from the IP addresses or CIDR blocks in the ACL are denied. The blacklist is used to prevent specified IP addresses from accessing an application. If the blacklist is enabled but the corresponding ACL does not contain IP addresses, the ALB listener forwards all requests. + +### `acl_config-acl_relations` + +The acl_relations supports the following: + +* `acl_id` - (Optional, Available since v1.136.0) Snooping Binding of the Access Policy Group ID List. +* `status` - (Optional) The status of the ACL relation. ## Attributes Reference The following attributes are exported: - -* `id` - The resource ID in terraform of Listener. +* `id` - The ID of the resource supplied above. ## 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 2 mins) Used when create the Listener. -* `update` - (Defaults to 2 mins) Used when update the Listener. -* `delete` - (Defaults to 2 mins) Used when delete the Listener. +* `create` - (Defaults to 5 mins) Used when create the Listener. +* `delete` - (Defaults to 5 mins) Used when delete the Listener. +* `update` - (Defaults to 5 mins) Used when update the Listener. ## Import @@ -304,4 +327,4 @@ Application Load Balancer (ALB) Listener can be imported using the id, e.g. ```shell $ terraform import alicloud_alb_listener.example -``` +``` \ No newline at end of file diff --git a/website/docs/r/alb_server_group.html.markdown b/website/docs/r/alb_server_group.html.markdown index 49294dab8715..60c64d2a55e5 100644 --- a/website/docs/r/alb_server_group.html.markdown +++ b/website/docs/r/alb_server_group.html.markdown @@ -2,16 +2,17 @@ subcategory: "Application Load Balancer (ALB)" layout: "alicloud" page_title: "Alicloud: alicloud_alb_server_group" -sidebar_current: "docs-alicloud-resource-alb-server-group" description: |- - Provides a Alicloud ALB Server Group resource. + Provides a Alicloud Application Load Balancer (ALB) Server Group resource. --- # alicloud_alb_server_group -Provides an ALB Server Group resource. +Provides a Application Load Balancer (ALB) Server Group resource. -For information about ALB Server Group and how to use it, see [What is Server Group](https://www.alibabacloud.com/help/en/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-createservergroup). + + +For information about Application Load Balancer (ALB) Server Group and how to use it, see [What is Server Group](https://www.alibabacloud.com/help/en/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-createservergroup). -> **NOTE:** Available since v1.131.0. @@ -19,12 +20,6 @@ For information about ALB Server Group and how to use it, see [What is Server Gr Basic Usage -
- ```terraform variable "name" { default = "terraform-example" @@ -116,91 +111,285 @@ resource "alicloud_alb_server_group" "example" { ## Argument Reference The following arguments are supported: +* `connection_drain_config` - (Optional, List, Available since v1.242.0) Elegant interrupt configuration. See [`connection_drain_config`](#connection_drain_config) below. +* `cross_zone_enabled` - (Optional, Computed, Available since v1.242.0) Indicates whether cross-zone load balancing is enabled for the server group. Valid values: + + * `true` (default) + + * `false` + +-> **NOTE:** + + * Basic ALB instances do not support server groups that have cross-zone load balancing disabled. Only Standard and WAF-enabled ALB instances support server groups that have cross-zone load balancing. + + * Cross-zone load balancing can be disabled for server groups of the server and IP type, but not for server groups of the Function Compute type. + + * When cross-zone load balancing is disabled, session persistence cannot be enabled. +* `health_check_config` - (Required, List) The configuration of health checks See [`health_check_config`](#health_check_config) below. +* `health_check_template_id` - (Optional, Available since v1.242.0) The template ID. +* `protocol` - (Optional, ForceNew, Computed) The backend protocol. Valid values: + + * `HTTP`: allows you to associate an HTTPS, HTTP, or QUIC listener with the server group. This is the default value. + + * `HTTPS`: allows you to associate HTTPS listeners with backend servers. + + * `gRPC`: allows you to associate an HTTPS or QUIC listener with the server group. + +-> **NOTE:** You do not need to specify a backend protocol if you set `ServerGroupType` to `Fc`. + +* `resource_group_id` - (Optional, Computed) The ID of the resource group to which you want to transfer the cloud resource. -* `server_group_name` - (Required) The name of the server group. -* `server_group_type` - (Optional, ForceNew, Available since v1.193.0) The type of the server group. Default value: `Instance`. Valid values: - - `Instance`: allows you add servers by specifying Ecs, Ens, or Eci. +-> **NOTE:** You can use resource groups to manage resources within your Alibaba Cloud account by group. This helps you resolve issues such as resource grouping and permission management for your Alibaba Cloud account. For more information, see [What is resource management?](https://www.alibabacloud.com/help/en/doc-detail/94475.html) + +* `scheduler` - (Optional, Computed) The scheduling algorithm. Valid values: + + * `Wrr` (default): The weighted round-robin algorithm is used. Backend servers that have higher weights receive more requests than those that have lower weights. + + * `Wlc`: The weighted least connections algorithm is used. Requests are distributed based on the weights and the number of connections to backend servers. If two backend servers have the same weight, the backend server that has fewer connections is expected to receive more requests. + + * `Sch`: The consistent hashing algorithm is used. Requests from the same source IP address are distributed to the same backend server. + +-> **NOTE:** This parameter takes effect when the `ServerGroupType` parameter is set to `Instance` or `Ip`. + +* `server_group_name` - (Required) The name of the server group. The name must be 2 to 128 characters in length, and can contain letters, digits, periods (.), underscores (\_), and hyphens (-). The name must start with a letter. +* `server_group_type` - (Optional, ForceNew, Computed, Available since v1.193.0) The type of server group. Valid values: + + - `Instance` (default): allows you to add servers by specifying `Ecs`, `Eni`, or `Eci`. - `Ip`: allows you to add servers by specifying IP addresses. - `Fc`: allows you to add servers by specifying functions of Function Compute. -* `protocol` - (Optional, ForceNew) The server protocol. Valid values: ` HTTP`, `HTTPS`, `gRPC`. While `server_group_type` is `Fc` this parameter will not take effect. From version 1.215.0, `protocol` can be set to `gRPC`. -* `vpc_id` - (Optional, ForceNew) The ID of the VPC that you want to access. **NOTE:** This parameter takes effect when the `server_group_type` parameter is set to `Instance` or `Ip`. -* `scheduler` - (Optional) The scheduling algorithm. Valid values: ` Sch`, ` Wlc`, `Wrr`. **NOTE:** This parameter takes effect when the `server_group_type` parameter is set to `Instance` or `Ip`. -* `resource_group_id` - (Optional) The ID of the resource group. -* `sticky_session_config` - (Optional, Set) The configuration of session persistence. See [`sticky_session_config`](#sticky_session_config) below. -* `health_check_config` - (Required, Set) The configuration of health checks. See [`health_check_config`](#health_check_config) below. -* `servers` - (Optional, Set) The backend servers. See [`servers`](#servers) below. -* `dry_run` - (Optional, Bool) The dry run. -* `tags` - (Optional) A mapping of tags to assign to the resource. +* `servers` - (Optional, Set) List of servers. See [`servers`](#servers) below. +* `slow_start_config` - (Optional, List, Available since v1.242.0) Slow start configuration. See [`slow_start_config`](#slow_start_config) below. +* `sticky_session_config` - (Optional, List) The configuration of the sticky session See [`sticky_session_config`](#sticky_session_config) below. +* `tags` - (Optional, Map) The tag of the resource +* `uch_config` - (Optional, List, Available since v1.242.0) Url consistency hash parameter configuration See [`uch_config`](#uch_config) below. +* `upstream_keepalive_enabled` - (Optional, Available since v1.242.0) Specifies whether to enable persistent TCP connections. +* `vpc_id` - (Optional, ForceNew) The ID of the virtual private cloud (VPC). You can add only servers that are deployed in the specified VPC to the server group. -### `sticky_session_config` +-> **NOTE:** This parameter takes effect when the `ServerGroupType` parameter is set to `Instance` or `Ip`. -The sticky_session_config supports the following: -* `sticky_session_enabled` - (Optional, Bool) Specifies whether to enable session persistence. Default value: `false`. Valid values: `true`, `false`. **NOTE:** This parameter takes effect when the `server_group_type` parameter is set to `Instance` or `Ip`. -* `sticky_session_type` - (Optional) The method that is used to handle a cookie. Valid values: `Server`, `Insert`. -* `cookie` - (Optional) The cookie to be configured on the server. **NOTE:** This parameter takes effect when the `sticky_session_enabled` parameter is set to `true` and the `sticky_session_type` parameter is set to `Server`. -* `cookie_timeout` - (Optional, Int) The timeout period of a cookie. Unit: seconds. Default value: `1000`. Valid values: `1` to `86400`. **NOTE:** This parameter takes effect when the `sticky_session_enabled` parameter is set to `true` and the `sticky_session_type` parameter is set to `Insert`. +### `connection_drain_config` + +The connection_drain_config supports the following: +* `connection_drain_enabled` - (Optional, Computed, Available since v1.242.0) Specifies whether to enable connection draining. Valid values: + + - `true` + - `false` (default) +* `connection_drain_timeout` - (Optional, Computed, Int, Available since v1.242.0) The timeout period of connection draining. + + Valid values: `0` to `900`. + + Default value: `300`. ### `health_check_config` The health_check_config supports the following: +* `health_check_codes` - (Optional, Computed, List) The status code for a successful health check +* `health_check_connect_port` - (Optional, Int) The backend port that is used for health checks. + + Valid values: `0` to `65535`. + + If you set the value to `0`, the backend port is used for health checks. + +-> **NOTE:** This parameter takes effect only if you set `HealthCheckEnabled` to `true`. + +* `health_check_enabled` - (Required) Specifies whether to enable the health check feature. Valid values: + + * `true` + + * `false` + +-> **NOTE:** If the `ServerGroupType` parameter is set to `Instance` or `Ip`, the health check feature is enabled by default. If the `ServerGroupType` parameter is set to `Fc`, the health check feature is disabled by default. + +* `health_check_host` - (Optional, Computed) The domain name that is used for health checks. + + * **Backend Server Internal IP** (default): Use the internal IP address of backend servers as the health check domain name. + + * **Custom Domain Name**: Enter a domain name. + + * The domain name must be 1 to 80 characters in length. + * The domain name can contain lowercase letters, digits, hyphens (-), and periods (.). + * The domain name must contain at least one period (.) but cannot start or end with a period (.). + * The rightmost domain label of the domain name can contain only letters, and cannot contain digits or hyphens (-). + * The domain name cannot start or end with a hyphen (-). + +-> **NOTE:** This parameter takes effect only if `HealthCheckProtocol` is set to `HTTP`, `HTTPS`, or `gRPC`. + +* `health_check_http_version` - (Optional, Computed) The HTTP version that is used for health checks. Valid values: + + * **HTTP1.0** + + * **HTTP1.1** + +-> **NOTE:** This parameter takes effect only if you set `HealthCheckEnabled` to true and `HealthCheckProtocol` to `HTTP` or `HTTPS`. + +* `health_check_interval` - (Optional, Computed, Int) The interval at which health checks are performed. Unit: seconds. + + Valid values: `1` to `50`. + +-> **NOTE:** This parameter takes effect only if you set `HealthCheckEnabled` to `true`. + +* `health_check_method` - (Optional, Computed) The HTTP method that is used for health checks. Valid values: + + * `GET`: If the length of a response exceeds 8 KB, the response is truncated. However, the health check result is not affected. + + * `POST`: gRPC health checks use the POST method by default. + + * `HEAD`: HTTP and HTTPS health checks use the HEAD method by default. + +-> **NOTE:** This parameter takes effect only if you set `HealthCheckEnabled` to true and `HealthCheckProtocol` to `HTTP`, `HTTPS`, or `gRPC`. + +* `health_check_path` - (Optional, Computed) The URL that is used for health checks. + + The URL must be 1 to 80 characters in length, and can contain letters, digits, and the following special characters: `- / . % ? # & =`. It can also contain the following extended characters: `_ ; ~ ! ( ) * [ ] @ $ ^ : ' , +`. The URL must start with a forward slash (`/`). + +-> **NOTE:** This parameter takes effect only if you set `HealthCheckEnabled` to `true` and `HealthCheckProtocol` to `HTTP` or `HTTPS`. -* `health_check_enabled` - (Required, Bool) Specifies whether to enable the health check feature. Valid values: `true`, `false`. -* `health_check_connect_port` - (Optional, Int) The backend port that is used for health checks. Default value: `0`. Valid values: `0` to `65535`. A value of 0 indicates that a backend server port is used for health checks. -* `health_check_host` - (Optional) The domain name that is used for health checks. -* `health_check_http_version` - (Optional) The version of the HTTP protocol. Default value: `HTTP1.1`. Valid values: `HTTP1.0` and `HTTP1.1`. **NOTE:** This parameter takes effect only when `health_check_protocol` is set to `HTTP` or `HTTPS`. -* `health_check_interval` - (Optional, Int) The interval at which health checks are performed. Unit: seconds. Default value: `2`. Valid values: `1` to `50`. -* `health_check_method` - (Optional) The HTTP method that is used for health checks. Default value: `GET`. Valid values: `GET`, `POST`, `HEAD`. **NOTE:** This parameter takes effect only when `health_check_protocol` is set to `HTTP`, `HTTPS`, or `gRPC`. From version 1.215.0, `health_check_method` can be set to `POST`. -* `health_check_path` - (Optional) The path that is used for health checks. **NOTE:** This parameter takes effect only when `health_check_protocol` is set to `HTTP` or `HTTPS`. -* `health_check_protocol` - (Optional) The protocol that is used for health checks. Valid values: `HTTP`, `HTTPS`, `TCP` and `gRPC`. -* `health_check_timeout` - (Optional, Int) The timeout period for a health check response. If a backend Elastic Compute Service (ECS) instance does not send an expected response within the specified period of time, the ECS instance is considered unhealthy. Unit: seconds. Default value: `5`. Valid values: `1` to `300`. **NOTE:** If the value of `health_check_timeout` is smaller than the value of `health_check_interval`, the value of `health_check_timeout` is ignored and the value of `health_check_interval` is used. -* `healthy_threshold` - (Optional, Int) The number of times that an unhealthy backend server must consecutively pass health checks before it is declared healthy. Default value: `3`. Valid values: `2` to `10`. -* `unhealthy_threshold` - (Optional, Int) The number of times that a healthy backend server must consecutively fail health checks before it is declared unhealthy. Default value: `3`. Valid values: `2` to `10`. -* `health_check_codes` - (Optional, List) The HTTP status codes that are used to indicate whether the backend server passes the health check. Valid values: - - If `health_check_protocol` is set to `HTTP` or `HTTPS`. Valid values: `http_2xx`, `http_3xx`, `http_4xx`, and `http_5xx`. Default value: `http_2xx`. - - If `health_check_protocol` is set to `gRPC`. Valid values: `0` to `99`. Default value: `0`. +* `health_check_protocol` - (Optional, Computed) The protocol that is used for health checks. Valid values: + + - `HTTP`: HTTP health checks simulate browser behaviors by sending HEAD or GET requests to probe the availability of backend servers. + - `HTTPS`: HTTPS health checks simulate browser behaviors by sending HEAD or GET requests to probe the availability of backend servers. HTTPS provides higher security than HTTP because HTTPS supports data encryption. + - `TCP`: TCP health checks send TCP SYN packets to a backend server to probe the availability of backend servers. + - `gRPC`: gRPC health checks send POST or GET requests to a backend server to check whether the backend server is healthy. +* `health_check_timeout` - (Optional, Computed, Int) The timeout period of a health check response. If a backend ECS instance does not respond within the specified timeout period, the ECS instance fails the health check. Unit: seconds. + + Valid values: `1` to `300`. + +-> **NOTE:** This parameter takes effect only if you set `HealthCheckEnabled` to `true`. + +* `healthy_threshold` - (Optional, Computed, Int) The number of times that an unhealthy backend server must consecutively pass health checks before it is declared healthy. In this case, the health check status of the backend server changes from `fail` to `success`. + + Valid values: `2` to `10`. + + Default value: `3`. +* `unhealthy_threshold` - (Optional, Computed, Int) The number of times that a healthy backend server must consecutively fail health checks before it is declared unhealthy. In this case, the health check status of the backend server changes from `success` to `fail`. + + Valid values: `2` to `10`. + + Default value: `3`. ### `servers` The servers supports the following: +* `description` - (Optional) The description of the backend server. The description must be 2 to 256 characters in length, and cannot start with http:// or https://. +* `port` - (Optional, Int) The port that is used by the backend server. Valid values: `1` to `65535`. You can specify at most 200 servers in each call. + +-> **NOTE:** This parameter is required if you set `ServerType` to `Ecs`, `Eni`, `Eci`, or `Ip`. You do not need to set this parameter if `ServerType` is set to `Fc`. + +* `remote_ip_enabled` - (Optional, Available since v1.194.0) Specifies whether to enable the remote IP feature. You can specify at most 200 servers in each call. Default values: + + * `true`: enables the feature. + + * `false`: disables the feature. + +-> **NOTE:** This parameter takes effect only when `ServerType` is set to `Ip`. + +* `server_id` - (Required) The ID of the backend server. You can specify at most 200 servers in each call. + + * If the server group is of the `Instance` type, set ServerId to the ID of a resource of the `Ecs`, `Eni`, or `Eci` type. + + * If the server group is of the `Ip` type, set ServerId to IP addresses. + +-> **NOTE:** You cannot perform this operation on a server group of the Function Compute type. You can call the [ListServerGroups](https://www.alibabacloud.com/help/en/doc-detail/213627.html) operation to query the type of server groups. + +* `server_ip` - (Optional) The IP address of the backend server. You can specify at most 200 servers in each call. + +-> **NOTE:** You do not need to set this parameter if you set `ServerType` to `Fc`. + +* `server_type` - (Required, Available since v1.194.0) The type of the backend server. You can specify at most 200 servers in each call. Default values: + + - `Ecs`: Elastic Compute Service (ECS) instance + - `Eni`: elastic network interface (ENI) + - `Eci`: elastic container instance + - `Ip`: IP address + - `Fc`: Function Compute +* `weight` - (Optional, Computed, Int) The weight of the backend server. Valid values: `0` to `100`. Default value: `100`. If the value is set to `0`, no requests are forwarded to the server. You can specify at most 200 servers in each call. + +-> **NOTE:** You do not need to set this parameter if you set `ServerType` to `Fc`. + + +### `slow_start_config` + +The slow_start_config supports the following: +* `slow_start_duration` - (Optional, Computed, Int, Available since v1.242.0) The duration of a slow start. + + Valid values: 30 to 900. + + Default value: 30. +* `slow_start_enabled` - (Optional, Computed, Available since v1.242.0) Indicates whether slow starts are enabled. Valid values: -* `server_id` - (Required) The ID of the backend server. - - If `server_group_type` is set to `Instance`, set the parameter to the ID of an Elastic Compute Service (ECS) instance, an elastic network interface (ENI), or an elastic container instance. These backend servers are specified by Ecs, Eni, or Eci. - - If `server_group_type` is set to `Ip`, set the parameter to an IP address specified in the server group. - - If `server_group_type` is set to `Fc`, set the parameter to the Alibaba Cloud Resource Name (ARN) of a function specified in the server group. -* `server_type` - (Required) The type of the server. The type of the server. Valid values: - - `Ecs`: an ECS instance. - - `Eni`: an ENI. - - `Eci`: an elastic container instance. - - `Ip`(Available since v1.194.0): an IP address. - - `Fc`(Available since v1.194.0): a function. -* `server_ip` - (Optional) The IP address of an Elastic Compute Service (ECS) instance, an elastic network interface (ENI), or an elastic container instance. **Note:** If `server_group_type` is set to `Fc`, you do not need to configure parameters, otherwise this attribute is required. If `server_group_type` is set to `Ip`, the value of this property is the same as the `server_id` value. -* `port` - (Optional, Int) The port used by the backend server. Valid values: `1` to `65535`. **Note:** This parameter is required if the `server_type` parameter is set to `Ecs`, `Eni`, `Eci`, or `Ip`. You do not need to configure this parameter if you set `server_type` to `Fc`. -* `remote_ip_enabled` - (Optional, Bool, Available since v1.194.0) Specifies whether to enable the remote IP address feature. You can specify up to 40 servers in each call. **Note:** If `server_type` is set to `Ip`, this parameter is available. -* `weight` - (Optional, Int) The weight of the server. Default value: `100`. Valid values: `0` to `100`. If the value is set to `0`, no requests are forwarded to the server. **Note:** You do not need to set this parameter if you set `server_type` to `Fc`. -* `description` - (Optional) The description of the backend server. + - `true` + - `false` + +### `sticky_session_config` + +The sticky_session_config supports the following: +* `cookie` - (Optional, Computed) The cookie to be configured on the server. + + The cookie must be 1 to 200 characters in length and can contain only ASCII characters and digits. It cannot contain commas (,), semicolons (;), or space characters. It cannot start with a dollar sign ($). + +-> **NOTE:** This parameter takes effect when the `StickySessionEnabled` parameter is set to `true` and the `StickySessionType` parameter is set to `Server`. + +* `cookie_timeout` - (Optional, Computed, Int) The maximum amount of time to wait before the session cookie expires. Unit: seconds. + + Valid values: `1` to `86400`. + + Default value: `1000`. + +-> **NOTE:** This parameter takes effect only when `StickySessionEnabled` is set to `true` and `StickySessionType` is set to `Insert`. + +* `sticky_session_enabled` - (Optional) Specifies whether to enable session persistence. Valid values: + + * `true` + + * `false` + +-> **NOTE:** This parameter takes effect when the `ServerGroupType` parameter is set to `Instance` or `Ip`. + +* `sticky_session_type` - (Optional, Computed) The method that is used to handle a cookie. Valid values: + + * `Insert`: inserts a cookie. + + ALB inserts a cookie (SERVERID) into the first HTTP or HTTPS response packet that is sent to a client. The next request from the client contains this cookie and the listener forwards this request to the recorded backend server. + + * `Server`: rewrites a cookie. + + When ALB detects a user-defined cookie, it overwrites the original cookie with the user-defined cookie. Subsequent requests to ALB carry this user-defined cookie, and ALB determines the destination servers of the requests based on the cookies. + +-> **NOTE:** This parameter takes effect when the `StickySessionEnabled` parameter is set to `true` for the server group. + + +### `uch_config` + +The uch_config supports the following: +* `type` - (Optional, Available since v1.242.0) The parameter type. Only QueryString can be filled. +* `value` - (Optional, Available since v1.242.0) Consistency hash parameter value ## Attributes Reference The following attributes are exported: - -* `id` - The resource ID in terraform of Server Group. -* `status` - The status of the Server Group. -* `servers` - The backend servers. - * `status` - The status of the backend server. +* `id` - The ID of the resource supplied above. +* `create_time` - The creation time of the resource +* `servers` - List of servers. + * `server_group_id` - The ID of the server group. + * `status` - The addition status of the backend server. Value: + - `Adding`: Adding. + - `Available`: normal availability. + - `Configuring`: The configuration is under configuration. + - `Removing`: Removing. +* `status` - The status of the resource ## 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 6 mins) Used when create the Server Group. -* `update` - (Defaults to 6 mins) Used when update the Server Group. -* `delete` - (Defaults to 6 mins) Used when delete the Server Group. +* `create` - (Defaults to 5 mins) Used when create the Server Group. +* `delete` - (Defaults to 5 mins) Used when delete the Server Group. +* `update` - (Defaults to 5 mins) Used when update the Server Group. ## Import -ALB Server Group can be imported using the id, e.g. +Application Load Balancer (ALB) Server Group can be imported using the id, e.g. ```shell $ terraform import alicloud_alb_server_group.example -``` +``` \ No newline at end of file