Merge "[aim-mapping] Implement policy classifier update"

This commit is contained in:
Jenkins 2017-01-26 21:51:27 +00:00 committed by Gerrit Code Review
commit 76ee7a5529
3 changed files with 374 additions and 203 deletions

View File

@ -31,6 +31,7 @@ from oslo_log import helpers as log
from oslo_log import log as logging
from oslo_utils import excutils
from gbpservice.neutron.db.grouppolicy import group_policy_db as gpdb
from gbpservice.neutron.db.grouppolicy import group_policy_mapping_db as gpmdb
from gbpservice.neutron.extensions import cisco_apic
from gbpservice.neutron.extensions import cisco_apic_gbp as aim_ext
@ -711,31 +712,107 @@ class AIMMappingDriver(nrd.CommonNeutronBase, aim_rpc.AIMMappingRPCMixin):
c_dir = context.current['direction']
o_prot = context.original['protocol']
c_prot = context.current['protocol']
# Process classifier update for direction or protocol change
if ((o_dir != c_dir) or (
(o_prot in alib.REVERSIBLE_PROTOCOLS) != (
c_prot in alib.REVERSIBLE_PROTOCOLS))):
# TODO(Sumit): Update corresponding AIM FilterEntries
# and ContractSubjects
raise Exception
o_port_min, o_port_max = (
gpmdb.GroupPolicyMappingDbPlugin._get_min_max_ports_from_range(
context.original['port_range']))
c_port_min, c_port_max = (
gpmdb.GroupPolicyMappingDbPlugin._get_min_max_ports_from_range(
context.current['port_range']))
if ((o_dir == c_dir) and (o_prot == c_prot) and (
o_port_min == c_port_min) and (o_port_max == c_port_max)):
# none of the fields relevant to the aim_mapping have changed
# so no further processing is required
return
prules = self._db_plugin(context._plugin).get_policy_rules(
context._plugin_context,
filters={'policy_classifier_id': [context.current['id']]})
if not prules:
# this policy_classifier has not yet been assocaited with
# a policy_rule and hence will not have any mapped aim
# resources
return
prule_ids = [x['id'] for x in prules]
prule_sets = self._get_prss_for_policy_rules(context, prule_ids)
for pr in prules:
session = context._plugin_context.session
aim_ctx = self._get_aim_context(context)
# delete old filter_entries
self._delete_filter_entries_for_policy_rule(
session, aim_ctx, pr)
aim_filter = self._aim_filter(session, pr)
aim_reverse_filter = self._aim_filter(
session, pr, reverse_prefix=True)
entries = alib.get_filter_entries_for_policy_classifier(
context.current)
remove_aim_reverse_filter = None
if not entries['reverse_rules']:
# the updated classifier's protocol does not have
# reverse filter_entries
if self.aim.get(aim_ctx, aim_reverse_filter):
# so remove the older reverse filter if it exists
self.aim.delete(aim_ctx, aim_reverse_filter)
remove_aim_reverse_filter = aim_reverse_filter.name
# Unset the reverse filter name so that its not
# used in further processing
aim_reverse_filter.name = None
# create new filter_entries mapping to the updated
# classifier and associated with aim_filters
self._create_policy_rule_aim_mappings(
session, aim_ctx, pr, entries)
# update contract_subject to put the filter in the
# appropriate in/out buckets corresponding to the
# updated direction of the policy_classifier
if remove_aim_reverse_filter or (o_dir != c_dir):
for prs in prule_sets:
aim_contract_subject = self._get_aim_contract_subject(
session, prs)
# Remove the older reverse filter if needed
for filters in [aim_contract_subject.in_filters,
aim_contract_subject.out_filters]:
if remove_aim_reverse_filter in filters:
filters.remove(remove_aim_reverse_filter)
if o_dir != c_dir:
# First remove the filter from the older
# direction list
for flist in [aim_contract_subject.in_filters,
aim_contract_subject.out_filters]:
for fname in [aim_filter.name,
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]
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)
@log.log_method_call
def create_policy_rule_precommit(self, context):
entries = alib.get_filter_entries_for_policy_rule(context)
if entries['forward_rules']:
session = context._plugin_context.session
aim_ctx = self._get_aim_context(context)
aim_filter = self._aim_filter(session, context.current)
self.aim.create(aim_ctx, aim_filter)
self._create_aim_filter_entries(session, aim_ctx, aim_filter,
entries['forward_rules'])
if entries['reverse_rules']:
# Also create reverse rule
aim_filter = self._aim_filter(session, context.current,
reverse_prefix=True)
self.aim.create(aim_ctx, aim_filter)
self._create_aim_filter_entries(session, aim_ctx, aim_filter,
entries['reverse_rules'])
session = context._plugin_context.session
aim_ctx = self._get_aim_context(context)
self._create_policy_rule_aim_mappings(
session, aim_ctx, context.current, entries)
@log.log_method_call
def update_policy_rule_precommit(self, context):
@ -746,11 +823,12 @@ class AIMMappingDriver(nrd.CommonNeutronBase, aim_rpc.AIMMappingRPCMixin):
def delete_policy_rule_precommit(self, context):
session = context._plugin_context.session
aim_ctx = self._get_aim_context(context)
self._delete_filter_entries_for_policy_rule(session,
aim_ctx, context.current)
aim_filter = self._aim_filter(session, context.current)
aim_reverse_filter = self._aim_filter(
session, context.current, reverse_prefix=True)
for afilter in [aim_filter, aim_reverse_filter]:
self._delete_aim_filter_entries(aim_ctx, afilter)
for afilter in filter(None, [aim_filter, aim_reverse_filter]):
self.aim.delete(aim_ctx, afilter)
@log.log_method_call
@ -1123,6 +1201,21 @@ class AIMMappingDriver(nrd.CommonNeutronBase, aim_rpc.AIMMappingRPCMixin):
aim_filter_entry = aim_resource.FilterEntry(**kwargs)
return aim_filter_entry
def _create_policy_rule_aim_mappings(
self, session, aim_context, pr, entries):
if entries['forward_rules']:
aim_filter = self._aim_filter(session, pr)
self.aim.create(aim_context, aim_filter, overwrite=True)
self._create_aim_filter_entries(session, aim_context, aim_filter,
entries['forward_rules'])
if entries['reverse_rules']:
# Also create reverse rule
aim_filter = self._aim_filter(session, pr,
reverse_prefix=True)
self.aim.create(aim_context, aim_filter, overwrite=True)
self._create_aim_filter_entries(
session, aim_context, aim_filter, entries['reverse_rules'])
def _delete_aim_filter_entries(self, aim_context, aim_filter):
aim_filter_entries = self.aim.find(
aim_context, aim_resource.FilterEntry,
@ -1131,6 +1224,13 @@ class AIMMappingDriver(nrd.CommonNeutronBase, aim_rpc.AIMMappingRPCMixin):
for entry in aim_filter_entries:
self.aim.delete(aim_context, entry)
def _delete_filter_entries_for_policy_rule(self, session, aim_context, pr):
aim_filter = self._aim_filter(session, pr)
aim_reverse_filter = self._aim_filter(
session, pr, reverse_prefix=True)
for afilter in filter(None, [aim_filter, aim_reverse_filter]):
self._delete_aim_filter_entries(aim_context, afilter)
def _create_aim_filter_entries(self, session, aim_ctx, aim_filter,
filter_entries):
for k, v in filter_entries.iteritems():
@ -1163,7 +1263,7 @@ class AIMMappingDriver(nrd.CommonNeutronBase, aim_rpc.AIMMappingRPCMixin):
def _get_aim_filter_names(self, session, policy_rule):
# Forward and Reverse AIM Filter names for a Policy Rule
aim_filters = self._get_aim_filters(session, policy_rule)
aim_filter_names = [f.name for f in aim_filters.values()]
aim_filter_names = [f.name for f in aim_filters.values() if f]
return aim_filter_names
def _get_aim_filter_entries(self, session, policy_rule):
@ -1172,15 +1272,16 @@ class AIMMappingDriver(nrd.CommonNeutronBase, aim_rpc.AIMMappingRPCMixin):
filters = self._get_aim_filters(session, policy_rule)
filters_entries = {}
for k, v in filters.iteritems():
aim_filter_entries = self.aim.find(
aim_ctx, aim_resource.FilterEntry,
tenant_name=v.tenant_name, filter_name=v.name)
if not aim_filter_entries:
LOG.debug("No %s FilterEntry found in AIM DB", k)
else:
LOG.debug("Got %s FilterEntry: %s",
(aim_filter_entries, k))
filters_entries[k] = aim_filter_entries
if v:
aim_filter_entries = self.aim.find(
aim_ctx, aim_resource.FilterEntry,
tenant_name=v.tenant_name, filter_name=v.name)
if not aim_filter_entries:
LOG.debug("No %s FilterEntry found in AIM DB", k)
else:
LOG.debug("Got %s FilterEntry: %s",
(aim_filter_entries, k))
filters_entries[k] = aim_filter_entries
return filters_entries
def _aim_contract(self, session, policy_rule_set):
@ -2168,3 +2269,16 @@ class AIMMappingDriver(nrd.CommonNeutronBase, aim_rpc.AIMMappingRPCMixin):
gpmdb.L3PolicyMapping).filter(
gpmdb.L2PolicyMapping.l3_policy_id ==
context.current['id']).all()]
def _get_prss_for_policy_rules(self, context, pr_ids):
return [self._get_policy_rule_set(
context._plugin_context, x['id']) for x in (
context._plugin_context.session.query(
gpdb.PolicyRuleSet).join(
gpdb.PRSToPRAssociation,
gpdb.PRSToPRAssociation.policy_rule_set_id ==
gpdb.PolicyRuleSet.id).join(
gpdb.PolicyRule,
gpdb.PRSToPRAssociation.policy_rule_id ==
gpdb.PolicyRule.id).filter(
gpdb.PolicyRule.id.in_(pr_ids)).all())]

View File

@ -59,6 +59,48 @@ class OnlyOneAddressIsAllowedPerExternalSegment(gpexc.GroupPolicyBadRequest):
"APIC GBP driver.")
def get_filter_entries_for_policy_classifier(classifier):
# forward_rules and reverse_rules is each a dict of filter_entries
# with each entry in the dict having the filter_entry name as the
# key and the filter_entry attributes as the value
entries = {'forward_rules': None, 'reverse_rules': None}
x = 0
port_min, port_max = (
gpdb.GroupPolicyMappingDbPlugin._get_min_max_ports_from_range(
classifier['port_range']))
f_attrs = {'etherT': 'unspecified'}
if classifier['protocol']:
f_attrs['etherT'] = 'ip'
f_attrs['prot'] = classifier['protocol'].lower()
if port_min and port_max:
f_attrs['dToPort'] = port_max
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:
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
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:
for reply_type in ICMP_REPLY_TYPES:
x += 1
r_entry = copy.deepcopy(r_attrs)
r_entry['icmpv4T'] = reply_type
r_entries[_get_filter_entry_name(x)] = r_entry
entries['reverse_rules'] = r_entries
return entries
def get_filter_entries_for_policy_rule(context):
# forward_rules and reverse_rules is each a dict of filter_entries
# with each entry in the dict having the filter_entry name as the
@ -69,41 +111,8 @@ def get_filter_entries_for_policy_rule(context):
classifier = context._plugin.get_policy_classifier(
context._plugin_context,
context.current['policy_classifier_id'])
x = 0
if action['action_type'] in ALLOWING_ACTIONS:
port_min, port_max = (
gpdb.GroupPolicyMappingDbPlugin._get_min_max_ports_from_range(
classifier['port_range']))
f_attrs = {'etherT': 'unspecified'}
if classifier['protocol']:
f_attrs['etherT'] = 'ip'
f_attrs['prot'] = classifier['protocol'].lower()
if port_min and port_max:
f_attrs['dToPort'] = port_max
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:
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
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:
for reply_type in ICMP_REPLY_TYPES:
x += 1
r_entry = copy.deepcopy(r_attrs)
r_entry['icmpv4T'] = reply_type
r_entries[_get_filter_entry_name(x)] = r_entry
entries['reverse_rules'] = r_entries
entries = get_filter_entries_for_policy_classifier(classifier)
return entries

View File

@ -618,6 +618,74 @@ class AIMBaseTestCase(test_nr_base.CommonNeutronBaseTestCase,
filter_by(policy_target_group_id=ptg_id).
all())
def _validate_contract_subject_filters(
self, contract_subject, policy_rules):
self.assertFalse(contract_subject.bi_filters)
expected_in_filters = []
expected_out_filters = []
for idx in xrange(0, len(policy_rules)):
pc = self.show_policy_classifier(
policy_rules[idx]['policy_classifier_id'])['policy_classifier']
fwd_filter = self.name_mapper.policy_rule(None,
policy_rules[idx]['id'])
protocol = pc['protocol']
if protocol in alib.REVERSIBLE_PROTOCOLS:
rev_filter = 'reverse-%s' % fwd_filter
else:
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)
if rev_filter:
ef.append(rev_filter)
self.assertItemsEqual(expected_in_filters,
contract_subject.in_filters)
self.assertItemsEqual(expected_out_filters,
contract_subject.out_filters)
def _validate_merged_status(self, contract, contract_subject, prs):
merged_status = self.driver._merge_aim_status(
self._neutron_context.session,
[contract, contract_subject])
self.assertEqual(merged_status, prs['status'])
def _validate_policy_rule_set_aim_mapping(self, prs, rules):
self.show_policy_rule_set(prs['id'], expected_res_status=200)
aim_contract_name = str(self.name_mapper.policy_rule_set(
self._neutron_context.session, prs['id']))
aim_contracts = self.aim_mgr.find(
self._aim_context, aim_resource.Contract, name=aim_contract_name)
self.assertEqual(1, len(aim_contracts))
self.assertEqual(prs['name'], aim_contracts[0].display_name)
aim_contract_subjects = self.aim_mgr.find(
self._aim_context, aim_resource.ContractSubject,
name=aim_contract_name)
self.assertEqual(1, len(aim_contract_subjects))
self._validate_contract_subject_filters(
aim_contract_subjects[0], rules)
self._validate_merged_status(
aim_contracts[0], aim_contract_subjects[0], prs)
def _validate_policy_rule_deleted(self, prs):
aim_contract_name = str(self.name_mapper.policy_rule_set(
self._neutron_context.session, prs['id']))
self.show_policy_rule_set(prs['id'], expected_res_status=404)
aim_contracts = self.aim_mgr.find(
self._aim_context, aim_resource.Contract, name=aim_contract_name)
self.assertEqual(0, len(aim_contracts))
class TestGBPStatus(AIMBaseTestCase):
@ -2517,13 +2585,42 @@ class TestPolicyTargetRollback(AIMBaseTestCase):
class TestPolicyRuleBase(AIMBaseTestCase):
def _test_policy_rule_create_update_result(self, aim_tenant_name,
aim_filter_name,
aim_reverse_filter_name,
policy_rule):
filter_entries = []
aim_obj_list = []
for filter_name in [aim_filter_name, aim_reverse_filter_name]:
def _validate_filter_entry(self, policy_rule, afilter, filter_entry):
filter_entry_name = 'os-entry-0'
self.assertEqual(filter_entry_name, filter_entry.name)
pc = self.show_policy_classifier(
policy_rule['policy_classifier_id'])['policy_classifier']
expected_entries = alib.get_filter_entries_for_policy_classifier(pc)
if 'reverse' in afilter.name:
del expected_entries['forward_rules']
else:
del expected_entries['reverse_rules']
expected_filter_entry = self.driver._aim_filter_entry(
self._neutron_context.session, afilter, filter_entry_name,
alib.map_to_aim_filter_entry(
expected_entries.items()[0][1].items()[0][1]))
self.assertItemsEqual(
expected_filter_entry.__dict__,
# special processing to convert unicode to str
dict((str(k), str(v)) for k, v in filter_entry.__dict__.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']))
filter_names = [aim_filter_name]
protocol = self.show_policy_classifier(
policy_rule['policy_classifier_id'])[
'policy_classifier']['protocol']
if protocol in alib.REVERSIBLE_PROTOCOLS:
aim_reverse_filter_name = str(self.name_mapper.policy_rule(
self._neutron_context.session, policy_rule['id'],
prefix=alib.REVERSE_PREFIX))
filter_names.append(aim_reverse_filter_name)
aim_tenant_name = md.COMMON_TENANT_NAME
filter_entries, aim_obj_list = [], []
for filter_name in filter_names:
aim_filters = self.aim_mgr.find(
self._aim_context, aim_resource.Filter, name=filter_name)
aim_obj_list.append(aim_filters[0])
@ -2537,24 +2634,83 @@ class TestPolicyRuleBase(AIMBaseTestCase):
tenant_name=aim_filters[0].tenant_name,
filter_name=aim_filters[0].name)
self.assertEqual(1, len(aim_filter_entries))
self.assertEqual('os-entry-0', aim_filter_entries[0].name)
self._validate_filter_entry(policy_rule, aim_filters[0],
aim_filter_entries[0])
filter_entries.append(aim_filter_entries[0])
aim_obj_list.append(filter_entries)
prule = policy_rule
self.assertEqual(
filter_entries[0].dn,
prule['apic:distinguished_names']['Forward-FilterEntries'][0])
self.assertEqual(
filter_entries[1].dn,
prule['apic:distinguished_names']['Reverse-FilterEntries'][0])
policy_rule['apic:distinguished_names'][
'Forward-FilterEntries'][0])
if len(filter_names) > 1:
self.assertEqual(
filter_entries[1].dn, policy_rule[
'apic:distinguished_names']['Reverse-FilterEntries'][0])
merged_status = self._gbp_plugin.policy_driver_manager.policy_drivers[
'aim_mapping'].obj._merge_aim_status(self._neutron_context.session,
aim_obj_list)
self.assertEqual(merged_status, prule['status'])
self.assertEqual(merged_status, policy_rule['status'])
def _test_policy_rule_delete_aim_mapping(self, policy_rule):
aim_filter_name = str(self.name_mapper.policy_rule(
self._neutron_context.session, policy_rule['id']))
aim_reverse_filter_name = str(self.name_mapper.policy_rule(
self._neutron_context.session, policy_rule['id'],
prefix=alib.REVERSE_PREFIX))
for filter_name in [aim_filter_name, aim_reverse_filter_name]:
aim_filters = self.aim_mgr.find(
self._aim_context, aim_resource.Filter, name=filter_name)
self.assertEqual(0, len(aim_filters))
class TestPolicyRule(TestPolicyRuleBase):
def _test_policy_classifier_update(self, pr):
orig_pc_id = pr['policy_classifier_id']
pc = self.create_policy_classifier(
direction='in', protocol='tcp', port_range=80)['policy_classifier']
new_pr = self.update_policy_rule(
pr['id'], expected_res_status=200,
policy_classifier_id=pc['id'])['policy_rule']
self._test_policy_rule_aim_mapping(new_pr)
prs = self.create_policy_rule_set(
name="ctr", policy_rules=[new_pr['id']])[
'policy_rule_set']
self._validate_policy_rule_set_aim_mapping(prs, [new_pr])
# Remove Classifier port
self.update_policy_classifier(pc['id'], port_range=None)
new_pr = self.update_policy_rule(
pr['id'], expected_res_status=200,
policy_classifier_id=pc['id'])['policy_rule']
self._test_policy_rule_aim_mapping(new_pr)
# Change direction
self.update_policy_classifier(pc['id'], direction='out')
new_pr = self.update_policy_rule(
pr['id'], expected_res_status=200,
policy_classifier_id=pc['id'])['policy_rule']
self._test_policy_rule_aim_mapping(new_pr)
# Check with protocol that does not require reverse filter
self.update_policy_classifier(pc['id'], protocol=None)
new_pr = self.update_policy_rule(
pr['id'], expected_res_status=200,
policy_classifier_id=pc['id'])['policy_rule']
self._test_policy_rule_aim_mapping(new_pr)
self.delete_policy_rule_set(prs['id'], expected_res_status=204)
new_pr = self.update_policy_rule(
pr['id'], expected_res_status=200,
policy_classifier_id=orig_pc_id)['policy_rule']
self._test_policy_rule_aim_mapping(new_pr)
self.delete_policy_classifier(pc['id'], expected_res_status=204)
def test_policy_rule_lifecycle(self):
action1 = self.create_policy_action(
action_type='redirect')['policy_action']
@ -2569,33 +2725,19 @@ class TestPolicyRule(TestPolicyRuleBase):
pr_name = pr['name']
self.show_policy_rule(pr_id, expected_res_status=200)
aim_filter_name = str(self.name_mapper.policy_rule(
self._neutron_context.session, pr_id))
aim_reverse_filter_name = str(self.name_mapper.policy_rule(
self._neutron_context.session, pr_id,
prefix=alib.REVERSE_PREFIX))
aim_tenant_name = md.COMMON_TENANT_NAME
self._test_policy_rule_create_update_result(
aim_tenant_name, aim_filter_name, aim_reverse_filter_name, pr)
self._test_policy_rule_aim_mapping(pr)
pr_name = 'new name'
new_pr = self.update_policy_rule(pr_id, expected_res_status=200,
name=pr_name)['policy_rule']
aim_filter_name = str(self.name_mapper.policy_rule(
self._neutron_context.session, pr_id))
aim_reverse_filter_name = str(self.name_mapper.policy_rule(
self._neutron_context.session, pr_id,
prefix=alib.REVERSE_PREFIX))
self._test_policy_rule_create_update_result(
aim_tenant_name, aim_filter_name, aim_reverse_filter_name, new_pr)
self._test_policy_rule_aim_mapping(new_pr)
self._test_policy_classifier_update(new_pr)
self.delete_policy_rule(pr_id, expected_res_status=204)
self.show_policy_rule(pr_id, expected_res_status=404)
for filter_name in [aim_filter_name, aim_reverse_filter_name]:
aim_filters = self.aim_mgr.find(
self._aim_context, aim_resource.Filter, name=filter_name)
self.assertEqual(0, len(aim_filters))
self._test_policy_rule_delete_aim_mapping(new_pr)
class TestPolicyRuleRollback(TestPolicyRuleBase):
@ -2638,22 +2780,11 @@ class TestPolicyRuleRollback(TestPolicyRuleBase):
pr = self.create_policy_rule(
name="pr1", policy_classifier_id=classifier['id'],
policy_actions=[action1['id']])['policy_rule']
aim_filter_name = str(self.name_mapper.policy_rule(
self._neutron_context.session, pr['id']))
aim_reverse_filter_name = str(self.name_mapper.policy_rule(
self._neutron_context.session, pr['id'],
prefix=alib.REVERSE_PREFIX))
self._test_policy_rule_aim_mapping(pr)
self.update_policy_rule(pr['id'], expected_res_status=500,
name='new name')
aim_filters = self.aim_mgr.find(
self._aim_context, aim_resource.Filter, name=aim_filter_name)
self.assertEqual(1, len(aim_filters))
aim_filters = self.aim_mgr.find(
self._aim_context, aim_resource.Filter,
name=aim_reverse_filter_name)
self.assertEqual(1, len(aim_filters))
self._test_policy_rule_aim_mapping(pr)
# restore mock
self.dummy.update_policy_rule_precommit = orig_func
@ -2674,98 +2805,31 @@ class TestPolicyRuleRollback(TestPolicyRuleBase):
pr_id = pr['id']
self.delete_policy_rule(pr_id, expected_res_status=500)
aim_filter_name = str(self.name_mapper.policy_rule(
self._neutron_context.session, pr_id))
aim_reverse_filter_name = str(self.name_mapper.policy_rule(
self._neutron_context.session, pr_id,
prefix=alib.REVERSE_PREFIX))
aim_tenant_name = md.COMMON_TENANT_NAME
self._test_policy_rule_create_update_result(
aim_tenant_name, aim_filter_name, aim_reverse_filter_name, pr)
self._test_policy_rule_aim_mapping(pr)
# restore mock
self.dummy.delete_policy_rule_precommit = orig_func
class TestPolicyRuleSetBase(AIMBaseTestCase):
def _validate_contract_subject_filters(
self, contract_subject, policy_rules):
expected_in_filters = []
expected_out_filters = []
for idx in xrange(0, len(policy_rules)):
# In this setup each policy_rule should result in
# forward and reverse filters
fwd_filter = self.name_mapper.policy_rule(None,
policy_rules[idx]['id'])
rev_filter = 'reverse-%s' % fwd_filter
if idx < 2: # in/bi-directional classifier
expected_in_filters.append(fwd_filter)
expected_in_filters.append(rev_filter)
if idx != 1: # out/bi-directional classifier
expected_out_filters.append(fwd_filter)
expected_out_filters.append(rev_filter)
self.assertFalse(contract_subject.bi_filters)
self.assertItemsEqual(expected_in_filters,
contract_subject.in_filters)
self.assertItemsEqual(expected_out_filters,
contract_subject.out_filters)
def _validate_merged_status(self, contract, contract_subject, prs):
merged_status = self.driver._merge_aim_status(
self._neutron_context.session,
[contract, contract_subject])
self.assertEqual(merged_status, prs['status'])
class TestPolicyRuleSet(TestPolicyRuleSetBase):
class TestPolicyRuleSet(AIMBaseTestCase):
def test_policy_rule_set_lifecycle(self):
rules = self._create_3_direction_rules()
prs = self.create_policy_rule_set(
name="ctr", policy_rules=[x['id'] for x in rules])[
'policy_rule_set']
self.show_policy_rule_set(prs['id'], expected_res_status=200)
aim_contract_name = str(self.name_mapper.policy_rule_set(
self._neutron_context.session, prs['id']))
aim_contracts = self.aim_mgr.find(
self._aim_context, aim_resource.Contract, name=aim_contract_name)
self.assertEqual(1, len(aim_contracts))
self.assertEqual(prs['name'], aim_contracts[0].display_name)
aim_contract_subjects = self.aim_mgr.find(
self._aim_context, aim_resource.ContractSubject,
name=aim_contract_name)
self.assertEqual(1, len(aim_contract_subjects))
self._validate_contract_subject_filters(
aim_contract_subjects[0], rules)
self._validate_merged_status(
aim_contracts[0], aim_contract_subjects[0], prs)
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],
expected_res_status=200)['policy_rule_set']
aim_contract_subjects = self.aim_mgr.find(
self._aim_context, aim_resource.ContractSubject,
name=aim_contract_name)
self.assertEqual(1, len(aim_contract_subjects))
self._validate_contract_subject_filters(
aim_contract_subjects[0], new_rules)
self._validate_merged_status(
aim_contracts[0], aim_contract_subjects[0], prs)
self._validate_policy_rule_set_aim_mapping(prs, new_rules)
self.delete_policy_rule_set(prs['id'], expected_res_status=204)
self.show_policy_rule_set(prs['id'], expected_res_status=404)
aim_contracts = self.aim_mgr.find(
self._aim_context, aim_resource.Contract, name=aim_contract_name)
self.assertEqual(0, len(aim_contracts))
class TestPolicyRuleSetRollback(TestPolicyRuleSetBase):
class TestPolicyRuleSetRollback(AIMBaseTestCase):
def test_policy_rule_set_create_fail(self):
orig_func = self.dummy.create_policy_rule_set_precommit
@ -2799,15 +2863,7 @@ class TestPolicyRuleSetRollback(TestPolicyRuleSetBase):
self.update_policy_rule_set(
prs['id'], expected_res_status=500, name='new name')
aim_contract_name = str(self.name_mapper.policy_rule_set(
self._neutron_context.session, prs['id']))
aim_contracts = self.aim_mgr.find(
self._aim_context, aim_resource.Contract, name=aim_contract_name)
self.assertEqual(1, len(aim_contracts))
aim_contract_subjects = self.aim_mgr.find(
self._aim_context, aim_resource.ContractSubject,
name=aim_contract_name)
self.assertEqual(1, len(aim_contract_subjects))
self._validate_policy_rule_set_aim_mapping(prs, rules)
# restore mock
self.dummy.update_policy_rule_set_precommit = orig_func
@ -2823,15 +2879,7 @@ class TestPolicyRuleSetRollback(TestPolicyRuleSetBase):
self.delete_policy_rule_set(prs['id'], expected_res_status=500)
aim_contract_name = str(self.name_mapper.policy_rule_set(
self._neutron_context.session, prs['id']))
aim_contracts = self.aim_mgr.find(
self._aim_context, aim_resource.Contract, name=aim_contract_name)
self.assertEqual(1, len(aim_contracts))
aim_contract_subjects = self.aim_mgr.find(
self._aim_context, aim_resource.ContractSubject,
name=aim_contract_name)
self.assertEqual(1, len(aim_contract_subjects))
self._validate_policy_rule_set_aim_mapping(prs, rules)
# restore mock
self.dummy.delete_policy_rule_set_precommit = orig_func