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
This commit is contained in:
Kobi Samoray 2019-04-18 12:24:34 +03:00 committed by Adit Sarfaty
parent 032b6b8e46
commit 7a39f6f524
3 changed files with 66 additions and 26 deletions

View File

@ -59,7 +59,8 @@ DEFAULT_EDGE_FIREWALL_RULE = {
'name': 'VSERule', 'name': 'VSERule',
'enabled': True, 'enabled': True,
'action': 'allow', 'action': 'allow',
'source_vnic_groups': ['vse']} 'source_vnic_groups': ['vse'],
'destination_vnic_groups': ['external']}
def get_router_fw_rules(): def get_router_fw_rules():
@ -86,6 +87,13 @@ def get_router_fw_rules():
'protocol': 'tcp', 'protocol': 'tcp',
'destination_port': dest_ports 'destination_port': dest_ports
}, },
{
'name': 'VSEMDInterEdgeNet',
'enabled': True,
'action': 'allow',
'source_vnic_groups': ['vse'],
'destination_ip_address': [INTERNAL_SUBNET]
},
{ {
'name': 'MDInterEdgeNet', 'name': 'MDInterEdgeNet',
'enabled': True, 'enabled': True,

View File

@ -37,29 +37,45 @@ from vmware_nsx.shell.admin.plugins.nsxv.resources import utils as utils
from vmware_nsx.shell import resources as shell from vmware_nsx.shell import resources as shell
INTERNAL_SUBNET = '169.254.128.0/17'
NSXV_MD_RULES = [ NSXV_MD_RULES = [
{'name': 'MDServiceIP', {
'destination': {'ipAddress': ['169.254.169.254']}, 'name': 'VSERule',
'enabled': True, 'enabled': True,
'application': {'service': [{'protocol': 'tcp', 'action': 'accept',
'port': [80, 443, 8775]}]}, 'source_vnic_groups': ['vse'],
'action': 'accept', 'destination_vnic_groups': ['external']},
'ruleTag': None}, {
{'name': 'MDInterEdgeNet', 'name': 'MDServiceIP',
'destination': {'ipAddress': ['169.254.128.0/17']}, 'destination': {'ipAddress': ['169.254.169.254']},
'enabled': True, 'enabled': True,
'action': 'deny', 'application': {'service': [{'protocol': 'tcp',
'ruleTag': None}] '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__) LOG = logging.getLogger(__name__)
nsxv = utils.get_nsxv_client() nsxv = utils.get_nsxv_client()
def _append_md_fw_rules(fw_rules): def _append_md_fw_rules(fw_rules):
fw_rules = NSXV_MD_RULES + fw_rules
# Set FW rules tags # Set FW rules tags
NSXV_MD_RULES[0]['ruleTag'] = len(fw_rules) + 1 for i in range(len(fw_rules)):
NSXV_MD_RULES[1]['ruleTag'] = len(fw_rules) + 2 fw_rules[i]['ruleTag'] = i + 1
fw_rules += NSXV_MD_RULES
return fw_rules return fw_rules
@ -70,15 +86,21 @@ def _handle_edge_firewall_rules(edge_id):
fw_cfg = {} fw_cfg = {}
LOG.error("Failed to retrieve firewall config for edge %(edge)s " LOG.error("Failed to retrieve firewall config for edge %(edge)s "
"with exception %(e)s", {'edge': edge_id, 'e': e}) "with exception %(e)s", {'edge': edge_id, 'e': e})
do_update = True
fw_rules = fw_cfg.get('firewallRules', {}).get('firewallRules', []) fw_rules = fw_cfg.get('firewallRules', {}).get('firewallRules', [])
md_rule_names = ['MDInterEdgeNet',
'MDServiceIP',
'VSEMDInterEdgeNet',
'VSERule']
new_rules = []
for rule in fw_rules: for rule in fw_rules:
if rule['name'] in ['MDInterEdgeNet', 'MDServiceIP']: if rule['name'] in md_rule_names:
do_update = False md_rule_names.remove(rule['name'])
break else:
if do_update: new_rules.append(rule)
fw_rules = _append_md_fw_rules(fw_rules)
fw_cfg['firewallRules']['firewallRules'] = fw_rules if md_rule_names:
new_rules = _append_md_fw_rules(new_rules)
fw_cfg['firewallRules']['firewallRules'] = new_rules
try: try:
nsxv.update_firewall(edge_id, fw_cfg) nsxv.update_firewall(edge_id, fw_cfg)
LOG.info('Added missing firewall rules for edge %s', edge_id) 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 ' LOG.error('Recreation of metadata components for edge '
'%(edge)s failed with error %(e)s', '%(edge)s failed with error %(e)s',
{'edge': edge_id, 'e': e}) {'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): def _update_md_lb_members(edge_id, edge_internal_ips, lb, pool):

View File

@ -3268,13 +3268,19 @@ class TestExclusiveRouterTestCase(L3NatTest, L3NatTestCaseBase,
vse_rule = {'action': 'allow', vse_rule = {'action': 'allow',
'enabled': True, 'enabled': True,
'name': 'VSERule', 'name': 'VSERule',
'source_vnic_groups': ['vse']} 'source_vnic_groups': ['vse'],
'destination_vnic_groups': ['external']}
dest_intern = [md_proxy.INTERNAL_SUBNET] dest_intern = [md_proxy.INTERNAL_SUBNET]
md_inter = {'action': 'deny', md_inter = {'action': 'deny',
'destination_ip_address': dest_intern, 'destination_ip_address': dest_intern,
'enabled': True, 'enabled': True,
'name': 'MDInterEdgeNet'} 'name': 'MDInterEdgeNet'}
dest_srvip = [md_proxy.METADATA_IP_ADDR] 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', md_srvip = {'action': 'allow',
'destination_ip_address': dest_srvip, 'destination_ip_address': dest_srvip,
'destination_port': '80,443,8775', 'destination_port': '80,443,8775',
@ -3282,6 +3288,7 @@ class TestExclusiveRouterTestCase(L3NatTest, L3NatTestCaseBase,
'name': 'MDServiceIP', 'name': 'MDServiceIP',
'protocol': 'tcp'} 'protocol': 'tcp'}
expected_fw = [fw_rule, expected_fw = [fw_rule,
vsmdienet,
vse_rule, vse_rule,
md_inter, md_inter,
md_srvip] md_srvip]
@ -3738,8 +3745,8 @@ class TestExclusiveRouterTestCase(L3NatTest, L3NatTestCaseBase,
# check fw rules # check fw rules
fw_rules = update_fw.call_args[0][3][ fw_rules = update_fw.call_args[0][3][
'firewall_rule_list'] 'firewall_rule_list']
exp_fw_len = 5 if self.with_md_proxy else 2 exp_fw_len = 6 if self.with_md_proxy else 2
pool_rule_ind = 4 if self.with_md_proxy else 1 pool_rule_ind = 5 if self.with_md_proxy else 1
pool_rule = fw_rules[pool_rule_ind] pool_rule = fw_rules[pool_rule_ind]
self.assertEqual(exp_fw_len, len(fw_rules)) self.assertEqual(exp_fw_len, len(fw_rules))
self.assertEqual('Allocation Pool Rule', self.assertEqual('Allocation Pool Rule',