11package vcd
22
33import (
4- "bytes"
54 "fmt"
6- "github.com/hashicorp/terraform/helper/hashcode"
75 "github.com/hashicorp/terraform/helper/schema"
86 "github.com/hmrc/vmware-govcd"
97 types "github.com/hmrc/vmware-govcd/types/v56"
8+ "log"
109 "strings"
1110)
1211
@@ -30,7 +29,7 @@ func resourceVcdFirewallRules() *schema.Resource {
3029 },
3130
3231 "rule" : & schema.Schema {
33- Type : schema .TypeSet ,
32+ Type : schema .TypeList ,
3433 Optional : true ,
3534 ForceNew : true ,
3635 Elem : & schema.Resource {
@@ -77,29 +76,30 @@ func resourceVcdFirewallRules() *schema.Resource {
7776 },
7877 },
7978 },
80- Set : resourceVcdNetworkFirewallRuleHash ,
8179 },
8280 },
8381 }
8482}
8583
8684func resourceVcdFirewallRulesCreate (d * schema.ResourceData , meta interface {}) error {
87- vcd_client := meta .(* govcd.VCDClient )
88- vcd_client .Mutex .Lock ()
89- defer vcd_client .Mutex .Unlock ()
85+ vcdClient := meta .(* govcd.VCDClient )
86+ vcdClient .Mutex .Lock ()
87+ defer vcdClient .Mutex .Unlock ()
9088
91- edgeGateway , err := vcd_client .OrgVdc .FindEdgeGateway (d .Get ("edge_gateway" ).(string ))
89+ edgeGateway , err := vcdClient .OrgVdc .FindEdgeGateway (d .Get ("edge_gateway" ).(string ))
9290 if err != nil {
9391 return fmt .Errorf ("Unable to find edge gateway: %s" , err )
9492 }
9593
9694 err = retryCall (5 , func () error {
9795 edgeGateway .Refresh ()
98- firewallRules , _ := expandFirewallRules (d . Get ( "rule" ).( * schema. Set ). List () , edgeGateway .EdgeGateway )
96+ firewallRules , _ := expandFirewallRules (d , edgeGateway .EdgeGateway )
9997 task , err := edgeGateway .CreateFirewallRules (d .Get ("default_action" ).(string ), firewallRules )
10098 if err != nil {
99+ log .Printf ("[INFO] Error setting firewall rules: %s" , err )
101100 return fmt .Errorf ("Error setting firewall rules: %#v" , err )
102101 }
102+
103103 return task .WaitTaskCompletion ()
104104 })
105105 if err != nil {
@@ -112,13 +112,13 @@ func resourceVcdFirewallRulesCreate(d *schema.ResourceData, meta interface{}) er
112112}
113113
114114func resourceFirewallRulesDelete (d * schema.ResourceData , meta interface {}) error {
115- vcd_client := meta .(* govcd.VCDClient )
116- vcd_client .Mutex .Lock ()
117- defer vcd_client .Mutex .Unlock ()
115+ vcdClient := meta .(* govcd.VCDClient )
116+ vcdClient .Mutex .Lock ()
117+ defer vcdClient .Mutex .Unlock ()
118118
119- edgeGateway , err := vcd_client .OrgVdc .FindEdgeGateway (d .Get ("edge_gateway" ).(string ))
119+ edgeGateway , err := vcdClient .OrgVdc .FindEdgeGateway (d .Get ("edge_gateway" ).(string ))
120120
121- firewallRules := deleteFirewallRules (d . Get ( "rule" ).( * schema. Set ). List () , edgeGateway .EdgeGateway )
121+ firewallRules := deleteFirewallRules (d , edgeGateway .EdgeGateway )
122122 defaultAction := edgeGateway .EdgeGateway .Configuration .EdgeGatewayServiceConfiguration .FirewallService .DefaultAction
123123 task , err := edgeGateway .CreateFirewallRules (defaultAction , firewallRules )
124124 if err != nil {
@@ -134,28 +134,42 @@ func resourceFirewallRulesDelete(d *schema.ResourceData, meta interface{}) error
134134}
135135
136136func resourceFirewallRulesRead (d * schema.ResourceData , meta interface {}) error {
137- vcd_client := meta .(* govcd.VCDClient )
137+ vcdClient := meta .(* govcd.VCDClient )
138138
139- edgeGateway , err := vcd_client .OrgVdc .FindEdgeGateway (d .Get ("edge_gateway" ).(string ))
139+ edgeGateway , err := vcdClient .OrgVdc .FindEdgeGateway (d .Get ("edge_gateway" ).(string ))
140140 if err != nil {
141141 return fmt .Errorf ("Error finding edge gateway: %#v" , err )
142142 }
143+ ruleList := d .Get ("rule" ).([]interface {})
143144 firewallRules := * edgeGateway .EdgeGateway .Configuration .EdgeGatewayServiceConfiguration .FirewallService
144- d .Set ("rule" , resourceVcdFirewallRulesGather (firewallRules .FirewallRule , d .Get ("rule" ).(* schema.Set ).List ()))
145+ rulesCount := d .Get ("rule.#" ).(int )
146+ for i := 0 ; i < rulesCount ; i ++ {
147+ prefix := fmt .Sprintf ("rule.%d" , i )
148+ if d .Get (prefix + ".id" ).(string ) == "" {
149+ log .Printf ("[INFO] Rule %d has no id. Searching..." , i )
150+ ruleid , err := matchFirewallRule (d , prefix , firewallRules .FirewallRule )
151+ if err == nil {
152+ currentRule := ruleList [i ].(map [string ]interface {})
153+ currentRule ["id" ] = ruleid
154+ ruleList [i ] = currentRule
155+ }
156+ }
157+ }
158+ d .Set ("rule" , ruleList )
145159 d .Set ("default_action" , firewallRules .DefaultAction )
146160
147161 return nil
148162}
149163
150- func deleteFirewallRules (configured [] interface {} , gateway * types.EdgeGateway ) []* types.FirewallRule {
164+ func deleteFirewallRules (d * schema. ResourceData , gateway * types.EdgeGateway ) []* types.FirewallRule {
151165 firewallRules := gateway .Configuration .EdgeGatewayServiceConfiguration .FirewallService .FirewallRule
152- fwrules := make ([]* types.FirewallRule , 0 , len (firewallRules )- len (configured ))
166+ rulesCount := d .Get ("rule.#" ).(int )
167+ fwrules := make ([]* types.FirewallRule , 0 , len (firewallRules )- rulesCount )
153168
154169 for _ , f := range firewallRules {
155170 keep := true
156- for _ , r := range configured {
157- data := r .(map [string ]interface {})
158- if data ["id" ].(string ) != f .ID {
171+ for i := 0 ; i < rulesCount ; i ++ {
172+ if d .Get (fmt .Sprintf ("rule.%d.id" , i )).(string ) != f .ID {
159173 continue
160174 }
161175 keep = false
@@ -167,75 +181,25 @@ func deleteFirewallRules(configured []interface{}, gateway *types.EdgeGateway) [
167181 return fwrules
168182}
169183
170- func resourceVcdFirewallRulesGather (rules []* types.FirewallRule , configured []interface {}) []map [string ]interface {} {
171- fwrules := make ([]map [string ]interface {}, 0 , len (configured ))
172-
173- for i := len (configured ) - 1 ; i >= 0 ; i -- {
174- data := configured [i ].(map [string ]interface {})
175- rule , err := matchFirewallRule (data , rules )
176- if err != nil {
177- continue
178- }
179- fwrules = append (fwrules , rule )
180- }
181- return fwrules
182- }
184+ func matchFirewallRule (d * schema.ResourceData , prefix string , rules []* types.FirewallRule ) (string , error ) {
183185
184- func matchFirewallRule (data map [string ]interface {}, rules []* types.FirewallRule ) (map [string ]interface {}, error ) {
185- rule := make (map [string ]interface {})
186186 for _ , m := range rules {
187- if data ["id" ].(string ) == "" {
188- if data ["description" ].(string ) == m .Description &&
189- data ["policy" ].(string ) == m .Policy &&
190- data ["protocol" ].(string ) == getProtocol (* m .Protocols ) &&
191- data ["destination_port" ].(string ) == getPortString (m .Port ) &&
192- strings .ToLower (data ["destination_ip" ].(string )) == strings .ToLower (m .DestinationIP ) &&
193- data ["source_port" ].(string ) == getPortString (m .SourcePort ) &&
194- strings .ToLower (data ["source_ip" ].(string )) == strings .ToLower (m .SourceIP ) {
195- rule ["id" ] = m .ID
196- rule ["description" ] = m .Description
197- rule ["policy" ] = m .Policy
198- rule ["protocol" ] = getProtocol (* m .Protocols )
199- rule ["destination_port" ] = getPortString (m .Port )
200- rule ["destination_ip" ] = strings .ToLower (m .DestinationIP )
201- rule ["source_port" ] = getPortString (m .SourcePort )
202- rule ["source_ip" ] = strings .ToLower (m .SourceIP )
203- return rule , nil
204- }
205- } else {
206- if data ["id" ].(string ) == m .ID {
207- rule ["id" ] = m .ID
208- rule ["description" ] = m .Description
209- rule ["policy" ] = m .Policy
210- rule ["protocol" ] = getProtocol (* m .Protocols )
211- rule ["destination_port" ] = getPortString (m .Port )
212- rule ["destination_ip" ] = strings .ToLower (m .DestinationIP )
213- rule ["source_port" ] = getPortString (m .SourcePort )
214- rule ["source_ip" ] = strings .ToLower (m .SourceIP )
215- return rule , nil
216- }
187+ log .Printf ("[INFO] %s - %s" , d .Get (prefix + ".description" ).(string ), m .Description )
188+ log .Printf ("[INFO] %s - %s" , d .Get (prefix + ".policy" ).(string ), m .Policy )
189+ log .Printf ("[INFO] %s - %s" , d .Get (prefix + ".protocol" ).(string ), getProtocol (* m .Protocols ))
190+ log .Printf ("[INFO] %s - %s" , d .Get (prefix + ".destination_port" ).(string ), getPortString (m .Port ))
191+ log .Printf ("[INFO] %s - %s" , strings .ToLower (d .Get (prefix + ".destination_ip" ).(string )), strings .ToLower (m .DestinationIP ))
192+ log .Printf ("[INFO] %s - %s" , d .Get (prefix + ".source_port" ).(string ), getPortString (m .SourcePort ))
193+ log .Printf ("[INFO] %s - %s" , strings .ToLower (d .Get (prefix + ".source_ip" ).(string )), strings .ToLower (m .SourceIP ))
194+ if d .Get (prefix + ".description" ).(string ) == m .Description &&
195+ d .Get (prefix + ".policy" ).(string ) == m .Policy &&
196+ strings .ToLower (d .Get (prefix + ".protocol" ).(string )) == getProtocol (* m .Protocols ) &&
197+ strings .ToLower (d .Get (prefix + ".destination_port" ).(string )) == getPortString (m .Port ) &&
198+ strings .ToLower (d .Get (prefix + ".destination_ip" ).(string )) == strings .ToLower (m .DestinationIP ) &&
199+ strings .ToLower (d .Get (prefix + ".source_port" ).(string )) == getPortString (m .SourcePort ) &&
200+ strings .ToLower (d .Get (prefix + ".source_ip" ).(string )) == strings .ToLower (m .SourceIP ) {
201+ return m .ID , nil
217202 }
218203 }
219- return rule , fmt .Errorf ("Unable to find rule" )
220- }
221-
222- func resourceVcdNetworkFirewallRuleHash (v interface {}) int {
223- var buf bytes.Buffer
224- m := v .(map [string ]interface {})
225- buf .WriteString (fmt .Sprintf ("%s-" ,
226- strings .ToLower (m ["description" ].(string ))))
227- buf .WriteString (fmt .Sprintf ("%s-" ,
228- strings .ToLower (m ["policy" ].(string ))))
229- buf .WriteString (fmt .Sprintf ("%s-" ,
230- strings .ToLower (m ["protocol" ].(string ))))
231- buf .WriteString (fmt .Sprintf ("%s-" ,
232- strings .ToLower (m ["destination_port" ].(string ))))
233- buf .WriteString (fmt .Sprintf ("%s-" ,
234- strings .ToLower (m ["destination_ip" ].(string ))))
235- buf .WriteString (fmt .Sprintf ("%s-" ,
236- strings .ToLower (m ["source_port" ].(string ))))
237- buf .WriteString (fmt .Sprintf ("%s-" ,
238- strings .ToLower (m ["source_ip" ].(string ))))
239-
240- return hashcode .String (buf .String ())
204+ return "" , fmt .Errorf ("Unable to find rule" )
241205}
0 commit comments