alibabacloudstack/resource_apsarastack_vpc_networkacl.go (393 lines of code) (raw):

package alibabacloudstack import ( "fmt" "log" "time" "github.com/aliyun/terraform-provider-alibabacloudstack/alibabacloudstack/connectivity" "github.com/aliyun/terraform-provider-alibabacloudstack/alibabacloudstack/errmsgs" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" ) func resourceAlibabacloudStackNetworkAcl() *schema.Resource { resource := &schema.Resource{ Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(10 * time.Minute), Delete: schema.DefaultTimeout(10 * time.Minute), Update: schema.DefaultTimeout(10 * time.Minute), }, Schema: map[string]*schema.Schema{ "description": { Type: schema.TypeString, Optional: true, ValidateFunc: validation.StringLenBetween(2, 256), }, "egress_acl_entries": { Type: schema.TypeList, Optional: true, Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "description": { Type: schema.TypeString, Optional: true, }, "destination_cidr_ip": { Type: schema.TypeString, Optional: true, }, "network_acl_entry_name": { Type: schema.TypeString, Optional: true, }, "policy": { Type: schema.TypeString, Optional: true, ValidateFunc: validation.StringInSlice([]string{"accept", "drop"}, false), }, "port": { Type: schema.TypeString, Optional: true, }, "protocol": { Type: schema.TypeString, Optional: true, ValidateFunc: validation.StringInSlice([]string{"icmp", "gre", "tcp", "udp", "all"}, false), }, }, }, }, "ingress_acl_entries": { Type: schema.TypeList, Optional: true, Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "description": { Type: schema.TypeString, Optional: true, }, "network_acl_entry_name": { Type: schema.TypeString, Optional: true, }, "policy": { Type: schema.TypeString, Optional: true, ValidateFunc: validation.StringInSlice([]string{"accept", "drop"}, false), }, "port": { Type: schema.TypeString, Optional: true, }, "protocol": { Type: schema.TypeString, Optional: true, ValidateFunc: validation.StringInSlice([]string{"icmp", "gre", "tcp", "udp", "all"}, false), }, "source_cidr_ip": { Type: schema.TypeString, Optional: true, }, }, }, }, "network_acl_name": { Type: schema.TypeString, Optional: true, Computed: true, ConflictsWith: []string{"name"}, ValidateFunc: validation.StringLenBetween(2, 128), }, "name": { Type: schema.TypeString, Optional: true, Computed: true, Deprecated: "Field 'name' has been deprecated from provider version 1.122.0. New field 'network_acl_name' instead", ConflictsWith: []string{"network_acl_name"}, ValidateFunc: validation.StringLenBetween(2, 128), }, "resources": { Type: schema.TypeSet, Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "resource_id": { Type: schema.TypeString, Optional: true, }, "resource_type": { Type: schema.TypeString, Optional: true, }, }, }, }, "status": { Type: schema.TypeString, Computed: true, }, "vpc_id": { Type: schema.TypeString, Required: true, ForceNew: true, }, }, } setResourceFunc(resource, resourceAlibabacloudStackNetworkAclCreate, resourceAlibabacloudStackNetworkAclRead, resourceAlibabacloudStackNetworkAclUpdate, resourceAlibabacloudStackNetworkAclDelete) return resource } func resourceAlibabacloudStackNetworkAclCreate(d *schema.ResourceData, meta interface{}) (err error) { client := meta.(*connectivity.AlibabacloudStackClient) vpcService := VpcService{client} var response map[string]interface{} action := "CreateNetworkAcl" request := make(map[string]interface{}) if v, ok := d.GetOk("description"); ok { request["Description"] = v } if v, ok := connectivity.GetResourceDataOk(d, "network_acl_name", "name"); ok { request["NetworkAclName"] = v } request["VpcId"] = d.Get("vpc_id") request["ClientToken"] = buildClientToken("CreateNetworkAcl") response, err = client.DoTeaRequest("POST", "Vpc", "2016-04-28", action, "", nil, nil, request) if err != nil { return err } responseNetworkAclAttribute := response["NetworkAclAttribute"].(map[string]interface{}) d.SetId(fmt.Sprint(responseNetworkAclAttribute["NetworkAclId"])) stateConf := BuildStateConf([]string{}, []string{"Available"}, d.Timeout(schema.TimeoutCreate), 5*time.Second, vpcService.NetworkAclStateRefreshFunc(d.Id(), []string{})) if _, err := stateConf.WaitForState(); err != nil { return errmsgs.WrapErrorf(err, errmsgs.IdMsg, d.Id()) } return nil } func resourceAlibabacloudStackNetworkAclRead(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AlibabacloudStackClient) vpcService := VpcService{client} object, err := vpcService.DescribeNetworkAcl(d.Id()) if err != nil { if errmsgs.NotFoundError(err) { log.Printf("[DEBUG] Resource alibabacloudstack_network_acl vpcService.DescribeNetworkAcl Failed!!! %s", err) d.SetId("") return nil } return errmsgs.WrapError(err) } d.Set("description", object["Description"]) egressAclEntry := make([]map[string]interface{}, 0) if egressAclEntryList, ok := object["EgressAclEntries"].(map[string]interface{})["EgressAclEntry"].([]interface{}); ok { for _, v := range egressAclEntryList { if m1, ok := v.(map[string]interface{}); ok { temp1 := map[string]interface{}{ "description": m1["Description"], "destination_cidr_ip": m1["DestinationCidrIp"], "network_acl_entry_name": m1["NetworkAclEntryName"], "policy": m1["Policy"], "port": m1["Port"], "protocol": m1["Protocol"], } egressAclEntry = append(egressAclEntry, temp1) } } } if err := d.Set("egress_acl_entries", egressAclEntry); err != nil { return errmsgs.WrapError(err) } ingressAclEntry := make([]map[string]interface{}, 0) if ingressAclEntryList, ok := object["IngressAclEntries"].(map[string]interface{})["IngressAclEntry"].([]interface{}); ok { for _, v := range ingressAclEntryList { if m1, ok := v.(map[string]interface{}); ok { temp1 := map[string]interface{}{ "description": m1["Description"], "network_acl_entry_name": m1["NetworkAclEntryName"], "policy": m1["Policy"], "port": m1["Port"], "protocol": m1["Protocol"], "source_cidr_ip": m1["SourceCidrIp"], } ingressAclEntry = append(ingressAclEntry, temp1) } } } if err := d.Set("ingress_acl_entries", ingressAclEntry); err != nil { return errmsgs.WrapError(err) } connectivity.SetResourceData(d, object["NetworkAclName"], "network_acl_name", "name") resourceMap := make([]map[string]interface{}, 0) if resourceMapList, ok := object["Resources"].(map[string]interface{})["Resource"].([]interface{}); ok { for _, v := range resourceMapList { if m1, ok := v.(map[string]interface{}); ok { temp1 := map[string]interface{}{ "resource_id": m1["ResourceId"], "resource_type": m1["ResourceType"], } resourceMap = append(resourceMap, temp1) } } } if err := d.Set("resources", resourceMap); err != nil { return errmsgs.WrapError(err) } d.Set("status", object["Status"]) d.Set("vpc_id", object["VpcId"]) return nil } func resourceAlibabacloudStackNetworkAclUpdate(d *schema.ResourceData, meta interface{}) (err error) { client := meta.(*connectivity.AlibabacloudStackClient) vpcService := VpcService{client} d.Partial(true) update := false request := map[string]interface{}{ "NetworkAclId": d.Id(), } if !d.IsNewResource() && d.HasChange("description") { update = true request["Description"] = d.Get("description") } if !d.IsNewResource() && d.HasChanges("name", "network_acl_name") { update = true request["NetworkAclName"] = connectivity.GetResourceData(d, "network_acl_name", "name").(string) } if update { action := "ModifyNetworkAclAttributes" request["ClientToken"] = buildClientToken("ModifyNetworkAclAttributes") _, err = client.DoTeaRequest("POST", "Vpc", "2016-04-28", action, "", nil, nil, request) if err != nil { return err } stateConf := BuildStateConf([]string{}, []string{"Available"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, vpcService.NetworkAclStateRefreshFunc(d.Id(), []string{})) if _, err := stateConf.WaitForState(); err != nil { return errmsgs.WrapErrorf(err, errmsgs.IdMsg, d.Id()) } } update = false updateNetworkAclEntriesReq := map[string]interface{}{ "NetworkAclId": d.Id(), } if d.HasChange("egress_acl_entries") { updateNetworkAclEntriesReq["UpdateEgressAclEntries"] = true update = true EgressAclEntries := make([]map[string]interface{}, len(d.Get("egress_acl_entries").([]interface{}))) for i, EgressAclEntriesValue := range d.Get("egress_acl_entries").([]interface{}) { EgressAclEntriesMap := EgressAclEntriesValue.(map[string]interface{}) EgressAclEntries[i] = make(map[string]interface{}) EgressAclEntries[i]["Description"] = EgressAclEntriesMap["description"] EgressAclEntries[i]["DestinationCidrIp"] = EgressAclEntriesMap["destination_cidr_ip"] EgressAclEntries[i]["NetworkAclEntryName"] = EgressAclEntriesMap["network_acl_entry_name"] EgressAclEntries[i]["Policy"] = EgressAclEntriesMap["policy"] EgressAclEntries[i]["Port"] = EgressAclEntriesMap["port"] EgressAclEntries[i]["Protocol"] = EgressAclEntriesMap["protocol"] } updateNetworkAclEntriesReq["EgressAclEntries"] = EgressAclEntries } if d.HasChange("ingress_acl_entries") { updateNetworkAclEntriesReq["UpdateIngressAclEntries"] = true update = true IngressAclEntries := make([]map[string]interface{}, len(d.Get("ingress_acl_entries").([]interface{}))) for i, IngressAclEntriesValue := range d.Get("ingress_acl_entries").([]interface{}) { IngressAclEntriesMap := IngressAclEntriesValue.(map[string]interface{}) IngressAclEntries[i] = make(map[string]interface{}) IngressAclEntries[i]["Description"] = IngressAclEntriesMap["description"] IngressAclEntries[i]["NetworkAclEntryName"] = IngressAclEntriesMap["network_acl_entry_name"] IngressAclEntries[i]["Policy"] = IngressAclEntriesMap["policy"] IngressAclEntries[i]["Port"] = IngressAclEntriesMap["port"] IngressAclEntries[i]["Protocol"] = IngressAclEntriesMap["protocol"] IngressAclEntries[i]["SourceCidrIp"] = IngressAclEntriesMap["source_cidr_ip"] } updateNetworkAclEntriesReq["IngressAclEntries"] = IngressAclEntries } if update { action := "UpdateNetworkAclEntries" updateNetworkAclEntriesReq["ClientToken"] = buildClientToken("UpdateNetworkAclEntries") _, err = client.DoTeaRequest("POST", "Vpc", "2016-04-28", action, "", nil, nil, updateNetworkAclEntriesReq) if err != nil { return err } stateConf := BuildStateConf([]string{}, []string{"Available"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, vpcService.NetworkAclStateRefreshFunc(d.Id(), []string{})) if _, err := stateConf.WaitForState(); err != nil { return errmsgs.WrapErrorf(err, errmsgs.IdMsg, d.Id()) } } d.Partial(false) if d.HasChange("resources") { oldResources, newResources := d.GetChange("resources") oldResourcesSet := oldResources.(*schema.Set) newResourcesSet := newResources.(*schema.Set) removed := oldResourcesSet.Difference(newResourcesSet) added := newResourcesSet.Difference(oldResourcesSet) if added.Len() > 0 { associatenetworkaclrequest := map[string]interface{}{ "NetworkAclId": d.Id(), } resourcesMaps := make([]map[string]interface{}, 0) for _, resources := range added.List() { resourcesArg := resources.(map[string]interface{}) resourcesMap := map[string]interface{}{ "ResourceId": resourcesArg["resource_id"], "ResourceType": resourcesArg["resource_type"], } resourcesMaps = append(resourcesMaps, resourcesMap) } associatenetworkaclrequest["Resource"] = resourcesMaps action := "AssociateNetworkAcl" associatenetworkaclrequest["ClientToken"] = buildClientToken("AssociateNetworkAcl") _, err = client.DoTeaRequest("POST", "Vpc", "2016-04-28", action, "", nil, nil, associatenetworkaclrequest) if err != nil { return err } stateConf := BuildStateConf([]string{}, []string{"Available"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, vpcService.NetworkAclStateRefreshFunc(d.Id(), []string{})) if _, err := stateConf.WaitForState(); err != nil { return errmsgs.WrapErrorf(err, errmsgs.IdMsg, d.Id()) } } if removed.Len() > 0 { unassociatenetworkaclrequest := map[string]interface{}{ "NetworkAclId": d.Id(), } resourcesMaps := make([]map[string]interface{}, 0) for _, resources := range removed.List() { resourcesArg := resources.(map[string]interface{}) resourcesMap := map[string]interface{}{ "ResourceId": resourcesArg["resource_id"], "ResourceType": resourcesArg["resource_type"], } resourcesMaps = append(resourcesMaps, resourcesMap) } unassociatenetworkaclrequest["Resource"] = resourcesMaps action := "UnassociateNetworkAcl" unassociatenetworkaclrequest["ClientToken"] = buildClientToken("UnassociateNetworkAcl") _, err = client.DoTeaRequest("POST", "Vpc", "2016-04-28", action, "", nil, nil, unassociatenetworkaclrequest) if err != nil { return err } stateConf := BuildStateConf([]string{}, []string{"Available"}, d.Timeout(schema.TimeoutUpdate), 5*time.Second, vpcService.NetworkAclStateRefreshFunc(d.Id(), []string{})) if _, err := stateConf.WaitForState(); err != nil { return errmsgs.WrapErrorf(err, errmsgs.IdMsg, d.Id()) } } } return nil } func resourceAlibabacloudStackNetworkAclDelete(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AlibabacloudStackClient) vpcService := VpcService{client} // Delete binging resources before delete the ACL _, err := vpcService.DeleteAclResources(d.Id()) if err != nil { return errmsgs.WrapError(err) } action := "DeleteNetworkAcl" request := map[string]interface{}{ "NetworkAclId": d.Id(), } request["ClientToken"] = buildClientToken("DeleteNetworkAcl") _, err = client.DoTeaRequest("POST", "Vpc", "2016-04-28", action, "", nil, nil, request) if err != nil { return err } stateConf := BuildStateConf([]string{}, []string{}, d.Timeout(schema.TimeoutDelete), 5*time.Second, vpcService.NetworkAclStateRefreshFunc(d.Id(), []string{})) if _, err := stateConf.WaitForState(); err != nil { return errmsgs.WrapErrorf(err, errmsgs.IdMsg, d.Id()) } return nil }