Skip to content

Commit 216679d

Browse files
Fix resource egress rule to accept protocol type ALL (#8)
1 parent 7b05815 commit 216679d

File tree

1 file changed

+54
-10
lines changed

1 file changed

+54
-10
lines changed

cloudstack/resource_cloudstack_egress_firewall.go

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ func resourceCloudStackEgressFirewall() *schema.Resource {
5858
Schema: map[string]*schema.Schema{
5959
"cidr_list": {
6060
Type: schema.TypeSet,
61-
Required: true,
61+
Optional: true,
6262
Elem: &schema.Schema{Type: schema.TypeString},
6363
Set: schema.HashString,
6464
},
@@ -180,10 +180,12 @@ func createEgressFirewallRule(d *schema.ResourceData, meta interface{}, rule map
180180

181181
// Set the CIDR list
182182
var cidrList []string
183-
for _, cidr := range rule["cidr_list"].(*schema.Set).List() {
184-
cidrList = append(cidrList, cidr.(string))
183+
if rs := rule["cidr_list"].(*schema.Set); rs.Len() > 0 {
184+
for _, cidr := range rule["cidr_list"].(*schema.Set).List() {
185+
cidrList = append(cidrList, cidr.(string))
186+
}
187+
p.SetCidrlist(cidrList)
185188
}
186-
p.SetCidrlist(cidrList)
187189

188190
// If the protocol is ICMP set the needed ICMP parameters
189191
if rule["protocol"].(string) == "icmp" {
@@ -198,8 +200,8 @@ func createEgressFirewallRule(d *schema.ResourceData, meta interface{}, rule map
198200
rule["uuids"] = uuids
199201
}
200202

201-
// If protocol is not ICMP, loop through all ports
202-
if rule["protocol"].(string) != "icmp" {
203+
// If protocol is not ICMP and not ALL, loop through all ports
204+
if rule["protocol"].(string) != "icmp" && strings.ToLower(rule["protocol"].(string)) != "all" {
203205
if ps := rule["ports"].(*schema.Set); ps.Len() > 0 {
204206

205207
// Create an empty schema.Set to hold all processed ports
@@ -244,6 +246,14 @@ func createEgressFirewallRule(d *schema.ResourceData, meta interface{}, rule map
244246
}
245247
}
246248

249+
if strings.ToLower(rule["protocol"].(string)) == "all" {
250+
r, err := cs.Firewall.CreateEgressFirewallRule(p)
251+
if err != nil {
252+
return err
253+
}
254+
uuids["all"] = r.Id
255+
rule["uuids"] = uuids
256+
}
247257
return nil
248258
}
249259

@@ -306,7 +316,7 @@ func resourceCloudStackEgressFirewallRead(d *schema.ResourceData, meta interface
306316
}
307317

308318
// If protocol is not ICMP, loop through all ports
309-
if rule["protocol"].(string) != "icmp" {
319+
if rule["protocol"].(string) != "icmp" && strings.ToLower(rule["protocol"].(string)) != "all" {
310320
if ps := rule["ports"].(*schema.Set); ps.Len() > 0 {
311321

312322
// Create an empty schema.Set to hold all ports
@@ -348,6 +358,35 @@ func resourceCloudStackEgressFirewallRead(d *schema.ResourceData, meta interface
348358
}
349359
}
350360
}
361+
if strings.ToLower(rule["protocol"].(string)) == "all" {
362+
id, ok := uuids["all"]
363+
if !ok {
364+
continue
365+
}
366+
367+
// Get the rule
368+
r, ok := ruleMap[id.(string)]
369+
if !ok {
370+
delete(uuids, "all")
371+
continue
372+
}
373+
374+
// Delete the known rule so only unknown rules remain in the ruleMap
375+
delete(ruleMap, id.(string))
376+
377+
// Create a set with all CIDR's
378+
if _, ok := rule["cidr_list"]; ok {
379+
cidrs := &schema.Set{F: schema.HashString}
380+
for _, cidr := range strings.Split(r.Cidrlist, ",") {
381+
cidrs.Add(cidr)
382+
}
383+
rule["cidr_list"] = cidrs
384+
}
385+
386+
// Update the values
387+
rule["protocol"] = r.Protocol
388+
rules.Add(rule)
389+
}
351390
}
352391
}
353392

@@ -532,9 +571,9 @@ func verifyEgressFirewallParams(d *schema.ResourceData) error {
532571

533572
func verifyEgressFirewallRuleParams(d *schema.ResourceData, rule map[string]interface{}) error {
534573
protocol := rule["protocol"].(string)
535-
if protocol != "tcp" && protocol != "udp" && protocol != "icmp" {
574+
if strings.ToLower(protocol) != "all" && protocol != "tcp" && protocol != "udp" && protocol != "icmp" {
536575
return fmt.Errorf(
537-
"%q is not a valid protocol. Valid options are 'tcp', 'udp' and 'icmp'", protocol)
576+
"%q is not a valid protocol. Valid options are 'ALL', 'tcp', 'udp' and 'icmp'", protocol)
538577
}
539578

540579
if protocol == "icmp" {
@@ -546,7 +585,7 @@ func verifyEgressFirewallRuleParams(d *schema.ResourceData, rule map[string]inte
546585
return fmt.Errorf(
547586
"Parameter icmp_code is a required parameter when using protocol 'icmp'")
548587
}
549-
} else {
588+
} else if strings.ToLower(protocol) != "all" {
550589
if ports, ok := rule["ports"].(*schema.Set); ok {
551590
for _, port := range ports.List() {
552591
m := splitPorts.FindStringSubmatch(port.(string))
@@ -559,6 +598,11 @@ func verifyEgressFirewallRuleParams(d *schema.ResourceData, rule map[string]inte
559598
return fmt.Errorf(
560599
"Parameter ports is a required parameter when *not* using protocol 'icmp'")
561600
}
601+
} else if strings.ToLower(protocol) == "all" {
602+
if ports, _ := rule["ports"].(*schema.Set); ports.Len() > 0 {
603+
return fmt.Errorf(
604+
"Parameter ports is not required when using protocol 'ALL'")
605+
}
562606
}
563607

564608
return nil

0 commit comments

Comments
 (0)