@@ -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
533572func 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