From 3ca9a9c4764e541ce8dff4291d0fe9d77994c1a0 Mon Sep 17 00:00:00 2001 From: Adit Sarfaty Date: Sun, 25 Jun 2017 15:10:21 +0300 Subject: [PATCH] NSX|v3: Add firewall tag to the router Add a new tag to the nsx router indicating the FWaaS firewall id. This tag is removed when the rotuer is detached from the firewall Change-Id: I88151b710c807c74ff9fd9b0e32e50316d2ad1b8 --- .../fwaas/nsx_v3/edge_fwaas_driver.py | 63 ++++++++++++++++--- .../tests/unit/nsx_v3/test_fwaas_driver.py | 27 +++++++- 2 files changed, 79 insertions(+), 11 deletions(-) diff --git a/vmware_nsx/services/fwaas/nsx_v3/edge_fwaas_driver.py b/vmware_nsx/services/fwaas/nsx_v3/edge_fwaas_driver.py index 039829d0f8..b15c4b5865 100644 --- a/vmware_nsx/services/fwaas/nsx_v3/edge_fwaas_driver.py +++ b/vmware_nsx/services/fwaas/nsx_v3/edge_fwaas_driver.py @@ -33,6 +33,7 @@ LOG = logging.getLogger(__name__) FWAAS_DRIVER_NAME = 'Fwaas NSX-V3 driver' RULE_NAME_PREFIX = 'Fwaas-' DEFAULT_RULE_NAME = 'Default LR Layer3 Rule' +NSX_FW_TAG = 'os-neutron-fw-id' class EdgeFwaasV3Driver(fwaas_base.FwaasDriverBase): @@ -176,11 +177,11 @@ class EdgeFwaasV3Driver(fwaas_base.FwaasDriverBase): if not firewall['admin_state_up']: self.apply_default_policy(agent_mode, apply_list, firewall) return - context = n_context.get_admin_context() rules = self._translate_rules(firewall['firewall_rule_list']) - # update each router using the core plugin code - self._update_backend_routers(context, apply_list, rules=rules) + # update each router on the backend + self._update_backend_routers(context, apply_list, firewall['id'], + rules=rules) def validate_backend_version(self): # prevent firewall actions if the backend does not support it @@ -210,7 +211,8 @@ class EdgeFwaasV3Driver(fwaas_base.FwaasDriverBase): """ self.validate_backend_version() context = n_context.get_admin_context() - self._update_backend_routers(context, apply_list, delete_fw=True) + self._update_backend_routers(context, apply_list, firewall['id'], + delete_fw=True) @log_helpers.log_method_call def apply_default_policy(self, agent_mode, apply_list, firewall): @@ -221,11 +223,12 @@ class EdgeFwaasV3Driver(fwaas_base.FwaasDriverBase): """ self.validate_backend_version() context = n_context.get_admin_context() - self._update_backend_routers(context, apply_list, rules=[]) + self._update_backend_routers(context, apply_list, firewall['id'], + rules=[]) - def _update_backend_routers(self, context, apply_list, rules=None, + def _update_backend_routers(self, context, apply_list, fw_id, rules=None, delete_fw=False): - # update each router using the core plugin code + # update each router on the backend for router_info in apply_list: # Skip unsupported routers @@ -238,7 +241,8 @@ class EdgeFwaasV3Driver(fwaas_base.FwaasDriverBase): if delete_fw: self._delete_nsx_router_firewall(context, router_id) else: - self._update_nsx_router_firewall(context, router_id, rules) + self._update_nsx_router_firewall(context, router_id, fw_id, + rules) def _get_backend_router_and_fw_section(self, context, router_id): # find the backend router id in the DB @@ -265,6 +269,41 @@ class EdgeFwaasV3Driver(fwaas_base.FwaasDriverBase): return nsx_router_id, section_id + def _update_nsx_router_tags(self, nsx_router_id, fw_id=None): + """Get the updated tags to put on the nsx-router + + With/without the firewall id + """ + # Get the current tags + nsx_router = self.nsx_router.get(nsx_router_id) + if 'tags' not in nsx_router: + nsx_router['tags'] = [] + tags = nsx_router['tags'] + + # Look for the firewall tag and update/remove it + update_tags = False + found_tag = False + for tag in tags: + if tag.get('scope') == NSX_FW_TAG: + found_tag = True + if not fw_id: + tags.remove(tag) + update_tags = True + break + if fw_id != tag.get('tag'): + tag['tag'] = fw_id + update_tags = True + break + # Add the tag if not found + if fw_id and not found_tag: + tags.append({'scope': NSX_FW_TAG, + 'tag': fw_id}) + update_tags = True + + # update tags on the backend router + if update_tags: + self.nsx_router.update(nsx_router_id, tags=tags) + def _delete_nsx_router_firewall(self, context, router_id): """Reset the router firewall back to it's default""" @@ -284,7 +323,10 @@ class EdgeFwaasV3Driver(fwaas_base.FwaasDriverBase): # Update the backend firewall section with the rules self.nsx_firewall.update(section_id, rules=[allow_all]) - def _update_nsx_router_firewall(self, context, router_id, rules): + # Also update the router tags + self._update_nsx_router_tags(nsx_router_id) + + def _update_nsx_router_firewall(self, context, router_id, fw_id, rules): """Update the backend router firewall section Adding all relevant north-south rules from the FWaaS firewall @@ -309,3 +351,6 @@ class EdgeFwaasV3Driver(fwaas_base.FwaasDriverBase): # Update the backend firewall section with the rules self.nsx_firewall.update(section_id, rules=rules + [drop_all]) + + # Also update the router tags + self._update_nsx_router_tags(nsx_router_id, fw_id=fw_id) diff --git a/vmware_nsx/tests/unit/nsx_v3/test_fwaas_driver.py b/vmware_nsx/tests/unit/nsx_v3/test_fwaas_driver.py index 918c04c0ce..fc312a157c 100644 --- a/vmware_nsx/tests/unit/nsx_v3/test_fwaas_driver.py +++ b/vmware_nsx/tests/unit/nsx_v3/test_fwaas_driver.py @@ -171,12 +171,22 @@ class Nsxv3FwaasTestCase(test_v3_plugin.NsxV3PluginTestCaseMixin): def test_create_firewall_no_rules(self): apply_list = self._fake_apply_list() firewall = self._fake_firewall_no_rule() + initial_tags = [{'scope': 'xxx', 'tag': 'yyy'}] with mock.patch("vmware_nsxlib.v3.security.NsxLibFirewallSection." - "update") as update_fw: + "update") as update_fw,\ + mock.patch("vmware_nsxlib.v3.core_resources.NsxLibLogicalRouter." + "update") as update_rtr,\ + mock.patch("vmware_nsxlib.v3.core_resources.NsxLibLogicalRouter." + "get", return_value={'tags': initial_tags}) as get_rtr: self.firewall.create_firewall('nsx', apply_list, firewall) update_fw.assert_called_once_with( MOCK_SECTION_ID, rules=[self._default_rule()]) + get_rtr.assert_called_once_with(MOCK_NSX_ID) + expected_tags = initial_tags + expected_tags.append({'scope': edge_fwaas_driver.NSX_FW_TAG, + 'tag': firewall['id']}) + update_rtr.assert_called_once_with(MOCK_NSX_ID, tags=expected_tags) def test_create_firewall_with_rules(self): self._setup_firewall_with_rules(self.firewall.create_firewall) @@ -191,12 +201,25 @@ class Nsxv3FwaasTestCase(test_v3_plugin.NsxV3PluginTestCaseMixin): def test_delete_firewall(self): apply_list = self._fake_apply_list() firewall = self._fake_firewall_no_rule() + initial_tags = [{'scope': 'xxx', 'tag': 'yyy'}, + {'scope': edge_fwaas_driver.NSX_FW_TAG, + 'tag': firewall['id']}] with mock.patch("vmware_nsxlib.v3.security.NsxLibFirewallSection." - "update") as update_fw: + "update") as update_fw,\ + mock.patch("vmware_nsxlib.v3.core_resources.NsxLibLogicalRouter." + "update") as update_rtr,\ + mock.patch("vmware_nsxlib.v3.core_resources.NsxLibLogicalRouter." + "get", return_value={'tags': initial_tags}) as get_rtr: self.firewall.delete_firewall('nsx', apply_list, firewall) update_fw.assert_called_once_with( MOCK_SECTION_ID, rules=[self._default_rule(drop=False)]) + get_rtr.assert_called_once_with(MOCK_NSX_ID) + expected_tags = initial_tags + expected_tags.pop() + expected_tags.append({'scope': edge_fwaas_driver.NSX_FW_TAG, + 'tag': firewall['id']}) + update_rtr.assert_called_once_with(MOCK_NSX_ID, tags=expected_tags) def test_create_firewall_with_admin_down(self): apply_list = self._fake_apply_list()