Fix resource egress rule to accept protocol type ALL
diff --git a/cloudstack/resource_cloudstack_egress_firewall.go b/cloudstack/resource_cloudstack_egress_firewall.go
index bc44cc6..5994cdd 100644
--- a/cloudstack/resource_cloudstack_egress_firewall.go
+++ b/cloudstack/resource_cloudstack_egress_firewall.go
@@ -58,7 +58,7 @@
Schema: map[string]*schema.Schema{
"cidr_list": {
Type: schema.TypeSet,
- Required: true,
+ Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},
@@ -180,10 +180,12 @@
// Set the CIDR list
var cidrList []string
- for _, cidr := range rule["cidr_list"].(*schema.Set).List() {
- cidrList = append(cidrList, cidr.(string))
+ if rs := rule["cidr_list"].(*schema.Set); rs.Len() > 0 {
+ for _, cidr := range rule["cidr_list"].(*schema.Set).List() {
+ cidrList = append(cidrList, cidr.(string))
+ }
+ p.SetCidrlist(cidrList)
}
- p.SetCidrlist(cidrList)
// If the protocol is ICMP set the needed ICMP parameters
if rule["protocol"].(string) == "icmp" {
@@ -198,8 +200,8 @@
rule["uuids"] = uuids
}
- // If protocol is not ICMP, loop through all ports
- if rule["protocol"].(string) != "icmp" {
+ // If protocol is not ICMP and not ALL, loop through all ports
+ if rule["protocol"].(string) != "icmp" && strings.ToLower(rule["protocol"].(string)) != "all" {
if ps := rule["ports"].(*schema.Set); ps.Len() > 0 {
// Create an empty schema.Set to hold all processed ports
@@ -244,6 +246,14 @@
}
}
+ if strings.ToLower(rule["protocol"].(string)) == "all" {
+ r, err := cs.Firewall.CreateEgressFirewallRule(p)
+ if err != nil {
+ return err
+ }
+ uuids["all"] = r.Id
+ rule["uuids"] = uuids
+ }
return nil
}
@@ -306,7 +316,7 @@
}
// If protocol is not ICMP, loop through all ports
- if rule["protocol"].(string) != "icmp" {
+ if rule["protocol"].(string) != "icmp" && strings.ToLower(rule["protocol"].(string)) != "all" {
if ps := rule["ports"].(*schema.Set); ps.Len() > 0 {
// Create an empty schema.Set to hold all ports
@@ -348,6 +358,35 @@
}
}
}
+ if strings.ToLower(rule["protocol"].(string)) == "all" {
+ id, ok := uuids["all"]
+ if !ok {
+ continue
+ }
+
+ // Get the rule
+ r, ok := ruleMap[id.(string)]
+ if !ok {
+ delete(uuids, "all")
+ continue
+ }
+
+ // Delete the known rule so only unknown rules remain in the ruleMap
+ delete(ruleMap, id.(string))
+
+ // Create a set with all CIDR's
+ if _, ok := rule["cidr_list"]; ok {
+ cidrs := &schema.Set{F: schema.HashString}
+ for _, cidr := range strings.Split(r.Cidrlist, ",") {
+ cidrs.Add(cidr)
+ }
+ rule["cidr_list"] = cidrs
+ }
+
+ // Update the values
+ rule["protocol"] = r.Protocol
+ rules.Add(rule)
+ }
}
}
@@ -532,9 +571,9 @@
func verifyEgressFirewallRuleParams(d *schema.ResourceData, rule map[string]interface{}) error {
protocol := rule["protocol"].(string)
- if protocol != "tcp" && protocol != "udp" && protocol != "icmp" {
+ if strings.ToLower(protocol) != "all" && protocol != "tcp" && protocol != "udp" && protocol != "icmp" {
return fmt.Errorf(
- "%q is not a valid protocol. Valid options are 'tcp', 'udp' and 'icmp'", protocol)
+ "%q is not a valid protocol. Valid options are 'ALL', 'tcp', 'udp' and 'icmp'", protocol)
}
if protocol == "icmp" {
@@ -546,7 +585,7 @@
return fmt.Errorf(
"Parameter icmp_code is a required parameter when using protocol 'icmp'")
}
- } else {
+ } else if strings.ToLower(protocol) != "all" {
if ports, ok := rule["ports"].(*schema.Set); ok {
for _, port := range ports.List() {
m := splitPorts.FindStringSubmatch(port.(string))
@@ -559,6 +598,11 @@
return fmt.Errorf(
"Parameter ports is a required parameter when *not* using protocol 'icmp'")
}
+ } else if strings.ToLower(protocol) == "all" {
+ if ports, _ := rule["ports"].(*schema.Set); ports.Len() > 0 {
+ return fmt.Errorf(
+ "Parameter ports is not required when using protocol 'ALL'")
+ }
}
return nil