diff --git a/alicloud/resource_alicloud_network_acl.go b/alicloud/resource_alicloud_network_acl.go index 4608e1df7f86..31fe433eac40 100644 --- a/alicloud/resource_alicloud_network_acl.go +++ b/alicloud/resource_alicloud_network_acl.go @@ -7,7 +7,6 @@ import ( "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" @@ -23,9 +22,9 @@ func resourceAliCloudVpcNetworkAcl() *schema.Resource { State: schema.ImportStatePassthrough, }, Timeouts: &schema.ResourceTimeout{ - Create: schema.DefaultTimeout(5 * time.Minute), - Update: schema.DefaultTimeout(5 * time.Minute), - Delete: schema.DefaultTimeout(5 * time.Minute), + Create: schema.DefaultTimeout(10 * time.Minute), + Update: schema.DefaultTimeout(10 * time.Minute), + Delete: schema.DefaultTimeout(10 * time.Minute), }, Schema: map[string]*schema.Schema{ "create_time": { @@ -46,7 +45,7 @@ func resourceAliCloudVpcNetworkAcl() *schema.Resource { "policy": { Type: schema.TypeString, Optional: true, - ValidateFunc: StringInSlice([]string{"accept", "drop"}, true), + ValidateFunc: StringInSlice([]string{"accept", "drop"}, false), }, "destination_cidr_ip": { Type: schema.TypeString, @@ -74,13 +73,17 @@ func resourceAliCloudVpcNetworkAcl() *schema.Resource { "protocol": { Type: schema.TypeString, Optional: true, - ValidateFunc: StringInSlice([]string{"icmp", "gre", "tcp", "udp", "all", "icmpv6"}, true), + ValidateFunc: StringInSlice([]string{"icmp", "gre", "tcp", "udp", "all"}, false), }, "network_acl_entry_name": { Type: schema.TypeString, Optional: true, ValidateFunc: StringLenBetween(1, 128), }, + "network_acl_entry_id": { + Type: schema.TypeString, + Computed: true, + }, }, }, }, @@ -93,7 +96,7 @@ func resourceAliCloudVpcNetworkAcl() *schema.Resource { "policy": { Type: schema.TypeString, Optional: true, - ValidateFunc: StringInSlice([]string{"accept", "drop"}, true), + ValidateFunc: StringInSlice([]string{"accept", "drop"}, false), }, "description": { Type: schema.TypeString, @@ -121,23 +124,31 @@ func resourceAliCloudVpcNetworkAcl() *schema.Resource { "protocol": { Type: schema.TypeString, Optional: true, - ValidateFunc: StringInSlice([]string{"icmp", "gre", "tcp", "udp", "all", "icmpv6"}, true), + ValidateFunc: StringInSlice([]string{"icmp", "gre", "tcp", "udp", "all"}, false), }, "network_acl_entry_name": { Type: schema.TypeString, Optional: true, ValidateFunc: StringLenBetween(1, 128), }, + "network_acl_entry_id": { + Type: schema.TypeString, + Computed: true, + }, }, }, }, "network_acl_name": { Type: schema.TypeString, Optional: true, - Computed: true, ConflictsWith: []string{"name"}, + Computed: true, ValidateFunc: StringLenBetween(2, 128), }, + "region_id": { + Type: schema.TypeString, + Computed: true, + }, "resources": { Type: schema.TypeSet, Optional: true, @@ -198,28 +209,24 @@ func resourceAliCloudVpcNetworkAclCreate(d *schema.ResourceData, meta interface{ request["ClientToken"] = buildClientToken(action) request["VpcId"] = d.Get("vpc_id") - if v, ok := d.GetOk("name"); ok { + if v, ok := d.GetOk("name"); ok || d.HasChange("name") { request["NetworkAclName"] = v } - if v, ok := d.GetOk("network_acl_name"); ok { + if v, ok := d.GetOk("network_acl_name"); ok && len(v.(string)) > 0 { request["NetworkAclName"] = v } - if v, ok := d.GetOk("description"); ok { + if v, ok := d.GetOk("description"); ok && len(v.(string)) > 0 { request["Description"] = v } if v, ok := d.GetOk("tags"); ok { tagsMap := ConvertTags(v.(map[string]interface{})) - request["Tags"] = tagsMap + request = expandTagsToMap(request, tagsMap) } - runtime := util.RuntimeOptions{} - runtime.SetAutoretry(true) wait := incrementalWait(3*time.Second, 5*time.Second) err = resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError { response, err = client.RpcPost("Vpc", "2016-04-28", action, query, request, true) - request["ClientToken"] = buildClientToken(action) - if err != nil { if IsExpectedErrors(err, []string{"IncorrectStatus.Vpc", "OperationConflict", "IncorrectStatus", "ServiceUnavailable", "LastTokenProcessing", "SystemBusy"}) || NeedRetry(err) { wait() @@ -227,9 +234,9 @@ func resourceAliCloudVpcNetworkAclCreate(d *schema.ResourceData, meta interface{ } return resource.NonRetryableError(err) } - addDebug(action, response, request) return nil }) + addDebug(action, response, request) if err != nil { return WrapErrorf(err, DefaultErrorMsg, "alicloud_network_acl", action, AlibabaCloudSdkGoERROR) @@ -264,67 +271,76 @@ func resourceAliCloudVpcNetworkAclRead(d *schema.ResourceData, meta interface{}) d.Set("create_time", objectRaw["CreationTime"]) d.Set("description", objectRaw["Description"]) d.Set("network_acl_name", objectRaw["NetworkAclName"]) + d.Set("region_id", objectRaw["RegionId"]) d.Set("status", objectRaw["Status"]) d.Set("vpc_id", objectRaw["VpcId"]) - egressAclEntry1Raw, _ := jsonpath.Get("$.EgressAclEntries.EgressAclEntry", objectRaw) + egressAclEntryRaw, _ := jsonpath.Get("$.EgressAclEntries.EgressAclEntry", objectRaw) egressAclEntriesMaps := make([]map[string]interface{}, 0) - if egressAclEntry1Raw != nil { - for _, egressAclEntryChild1Raw := range egressAclEntry1Raw.([]interface{}) { + if egressAclEntryRaw != nil { + for _, egressAclEntryChildRaw := range egressAclEntryRaw.([]interface{}) { egressAclEntriesMap := make(map[string]interface{}) - egressAclEntryChild1Raw := egressAclEntryChild1Raw.(map[string]interface{}) - if egressAclEntryChild1Raw["EntryType"] == "service" || egressAclEntryChild1Raw["EntryType"] == "system" { + egressAclEntryChildRaw := egressAclEntryChildRaw.(map[string]interface{}) + if egressAclEntryChildRaw["EntryType"] == "service" || egressAclEntryChildRaw["EntryType"] == "system" { continue } - egressAclEntriesMap["description"] = egressAclEntryChild1Raw["Description"] - egressAclEntriesMap["destination_cidr_ip"] = egressAclEntryChild1Raw["DestinationCidrIp"] - egressAclEntriesMap["entry_type"] = egressAclEntryChild1Raw["EntryType"] - egressAclEntriesMap["ip_version"] = egressAclEntryChild1Raw["IpVersion"] - egressAclEntriesMap["network_acl_entry_name"] = egressAclEntryChild1Raw["NetworkAclEntryName"] - egressAclEntriesMap["policy"] = egressAclEntryChild1Raw["Policy"] - egressAclEntriesMap["port"] = egressAclEntryChild1Raw["Port"] - egressAclEntriesMap["protocol"] = egressAclEntryChild1Raw["Protocol"] + egressAclEntriesMap["description"] = egressAclEntryChildRaw["Description"] + egressAclEntriesMap["destination_cidr_ip"] = egressAclEntryChildRaw["DestinationCidrIp"] + egressAclEntriesMap["entry_type"] = egressAclEntryChildRaw["EntryType"] + egressAclEntriesMap["ip_version"] = egressAclEntryChildRaw["IpVersion"] + egressAclEntriesMap["network_acl_entry_id"] = egressAclEntryChildRaw["NetworkAclEntryId"] + egressAclEntriesMap["network_acl_entry_name"] = egressAclEntryChildRaw["NetworkAclEntryName"] + egressAclEntriesMap["policy"] = egressAclEntryChildRaw["Policy"] + egressAclEntriesMap["port"] = egressAclEntryChildRaw["Port"] + egressAclEntriesMap["protocol"] = egressAclEntryChildRaw["Protocol"] egressAclEntriesMaps = append(egressAclEntriesMaps, egressAclEntriesMap) } } - d.Set("egress_acl_entries", egressAclEntriesMaps) - ingressAclEntry1Raw, _ := jsonpath.Get("$.IngressAclEntries.IngressAclEntry", objectRaw) + if err := d.Set("egress_acl_entries", egressAclEntriesMaps); err != nil { + return err + } + ingressAclEntryRaw, _ := jsonpath.Get("$.IngressAclEntries.IngressAclEntry", objectRaw) ingressAclEntriesMaps := make([]map[string]interface{}, 0) - if ingressAclEntry1Raw != nil { - for _, ingressAclEntryChild1Raw := range ingressAclEntry1Raw.([]interface{}) { + if ingressAclEntryRaw != nil { + for _, ingressAclEntryChildRaw := range ingressAclEntryRaw.([]interface{}) { ingressAclEntriesMap := make(map[string]interface{}) - ingressAclEntryChild1Raw := ingressAclEntryChild1Raw.(map[string]interface{}) - if ingressAclEntryChild1Raw["EntryType"] == "service" || ingressAclEntryChild1Raw["EntryType"] == "system" { + ingressAclEntryChildRaw := ingressAclEntryChildRaw.(map[string]interface{}) + if ingressAclEntryChildRaw["EntryType"] == "service" || ingressAclEntryChildRaw["EntryType"] == "system" { continue } - ingressAclEntriesMap["description"] = ingressAclEntryChild1Raw["Description"] - ingressAclEntriesMap["entry_type"] = ingressAclEntryChild1Raw["EntryType"] - ingressAclEntriesMap["ip_version"] = ingressAclEntryChild1Raw["IpVersion"] - ingressAclEntriesMap["network_acl_entry_name"] = ingressAclEntryChild1Raw["NetworkAclEntryName"] - ingressAclEntriesMap["policy"] = ingressAclEntryChild1Raw["Policy"] - ingressAclEntriesMap["port"] = ingressAclEntryChild1Raw["Port"] - ingressAclEntriesMap["protocol"] = ingressAclEntryChild1Raw["Protocol"] - ingressAclEntriesMap["source_cidr_ip"] = ingressAclEntryChild1Raw["SourceCidrIp"] + ingressAclEntriesMap["description"] = ingressAclEntryChildRaw["Description"] + ingressAclEntriesMap["entry_type"] = ingressAclEntryChildRaw["EntryType"] + ingressAclEntriesMap["ip_version"] = ingressAclEntryChildRaw["IpVersion"] + ingressAclEntriesMap["network_acl_entry_id"] = ingressAclEntryChildRaw["NetworkAclEntryId"] + ingressAclEntriesMap["network_acl_entry_name"] = ingressAclEntryChildRaw["NetworkAclEntryName"] + ingressAclEntriesMap["policy"] = ingressAclEntryChildRaw["Policy"] + ingressAclEntriesMap["port"] = ingressAclEntryChildRaw["Port"] + ingressAclEntriesMap["protocol"] = ingressAclEntryChildRaw["Protocol"] + ingressAclEntriesMap["source_cidr_ip"] = ingressAclEntryChildRaw["SourceCidrIp"] ingressAclEntriesMaps = append(ingressAclEntriesMaps, ingressAclEntriesMap) } } - d.Set("ingress_acl_entries", ingressAclEntriesMaps) - resource1Raw, _ := jsonpath.Get("$.Resources.Resource", objectRaw) + if err := d.Set("ingress_acl_entries", ingressAclEntriesMaps); err != nil { + return err + } + resourceRaw, _ := jsonpath.Get("$.Resources.Resource", objectRaw) resourcesMaps := make([]map[string]interface{}, 0) - if resource1Raw != nil { - for _, resourceChild1Raw := range resource1Raw.([]interface{}) { + if resourceRaw != nil { + for _, resourceChildRaw := range resourceRaw.([]interface{}) { resourcesMap := make(map[string]interface{}) - resourceChild1Raw := resourceChild1Raw.(map[string]interface{}) - resourcesMap["resource_id"] = resourceChild1Raw["ResourceId"] - resourcesMap["resource_type"] = resourceChild1Raw["ResourceType"] - resourcesMap["status"] = resourceChild1Raw["Status"] + resourceChildRaw := resourceChildRaw.(map[string]interface{}) + resourcesMap["resource_id"] = resourceChildRaw["ResourceId"] + resourcesMap["resource_type"] = resourceChildRaw["ResourceType"] + resourcesMap["status"] = resourceChildRaw["Status"] resourcesMaps = append(resourcesMaps, resourcesMap) } } - d.Set("resources", resourcesMaps) + if err := d.Set("resources", resourcesMaps); err != nil { + return err + } tagsMaps, _ := jsonpath.Get("$.Tags.Tag", objectRaw) d.Set("tags", tagsToMap(tagsMaps)) @@ -339,11 +355,12 @@ func resourceAliCloudVpcNetworkAclUpdate(d *schema.ResourceData, meta interface{ var query map[string]interface{} update := false d.Partial(true) - action := "ModifyNetworkAclAttributes" + var err error + action := "ModifyNetworkAclAttributes" request = make(map[string]interface{}) query = make(map[string]interface{}) - query["NetworkAclId"] = d.Id() + request["NetworkAclId"] = d.Id() request["RegionId"] = client.RegionId request["ClientToken"] = buildClientToken(action) if !d.IsNewResource() && d.HasChange("name") { @@ -362,13 +379,9 @@ func resourceAliCloudVpcNetworkAclUpdate(d *schema.ResourceData, meta interface{ } if update { - runtime := util.RuntimeOptions{} - runtime.SetAutoretry(true) wait := incrementalWait(3*time.Second, 5*time.Second) err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { response, err = client.RpcPost("Vpc", "2016-04-28", action, query, request, true) - request["ClientToken"] = buildClientToken(action) - if err != nil { if IsExpectedErrors(err, []string{"IncorrectStatus.Vpc", "OperationConflict", "IncorrectStatus", "ServiceUnavailable", "LastTokenProcessing", "SystemBusy"}) || NeedRetry(err) { wait() @@ -376,9 +389,9 @@ func resourceAliCloudVpcNetworkAclUpdate(d *schema.ResourceData, meta interface{ } return resource.NonRetryableError(err) } - addDebug(action, response, request) return nil }) + addDebug(action, response, request) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) } @@ -387,68 +400,76 @@ func resourceAliCloudVpcNetworkAclUpdate(d *schema.ResourceData, meta interface{ if _, err := stateConf.WaitForState(); err != nil { return WrapErrorf(err, IdMsg, d.Id()) } - d.SetPartial("network_acl_name") - d.SetPartial("description") } update = false action = "UpdateNetworkAclEntries" request = make(map[string]interface{}) query = make(map[string]interface{}) - query["NetworkAclId"] = d.Id() + request["NetworkAclId"] = d.Id() request["RegionId"] = client.RegionId request["ClientToken"] = buildClientToken(action) if d.HasChange("ingress_acl_entries") { request["UpdateIngressAclEntries"] = "true" update = true - if v, ok := d.GetOk("ingress_acl_entries"); ok { - ingressAclEntriesMaps := make([]map[string]interface{}, 0) + if v, ok := d.GetOk("ingress_acl_entries"); ok || d.HasChange("ingress_acl_entries") { + ingressAclEntriesMapsArray := make([]interface{}, 0) for _, dataLoop := range v.([]interface{}) { dataLoopTmp := dataLoop.(map[string]interface{}) dataLoopMap := make(map[string]interface{}) dataLoopMap["Policy"] = dataLoopTmp["policy"] - dataLoopMap["NetworkAclEntryName"] = dataLoopTmp["network_acl_entry_name"] + if len(dataLoopTmp["network_acl_entry_name"].(string)) > 0 { + dataLoopMap["NetworkAclEntryName"] = dataLoopTmp["network_acl_entry_name"] + } dataLoopMap["SourceCidrIp"] = dataLoopTmp["source_cidr_ip"] dataLoopMap["Protocol"] = dataLoopTmp["protocol"] dataLoopMap["Port"] = dataLoopTmp["port"] - dataLoopMap["Description"] = dataLoopTmp["description"] + if len(dataLoopTmp["description"].(string)) > 0 { + dataLoopMap["Description"] = dataLoopTmp["description"] + } dataLoopMap["IpVersion"] = dataLoopTmp["ip_version"] dataLoopMap["EntryType"] = dataLoopTmp["entry_type"] - ingressAclEntriesMaps = append(ingressAclEntriesMaps, dataLoopMap) + if len(dataLoopTmp["network_acl_entry_id"].(string)) > 0 { + dataLoopMap["NetworkAclEntryId"] = dataLoopTmp["network_acl_entry_id"] + } + ingressAclEntriesMapsArray = append(ingressAclEntriesMapsArray, dataLoopMap) } - request["IngressAclEntries"] = ingressAclEntriesMaps + request["IngressAclEntries"] = ingressAclEntriesMapsArray } } if d.HasChange("egress_acl_entries") { request["UpdateEgressAclEntries"] = "true" update = true - if v, ok := d.GetOk("egress_acl_entries"); ok { - egressAclEntriesMaps := make([]map[string]interface{}, 0) + if v, ok := d.GetOk("egress_acl_entries"); ok || d.HasChange("egress_acl_entries") { + egressAclEntriesMapsArray := make([]interface{}, 0) for _, dataLoop1 := range v.([]interface{}) { dataLoop1Tmp := dataLoop1.(map[string]interface{}) dataLoop1Map := make(map[string]interface{}) dataLoop1Map["Policy"] = dataLoop1Tmp["policy"] - dataLoop1Map["NetworkAclEntryName"] = dataLoop1Tmp["network_acl_entry_name"] - dataLoop1Map["Description"] = dataLoop1Tmp["description"] + if len(dataLoop1Tmp["network_acl_entry_name"].(string)) > 0 { + dataLoop1Map["NetworkAclEntryName"] = dataLoop1Tmp["network_acl_entry_name"] + } + if len(dataLoop1Tmp["description"].(string)) > 0 { + dataLoop1Map["Description"] = dataLoop1Tmp["description"] + } dataLoop1Map["Protocol"] = dataLoop1Tmp["protocol"] dataLoop1Map["DestinationCidrIp"] = dataLoop1Tmp["destination_cidr_ip"] dataLoop1Map["Port"] = dataLoop1Tmp["port"] dataLoop1Map["EntryType"] = dataLoop1Tmp["entry_type"] dataLoop1Map["IpVersion"] = dataLoop1Tmp["ip_version"] - egressAclEntriesMaps = append(egressAclEntriesMaps, dataLoop1Map) + if len(dataLoop1Tmp["network_acl_entry_id"].(string)) > 0 { + dataLoop1Map["NetworkAclEntryId"] = dataLoop1Tmp["network_acl_entry_id"] + } + egressAclEntriesMapsArray = append(egressAclEntriesMapsArray, dataLoop1Map) } - request["EgressAclEntries"] = egressAclEntriesMaps + request["EgressAclEntries"] = egressAclEntriesMapsArray } } if update { - runtime := util.RuntimeOptions{} - runtime.SetAutoretry(true) wait := incrementalWait(3*time.Second, 5*time.Second) err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { response, err = client.RpcPost("Vpc", "2016-04-28", action, query, request, true) - request["ClientToken"] = buildClientToken(action) - if err != nil { if IsExpectedErrors(err, []string{"IncorrectStatus.Vpc", "OperationConflict", "IncorrectStatus", "ServiceUnavailable", "LastTokenProcessing", "SystemBusy"}) || NeedRetry(err) { wait() @@ -456,9 +477,9 @@ func resourceAliCloudVpcNetworkAclUpdate(d *schema.ResourceData, meta interface{ } return resource.NonRetryableError(err) } - addDebug(action, response, request) return nil }) + addDebug(action, response, request) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) } @@ -472,21 +493,14 @@ func resourceAliCloudVpcNetworkAclUpdate(d *schema.ResourceData, meta interface{ action = "CopyNetworkAclEntries" request = make(map[string]interface{}) query = make(map[string]interface{}) - query["NetworkAclId"] = d.Id() + request["NetworkAclId"] = d.Id() request["RegionId"] = client.RegionId request["ClientToken"] = buildClientToken(action) - if v, ok := d.GetOk("source_network_acl_id"); ok && d.HasChange("source_network_acl_id") { - update = true - request["SourceNetworkAclId"] = v - } + request["SourceNetworkAclId"] = d.Get("source_network_acl_id") if update { - runtime := util.RuntimeOptions{} - runtime.SetAutoretry(true) wait := incrementalWait(3*time.Second, 5*time.Second) err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { response, err = client.RpcPost("Vpc", "2016-04-28", action, query, request, true) - request["ClientToken"] = buildClientToken(action) - if err != nil { if IsExpectedErrors(err, []string{"IncorrectStatus.Vpc", "OperationConflict", "IncorrectStatus", "ServiceUnavailable", "LastTokenProcessing", "SystemBusy"}) || NeedRetry(err) { wait() @@ -494,9 +508,9 @@ func resourceAliCloudVpcNetworkAclUpdate(d *schema.ResourceData, meta interface{ } return resource.NonRetryableError(err) } - addDebug(action, response, request) return nil }) + addDebug(action, response, request) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) } @@ -505,7 +519,6 @@ func resourceAliCloudVpcNetworkAclUpdate(d *schema.ResourceData, meta interface{ if _, err := stateConf.WaitForState(); err != nil { return WrapErrorf(err, IdMsg, d.Id()) } - d.SetPartial("source_network_acl_id") } if d.HasChange("resources") { @@ -519,37 +532,33 @@ func resourceAliCloudVpcNetworkAclUpdate(d *schema.ResourceData, meta interface{ action := "UnassociateNetworkAcl" request = make(map[string]interface{}) query = make(map[string]interface{}) - query["NetworkAclId"] = d.Id() + request["NetworkAclId"] = d.Id() request["RegionId"] = client.RegionId request["ClientToken"] = buildClientToken(action) localData := removed.List() - resourceMaps := make([]map[string]interface{}, 0) + resourceMapsArray := make([]interface{}, 0) for _, dataLoop := range localData { dataLoopTmp := dataLoop.(map[string]interface{}) dataLoopMap := make(map[string]interface{}) dataLoopMap["ResourceType"] = dataLoopTmp["resource_type"] dataLoopMap["ResourceId"] = dataLoopTmp["resource_id"] - resourceMaps = append(resourceMaps, dataLoopMap) + resourceMapsArray = append(resourceMapsArray, dataLoopMap) } - request["Resource"] = resourceMaps + request["Resource"] = resourceMapsArray - 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 = client.RpcPost("Vpc", "2016-04-28", action, query, request, true) - request["ClientToken"] = buildClientToken(action) - if err != nil { - if IsExpectedErrors(err, []string{"IncorrectStatus.Vpc", "OperationConflict", "IncorrectStatus", "ServiceUnavailable", "LastTokenProcessing", "SystemBusy", "ResourceStatus.Error"}) || NeedRetry(err) { + if IsExpectedErrors(err, []string{"IncorrectStatus.Vpc", "OperationConflict", "IncorrectStatus", "ServiceUnavailable", "LastTokenProcessing", "SystemBusy", "ResourceStatus.Error", "NetworkAclExistBinding"}) || NeedRetry(err) { wait() return resource.RetryableError(err) } return resource.NonRetryableError(err) } - addDebug(action, response, request) return nil }) + addDebug(action, response, request) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) } @@ -565,37 +574,33 @@ func resourceAliCloudVpcNetworkAclUpdate(d *schema.ResourceData, meta interface{ action := "AssociateNetworkAcl" request = make(map[string]interface{}) query = make(map[string]interface{}) - query["NetworkAclId"] = d.Id() + request["NetworkAclId"] = d.Id() request["RegionId"] = client.RegionId request["ClientToken"] = buildClientToken(action) localData := added.List() - resourceMaps := make([]map[string]interface{}, 0) + resourceMapsArray := make([]interface{}, 0) for _, dataLoop := range localData { dataLoopTmp := dataLoop.(map[string]interface{}) dataLoopMap := make(map[string]interface{}) dataLoopMap["ResourceType"] = dataLoopTmp["resource_type"] dataLoopMap["ResourceId"] = dataLoopTmp["resource_id"] - resourceMaps = append(resourceMaps, dataLoopMap) + resourceMapsArray = append(resourceMapsArray, dataLoopMap) } - request["Resource"] = resourceMaps + request["Resource"] = resourceMapsArray - 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 = client.RpcPost("Vpc", "2016-04-28", action, query, request, true) - request["ClientToken"] = buildClientToken(action) - if err != nil { - if IsExpectedErrors(err, []string{"IncorrectStatus.Vpc", "OperationConflict", "IncorrectStatus", "ServiceUnavailable", "LastTokenProcessing", "SystemBusy", "ResourceStatus.Error"}) || NeedRetry(err) { + if IsExpectedErrors(err, []string{"IncorrectStatus.Vpc", "OperationConflict", "IncorrectStatus", "ServiceUnavailable", "LastTokenProcessing", "SystemBusy"}) || NeedRetry(err) { wait() return resource.RetryableError(err) } return resource.NonRetryableError(err) } - addDebug(action, response, request) return nil }) + addDebug(action, response, request) if err != nil { return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) } @@ -613,7 +618,6 @@ func resourceAliCloudVpcNetworkAclUpdate(d *schema.ResourceData, meta interface{ if err := vpcServiceV2.SetResourceTags(d, "NETWORKACL"); err != nil { return WrapError(err) } - d.SetPartial("tags") } d.Partial(false) return resourceAliCloudVpcNetworkAclRead(d, meta) @@ -621,9 +625,9 @@ func resourceAliCloudVpcNetworkAclUpdate(d *schema.ResourceData, meta interface{ func resourceAliCloudVpcNetworkAclDelete(d *schema.ResourceData, meta interface{}) error { vpcService := VpcService{meta.(*connectivity.AliyunClient)} - _, err := vpcService.DeleteAclResources(d.Id()) - if err != nil { - return WrapError(err) + _, errMsg := vpcService.DeleteAclResources(d.Id()) + if errMsg != nil { + return WrapError(errMsg) } client := meta.(*connectivity.AliyunClient) @@ -631,14 +635,12 @@ func resourceAliCloudVpcNetworkAclDelete(d *schema.ResourceData, meta interface{ var request map[string]interface{} var response map[string]interface{} query := make(map[string]interface{}) + var err error request = make(map[string]interface{}) - query["NetworkAclId"] = d.Id() + request["NetworkAclId"] = d.Id() request["RegionId"] = client.RegionId - request["ClientToken"] = buildClientToken(action) - runtime := util.RuntimeOptions{} - runtime.SetAutoretry(true) wait := incrementalWait(3*time.Second, 5*time.Second) err = resource.Retry(d.Timeout(schema.TimeoutDelete), func() *resource.RetryError { response, err = client.RpcPost("Vpc", "2016-04-28", action, query, request, true) @@ -651,11 +653,14 @@ func resourceAliCloudVpcNetworkAclDelete(d *schema.ResourceData, meta interface{ } return resource.NonRetryableError(err) } - addDebug(action, response, request) return nil }) + addDebug(action, response, request) if err != nil { + if NotFoundError(err) { + return nil + } return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) } @@ -664,5 +669,6 @@ func resourceAliCloudVpcNetworkAclDelete(d *schema.ResourceData, meta interface{ if _, err := stateConf.WaitForState(); err != nil { return WrapErrorf(err, IdMsg, d.Id()) } + return nil } diff --git a/alicloud/service_alicloud_vpc_v2.go b/alicloud/service_alicloud_vpc_v2.go index 1f425ee0b511..80587748acb2 100644 --- a/alicloud/service_alicloud_vpc_v2.go +++ b/alicloud/service_alicloud_vpc_v2.go @@ -88,8 +88,8 @@ func (s *VpcServiceV2) VpcPublicIpAddressPoolStateRefreshFunc(id string, field s // SetResourceTags <<< Encapsulated tag function for Vpc. func (s *VpcServiceV2) SetResourceTags(d *schema.ResourceData, resourceType string) error { if d.HasChange("tags") { - var err error var action string + var err error client := s.client var request map[string]interface{} var response map[string]interface{} @@ -108,14 +108,14 @@ func (s *VpcServiceV2) SetResourceTags(d *schema.ResourceData, resourceType stri query = make(map[string]interface{}) request["ResourceId.1"] = d.Id() request["RegionId"] = client.RegionId - request["ResourceType"] = resourceType for i, key := range removedTagKeys { request[fmt.Sprintf("TagKey.%d", i+1)] = key } + request["ResourceType"] = resourceType wait := incrementalWait(3*time.Second, 5*time.Second) err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { - response, err = client.RpcPost("Vpc", "2016-04-28", action, query, request, false) + response, err = client.RpcPost("Vpc", "2016-04-28", action, query, request, true) if err != nil { if NeedRetry(err) { wait() @@ -138,7 +138,6 @@ func (s *VpcServiceV2) SetResourceTags(d *schema.ResourceData, resourceType stri query = make(map[string]interface{}) request["ResourceId.1"] = d.Id() request["RegionId"] = client.RegionId - request["ResourceType"] = resourceType count := 1 for key, value := range added { request[fmt.Sprintf("Tag.%d.Key", count)] = key @@ -146,9 +145,10 @@ func (s *VpcServiceV2) SetResourceTags(d *schema.ResourceData, resourceType stri count++ } + request["ResourceType"] = resourceType wait := incrementalWait(3*time.Second, 5*time.Second) err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { - response, err = client.RpcPost("Vpc", "2016-04-28", action, query, request, false) + response, err = client.RpcPost("Vpc", "2016-04-28", action, query, request, true) if err != nil { if NeedRetry(err) { wait() @@ -1073,11 +1073,11 @@ func (s *VpcServiceV2) DescribeVpcNetworkAcl(id string) (object map[string]inter var request map[string]interface{} var response map[string]interface{} var query map[string]interface{} - action := "DescribeNetworkAclAttributes" request = make(map[string]interface{}) query = make(map[string]interface{}) - query["NetworkAclId"] = id - query["RegionId"] = client.RegionId + request["NetworkAclId"] = id + request["RegionId"] = client.RegionId + action := "DescribeNetworkAclAttributes" request["ClientToken"] = buildClientToken(action) wait := incrementalWait(3*time.Second, 5*time.Second) @@ -1092,14 +1092,13 @@ func (s *VpcServiceV2) DescribeVpcNetworkAcl(id string) (object map[string]inter } return resource.NonRetryableError(err) } - addDebug(action, response, request) return nil }) + addDebug(action, response, request) if err != nil { if IsExpectedErrors(err, []string{"InvalidNetworkAcl.NotFound"}) { return object, WrapErrorf(Error(GetNotFoundMessage("NetworkAcl", id)), NotFoundMsg, response) } - addDebug(action, response, request) return object, WrapErrorf(err, DefaultErrorMsg, id, action, AlibabaCloudSdkGoERROR) } @@ -1124,6 +1123,13 @@ func (s *VpcServiceV2) VpcNetworkAclStateRefreshFunc(id string, field string, fa 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)) diff --git a/website/docs/r/network_acl.html.markdown b/website/docs/r/network_acl.html.markdown index 04cb852ad814..89e0e979fea1 100644 --- a/website/docs/r/network_acl.html.markdown +++ b/website/docs/r/network_acl.html.markdown @@ -8,7 +8,9 @@ description: |- # alicloud_network_acl -Provides a VPC Network Acl resource. Network Access Control List (ACL) is a Network Access Control function in VPC. You can customize the network ACL rules and bind the network ACL to the switch to control the traffic of ECS instances in the switch. +Provides a VPC Network Acl resource. + +Network Access Control List (ACL) is a Network Access Control function in VPC. You can customize the network ACL rules and bind the network ACL to the switch to control the traffic of ECS instances in the switch. For information about VPC Network Acl and how to use it, see [What is Network Acl](https://www.alibabacloud.com/help/en/ens/latest/createnetworkacl). @@ -18,12 +20,6 @@ For information about VPC Network Acl and how to use it, see [What is Network Ac Basic Usage -
- - Open in AliCloud - -
- ```terraform variable "name" { default = "tf-example" @@ -73,12 +69,14 @@ resource "alicloud_network_acl" "example" { ## Argument Reference The following arguments are supported: -* `description` - (Optional) The description of the network ACL. The description must be 1 to 256 characters in length and cannot start with http:// or https. -* `egress_acl_entries` - (Optional, Computed) Out direction rule information. See [`egress_acl_entries`](#egress_acl_entries) below. -* `ingress_acl_entries` - (Optional, Computed) Inward direction rule information. See [`ingress_acl_entries`](#ingress_acl_entries) below. -* `network_acl_name` - (Optional) The name of the network ACL. The name must be 1 to 128 characters in length and cannot start with http:// or https. -* `resources` - (Optional, Computed) The associated resource. See [`resources`](#resources) below. -* `source_network_acl_id` - (Optional, Available since v1.220.0) SOURCE NetworkAcl specified by CopyNetworkAclEntries. +* `description` - (Optional) The description of the network ACL. +The description must be 1 to 256 characters in length and cannot start with http:// or https. +* `egress_acl_entries` - (Optional, Computed, List) Out direction rule information. See [`egress_acl_entries`](#egress_acl_entries) below. +* `ingress_acl_entries` - (Optional, Computed, List) Inward direction rule information. See [`ingress_acl_entries`](#ingress_acl_entries) below. +* `network_acl_name` - (Optional) The name of the network ACL. +The name must be 1 to 128 characters in length and cannot start with http:// or https. +* `resources` - (Optional, Computed, Set) The associated resource. See [`resources`](#resources) below. +* `source_network_acl_id` - (Optional, Available since v1.220.0) SOURCE NetworkAcl specified by CopyNetworkAclEntries * `tags` - (Optional, Map, Available since v1.206.0) The tags of this resource. * `vpc_id` - (Required, ForceNew) The ID of the associated VPC. @@ -88,15 +86,23 @@ The following arguments will be discarded. Please use new fields as soon as poss ### `egress_acl_entries` The egress_acl_entries supports the following: -* `description` - (Optional) The description of the outbound rule. The description must be 1 to 256 characters in length and cannot start with http:// or https. +* `description` - (Optional) The description of the outbound rule. +The description must be 1 to 256 characters in length and cannot start with http:// or https. * `destination_cidr_ip` - (Optional) The network of the destination address. -* `entry_type` - (Optional, Available since v1.220.0) The route entry type. The value can be `custom`, indicating custom. -* `ip_version` - (Optional, Available since v1.220.0) The IP protocol version of the route entry. Valid values: "IPV4" and "IPV4'. -* `network_acl_entry_name` - (Optional) Name of the outbound rule entry. The name must be 1 to 128 characters in length and cannot start with http:// or https. +* `entry_type` - (Optional, Available since v1.220.0) The route entry type. Value + - `custom`: custom rule + - `system`: system rules + - `service`: Cloud service rules +* `ip_version` - (Optional, Available since v1.220.0) The IP protocol version of the route entry. Valid values: "Ipv4" and "ipv6' +* `network_acl_entry_id` - (Optional, ForceNew, Available since v1.244.0) Network acl entry id. +* `network_acl_entry_name` - (Optional) Name of the outbound rule entry. +The name must be 1 to 128 characters in length and cannot start with http:// or https. * `policy` - (Optional) Authorization policy. Value: - accept: Allow. - drop: Refused. -* `port` - (Optional) The destination port range of the outbound rule. When the Protocol type of the outbound rule is all, icmp, or gre, the port range is - 1/-1, indicating that the port is not restricted. When the Protocol type of the outbound rule is tcp or udp, the port range is 1 to 65535, and the format is 1/200 or 80/80, indicating port 1 to port 200 or port 80. +* `port` - (Optional) The destination port range of the outbound rule. +When the Protocol type of the outbound rule is all, icmp, or gre, the port range is - 1/-1, indicating that the port is not restricted. +When the Protocol type of the outbound rule is tcp or udp, the port range is 1 to 65535, and the format is 1/200 or 80/80, indicating port 1 to port 200 or port 80. * `protocol` - (Optional) The protocol type. Value: - icmp: Network Control Message Protocol. - gre: Generic Routing Encapsulation Protocol. @@ -107,14 +113,22 @@ The egress_acl_entries supports the following: ### `ingress_acl_entries` The ingress_acl_entries supports the following: -* `description` - (Optional) Description of the inbound rule. The description must be 1 to 256 characters in length and cannot start with http:// or https. -* `entry_type` - (Optional, Available since v1.220.0) The route entry type. The value can be `custom`, indicating custom. -* `ip_version` - (Optional, Available since v1.220.0) The IP protocol version of the route entry. Valid values: "IPV4" and "IPV6'. -* `network_acl_entry_name` - (Optional) The name of the inbound rule entry. The name must be 1 to 128 characters in length and cannot start with http:// or https. +* `description` - (Optional) Description of the inbound rule. +The description must be 1 to 256 characters in length and cannot start with http:// or https. +* `entry_type` - (Optional, Available since v1.220.0) The route entry type. Value + - `custom`: custom rule + - `system`: system rules + - `service`: Cloud service rules +* `ip_version` - (Optional, Available since v1.220.0) The IP protocol version of the route entry. Valid values: "Ipv4" and "ipv6' +* `network_acl_entry_id` - (Optional, ForceNew, Available since v1.244.0) Network acl entry id. +* `network_acl_entry_name` - (Optional) The name of the inbound rule entry. +The name must be 1 to 128 characters in length and cannot start with http:// or https. * `policy` - (Optional) Authorization policy. Value: - accept: Allow. - drop: Refused. -* `port` - (Optional) The source port range of the inbound rule. When the Protocol type of the inbound rule is all, icmp, or gre, the port range is - 1/-1, indicating that the port is not restricted. When the Protocol type of the inbound rule is tcp or udp, the port range is 1 to 65535, and the format is 1/200 or 80/80, indicating port 1 to port 200 or port 80. +* `port` - (Optional) The source port range of the inbound rule. +When the Protocol type of the inbound rule is all, icmp, or gre, the port range is - 1/-1, indicating that the port is not restricted. +When the Protocol type of the inbound rule is tcp or udp, the port range is 1 to 65535, and the format is 1/200 or 80/80, indicating port 1 to port 200 or port 80. * `protocol` - (Optional) The protocol type. Value: - icmp: Network Control Message Protocol. - gre: Generic Routing Encapsulation Protocol. @@ -134,16 +148,17 @@ The resources supports the following: The following attributes are exported: * `id` - The ID of the resource supplied above. * `create_time` - The creation time of the resource. +* `region_id` - The region * `resources` - The associated resource. - * `status` - The state of the associated resource. + * `status` - The state of the associated resource * `status` - The state of the network ACL. ## Timeouts The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration-0-11/resources.html#timeouts) for certain actions: -* `create` - (Defaults to 5 mins) Used when create the Network Acl. -* `delete` - (Defaults to 5 mins) Used when delete the Network Acl. -* `update` - (Defaults to 5 mins) Used when update the Network Acl. +* `create` - (Defaults to 10 mins) Used when create the Network Acl. +* `delete` - (Defaults to 10 mins) Used when delete the Network Acl. +* `update` - (Defaults to 10 mins) Used when update the Network Acl. ## Import