diff --git a/cloudstack/resource_cloudstack_security_group_rule.go b/cloudstack/resource_cloudstack_security_group_rule.go index a1b21dd6..3056991e 100644 --- a/cloudstack/resource_cloudstack_security_group_rule.go +++ b/cloudstack/resource_cloudstack_security_group_rule.go @@ -247,6 +247,16 @@ func createSecurityGroupRule(d *schema.ResourceData, meta interface{}, rule map[ // Set the protocol p.SetProtocol(rule["protocol"].(string)) + if rule["protocol"].(string) == "all" { + ruleID, err := createIngressOrEgressRule(cs, p) + if err != nil { + return err + } + + uuids[uuid+"all"] = ruleID + rule["uuids"] = uuids + } + // If the protocol is ICMP set the needed ICMP parameters if rule["protocol"].(string) == "icmp" { p.SetIcmptype(rule["icmp_type"].(int)) @@ -393,6 +403,32 @@ func readSecurityGroupRule(sg *cloudstack.SecurityGroup, ruleIndex map[string]in uuids := rule["uuids"].(map[string]interface{}) sgRules := append(sg.Ingressrule, sg.Egressrule...) + if rule["protocol"].(string) == "all" { + id, ok := uuids[uuid+"all"] + if !ok { + return + } + + // Get the rule + idx, ok := ruleIndex[id.(string)] + if !ok { + return + } + + r := sgRules[idx] + + // Update the values + if r.Cidr != "" { + rule["cidr_list"].(*schema.Set).Add(r.Cidr) + } + + if r.Securitygroupname != "" { + rule["user_security_group_list"].(*schema.Set).Add(r.Securitygroupname) + } + + rule["protocol"] = r.Protocol + } + if rule["protocol"].(string) == "icmp" { id, ok := uuids[uuid+"icmp"] if !ok { @@ -610,6 +646,8 @@ func verifySecurityGroupRuleParams(d *schema.ResourceData, rule map[string]inter protocol := rule["protocol"].(string) switch protocol { + case "all": + break case "icmp": if _, ok := rule["icmp_type"]; !ok { return fmt.Errorf( diff --git a/cloudstack/resource_cloudstack_security_group_rule_test.go b/cloudstack/resource_cloudstack_security_group_rule_test.go index 804a4a80..223f736b 100644 --- a/cloudstack/resource_cloudstack_security_group_rule_test.go +++ b/cloudstack/resource_cloudstack_security_group_rule_test.go @@ -40,27 +40,33 @@ func TestAccCloudStackSecurityGroupRule_basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckCloudStackSecurityGroupRulesExist("cloudstack_security_group.foo"), resource.TestCheckResourceAttr( - "cloudstack_security_group_rule.foo", "rule.#", "2"), + "cloudstack_security_group_rule.foo", "rule.#", "3"), resource.TestCheckResourceAttr( - "cloudstack_security_group_rule.foo", "rule.0.cidr_list.0", "172.18.100.0/24"), + "cloudstack_security_group_rule.foo", "rule.0.protocol", "all"), resource.TestCheckResourceAttr( - "cloudstack_security_group_rule.foo", "rule.0.protocol", "tcp"), + "cloudstack_security_group_rule.foo", "rule.0.cidr_list.0", "172.0.0.0/8"), resource.TestCheckResourceAttr( - "cloudstack_security_group_rule.foo", "rule.0.ports.#", "1"), + "cloudstack_security_group_rule.foo", "rule.0.traffic_type", "egress"), resource.TestCheckResourceAttr( - "cloudstack_security_group_rule.foo", "rule.0.ports.0", "80"), - resource.TestCheckResourceAttr( - "cloudstack_security_group_rule.foo", "rule.0.traffic_type", "ingress"), + "cloudstack_security_group_rule.foo", "rule.1.cidr_list.0", "172.18.100.0/24"), resource.TestCheckResourceAttr( "cloudstack_security_group_rule.foo", "rule.1.protocol", "tcp"), resource.TestCheckResourceAttr( - "cloudstack_security_group_rule.foo", "rule.1.ports.1", "80"), + "cloudstack_security_group_rule.foo", "rule.1.ports.#", "1"), + resource.TestCheckResourceAttr( + "cloudstack_security_group_rule.foo", "rule.1.ports.0", "80"), + resource.TestCheckResourceAttr( + "cloudstack_security_group_rule.foo", "rule.1.traffic_type", "ingress"), + resource.TestCheckResourceAttr( + "cloudstack_security_group_rule.foo", "rule.2.protocol", "tcp"), + resource.TestCheckResourceAttr( + "cloudstack_security_group_rule.foo", "rule.2.ports.1", "80"), resource.TestCheckResourceAttr( - "cloudstack_security_group_rule.foo", "rule.1.ports.0", "443"), + "cloudstack_security_group_rule.foo", "rule.2.ports.0", "443"), resource.TestCheckResourceAttr( - "cloudstack_security_group_rule.foo", "rule.1.traffic_type", "egress"), + "cloudstack_security_group_rule.foo", "rule.2.traffic_type", "egress"), resource.TestCheckResourceAttr( - "cloudstack_security_group_rule.foo", "rule.1.user_security_group_list.0", "terraform-security-group-bar"), + "cloudstack_security_group_rule.foo", "rule.2.user_security_group_list.0", "terraform-security-group-bar"), ), }, }, @@ -78,27 +84,33 @@ func TestAccCloudStackSecurityGroupRule_update(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckCloudStackSecurityGroupRulesExist("cloudstack_security_group.foo"), resource.TestCheckResourceAttr( - "cloudstack_security_group_rule.foo", "rule.#", "2"), - resource.TestCheckResourceAttr( - "cloudstack_security_group_rule.foo", "rule.0.cidr_list.0", "172.18.100.0/24"), + "cloudstack_security_group_rule.foo", "rule.#", "3"), resource.TestCheckResourceAttr( - "cloudstack_security_group_rule.foo", "rule.0.protocol", "tcp"), + "cloudstack_security_group_rule.foo", "rule.0.protocol", "all"), resource.TestCheckResourceAttr( - "cloudstack_security_group_rule.foo", "rule.0.ports.#", "1"), + "cloudstack_security_group_rule.foo", "rule.0.cidr_list.0", "172.0.0.0/8"), resource.TestCheckResourceAttr( - "cloudstack_security_group_rule.foo", "rule.0.ports.0", "80"), + "cloudstack_security_group_rule.foo", "rule.0.traffic_type", "egress"), resource.TestCheckResourceAttr( - "cloudstack_security_group_rule.foo", "rule.0.traffic_type", "ingress"), + "cloudstack_security_group_rule.foo", "rule.1.cidr_list.0", "172.18.100.0/24"), resource.TestCheckResourceAttr( "cloudstack_security_group_rule.foo", "rule.1.protocol", "tcp"), resource.TestCheckResourceAttr( - "cloudstack_security_group_rule.foo", "rule.1.ports.1", "80"), + "cloudstack_security_group_rule.foo", "rule.1.ports.#", "1"), + resource.TestCheckResourceAttr( + "cloudstack_security_group_rule.foo", "rule.1.ports.0", "80"), + resource.TestCheckResourceAttr( + "cloudstack_security_group_rule.foo", "rule.1.traffic_type", "ingress"), + resource.TestCheckResourceAttr( + "cloudstack_security_group_rule.foo", "rule.2.protocol", "tcp"), + resource.TestCheckResourceAttr( + "cloudstack_security_group_rule.foo", "rule.2.ports.1", "80"), resource.TestCheckResourceAttr( - "cloudstack_security_group_rule.foo", "rule.1.ports.0", "443"), + "cloudstack_security_group_rule.foo", "rule.2.ports.0", "443"), resource.TestCheckResourceAttr( - "cloudstack_security_group_rule.foo", "rule.1.traffic_type", "egress"), + "cloudstack_security_group_rule.foo", "rule.2.traffic_type", "egress"), resource.TestCheckResourceAttr( - "cloudstack_security_group_rule.foo", "rule.1.user_security_group_list.0", "terraform-security-group-bar"), + "cloudstack_security_group_rule.foo", "rule.2.user_security_group_list.0", "terraform-security-group-bar"), ), }, @@ -107,7 +119,7 @@ func TestAccCloudStackSecurityGroupRule_update(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckCloudStackSecurityGroupRulesExist("cloudstack_security_group.foo"), resource.TestCheckResourceAttr( - "cloudstack_security_group_rule.foo", "rule.#", "3"), + "cloudstack_security_group_rule.foo", "rule.#", "4"), resource.TestCheckResourceAttr( "cloudstack_security_group_rule.foo", "rule.0.cidr_list.0", "172.18.100.0/24"), resource.TestCheckResourceAttr( @@ -127,15 +139,23 @@ func TestAccCloudStackSecurityGroupRule_update(t *testing.T) { resource.TestCheckResourceAttr( "cloudstack_security_group_rule.foo", "rule.1.icmp_type", "-1"), resource.TestCheckResourceAttr( - "cloudstack_security_group_rule.foo", "rule.2.protocol", "tcp"), + "cloudstack_security_group_rule.foo", "rule.2.protocol", "all"), resource.TestCheckResourceAttr( - "cloudstack_security_group_rule.foo", "rule.2.ports.#", "1"), + "cloudstack_security_group_rule.foo", "rule.2.cidr_list.0", "172.20.100.0/24"), resource.TestCheckResourceAttr( - "cloudstack_security_group_rule.foo", "rule.2.ports.0", "80"), + "cloudstack_security_group_rule.foo", "rule.2.cidr_list.1", "192.168.0.0/32"), resource.TestCheckResourceAttr( - "cloudstack_security_group_rule.foo", "rule.2.traffic_type", "egress"), + "cloudstack_security_group_rule.foo", "rule.2.traffic_type", "ingress"), resource.TestCheckResourceAttr( - "cloudstack_security_group_rule.foo", "rule.2.user_security_group_list.0", "terraform-security-group-bar"), + "cloudstack_security_group_rule.foo", "rule.3.protocol", "tcp"), + resource.TestCheckResourceAttr( + "cloudstack_security_group_rule.foo", "rule.3.ports.#", "1"), + resource.TestCheckResourceAttr( + "cloudstack_security_group_rule.foo", "rule.3.ports.0", "80"), + resource.TestCheckResourceAttr( + "cloudstack_security_group_rule.foo", "rule.3.traffic_type", "egress"), + resource.TestCheckResourceAttr( + "cloudstack_security_group_rule.foo", "rule.3.user_security_group_list.0", "terraform-security-group-bar"), ), }, }, @@ -238,6 +258,12 @@ resource "cloudstack_security_group" "bar" { resource "cloudstack_security_group_rule" "foo" { security_group_id = cloudstack_security_group.foo.id + rule { + protocol = "all" + cidr_list = ["172.0.0.0/8"] + traffic_type = "egress" + } + rule { cidr_list = ["172.18.100.0/24"] protocol = "tcp" @@ -268,6 +294,12 @@ resource "cloudstack_security_group" "bar" { resource "cloudstack_security_group_rule" "foo" { security_group_id = cloudstack_security_group.foo.id + rule { + protocol = "all" + cidr_list = ["172.20.100.0/24", "192.168.0.0/32"] + traffic_type = "ingress" + } + rule { cidr_list = ["172.18.100.0/24", "172.18.200.0/24"] protocol = "tcp"