From 7a39f6f524b521de475f76d2f7b5bbdc796a977d Mon Sep 17 00:00:00 2001 From: Kobi Samoray Date: Thu, 18 Apr 2019 12:24:34 +0300 Subject: [PATCH] NSXv: Resolve FWaaS-LBaaS conflict While using nsxv_use_routers_as_lbaas_platform option, FWaaS rules do not apply to LBaaS VIPs because of metadata's VSERule. Change-Id: If09a3f2cc445cb6867c6dd0f389f9105471a3cde --- vmware_nsx/plugins/nsx_v/md_proxy.py | 10 ++- .../admin/plugins/nsxv/resources/metadata.py | 69 +++++++++++++------ vmware_nsx/tests/unit/nsx_v/test_plugin.py | 13 +++- 3 files changed, 66 insertions(+), 26 deletions(-) diff --git a/vmware_nsx/plugins/nsx_v/md_proxy.py b/vmware_nsx/plugins/nsx_v/md_proxy.py index bfad05acfa..1ec6f1c2a5 100644 --- a/vmware_nsx/plugins/nsx_v/md_proxy.py +++ b/vmware_nsx/plugins/nsx_v/md_proxy.py @@ -59,7 +59,8 @@ DEFAULT_EDGE_FIREWALL_RULE = { 'name': 'VSERule', 'enabled': True, 'action': 'allow', - 'source_vnic_groups': ['vse']} + 'source_vnic_groups': ['vse'], + 'destination_vnic_groups': ['external']} def get_router_fw_rules(): @@ -86,6 +87,13 @@ def get_router_fw_rules(): 'protocol': 'tcp', 'destination_port': dest_ports }, + { + 'name': 'VSEMDInterEdgeNet', + 'enabled': True, + 'action': 'allow', + 'source_vnic_groups': ['vse'], + 'destination_ip_address': [INTERNAL_SUBNET] + }, { 'name': 'MDInterEdgeNet', 'enabled': True, diff --git a/vmware_nsx/shell/admin/plugins/nsxv/resources/metadata.py b/vmware_nsx/shell/admin/plugins/nsxv/resources/metadata.py index 11b2287183..cf1633b4f2 100644 --- a/vmware_nsx/shell/admin/plugins/nsxv/resources/metadata.py +++ b/vmware_nsx/shell/admin/plugins/nsxv/resources/metadata.py @@ -37,29 +37,45 @@ from vmware_nsx.shell.admin.plugins.nsxv.resources import utils as utils from vmware_nsx.shell import resources as shell +INTERNAL_SUBNET = '169.254.128.0/17' + NSXV_MD_RULES = [ - {'name': 'MDServiceIP', - 'destination': {'ipAddress': ['169.254.169.254']}, - 'enabled': True, - 'application': {'service': [{'protocol': 'tcp', - 'port': [80, 443, 8775]}]}, - 'action': 'accept', - 'ruleTag': None}, - {'name': 'MDInterEdgeNet', - 'destination': {'ipAddress': ['169.254.128.0/17']}, - 'enabled': True, - 'action': 'deny', - 'ruleTag': None}] + { + 'name': 'VSERule', + 'enabled': True, + 'action': 'accept', + 'source_vnic_groups': ['vse'], + 'destination_vnic_groups': ['external']}, + { + 'name': 'MDServiceIP', + 'destination': {'ipAddress': ['169.254.169.254']}, + 'enabled': True, + 'application': {'service': [{'protocol': 'tcp', + 'port': [80, 443, 8775]}]}, + 'action': 'accept', + 'ruleTag': None}, + { + 'name': 'VSEMDInterEdgeNet', + 'enabled': True, + 'action': 'accept', + 'source_vnic_groups': ['vse'], + 'destination_ip_address': [INTERNAL_SUBNET]}, + { + 'name': 'MDInterEdgeNet', + 'destination': {'ipAddress': ['169.254.128.0/17']}, + 'enabled': True, + 'action': 'deny', + 'ruleTag': None}] LOG = logging.getLogger(__name__) nsxv = utils.get_nsxv_client() def _append_md_fw_rules(fw_rules): + fw_rules = NSXV_MD_RULES + fw_rules # Set FW rules tags - NSXV_MD_RULES[0]['ruleTag'] = len(fw_rules) + 1 - NSXV_MD_RULES[1]['ruleTag'] = len(fw_rules) + 2 - fw_rules += NSXV_MD_RULES + for i in range(len(fw_rules)): + fw_rules[i]['ruleTag'] = i + 1 return fw_rules @@ -70,15 +86,21 @@ def _handle_edge_firewall_rules(edge_id): fw_cfg = {} LOG.error("Failed to retrieve firewall config for edge %(edge)s " "with exception %(e)s", {'edge': edge_id, 'e': e}) - do_update = True fw_rules = fw_cfg.get('firewallRules', {}).get('firewallRules', []) + md_rule_names = ['MDInterEdgeNet', + 'MDServiceIP', + 'VSEMDInterEdgeNet', + 'VSERule'] + new_rules = [] for rule in fw_rules: - if rule['name'] in ['MDInterEdgeNet', 'MDServiceIP']: - do_update = False - break - if do_update: - fw_rules = _append_md_fw_rules(fw_rules) - fw_cfg['firewallRules']['firewallRules'] = fw_rules + if rule['name'] in md_rule_names: + md_rule_names.remove(rule['name']) + else: + new_rules.append(rule) + + if md_rule_names: + new_rules = _append_md_fw_rules(new_rules) + fw_cfg['firewallRules']['firewallRules'] = new_rules try: nsxv.update_firewall(edge_id, fw_cfg) LOG.info('Added missing firewall rules for edge %s', edge_id) @@ -102,6 +124,9 @@ def _recreate_rtr_metadata_cfg(context, plugin, az_name, edge_id): LOG.error('Recreation of metadata components for edge ' '%(edge)s failed with error %(e)s', {'edge': edge_id, 'e': e}) + else: + LOG.error('Could not find a metadata handler for availability zone %s', + az_name) def _update_md_lb_members(edge_id, edge_internal_ips, lb, pool): diff --git a/vmware_nsx/tests/unit/nsx_v/test_plugin.py b/vmware_nsx/tests/unit/nsx_v/test_plugin.py index c2184d4191..e82a8b68ac 100644 --- a/vmware_nsx/tests/unit/nsx_v/test_plugin.py +++ b/vmware_nsx/tests/unit/nsx_v/test_plugin.py @@ -3268,13 +3268,19 @@ class TestExclusiveRouterTestCase(L3NatTest, L3NatTestCaseBase, vse_rule = {'action': 'allow', 'enabled': True, 'name': 'VSERule', - 'source_vnic_groups': ['vse']} + 'source_vnic_groups': ['vse'], + 'destination_vnic_groups': ['external']} dest_intern = [md_proxy.INTERNAL_SUBNET] md_inter = {'action': 'deny', 'destination_ip_address': dest_intern, 'enabled': True, 'name': 'MDInterEdgeNet'} dest_srvip = [md_proxy.METADATA_IP_ADDR] + vsmdienet = {'action': 'allow', + 'destination_ip_address': [md_proxy.INTERNAL_SUBNET], + 'enabled': True, + 'name': 'VSEMDInterEdgeNet', + 'source_vnic_groups': ['vse']} md_srvip = {'action': 'allow', 'destination_ip_address': dest_srvip, 'destination_port': '80,443,8775', @@ -3282,6 +3288,7 @@ class TestExclusiveRouterTestCase(L3NatTest, L3NatTestCaseBase, 'name': 'MDServiceIP', 'protocol': 'tcp'} expected_fw = [fw_rule, + vsmdienet, vse_rule, md_inter, md_srvip] @@ -3738,8 +3745,8 @@ class TestExclusiveRouterTestCase(L3NatTest, L3NatTestCaseBase, # check fw rules fw_rules = update_fw.call_args[0][3][ 'firewall_rule_list'] - exp_fw_len = 5 if self.with_md_proxy else 2 - pool_rule_ind = 4 if self.with_md_proxy else 1 + exp_fw_len = 6 if self.with_md_proxy else 2 + pool_rule_ind = 5 if self.with_md_proxy else 1 pool_rule = fw_rules[pool_rule_ind] self.assertEqual(exp_fw_len, len(fw_rules)) self.assertEqual('Allocation Pool Rule',