Merge "[aim-mapping] Implement policy classifier update"
This commit is contained in:
commit
76ee7a5529
@ -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())]
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user