Merge "Verify metering label exists before applying rule"

This commit is contained in:
Jenkins 2017-05-02 21:01:30 +00:00 committed by Gerrit Code Review
commit 96d13e42f4
2 changed files with 67 additions and 8 deletions

View File

@ -232,24 +232,22 @@ class IptablesMeteringDriver(abstract_driver.MeteringAbstractDriver):
label_chain = iptables_manager.get_chain_name(
WRAP_NAME + LABEL + label_id, wrap=False)
im.ipv4['filter'].add_chain(label_chain, wrap=False)
rules_chain = iptables_manager.get_chain_name(
WRAP_NAME + RULE + label_id, wrap=False)
im.ipv4['filter'].add_chain(rules_chain, wrap=False)
im.ipv4['filter'].add_rule(
TOP_CHAIN, '-j ' + rules_chain, wrap=False)
im.ipv4['filter'].add_rule(
label_chain, '', wrap=False)
exists = rm.metering_labels.get(label_id)
if not exists:
self._create_metering_label_chain(rm,
label_chain,
rules_chain)
rm.metering_labels[label_id] = label
rules = label.get('rules')
if rules:
self._process_metering_label_rules(
rules, label_chain, rules_chain, ext_dev, im)
rm.metering_labels[label_id] = label
def _process_associate_metering_label(self, router):
self._update_router(router)
rm = self.routers.get(router['id'])
@ -318,9 +316,18 @@ class IptablesMeteringDriver(abstract_driver.MeteringAbstractDriver):
def _remove_metering_label_rule(self, router):
self._process_metering_rule_action(router, 'delete')
def _create_metering_label_chain(self, rm, label_chain, rules_chain):
rm.iptables_manager.ipv4['filter'].add_chain(label_chain, wrap=False)
rm.iptables_manager.ipv4['filter'].add_chain(rules_chain, wrap=False)
rm.iptables_manager.ipv4['filter'].add_rule(
TOP_CHAIN, '-j ' + rules_chain, wrap=False)
rm.iptables_manager.ipv4['filter'].add_rule(
label_chain, '', wrap=False)
def _process_metering_rule_action_based_on_ns(
self, router, action, ext_dev, im):
'''Process metering rule actions based specific namespaces.'''
rm = self.routers.get(router['id'])
with IptablesManagerTransaction(im):
labels = router.get(constants.METERING_LABEL_KEY, [])
for label in labels:
@ -330,6 +337,14 @@ class IptablesMeteringDriver(abstract_driver.MeteringAbstractDriver):
rules_chain = iptables_manager.get_chain_name(
WRAP_NAME + RULE + label_id, wrap=False)
exists = rm.metering_labels.get(label_id)
if action == 'create' and not exists:
self._create_metering_label_chain(rm,
label_chain,
rules_chain)
rm.metering_labels[label_id] = label
rule = label.get('rule')
if rule:
if action == 'create':

View File

@ -104,6 +104,22 @@ TEST_ROUTERS_WITH_ONE_RULE = [
'tenant_id': '6c5f5d2a1fa2441e88e35422926f48e8'},
]
TEST_ROUTERS_WITH_NEW_LABEL = [
{'_metering_labels': [
{'id': 'e27fe2df-376e-4ac7-ae13-92f050a21f84',
'rule': {
'direction': 'ingress',
'excluded': False,
'id': '7f1a261f-2489-4ed1-870c-a62754501379',
'metering_label_id': 'e27fe2df-376e-4ac7-ae13-92f050a21f84',
'remote_ip_prefix': '50.0.0.0/24'}}],
'admin_state_up': True,
'gw_port_id': '6d411f48-ecc7-45e0-9ece-3b5bdb54fcee',
'id': '473ec392-1711-44e3-b008-3251ccfc5099',
'name': 'router1',
'status': 'ACTIVE',
'tenant_id': '6c5f5d2a1fa2441e88e35422926f48e8'}]
class IptablesDriverTestCase(base.BaseTestCase):
def setUp(self):
@ -440,7 +456,35 @@ class IptablesDriverTestCase(base.BaseTestCase):
'-d 40.0.0.0/24 -o qg-7d411f48-ec'
' -j neutron-meter-l-eeef45da-c60',
wrap=False, top=False),
]
self.v4filter_inst.assert_has_calls(calls)
def test_add_metering_label_rule_without_label(self):
new_routers_rules = TEST_ROUTERS_WITH_NEW_LABEL
# clear all the metering labels
for r in TEST_ROUTERS:
rm = iptables_driver.RouterWithMetering(self.metering.conf, r)
rm.metering_labels = {}
self.metering.update_routers(None, TEST_ROUTERS)
self.metering.add_metering_label_rule(None, new_routers_rules)
calls = [
mock.call.add_chain('neutron-meter-l-e27fe2df-376',
wrap=False),
mock.call.add_chain('neutron-meter-r-e27fe2df-376',
wrap=False),
mock.call.add_rule('neutron-meter-FORWARD',
'-j neutron-meter-r-e27fe2df-376',
wrap=False),
mock.call.add_rule('neutron-meter-l-e27fe2df-376',
'',
wrap=False),
mock.call.add_rule('neutron-meter-r-e27fe2df-376',
'-s 50.0.0.0/24 '
'-i qg-6d411f48-ec '
'-j neutron-meter-l-e27fe2df-376',
top=False,
wrap=False)
]
self.v4filter_inst.assert_has_calls(calls)