summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2017-06-18 11:15:17 +0000
committerGerrit Code Review <review@openstack.org>2017-06-18 11:15:17 +0000
commit753c72ed55199022d2c5e10a745dc7aee8c3e68f (patch)
tree98213824de321f3a373c148ca3a91bf5a0168619
parent03635768e02eb6437eae3ba02b96f85a4ea7dc18 (diff)
parent41fb262771090f30079c77ddf31e32faa25b37d0 (diff)
Merge "NSX|v: refactor FWaaS driver"
-rw-r--r--vmware_nsx/plugins/nsx_v/plugin.py57
-rw-r--r--vmware_nsx/services/fwaas/nsx_v/edge_fwaas_driver.py162
-rw-r--r--vmware_nsx/tests/unit/nsx_v/test_fwaas_driver.py118
3 files changed, 157 insertions, 180 deletions
diff --git a/vmware_nsx/plugins/nsx_v/plugin.py b/vmware_nsx/plugins/nsx_v/plugin.py
index dd527a5..b89e907 100644
--- a/vmware_nsx/plugins/nsx_v/plugin.py
+++ b/vmware_nsx/plugins/nsx_v/plugin.py
@@ -3593,18 +3593,47 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
3593 if router_id: 3593 if router_id:
3594 self._update_edge_router(context, router_id) 3594 self._update_edge_router(context, router_id)
3595 3595
3596 def _update_subnets_and_dnat_firewall(self, context, router, 3596 def _update_subnets_and_dnat_firewall(self, context, router_db,
3597 router_id=None): 3597 router_id=None):
3598 # Note(asarfaty): If changing the order or names of rules here, 3598 """Update the router edge firewall with all the relevant rules.
3599 # please take care of fwaas _get_other_backend_rules too. 3599
3600 fw_rules = [] 3600 router_db is the neutron router structure
3601 router_id is the id of the actual router that will be updated on
3602 the NSX (in case of distributed router it can be plr or tlr)
3603 """
3601 if not router_id: 3604 if not router_id:
3602 router_id = router['id'] 3605 router_id = router_db['id']
3606
3607 # Add fw rules if FWaaS is enabled
3608 # in case of a distributed-router:
3609 # router['id'] is the id of the neutron router (=tlr)
3610 # and router_id is the plr/tlr (the one that is being updated)
3611 fwaas_rules = None
3612 if (self.fwaas_callbacks.should_apply_firewall_to_router(
3613 context, router_db, router_id)):
3614 fwaas_rules = self.fwaas_callbacks.get_fwaas_rules_for_router(
3615 context, router_db['id'])
3616
3617 self.update_router_firewall(context, router_id, router_db,
3618 fwaas_rules=fwaas_rules)
3619
3620 def update_router_firewall(self, context, router_id, router_db,
3621 fwaas_rules=None):
3622 """Recreate all rules in the router edge firewall
3623
3624 router_db is the neutron router structure
3625 router_id is the id of the actual router that will be updated on
3626 the NSX (in case of distributed router it can be plr or tlr)
3627 if fwaas_rules is not none - this router is attached to a firewall
3628 """
3629 fw_rules = []
3630 router_with_firewall = True if fwaas_rules is not None else False
3631 neutron_id = router_db['id']
3603 3632
3604 # Add FW rule to open subnets firewall flows and static routes 3633 # Add FW rule to open subnets firewall flows and static routes
3605 # relative flows 3634 # relative flows
3606 subnet_cidrs = self._find_router_subnets_cidrs(context, router['id']) 3635 subnet_cidrs = self._find_router_subnets_cidrs(context, neutron_id)
3607 routes = self._get_extra_routes_by_router_id(context, router_id) 3636 routes = self._get_extra_routes_by_router_id(context, neutron_id)
3608 subnet_cidrs.extend([route['destination'] for route in routes]) 3637 subnet_cidrs.extend([route['destination'] for route in routes])
3609 if subnet_cidrs: 3638 if subnet_cidrs:
3610 subnet_fw_rule = { 3639 subnet_fw_rule = {
@@ -3619,17 +3648,13 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
3619 if self.metadata_proxy_handler: 3648 if self.metadata_proxy_handler:
3620 fw_rules += nsx_v_md_proxy.get_router_fw_rules() 3649 fw_rules += nsx_v_md_proxy.get_router_fw_rules()
3621 3650
3622 # Add fw rules if FWaaS is enabled 3651 # Add FWaaS rules
3623 router_with_firewall = False 3652 if router_with_firewall and fwaas_rules:
3624 if (self.fwaas_callbacks.should_apply_firewall_to_router( 3653 fw_rules += fwaas_rules
3625 context, router, router_id)):
3626 fw_rules.extend(self.fwaas_callbacks.get_fwaas_rules_for_router(
3627 context, router['id']))
3628 router_with_firewall = True
3629 3654
3630 if not router_with_firewall: 3655 if not router_with_firewall:
3631 # Add FW rule to open dnat firewall flows 3656 # Add FW rule to open dnat firewall flows
3632 _, dnat_rules = self._get_nat_rules(context, router) 3657 _, dnat_rules = self._get_nat_rules(context, router_db)
3633 dnat_cidrs = [rule['dst'] for rule in dnat_rules] 3658 dnat_cidrs = [rule['dst'] for rule in dnat_rules]
3634 if dnat_cidrs: 3659 if dnat_cidrs:
3635 dnat_fw_rule = { 3660 dnat_fw_rule = {
@@ -3641,7 +3666,7 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
3641 3666
3642 # Add no-snat rules 3667 # Add no-snat rules
3643 nosnat_fw_rules = self._get_nosnat_subnets_fw_rules( 3668 nosnat_fw_rules = self._get_nosnat_subnets_fw_rules(
3644 context, router) 3669 context, router_db)
3645 fw_rules.extend(nosnat_fw_rules) 3670 fw_rules.extend(nosnat_fw_rules)
3646 3671
3647 # Get the load balancer rules in case they are refreshed 3672 # Get the load balancer rules in case they are refreshed
diff --git a/vmware_nsx/services/fwaas/nsx_v/edge_fwaas_driver.py b/vmware_nsx/services/fwaas/nsx_v/edge_fwaas_driver.py
index d31bf5f..1b5b731 100644
--- a/vmware_nsx/services/fwaas/nsx_v/edge_fwaas_driver.py
+++ b/vmware_nsx/services/fwaas/nsx_v/edge_fwaas_driver.py
@@ -22,11 +22,7 @@ from neutron_fwaas.common import exceptions
22from neutron_fwaas.services.firewall.drivers import fwaas_base 22from neutron_fwaas.services.firewall.drivers import fwaas_base
23 23
24from vmware_nsx.common import locking 24from vmware_nsx.common import locking
25from vmware_nsx.plugins.nsx_v.vshield.common import (
26 exceptions as vcns_exc)
27from vmware_nsx.plugins.nsx_v.vshield import edge_firewall_driver
28from vmware_nsx.plugins.nsx_v.vshield import edge_utils 25from vmware_nsx.plugins.nsx_v.vshield import edge_utils
29from vmware_nsx.plugins.nsx_v.vshield import vcns_driver
30 26
31LOG = logging.getLogger(__name__) 27LOG = logging.getLogger(__name__)
32FWAAS_DRIVER_NAME = 'Fwaas NSX-V driver' 28FWAAS_DRIVER_NAME = 'Fwaas NSX-V driver'
@@ -37,13 +33,16 @@ class EdgeFwaasDriver(fwaas_base.FwaasDriverBase):
37 """NSX-V driver for Firewall As A Service - V1.""" 33 """NSX-V driver for Firewall As A Service - V1."""
38 34
39 @property 35 @property
36 def core_plugin(self):
37 return directory.get_plugin()
38
39 @property
40 def edge_manager(self): 40 def edge_manager(self):
41 return directory.get_plugin().edge_manager 41 return self.core_plugin.edge_manager
42 42
43 def __init__(self): 43 def __init__(self):
44 LOG.debug("Loading FWaaS NsxVDriver.") 44 LOG.debug("Loading FWaaS NsxVDriver.")
45 super(EdgeFwaasDriver, self).__init__() 45 super(EdgeFwaasDriver, self).__init__()
46 self._nsxv = vcns_driver.VcnsDriver(None)
47 46
48 def should_apply_firewall_to_router(self, router_data): 47 def should_apply_firewall_to_router(self, router_data):
49 """Return True if the firewall rules should be added the router 48 """Return True if the firewall rules should be added the router
@@ -81,7 +80,7 @@ class EdgeFwaasDriver(fwaas_base.FwaasDriverBase):
81 # Get edges for all the routers in the apply list. 80 # Get edges for all the routers in the apply list.
82 # note that shared routers are currently not supported 81 # note that shared routers are currently not supported
83 edge_manager = self.edge_manager 82 edge_manager = self.edge_manager
84 edges = [] 83 edges_map = {}
85 for router_info in apply_list: 84 for router_info in apply_list:
86 85
87 # No FWaaS rules needed if there is no external gateway 86 # No FWaaS rules needed if there is no external gateway
@@ -102,8 +101,9 @@ class EdgeFwaasDriver(fwaas_base.FwaasDriverBase):
102 # look for the edge id in the DB 101 # look for the edge id in the DB
103 edge_id = edge_utils.get_router_edge_id(context, lookup_id) 102 edge_id = edge_utils.get_router_edge_id(context, lookup_id)
104 if edge_id: 103 if edge_id:
105 edges.append(edge_id) 104 edges_map[router_id] = {'edge_id': edge_id,
106 return edges 105 'lookup_id': lookup_id}
106 return edges_map
107 107
108 def _translate_rules(self, fwaas_rules): 108 def _translate_rules(self, fwaas_rules):
109 translated_rules = [] 109 translated_rules = []
@@ -128,91 +128,29 @@ class EdgeFwaasDriver(fwaas_base.FwaasDriverBase):
128 128
129 return translated_rules 129 return translated_rules
130 130
131 def _is_allow_external_rule(self, rule): 131 def _set_rules_on_router_edge(self, context, router_id, neutron_id,
132 rule_name = rule.get('name', '') 132 edge_id, fw_id, translated_rules,
133 if rule_name == edge_firewall_driver.FWAAS_ALLOW_EXT_RULE_NAME: 133 delete_fw=False):
134 return True 134 """Recreate router edge firewall rules
135 # For older routers, the allow-external rule didn't have a name 135
136 # TODO(asarfaty): delete this in the future 136 Using the plugin code to recreate all the rules with the additional
137 if (not rule_name and
138 rule.get('action') == edge_firewall_driver.FWAAS_ALLOW and
139 rule.get('destination_vnic_groups', []) == ['external']):
140 return True
141 return False
142
143 def _get_other_backend_rules(self, context, edge_id):
144 """Get a list of current backend rules from other applications
145
146 Those rules should stay on the backend firewall, when updating the
147 FWaaS rules. 137 FWaaS rules.
148 138
149 Return it as 2 separate lists of rules, which should go before/after 139 router_id is the is of the router about to be updated
150 the fwaas rules. 140 (in case of distributed router - the plr)
141 neutron_id is the neutron router id
151 """ 142 """
152 try:
153 backend_fw = self._nsxv.get_firewall(context, edge_id)
154 backend_rules = backend_fw['firewall_rule_list']
155 except vcns_exc.VcnsApiException:
156 # Need to create a new one
157 backend_rules = []
158 # remove old FWaaS rules from the rules list.
159 # also delete the allow-external rule, if it is there.
160 # If necessary - we will add it again later
161 before_rules = []
162 after_rules = []
163 go_after = False
164 for rule_item in backend_rules:
165 rule = rule_item['firewall_rule']
166 rule_name = rule.get('name', '')
167 fwaas_rule = rule_name.startswith(RULE_NAME_PREFIX)
168 if fwaas_rule:
169 # reached the fwaas part, the rest of the rules should be
170 # in the 'after' list
171 go_after = True
172 if (rule_name == edge_firewall_driver.DNAT_RULE_NAME or
173 rule_name == edge_firewall_driver.NO_SNAT_RULE_NAME):
174 # passed the fwaas part, the rest of the rules should be
175 # in the 'after' list
176 go_after = True
177 if (not fwaas_rule and
178 not self._is_allow_external_rule(rule)):
179 if go_after:
180 after_rules.append(rule)
181 else:
182 before_rules.append(rule)
183
184 return before_rules, after_rules
185
186 def _set_rules_on_edge(self, context, edge_id, fw_id, translated_rules,
187 allow_external=False):
188 """delete old FWaaS rules from the Edge, and add new ones
189
190 Note that the edge might have other FW rules like NAT or LBaas
191 that should remain there.
192
193 allow_external is usually False because it shouldn't exist with a
194 firewall. It should only be True when the firewall is being deleted.
195 """
196 # Get the existing backend rules which do not belong to FWaaS
197 backend_rules, after_rules = self._get_other_backend_rules(
198 context, edge_id)
199
200 # add new FWaaS rules at the correct location by their original order
201 backend_rules.extend(translated_rules)
202 backend_rules.extend(after_rules)
203
204 # update the backend 143 # update the backend
144 router_db = self.core_plugin._get_router(context, neutron_id)
205 try: 145 try:
206 with locking.LockManager.get_lock(str(edge_id)): 146 with locking.LockManager.get_lock(str(edge_id)):
207 self._nsxv.update_firewall( 147 self.core_plugin.update_router_firewall(
208 edge_id, 148 context, router_id, router_db,
209 {'firewall_rule_list': backend_rules}, 149 fwaas_rules=translated_rules)
210 context,
211 allow_external=allow_external)
212 except Exception as e: 150 except Exception as e:
213 # catch known library exceptions and raise Fwaas generic exception 151 # catch known library exceptions and raise Fwaas generic exception
214 LOG.error("Failed to update backend firewall %(fw)s: " 152 LOG.error("Failed to update firewall %(fw)s on edge %(edge_id)s: "
215 "%(e)s", {'e': e, 'fw': fw_id}) 153 "%(e)s", {'e': e, 'fw': fw_id, 'edge_id': edge_id})
216 raise exceptions.FirewallInternalDriverError( 154 raise exceptions.FirewallInternalDriverError(
217 driver=FWAAS_DRIVER_NAME) 155 driver=FWAAS_DRIVER_NAME)
218 156
@@ -222,20 +160,27 @@ class EdgeFwaasDriver(fwaas_base.FwaasDriverBase):
222 self.apply_default_policy(agent_mode, apply_list, firewall) 160 self.apply_default_policy(agent_mode, apply_list, firewall)
223 return 161 return
224 162
163 # get router-edge mapping
225 context = n_context.get_admin_context() 164 context = n_context.get_admin_context()
226 165 edges_map = self._get_routers_edges(context, apply_list)
227 # Find out the relevant edges 166 if not edges_map:
228 router_edges = self._get_routers_edges(context, apply_list) 167 routers = [r.router_id for r in apply_list]
229 if not router_edges: 168 LOG.warning("Cannot apply the firewall %(fw)s to any of the "
230 LOG.warning("Cannot apply the firewall to any of the routers %s", 169 "routers %(rtrs)s",
231 apply_list) 170 {'fw': firewall['id'], 'rtrs': routers})
232 return 171 return
233 172
173 # Translate the FWaaS rules
234 rules = self._translate_rules(firewall['firewall_rule_list']) 174 rules = self._translate_rules(firewall['firewall_rule_list'])
235 # update each edge 175
236 for edge_id in router_edges: 176 # update each relevant edge with the new rules
237 self._set_rules_on_edge( 177 for router_info in apply_list:
238 context, edge_id, firewall['id'], rules) 178 neutron_id = router_info.router_id
179 info = edges_map.get(neutron_id)
180 if info:
181 self._set_rules_on_router_edge(
182 context, info['lookup_id'], neutron_id, info['edge_id'],
183 firewall['id'], rules)
239 184
240 @log_helpers.log_method_call 185 @log_helpers.log_method_call
241 def create_firewall(self, agent_mode, apply_list, firewall): 186 def create_firewall(self, agent_mode, apply_list, firewall):
@@ -248,13 +193,22 @@ class EdgeFwaasDriver(fwaas_base.FwaasDriverBase):
248 self._create_or_update_firewall(agent_mode, apply_list, firewall) 193 self._create_or_update_firewall(agent_mode, apply_list, firewall)
249 194
250 def _delete_firewall_or_set_default_policy(self, apply_list, firewall, 195 def _delete_firewall_or_set_default_policy(self, apply_list, firewall,
251 allow_external): 196 delete_fw=False):
197 # get router-edge mapping
252 context = n_context.get_admin_context() 198 context = n_context.get_admin_context()
253 router_edges = self._get_routers_edges(context, apply_list) 199 edges_map = self._get_routers_edges(context, apply_list)
254 if router_edges: 200
255 for edge_id in router_edges: 201 # if the firewall is deleted, rules should be None
256 self._set_rules_on_edge(context, edge_id, firewall['id'], [], 202 rules = None if delete_fw else []
257 allow_external=allow_external) 203
204 # Go over all routers and update them on backend
205 for router_info in apply_list:
206 neutron_id = router_info.router_id
207 info = edges_map.get(neutron_id)
208 if info:
209 self._set_rules_on_router_edge(
210 context, info['lookup_id'], neutron_id, info['edge_id'],
211 firewall['id'], rules, delete_fw=delete_fw)
258 212
259 @log_helpers.log_method_call 213 @log_helpers.log_method_call
260 def delete_firewall(self, agent_mode, apply_list, firewall): 214 def delete_firewall(self, agent_mode, apply_list, firewall):
@@ -264,7 +218,7 @@ class EdgeFwaasDriver(fwaas_base.FwaasDriverBase):
264 And add the default allow-external rule. 218 And add the default allow-external rule.
265 """ 219 """
266 self._delete_firewall_or_set_default_policy(apply_list, firewall, 220 self._delete_firewall_or_set_default_policy(apply_list, firewall,
267 allow_external=True) 221 delete_fw=True)
268 222
269 @log_helpers.log_method_call 223 @log_helpers.log_method_call
270 def apply_default_policy(self, agent_mode, apply_list, firewall): 224 def apply_default_policy(self, agent_mode, apply_list, firewall):
@@ -274,7 +228,7 @@ class EdgeFwaasDriver(fwaas_base.FwaasDriverBase):
274 so we only need to delete the current rules. 228 so we only need to delete the current rules.
275 """ 229 """
276 self._delete_firewall_or_set_default_policy(apply_list, firewall, 230 self._delete_firewall_or_set_default_policy(apply_list, firewall,
277 allow_external=False) 231 delete_fw=False)
278 232
279 def get_firewall_translated_rules(self, firewall): 233 def get_firewall_translated_rules(self, firewall):
280 if firewall['admin_state_up']: 234 if firewall['admin_state_up']:
diff --git a/vmware_nsx/tests/unit/nsx_v/test_fwaas_driver.py b/vmware_nsx/tests/unit/nsx_v/test_fwaas_driver.py
index 48e1719..95cb0a1 100644
--- a/vmware_nsx/tests/unit/nsx_v/test_fwaas_driver.py
+++ b/vmware_nsx/tests/unit/nsx_v/test_fwaas_driver.py
@@ -15,6 +15,7 @@
15 15
16import copy 16import copy
17import mock 17import mock
18from oslo_utils import uuidutils
18 19
19from neutron_fwaas.common import exceptions 20from neutron_fwaas.common import exceptions
20 21
@@ -28,8 +29,6 @@ class NsxvFwaasTestCase(test_v_plugin.NsxVPluginV2TestCase):
28 def setUp(self): 29 def setUp(self):
29 super(NsxvFwaasTestCase, self).setUp() 30 super(NsxvFwaasTestCase, self).setUp()
30 self.firewall = edge_fwaas_driver.EdgeFwaasDriver() 31 self.firewall = edge_fwaas_driver.EdgeFwaasDriver()
31 self.firewall._get_routers_edges = mock.Mock()
32 self.firewall._get_routers_edges.return_value = ['edge-1']
33 32
34 def _fake_rules_v4(self): 33 def _fake_rules_v4(self):
35 rule1 = {'enabled': True, 34 rule1 = {'enabled': True,
@@ -81,40 +80,60 @@ class NsxvFwaasTestCase(test_v_plugin.NsxVPluginV2TestCase):
81 def _fake_apply_list(self, router_count=1): 80 def _fake_apply_list(self, router_count=1):
82 apply_list = [] 81 apply_list = []
83 while router_count > 0: 82 while router_count > 0:
84 router_inst = {} 83 rtr_id = uuidutils.generate_uuid()
84 router_inst = {'id': rtr_id}
85 router_info_inst = mock.Mock() 85 router_info_inst = mock.Mock()
86 router_info_inst.router = router_inst 86 router_info_inst.router = router_inst
87 router_info_inst.router_id = rtr_id
87 apply_list.append(router_info_inst) 88 apply_list.append(router_info_inst)
88 router_count -= 1 89 router_count -= 1
89 return apply_list 90 return apply_list
90 91
92 def _get_fake_mapping(self, apply_list):
93 router_edge_map = {}
94 for router_info in apply_list:
95 router_edge_map[router_info.router_id] = {
96 'edge_id': 'edge-1',
97 'lookup_id': router_info.router_id}
98 return router_edge_map
99
91 def _setup_firewall_with_rules(self, func, router_count=1): 100 def _setup_firewall_with_rules(self, func, router_count=1):
92 apply_list = self._fake_apply_list(router_count=router_count) 101 apply_list = self._fake_apply_list(router_count=router_count)
93 rule_list = self._fake_rules_v4() 102 rule_list = self._fake_rules_v4()
94 firewall = self._fake_firewall(rule_list) 103 firewall = self._fake_firewall(rule_list)
95 edges = ['edge-1'] * router_count 104 edges = self._get_fake_mapping(apply_list)
96 with mock.patch.object(self.firewall._nsxv, 105
97 "update_firewall") as update_fw,\ 106 with mock.patch("vmware_nsx.plugins.nsx_v.plugin.NsxVPluginV2."
107 "update_router_firewall") as update_fw,\
108 mock.patch("vmware_nsx.plugins.nsx_v.plugin.NsxVPluginV2."
109 "_get_router"),\
98 mock.patch.object(self.firewall, 110 mock.patch.object(self.firewall,
99 "_get_routers_edges", return_value=edges): 111 "_get_routers_edges", return_value=edges):
100 func('nsx', apply_list, firewall) 112 func('nsx', apply_list, firewall)
101 self.assertEqual(router_count, update_fw.call_count) 113 self.assertEqual(router_count, update_fw.call_count)
102 backend_rules = update_fw.call_args[0][1]['firewall_rule_list'] 114 # Validate the args of the last call
115 self.assertEqual(apply_list[-1].router_id,
116 update_fw.call_args[0][1])
117 backend_rules = update_fw.call_args[1]['fwaas_rules']
103 self.assertEqual(len(rule_list), len(backend_rules)) 118 self.assertEqual(len(rule_list), len(backend_rules))
104 allow_ext = update_fw.call_args[1]['allow_external']
105 self.assertEqual(False, allow_ext)
106 119
107 def test_create_firewall_no_rules(self): 120 def test_create_firewall_no_rules(self):
108 apply_list = self._fake_apply_list() 121 apply_list = self._fake_apply_list()
109 firewall = self._fake_firewall_no_rule() 122 firewall = self._fake_firewall_no_rule()
110 with mock.patch.object(self.firewall._nsxv, 123 edges = self._get_fake_mapping(apply_list)
111 "update_firewall") as update_fw: 124 with mock.patch("vmware_nsx.plugins.nsx_v.plugin.NsxVPluginV2."
125 "update_router_firewall") as update_fw,\
126 mock.patch("vmware_nsx.plugins.nsx_v.plugin.NsxVPluginV2."
127 "_get_router"),\
128 mock.patch.object(self.firewall,
129 "_get_routers_edges", return_value=edges):
112 self.firewall.create_firewall('nsx', apply_list, firewall) 130 self.firewall.create_firewall('nsx', apply_list, firewall)
113 self.assertEqual(1, update_fw.call_count) 131 self.assertEqual(1, update_fw.call_count)
114 backend_rules = update_fw.call_args[0][1]['firewall_rule_list'] 132 # Validate the args of the last call
115 self.assertEqual(0, len(backend_rules)) 133 self.assertEqual(apply_list[0].router_id,
116 allow_ext = update_fw.call_args[1]['allow_external'] 134 update_fw.call_args[0][1])
117 self.assertEqual(False, allow_ext) 135 backend_rules = update_fw.call_args[1]['fwaas_rules']
136 self.assertEqual([], backend_rules)
118 137
119 def test_create_firewall_with_rules(self): 138 def test_create_firewall_with_rules(self):
120 self._setup_firewall_with_rules(self.firewall.create_firewall) 139 self._setup_firewall_with_rules(self.firewall.create_firewall)
@@ -126,63 +145,42 @@ class NsxvFwaasTestCase(test_v_plugin.NsxVPluginV2TestCase):
126 def test_update_firewall_with_rules(self): 145 def test_update_firewall_with_rules(self):
127 self._setup_firewall_with_rules(self.firewall.update_firewall) 146 self._setup_firewall_with_rules(self.firewall.update_firewall)
128 147
129 def test_create_firewall_with_existing_backend_rules(self):
130 apply_list = self._fake_apply_list()
131 rule_list = self._fake_rules_v4()
132 firewall = self._fake_firewall(rule_list)
133 edge_id = 'edge-1'
134 # backend fw already has 3 rules.
135 # The fwaas rule should come in the middle, and replace the fwaas rule
136 existing_rules = [{'name': 'Subnet Rule',
137 'action': 'accept',
138 'enabled': True},
139 {'name': 'Fwaas-1',
140 'action': 'deny',
141 'enabled': True},
142 {'name': 'DNAT Rule',
143 'action': 'accept',
144 'enabled': True}]
145 for rule in existing_rules:
146 self.firewall._nsxv.vcns.add_firewall_rule(edge_id, rule)
147
148 with mock.patch.object(self.firewall._nsxv,
149 "update_firewall") as update_fw,\
150 mock.patch.object(self.firewall,
151 "_get_routers_edges", return_value=[edge_id]):
152 self.firewall.create_firewall('nsx', apply_list, firewall)
153 self.assertEqual(1, update_fw.call_count)
154 backend_rules = update_fw.call_args[0][1]['firewall_rule_list']
155 self.assertEqual(len(rule_list) + len(existing_rules) - 1,
156 len(backend_rules))
157 self.assertEqual('Subnet Rule', backend_rules[0]['name'])
158 self.assertEqual('DNAT Rule', backend_rules[-1]['name'])
159 allow_ext = update_fw.call_args[1]['allow_external']
160 self.assertEqual(False, allow_ext)
161
162 def test_delete_firewall(self): 148 def test_delete_firewall(self):
163 apply_list = self._fake_apply_list() 149 apply_list = self._fake_apply_list()
164 firewall = self._fake_firewall_no_rule() 150 firewall = self._fake_firewall_no_rule()
165 with mock.patch.object(self.firewall._nsxv, 151 edges = self._get_fake_mapping(apply_list)
166 "update_firewall") as update_fw: 152 with mock.patch("vmware_nsx.plugins.nsx_v.plugin.NsxVPluginV2."
153 "update_router_firewall") as update_fw,\
154 mock.patch("vmware_nsx.plugins.nsx_v.plugin.NsxVPluginV2."
155 "_get_router"),\
156 mock.patch.object(self.firewall,
157 "_get_routers_edges", return_value=edges):
167 self.firewall.delete_firewall('nsx', apply_list, firewall) 158 self.firewall.delete_firewall('nsx', apply_list, firewall)
168 self.assertEqual(1, update_fw.call_count) 159 self.assertEqual(1, update_fw.call_count)
169 backend_rules = update_fw.call_args[0][1]['firewall_rule_list'] 160 # Validate the args of the last call
170 self.assertEqual(0, len(backend_rules)) 161 self.assertEqual(apply_list[0].router_id,
171 allow_ext = update_fw.call_args[1]['allow_external'] 162 update_fw.call_args[0][1])
172 self.assertEqual(True, allow_ext) 163 backend_rules = update_fw.call_args[1]['fwaas_rules']
164 self.assertIsNone(backend_rules)
173 165
174 def test_create_firewall_with_admin_down(self): 166 def test_create_firewall_with_admin_down(self):
175 apply_list = self._fake_apply_list() 167 apply_list = self._fake_apply_list()
176 rule_list = self._fake_rules_v4() 168 rule_list = self._fake_rules_v4()
177 firewall = self._fake_firewall_with_admin_down(rule_list) 169 firewall = self._fake_firewall_with_admin_down(rule_list)
178 with mock.patch.object(self.firewall._nsxv, 170 edges = self._get_fake_mapping(apply_list)
179 "update_firewall") as update_fw: 171 with mock.patch("vmware_nsx.plugins.nsx_v.plugin.NsxVPluginV2."
172 "update_router_firewall") as update_fw,\
173 mock.patch("vmware_nsx.plugins.nsx_v.plugin.NsxVPluginV2."
174 "_get_router"),\
175 mock.patch.object(self.firewall,
176 "_get_routers_edges", return_value=edges):
180 self.firewall.create_firewall('nsx', apply_list, firewall) 177 self.firewall.create_firewall('nsx', apply_list, firewall)
181 self.assertEqual(1, update_fw.call_count) 178 self.assertEqual(1, update_fw.call_count)
182 backend_rules = update_fw.call_args[0][1]['firewall_rule_list'] 179 # Validate the args of the last call
183 self.assertEqual(0, len(backend_rules)) 180 self.assertEqual(apply_list[0].router_id,
184 allow_ext = update_fw.call_args[1]['allow_external'] 181 update_fw.call_args[0][1])
185 self.assertEqual(False, allow_ext) 182 backend_rules = update_fw.call_args[1]['fwaas_rules']
183 self.assertEqual([], backend_rules)
186 184
187 def test_should_apply_firewall_to_router(self): 185 def test_should_apply_firewall_to_router(self):
188 router = {'id': 'fake_id', 186 router = {'id': 'fake_id',