Merge "[aim-mapping] Fix policy-classifier direction impl"
This commit is contained in:
commit
5cac3ffcff
|
@ -809,20 +809,28 @@ class AIMMappingDriver(nrd.CommonNeutronBase, aim_rpc.AIMMappingRPCMixin):
|
|||
aim_reverse_filter.name]:
|
||||
if fname in flist:
|
||||
flist.remove(fname)
|
||||
to_add = []
|
||||
# Now add it to the relevant direction list(s)
|
||||
if c_dir == g_const.GP_DIRECTION_IN:
|
||||
to_add = [aim_contract_subject.in_filters]
|
||||
aim_contract_subject.in_filters.append(
|
||||
aim_filter.name)
|
||||
aim_contract_subject.out_filters.append(
|
||||
aim_reverse_filter.name)
|
||||
elif c_dir == g_const.GP_DIRECTION_OUT:
|
||||
to_add = [aim_contract_subject.out_filters]
|
||||
elif c_dir == g_const.GP_DIRECTION_BI:
|
||||
to_add = [aim_contract_subject.in_filters,
|
||||
aim_contract_subject.out_filters]
|
||||
for flist in to_add:
|
||||
for fname in filter(
|
||||
None, [aim_filter.name,
|
||||
aim_reverse_filter.name]):
|
||||
flist.append(fname)
|
||||
aim_contract_subject.in_filters.append(
|
||||
aim_reverse_filter.name)
|
||||
aim_contract_subject.out_filters.append(
|
||||
aim_filter.name)
|
||||
else:
|
||||
aim_contract_subject.in_filters.append(
|
||||
aim_filter.name)
|
||||
aim_contract_subject.out_filters.append(
|
||||
aim_reverse_filter.name)
|
||||
aim_contract_subject.in_filters.append(
|
||||
aim_reverse_filter.name)
|
||||
aim_contract_subject.out_filters.append(
|
||||
aim_filter.name)
|
||||
self.aim.create(aim_ctx, aim_contract_subject,
|
||||
overwrite=True)
|
||||
|
||||
@log.log_method_call
|
||||
def create_policy_rule_precommit(self, context):
|
||||
|
@ -1406,9 +1414,17 @@ class AIMMappingDriver(nrd.CommonNeutronBase, aim_rpc.AIMMappingRPCMixin):
|
|||
classifier = context._plugin.get_policy_classifier(
|
||||
context._plugin_context, rule['policy_classifier_id'])
|
||||
if classifier['direction'] == g_const.GP_DIRECTION_IN:
|
||||
in_filters += aim_filters
|
||||
for fltr in aim_filters:
|
||||
if fltr.startswith(alib.REVERSE_PREFIX):
|
||||
out_filters.append(fltr)
|
||||
else:
|
||||
in_filters.append(fltr)
|
||||
elif classifier['direction'] == g_const.GP_DIRECTION_OUT:
|
||||
out_filters += aim_filters
|
||||
for fltr in aim_filters:
|
||||
if fltr.startswith(alib.REVERSE_PREFIX):
|
||||
in_filters.append(fltr)
|
||||
else:
|
||||
out_filters.append(fltr)
|
||||
else:
|
||||
in_filters += aim_filters
|
||||
out_filters += aim_filters
|
||||
|
|
|
@ -27,7 +27,7 @@ IMPLICIT_PREFIX = 'implicit-'
|
|||
PER_PROJECT = 'per-project'
|
||||
REVERSIBLE_PROTOCOLS = [n_constants.PROTO_NAME_TCP.lower(),
|
||||
n_constants.PROTO_NAME_UDP.lower(),
|
||||
n_constants.PROTO_NAME_ICMP.lower()]
|
||||
n_constants.PROTO_NAME_ICMP.lower(), None]
|
||||
ICMP_REPLY_TYPES = ['echo-rep', 'dst-unreach', 'src-quench', 'time-exceeded']
|
||||
CP_ENTRY = 'os-entry'
|
||||
|
||||
|
@ -78,24 +78,43 @@ def get_filter_entries_for_policy_classifier(classifier):
|
|||
f_attrs['dFromPort'] = port_min
|
||||
entries['forward_rules'] = {_get_filter_entry_name(x): f_attrs}
|
||||
# Also create reverse rule
|
||||
if f_attrs.get('prot') in REVERSIBLE_PROTOCOLS:
|
||||
if not f_attrs.get('prot') or (
|
||||
f_attrs.get('prot') in REVERSIBLE_PROTOCOLS):
|
||||
r_entries = {}
|
||||
r_attrs = copy.deepcopy(f_attrs)
|
||||
if r_attrs.get('dToPort') and r_attrs.get('dFromPort'):
|
||||
r_attrs.pop('dToPort')
|
||||
r_attrs.pop('dFromPort')
|
||||
r_attrs['sToPort'] = port_max
|
||||
r_attrs['sFromPort'] = port_min
|
||||
if r_attrs['prot'] == n_constants.PROTO_NAME_TCP.lower():
|
||||
# Only match on established sessions
|
||||
if f_attrs.get('prot') == n_constants.PROTO_NAME_TCP.lower() or (
|
||||
f_attrs.get('prot') == n_constants.PROTO_NAME_UDP.lower()):
|
||||
r_attrs = copy.deepcopy(f_attrs)
|
||||
if f_attrs.get('dToPort') and f_attrs.get('dFromPort'):
|
||||
r_attrs.pop('dToPort')
|
||||
r_attrs.pop('dFromPort')
|
||||
r_attrs['sToPort'] = port_max
|
||||
r_attrs['sFromPort'] = port_min
|
||||
if f_attrs.get('prot') == n_constants.PROTO_NAME_TCP.lower():
|
||||
# Only match on established sessions for tcp
|
||||
r_attrs['tcpRules'] = 'est'
|
||||
r_entries[_get_filter_entry_name(x)] = r_attrs
|
||||
if not f_attrs.get('prot'):
|
||||
# when no protocol is specified add reverse tcp rule
|
||||
# only for established sessions
|
||||
r_attrs = copy.deepcopy(f_attrs)
|
||||
r_attrs['etherT'] = 'ip'
|
||||
r_attrs['prot'] = n_constants.PROTO_NAME_TCP.lower()
|
||||
r_attrs['tcpRules'] = 'est'
|
||||
r_entries[_get_filter_entry_name(x)] = r_attrs
|
||||
if r_attrs['prot'] == n_constants.PROTO_NAME_ICMP.lower():
|
||||
r_entries = {}
|
||||
# create more entries:
|
||||
r_entries[_get_filter_entry_name(x)] = r_attrs
|
||||
# add another reverse rulw for UDP
|
||||
r_attrs = copy.deepcopy(f_attrs)
|
||||
r_attrs['etherT'] = 'ip'
|
||||
r_attrs['prot'] = n_constants.PROTO_NAME_UDP.lower()
|
||||
x += 1
|
||||
r_entries[_get_filter_entry_name(x)] = r_attrs
|
||||
if f_attrs.get('prot') == n_constants.PROTO_NAME_ICMP.lower() or (
|
||||
not f_attrs.get('prot')):
|
||||
# create more entries for icmp and no protocol cases
|
||||
for reply_type in ICMP_REPLY_TYPES:
|
||||
x += 1
|
||||
r_entry = copy.deepcopy(r_attrs)
|
||||
r_entry = copy.deepcopy(f_attrs)
|
||||
r_entry['etherT'] = 'ip'
|
||||
r_entry['prot'] = n_constants.PROTO_NAME_ICMP.lower()
|
||||
r_entry['icmpv4T'] = reply_type
|
||||
r_entries[_get_filter_entry_name(x)] = r_entry
|
||||
entries['reverse_rules'] = r_entries
|
||||
|
|
|
@ -849,18 +849,20 @@ class AIMBaseTestCase(test_nr_base.CommonNeutronBaseTestCase,
|
|||
rev_filter = None
|
||||
|
||||
direction = pc['direction']
|
||||
expected_filters = []
|
||||
if direction == gp_const.GP_DIRECTION_IN:
|
||||
expected_filters = [expected_in_filters]
|
||||
elif direction == gp_const.GP_DIRECTION_OUT:
|
||||
expected_filters = [expected_out_filters]
|
||||
else:
|
||||
expected_filters = [expected_in_filters,
|
||||
expected_out_filters]
|
||||
for ef in expected_filters:
|
||||
ef.append(fwd_filter)
|
||||
expected_in_filters.append(fwd_filter)
|
||||
if rev_filter:
|
||||
ef.append(rev_filter)
|
||||
expected_out_filters.append(rev_filter)
|
||||
elif direction == gp_const.GP_DIRECTION_OUT:
|
||||
expected_out_filters.append(fwd_filter)
|
||||
if rev_filter:
|
||||
expected_in_filters.append(rev_filter)
|
||||
else:
|
||||
expected_in_filters.append(fwd_filter)
|
||||
expected_out_filters.append(fwd_filter)
|
||||
if rev_filter:
|
||||
expected_in_filters.append(rev_filter)
|
||||
expected_out_filters.append(rev_filter)
|
||||
|
||||
self.assertItemsEqual(expected_in_filters,
|
||||
contract_subject.in_filters)
|
||||
|
@ -3695,6 +3697,25 @@ class TestPolicyRuleBase(AIMBaseTestCase):
|
|||
dict((str(k), str(v)) for k, v in aim_object_to_dict(
|
||||
filter_entry).items()))
|
||||
|
||||
def _validate_1_to_many_reverse_filter_entries(
|
||||
self, policy_rule, afilter, filter_entries):
|
||||
pc = self.show_policy_classifier(
|
||||
policy_rule['policy_classifier_id'])['policy_classifier']
|
||||
expected_entries = alib.get_filter_entries_for_policy_classifier(pc)
|
||||
|
||||
for e_name, value in expected_entries['reverse_rules'].items():
|
||||
expected_filter_entry = self.driver._aim_filter_entry(
|
||||
self._neutron_context.session, afilter, e_name,
|
||||
alib.map_to_aim_filter_entry(value))
|
||||
filter_entry = (
|
||||
entry for entry in filter_entries if entry.name == e_name
|
||||
).next()
|
||||
self.assertItemsEqual(
|
||||
aim_object_to_dict(expected_filter_entry),
|
||||
# special processing to convert unicode to str
|
||||
dict((str(k), str(v)) for k, v in aim_object_to_dict(
|
||||
filter_entry).items()))
|
||||
|
||||
def _test_policy_rule_aim_mapping(self, policy_rule):
|
||||
aim_filter_name = str(self.name_mapper.policy_rule(
|
||||
self._neutron_context.session, policy_rule['id']))
|
||||
|
@ -3722,11 +3743,27 @@ class TestPolicyRuleBase(AIMBaseTestCase):
|
|||
self._aim_context, aim_resource.FilterEntry,
|
||||
tenant_name=aim_filters[0].tenant_name,
|
||||
filter_name=aim_filters[0].name)
|
||||
self.assertEqual(1, len(aim_filter_entries))
|
||||
self._validate_filter_entry(policy_rule, aim_filters[0],
|
||||
aim_filter_entries[0])
|
||||
if protocol == 'tcp' or protocol == 'udp' or not (
|
||||
filter_name.startswith('reverse')):
|
||||
# this will also check the forward entries for
|
||||
# icmp and no protocol case
|
||||
self.assertEqual(1, len(aim_filter_entries))
|
||||
self._validate_filter_entry(policy_rule, aim_filters[0],
|
||||
aim_filter_entries[0])
|
||||
elif protocol == 'icmp':
|
||||
# this is only for reverse entries with ICMP
|
||||
self.assertEqual(4, len(aim_filter_entries))
|
||||
self._validate_1_to_many_reverse_filter_entries(
|
||||
policy_rule, aim_filters[0], aim_filter_entries)
|
||||
else:
|
||||
# this is only for reverse entries when no protocol
|
||||
# is specified. One entry for TCP, one for UDP and
|
||||
# four entries for ICMP
|
||||
self.assertEqual(6, len(aim_filter_entries))
|
||||
self._validate_1_to_many_reverse_filter_entries(
|
||||
policy_rule, aim_filters[0], aim_filter_entries)
|
||||
filter_entries.append(aim_filter_entries[0])
|
||||
aim_obj_list.append(filter_entries)
|
||||
aim_obj_list.extend(filter_entries)
|
||||
self.assertEqual(
|
||||
filter_entries[0].dn,
|
||||
policy_rule[DN]['Forward-FilterEntries'][0])
|
||||
|
@ -3799,12 +3836,20 @@ class TestPolicyRule(TestPolicyRuleBase):
|
|||
|
||||
self.delete_policy_classifier(pc['id'], expected_res_status=204)
|
||||
|
||||
def test_policy_rule_lifecycle(self):
|
||||
def _test_policy_rule_lifecycle(self, protocol, direction):
|
||||
action1 = self.create_policy_action(
|
||||
action_type='redirect')['policy_action']
|
||||
classifier = self.create_policy_classifier(
|
||||
protocol='TCP', port_range="22",
|
||||
direction='bi')['policy_classifier']
|
||||
if protocol == 'ANY':
|
||||
classifier = self.create_policy_classifier(
|
||||
direction=direction)['policy_classifier']
|
||||
elif protocol in ['TCP', 'UDP']:
|
||||
classifier = self.create_policy_classifier(
|
||||
protocol=protocol, port_range="22",
|
||||
direction=direction)['policy_classifier']
|
||||
else:
|
||||
classifier = self.create_policy_classifier(
|
||||
protocol='ICMP',
|
||||
direction=direction)['policy_classifier']
|
||||
|
||||
pr = self.create_policy_rule(
|
||||
name="pr1", policy_classifier_id=classifier['id'],
|
||||
|
@ -3827,6 +3872,42 @@ class TestPolicyRule(TestPolicyRuleBase):
|
|||
|
||||
self._test_policy_rule_delete_aim_mapping(new_pr)
|
||||
|
||||
def test_policy_rule_lifecycle_tcp_in(self):
|
||||
self._test_policy_rule_lifecycle(protocol='TCP', direction='in')
|
||||
|
||||
def test_policy_rule_lifecycle_tcp_out(self):
|
||||
self._test_policy_rule_lifecycle(protocol='TCP', direction='out')
|
||||
|
||||
def test_policy_rule_lifecycle_tcp_bi(self):
|
||||
self._test_policy_rule_lifecycle(protocol='TCP', direction='bi')
|
||||
|
||||
def test_policy_rule_lifecycle_icmp_in(self):
|
||||
self._test_policy_rule_lifecycle(protocol='ICMP', direction='in')
|
||||
|
||||
def test_policy_rule_lifecycle_icmp_out(self):
|
||||
self._test_policy_rule_lifecycle(protocol='ICMP', direction='out')
|
||||
|
||||
def test_policy_rule_lifecycle_icmp_bi(self):
|
||||
self._test_policy_rule_lifecycle(protocol='ICMP', direction='bi')
|
||||
|
||||
def test_policy_rule_lifecycle_udp_in(self):
|
||||
self._test_policy_rule_lifecycle(protocol='UDP', direction='in')
|
||||
|
||||
def test_policy_rule_lifecycle_udp_out(self):
|
||||
self._test_policy_rule_lifecycle(protocol='UDP', direction='out')
|
||||
|
||||
def test_policy_rule_lifecycle_udp_bi(self):
|
||||
self._test_policy_rule_lifecycle(protocol='UDP', direction='bi')
|
||||
|
||||
def test_policy_rule_lifecycle_any_in(self):
|
||||
self._test_policy_rule_lifecycle(protocol='ANY', direction='in')
|
||||
|
||||
def test_policy_rule_lifecycle_any_out(self):
|
||||
self._test_policy_rule_lifecycle(protocol='ANY', direction='out')
|
||||
|
||||
def test_policy_rule_lifecycle_any_bi(self):
|
||||
self._test_policy_rule_lifecycle(protocol='ANY', direction='bi')
|
||||
|
||||
|
||||
class TestPolicyRuleRollback(TestPolicyRuleBase):
|
||||
|
||||
|
@ -3908,6 +3989,20 @@ class TestPolicyRuleSet(AIMBaseTestCase):
|
|||
'policy_rule_set']
|
||||
self._validate_policy_rule_set_aim_mapping(prs, rules)
|
||||
|
||||
# update directions of policy classifiers
|
||||
for r in rules:
|
||||
pc = self.show_policy_classifier(
|
||||
r['policy_classifier_id'])['policy_classifier']
|
||||
if pc['direction'] == 'in':
|
||||
new_direction = 'bi'
|
||||
elif pc['direction'] == 'out':
|
||||
new_direction = 'in'
|
||||
else:
|
||||
new_direction = 'out'
|
||||
self.update_policy_classifier(pc['id'],
|
||||
direction=new_direction)
|
||||
self._validate_policy_rule_set_aim_mapping(prs, rules)
|
||||
|
||||
new_rules = self._create_3_direction_rules()
|
||||
prs = self.update_policy_rule_set(
|
||||
prs['id'], policy_rules=[x['id'] for x in new_rules],
|
||||
|
|
Loading…
Reference in New Issue