AIM Policy Driver - Part 3 - Policy Rules
Policy Rule is mapped to an AIM Filter, and the Policy Classifier is mapped to an AIM FilterEntry. The older apic_mapping driver has been refactored slightly to create a new library of functions called apic_mapping_lib that can be used both from the apic_mapping driver as well as the new aim_mapping driver. The rollback testing for the aim_driver has been enhanced by adding the dummy_driver as second policy driver for testing, and having the dummy_driver raise exception to trigger the rollback. This ensures that the entire code in the aim_driver is executed before the exception, and hence the complete rollback is tested. This also fixes a bug in the _get_status_from_drivers() logic which resulted in the driver extension attributes being dropped from the result that was returned. This fix now allows validating the "apic:distinguished_names". Change-Id: I7da7ecedd33a4c38623c944e366fbc01d216fdfa
This commit is contained in:
@@ -23,6 +23,10 @@ EXTENDED_ATTRIBUTES_2_0 = {
|
||||
DIST_NAMES: {
|
||||
'allow_post': False, 'allow_put': False, 'is_visible': True},
|
||||
},
|
||||
gp.POLICY_RULES: {
|
||||
DIST_NAMES: {
|
||||
'allow_post': False, 'allow_put': False, 'is_visible': True},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -60,12 +60,23 @@ class APICNameMapper(object):
|
||||
def mapper(name_type):
|
||||
"""Wrapper to land all the common operations between mappers."""
|
||||
def wrap(func):
|
||||
def inner(inst, session, resource_id, resource_name=None):
|
||||
def inner(inst, session, resource_id, resource_name=None,
|
||||
prefix=None):
|
||||
# REVISIT(Bob): Optional argument for reserving characters in
|
||||
# the prefix?
|
||||
saved_name = inst.db.get_apic_name(session,
|
||||
resource_id,
|
||||
name_type)
|
||||
if saved_name:
|
||||
result = saved_name[0]
|
||||
# REVISIT(Sumit): Should this name mapper be aware of
|
||||
# this prefixing logic, or should we instead prepend
|
||||
# the prefix at the point from where this is being
|
||||
# invoked. The latter approach has the disadvantage
|
||||
# of having to replicate the logic in many places.
|
||||
if prefix:
|
||||
result = prefix + result
|
||||
result = truncate(result, MAX_APIC_NAME_LENGTH)
|
||||
return result
|
||||
name = ''
|
||||
try:
|
||||
@@ -94,6 +105,9 @@ class APICNameMapper(object):
|
||||
|
||||
inst.db.add_apic_name(session, resource_id,
|
||||
name_type, result)
|
||||
if prefix:
|
||||
result = prefix + result
|
||||
result = truncate(result, MAX_APIC_NAME_LENGTH)
|
||||
return result
|
||||
return inner
|
||||
return wrap
|
||||
@@ -155,10 +169,9 @@ class APICNameMapper(object):
|
||||
return policy_rule_set['name']
|
||||
|
||||
@mapper(NAME_TYPE_POLICY_RULE)
|
||||
def policy_rule(self, context, policy_rule_id):
|
||||
policy_rule = context._plugin.get_policy_rule(context._plugin_context,
|
||||
policy_rule_id)
|
||||
return policy_rule['name']
|
||||
def policy_rule(self, context, policy_rule_id,
|
||||
policy_rule_name=None):
|
||||
return policy_rule_name
|
||||
|
||||
@mapper(NAME_TYPE_EXTERNAL_SEGMENT)
|
||||
def external_segment(self, context, external_segment_id):
|
||||
|
||||
@@ -29,10 +29,19 @@ from gbpservice.neutron.services.grouppolicy.common import (
|
||||
from gbpservice.neutron.services.grouppolicy.common import exceptions as gpexc
|
||||
from gbpservice.neutron.services.grouppolicy.drivers import (
|
||||
neutron_resources as nrd)
|
||||
from gbpservice.neutron.services.grouppolicy.drivers.cisco.apic import (
|
||||
apic_mapping_lib as alib)
|
||||
from gbpservice.neutron.services.grouppolicy import plugin as gbp_plugin
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
FORWARD = 'Forward'
|
||||
REVERSE = 'Reverse'
|
||||
FILTER_DIRECTIONS = {FORWARD: False, REVERSE: True}
|
||||
FORWARD_FILTER_ENTRIES = 'Forward-FilterEntries'
|
||||
REVERSE_FILTER_ENTRIES = 'Reverse-FilterEntries'
|
||||
|
||||
# Definitions duplicated from apicapi lib
|
||||
APIC_OWNED = 'apic_owned_'
|
||||
|
||||
|
||||
@@ -190,33 +199,74 @@ class AIMMappingDriver(nrd.CommonNeutronBase):
|
||||
|
||||
@log.log_method_call
|
||||
def create_policy_rule_precommit(self, context):
|
||||
pass
|
||||
# TODO(sumit): uncomment the following when AIM supports TenantFilter
|
||||
# aim_context = aim_manager.AimContext(context._plugin_context.session)
|
||||
# tenant = context.current['tenant_id']
|
||||
# pr_id = context.current['id']
|
||||
# pr_name = context.current['name']
|
||||
# rn = self.mapper.tenant_filter(tenant, pr_id, name=pr_name)
|
||||
# tf = aim_resource.TenantFilter(tenant_rn=tenant, rn=rn)
|
||||
# self.aim.create(aim_context, tf)
|
||||
# pr_db = context._plugin_context.session.query(
|
||||
# gpdb.PolicyRule).get(context.current['id'])
|
||||
# context._plugin_context.session.expunge(pr_db)
|
||||
# TODO(sumit): uncomment the following line when the GBP resource
|
||||
# is appropriately extended to hold AIM references
|
||||
# pr_db['aim_id'] = rn
|
||||
# context._plugin_context.session.add(pr_db)
|
||||
entries = alib.get_filter_entries_for_policy_rule(context)
|
||||
if entries['forward_rules']:
|
||||
session = context._plugin_context.session
|
||||
aim_ctx = aim_context.AimContext(session)
|
||||
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'])
|
||||
|
||||
@log.log_method_call
|
||||
def update_policy_rule_precommit(self, context):
|
||||
self.delete_policy_rule_precommit(context)
|
||||
self.create_policy_rule_precommit(context)
|
||||
|
||||
@log.log_method_call
|
||||
def delete_policy_rule_precommit(self, context):
|
||||
pass
|
||||
# TODO(sumit): uncomment the following when AIM supports TenantFilter
|
||||
# aim_context = aim_manager.AimContext(context._plugin_context.session)
|
||||
# tenant = context.current['tenant_id']
|
||||
# pr_id = context.current['id']
|
||||
# rn = self.mapper.tenant_filter(tenant, pr_id)
|
||||
# tf = aim_resource.TenantFilter(tenant_rn=tenant, rn=rn)
|
||||
# self.aim.delete(aim_context, tf)
|
||||
session = context._plugin_context.session
|
||||
aim_ctx = aim_context.AimContext(session)
|
||||
aim_filter = self._aim_filter(session, context.current)
|
||||
aim_filter_entries = self.aim.find(
|
||||
aim_ctx, aim_resource.FilterEntry,
|
||||
tenant_name=aim_filter.tenant_name,
|
||||
filter_name=aim_filter.name)
|
||||
for entry in aim_filter_entries:
|
||||
self.aim.delete(aim_ctx, entry)
|
||||
self.aim.delete(aim_ctx, aim_filter)
|
||||
aim_reverse_filter = self._aim_filter(
|
||||
session, context.current, reverse_prefix=True)
|
||||
if aim_reverse_filter:
|
||||
aim_reverse_filter_entries = self.aim.find(
|
||||
aim_ctx, aim_resource.FilterEntry,
|
||||
tenant_name=aim_reverse_filter.tenant_name,
|
||||
filter_name=aim_reverse_filter.name)
|
||||
for entry in aim_reverse_filter_entries:
|
||||
self.aim.delete(aim_ctx, entry)
|
||||
self.aim.delete(aim_ctx, aim_reverse_filter)
|
||||
self.name_mapper.delete_apic_name(session, context.current['id'])
|
||||
|
||||
@log.log_method_call
|
||||
def extend_policy_rule_dict(self, session, result):
|
||||
result[cisco_apic.DIST_NAMES] = {}
|
||||
aim_filter_entries = self._get_aim_filter_entries(session, result)
|
||||
for k, v in aim_filter_entries.iteritems():
|
||||
dn_list = []
|
||||
for entry in v:
|
||||
dn_list.append(entry.dn)
|
||||
if k == FORWARD:
|
||||
result[cisco_apic.DIST_NAMES].update(
|
||||
{FORWARD_FILTER_ENTRIES: dn_list})
|
||||
else:
|
||||
result[cisco_apic.DIST_NAMES].update(
|
||||
{REVERSE_FILTER_ENTRIES: dn_list})
|
||||
|
||||
@log.log_method_call
|
||||
def get_policy_rule_status(self, context):
|
||||
session = context._plugin_context.session
|
||||
aim_filters = self._get_aim_filters(session, context.current)
|
||||
aim_filter_entries = self._get_aim_filter_entries(session,
|
||||
context.current)
|
||||
context.current['status'] = self._merge_aim_status(
|
||||
session, aim_filters.values() + aim_filter_entries.values())
|
||||
|
||||
def _aim_tenant_name(self, session, tenant_id):
|
||||
tenant_name = self.name_mapper.tenant(session, tenant_id)
|
||||
@@ -256,6 +306,79 @@ class AIMMappingDriver(nrd.CommonNeutronBase):
|
||||
LOG.debug("Got epg: %s", epg_fetched.__dict__)
|
||||
return epg_fetched
|
||||
|
||||
def _aim_filter(self, session, pr, reverse_prefix=False):
|
||||
# This returns a new AIM Filter resource
|
||||
tenant_id = pr['tenant_id']
|
||||
tenant_name = self._aim_tenant_name(session, tenant_id)
|
||||
id = pr['id']
|
||||
name = pr['name']
|
||||
if reverse_prefix:
|
||||
filter_name = self.name_mapper.policy_rule(
|
||||
session, id, resource_name=name, prefix=alib.REVERSE_PREFIX)
|
||||
else:
|
||||
filter_name = self.name_mapper.policy_rule(session, id,
|
||||
resource_name=name)
|
||||
LOG.debug("Mapped policy_rule_id %(id)s with name %(name)s to",
|
||||
"%(apic_name)s",
|
||||
{'id': id, 'name': name, 'apic_name': filter_name})
|
||||
kwargs = {'tenant_name': str(tenant_name),
|
||||
'name': str(filter_name)}
|
||||
|
||||
aim_filter = aim_resource.Filter(**kwargs)
|
||||
return aim_filter
|
||||
|
||||
def _aim_filter_entry(self, session, aim_filter, filter_entry_name,
|
||||
filter_entry_attrs):
|
||||
# This returns a new AIM FilterEntry resource
|
||||
tenant_name = aim_filter.tenant_name
|
||||
filter_name = aim_filter.name
|
||||
kwargs = {'tenant_name': tenant_name,
|
||||
'filter_name': filter_name,
|
||||
'name': filter_entry_name}
|
||||
kwargs.update(filter_entry_attrs)
|
||||
|
||||
aim_filter_entry = aim_resource.FilterEntry(**kwargs)
|
||||
return aim_filter_entry
|
||||
|
||||
def _create_aim_filter_entries(self, session, aim_ctx, aim_filter,
|
||||
filter_entries):
|
||||
for k, v in filter_entries.iteritems():
|
||||
aim_filter_entry = self._aim_filter_entry(
|
||||
session, aim_filter, k, v)
|
||||
self.aim.create(aim_ctx, aim_filter_entry)
|
||||
|
||||
def _get_aim_filters(self, session, policy_rule):
|
||||
# This gets the Forward and Reverse Filters from the AIM DB
|
||||
aim_ctx = aim_context.AimContext(session)
|
||||
filters = {}
|
||||
for k, v in FILTER_DIRECTIONS.iteritems():
|
||||
aim_filter = self._aim_filter(session, policy_rule, v)
|
||||
aim_filter_fetched = self.aim.get(aim_ctx, aim_filter)
|
||||
if not aim_filter_fetched:
|
||||
LOG.debug("No %s Filter found in AIM DB", k)
|
||||
else:
|
||||
LOG.debug("Got %s Filter: %s",
|
||||
(aim_filter_fetched.__dict__, k))
|
||||
filters[k] = aim_filter_fetched
|
||||
return filters
|
||||
|
||||
def _get_aim_filter_entries(self, session, policy_rule):
|
||||
# This gets the Forward and Reverse FilterEntries from the AIM DB
|
||||
aim_ctx = aim_context.AimContext(session)
|
||||
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
|
||||
return filters_entries
|
||||
|
||||
def _aim_bridge_domain(self, session, tenant_id, network_id, network_name):
|
||||
# This returns a new AIM BD resource
|
||||
tenant_name = self._aim_tenant_name(session, tenant_id)
|
||||
@@ -335,5 +458,20 @@ class AIMMappingDriver(nrd.CommonNeutronBase):
|
||||
else:
|
||||
return gp_const.STATUS_ACTIVE
|
||||
|
||||
def _merge_aim_status(self, session, aim_resource_obj_list):
|
||||
# Note that this implementation assumes that this driver
|
||||
# is the only policy driver configured, and no merging
|
||||
# with any previous status is required.
|
||||
# When merging states of multiple AIM objects, the status
|
||||
# priority is ERROR > BUILD > ACTIVE.
|
||||
merged_status = gp_const.STATUS_ACTIVE
|
||||
for aim_obj in aim_resource_obj_list:
|
||||
status = self._map_aim_status(session, aim_obj)
|
||||
if status != gp_const.STATUS_ACTIVE:
|
||||
merged_status = status
|
||||
if merged_status == gp_const.STATUS_ERROR:
|
||||
break
|
||||
return merged_status
|
||||
|
||||
def _db_plugin(self, plugin_obj):
|
||||
return super(gbp_plugin.GroupPolicyPlugin, plugin_obj)
|
||||
|
||||
@@ -56,6 +56,8 @@ from gbpservice.neutron.services.grouppolicy.common import constants as g_const
|
||||
from gbpservice.neutron.services.grouppolicy.common import exceptions as gpexc
|
||||
from gbpservice.neutron.services.grouppolicy.drivers import (
|
||||
resource_mapping as api)
|
||||
from gbpservice.neutron.services.grouppolicy.drivers.cisco.apic import (
|
||||
apic_mapping_lib as alib)
|
||||
from gbpservice.neutron.services.grouppolicy.drivers.cisco.apic import (
|
||||
name_manager as name_manager)
|
||||
from gbpservice.neutron.services.grouppolicy.drivers.cisco.apic import (
|
||||
@@ -212,7 +214,6 @@ class TenantSpecificNatEpg(model_base.BASEV2):
|
||||
tenant_id = sa.Column(sa.String(36), primary_key=True)
|
||||
|
||||
|
||||
REVERSE_PREFIX = 'reverse-'
|
||||
SHADOW_PREFIX = 'Shd-'
|
||||
AUTO_PREFIX = 'Auto-'
|
||||
SERVICE_PREFIX = 'Svc-'
|
||||
@@ -223,13 +224,8 @@ APIC_OWNED = 'apic_owned_'
|
||||
APIC_OWNED_RES = 'apic_owned_res_'
|
||||
PROMISCUOUS_TYPES = [n_constants.DEVICE_OWNER_DHCP,
|
||||
n_constants.DEVICE_OWNER_LOADBALANCER]
|
||||
ALLOWING_ACTIONS = [g_const.GP_ACTION_ALLOW, g_const.GP_ACTION_REDIRECT]
|
||||
REVERTIBLE_PROTOCOLS = [n_constants.PROTO_NAME_TCP.lower(),
|
||||
n_constants.PROTO_NAME_UDP.lower(),
|
||||
n_constants.PROTO_NAME_ICMP.lower()]
|
||||
PROXY_PORT_PREFIX = "opflex_proxy:"
|
||||
EOC_PREFIX = "opflex_eoc:"
|
||||
ICMP_REPLY_TYPES = ['echo-rep', 'dst-unreach', 'src-quench', 'time-exceeded']
|
||||
|
||||
|
||||
class ApicMappingDriver(api.ResourceMappingDriver,
|
||||
@@ -750,49 +746,21 @@ class ApicMappingDriver(api.ResourceMappingDriver,
|
||||
pass
|
||||
|
||||
def create_policy_rule_postcommit(self, context, transaction=None):
|
||||
action = context._plugin.get_policy_action(
|
||||
context._plugin_context, context.current['policy_actions'][0])
|
||||
classifier = context._plugin.get_policy_classifier(
|
||||
context._plugin_context,
|
||||
context.current['policy_classifier_id'])
|
||||
if action['action_type'] in ALLOWING_ACTIONS:
|
||||
port_min, port_max = (
|
||||
gpdb.GroupPolicyMappingDbPlugin._get_min_max_ports_from_range(
|
||||
classifier['port_range']))
|
||||
attrs = {'etherT': 'unspecified'}
|
||||
if classifier['protocol']:
|
||||
attrs['etherT'] = 'ip'
|
||||
attrs['prot'] = classifier['protocol'].lower()
|
||||
if port_min and port_max:
|
||||
attrs['dToPort'] = port_max
|
||||
attrs['dFromPort'] = port_min
|
||||
entries = alib.get_filter_entries_for_policy_rule(context)
|
||||
if entries['forward_rules']:
|
||||
tenant = self._tenant_by_sharing_policy(context.current)
|
||||
policy_rule = self.name_mapper.policy_rule(context,
|
||||
context.current)
|
||||
entries = [attrs]
|
||||
with self.apic_manager.apic.transaction(transaction) as trs:
|
||||
self._create_tenant_filter(policy_rule, tenant, entries,
|
||||
self._create_tenant_filter(policy_rule, tenant,
|
||||
entries['forward_rules'],
|
||||
transaction=trs)
|
||||
# Also create reverse rule
|
||||
if attrs.get('prot') in REVERTIBLE_PROTOCOLS:
|
||||
if entries['reverse_rules']:
|
||||
# Also create reverse rule
|
||||
policy_rule = self.name_mapper.policy_rule(
|
||||
context, context.current, prefix=REVERSE_PREFIX)
|
||||
if attrs.get('dToPort') and attrs.get('dFromPort'):
|
||||
attrs.pop('dToPort')
|
||||
attrs.pop('dFromPort')
|
||||
attrs['sToPort'] = port_max
|
||||
attrs['sFromPort'] = port_min
|
||||
if attrs['prot'] == n_constants.PROTO_NAME_TCP.lower():
|
||||
# Only match on established sessions
|
||||
attrs['tcpRules'] = 'est'
|
||||
if attrs['prot'] == n_constants.PROTO_NAME_ICMP.lower():
|
||||
# create more entries:
|
||||
entries = []
|
||||
for reply_type in ICMP_REPLY_TYPES:
|
||||
entry = copy.deepcopy(attrs)
|
||||
entry['icmpv4T'] = reply_type
|
||||
entries.append(entry)
|
||||
self._create_tenant_filter(policy_rule, tenant, entries,
|
||||
context, context.current, prefix=alib.REVERSE_PREFIX)
|
||||
self._create_tenant_filter(policy_rule, tenant,
|
||||
entries['reverse_rules'],
|
||||
transaction=trs)
|
||||
|
||||
def create_policy_rule_set_precommit(self, context):
|
||||
@@ -1041,7 +1009,7 @@ class ApicMappingDriver(api.ResourceMappingDriver,
|
||||
transaction=trs)
|
||||
# Delete policy reverse rule
|
||||
policy_rule = self.name_mapper.policy_rule(
|
||||
context, context.current, prefix=REVERSE_PREFIX)
|
||||
context, context.current, prefix=alib.REVERSE_PREFIX)
|
||||
self.apic_manager.delete_tenant_filter(policy_rule, owner=tenant,
|
||||
transaction=trs)
|
||||
|
||||
@@ -1345,8 +1313,8 @@ class ApicMappingDriver(api.ResourceMappingDriver,
|
||||
c_prot = context.current['protocol']
|
||||
# TODO(ivar): Optimize by aggregating on PRS ID
|
||||
if ((o_dir != c_dir) or
|
||||
((o_prot in REVERTIBLE_PROTOCOLS) !=
|
||||
(c_prot in REVERTIBLE_PROTOCOLS))):
|
||||
((o_prot in alib.REVERSIBLE_PROTOCOLS) !=
|
||||
(c_prot in alib.REVERSIBLE_PROTOCOLS))):
|
||||
for prs in context._plugin.get_policy_rule_sets(
|
||||
admin_context,
|
||||
filters={'id': rule['policy_rule_sets']}):
|
||||
@@ -1612,7 +1580,7 @@ class ApicMappingDriver(api.ResourceMappingDriver,
|
||||
rule['policy_classifier_id'])
|
||||
policy_rule = self.name_mapper.policy_rule(context, rule)
|
||||
reverse_policy_rule = self.name_mapper.policy_rule(
|
||||
context, rule, prefix=REVERSE_PREFIX)
|
||||
context, rule, prefix=alib.REVERSE_PREFIX)
|
||||
rule_owner = self._tenant_by_sharing_policy(rule)
|
||||
with self.apic_manager.apic.transaction(transaction) as trs:
|
||||
if classifier['direction'] in in_dir:
|
||||
@@ -1623,7 +1591,7 @@ class ApicMappingDriver(api.ResourceMappingDriver,
|
||||
rule_owner=rule_owner)
|
||||
if classifier['protocol'] and (
|
||||
classifier['protocol'].lower() in
|
||||
REVERTIBLE_PROTOCOLS):
|
||||
alib.REVERSIBLE_PROTOCOLS):
|
||||
(self.apic_manager.
|
||||
manage_contract_subject_out_filter(
|
||||
contract, contract, reverse_policy_rule,
|
||||
@@ -1637,7 +1605,7 @@ class ApicMappingDriver(api.ResourceMappingDriver,
|
||||
rule_owner=rule_owner)
|
||||
if classifier['protocol'] and (
|
||||
classifier['protocol'].lower() in
|
||||
REVERTIBLE_PROTOCOLS):
|
||||
alib.REVERSIBLE_PROTOCOLS):
|
||||
(self.apic_manager.
|
||||
manage_contract_subject_in_filter(
|
||||
contract, contract, reverse_policy_rule,
|
||||
@@ -2621,7 +2589,7 @@ class ApicMappingDriver(api.ResourceMappingDriver,
|
||||
contract, owner=tenant, transaction=trs)
|
||||
|
||||
# Create ARP filter/subject
|
||||
attrs = {'etherT': 'arp'}
|
||||
attrs = alib.get_arp_filter_entry()
|
||||
self._associate_service_filter(tenant, contract, 'arp',
|
||||
'arp', transaction=trs, **attrs)
|
||||
|
||||
@@ -2645,61 +2613,40 @@ class ApicMappingDriver(api.ResourceMappingDriver,
|
||||
tenant, shadow_epg, contract, provider=True,
|
||||
contract_owner=tenant, transaction=trs)
|
||||
|
||||
entries = alib.get_service_contract_filter_entries()
|
||||
|
||||
# Create DNS filter/subject
|
||||
attrs = {'etherT': 'ip',
|
||||
'prot': 'udp',
|
||||
'dToPort': 'dns',
|
||||
'dFromPort': 'dns'}
|
||||
self._associate_service_filter(tenant, contract, 'dns',
|
||||
'dns', transaction=trs, **attrs)
|
||||
attrs = {'etherT': 'ip',
|
||||
'prot': 'udp',
|
||||
'sToPort': 'dns',
|
||||
'sFromPort': 'dns'}
|
||||
'dns', transaction=trs,
|
||||
**entries['dns'])
|
||||
self._associate_service_filter(tenant, contract, 'dns',
|
||||
'r-dns', transaction=trs, **attrs)
|
||||
'r-dns', transaction=trs,
|
||||
**entries['r-dns'])
|
||||
|
||||
# Create HTTP filter/subject
|
||||
attrs = {'etherT': 'ip',
|
||||
'prot': 'tcp',
|
||||
'dToPort': 80,
|
||||
'dFromPort': 80}
|
||||
self._associate_service_filter(tenant, contract, 'http',
|
||||
'http', transaction=trs, **attrs)
|
||||
attrs = {'etherT': 'ip',
|
||||
'prot': 'tcp',
|
||||
'sToPort': 80,
|
||||
'sFromPort': 80}
|
||||
'http', transaction=trs,
|
||||
**entries['http'])
|
||||
self._associate_service_filter(tenant, contract, 'http',
|
||||
'r-http', transaction=trs, **attrs)
|
||||
'r-http', transaction=trs,
|
||||
**entries['r-http'])
|
||||
|
||||
attrs = {'etherT': 'ip',
|
||||
'prot': 'icmp'}
|
||||
self._associate_service_filter(tenant, contract, 'icmp',
|
||||
'icmp', transaction=trs, **attrs)
|
||||
'icmp', transaction=trs,
|
||||
**entries['icmp'])
|
||||
|
||||
# Create DHCP filter/subject
|
||||
attrs = {'etherT': 'ip',
|
||||
'prot': 'udp',
|
||||
'dToPort': 68,
|
||||
'dFromPort': 68,
|
||||
'sToPort': 67,
|
||||
'sFromPort': 67}
|
||||
self._associate_service_filter(tenant, contract, 'dhcp',
|
||||
'dhcp', transaction=trs, **attrs)
|
||||
attrs = {'etherT': 'ip',
|
||||
'prot': 'udp',
|
||||
'dToPort': 67,
|
||||
'dFromPort': 67,
|
||||
'sToPort': 68,
|
||||
'sFromPort': 68}
|
||||
'dhcp', transaction=trs,
|
||||
**entries['dhcp'])
|
||||
self._associate_service_filter(tenant, contract, 'dhcp',
|
||||
'r-dhcp', transaction=trs, **attrs)
|
||||
'r-dhcp', transaction=trs,
|
||||
**entries['r-dhcp'])
|
||||
|
||||
# Create ARP filter/subject
|
||||
attrs = {'etherT': 'arp'}
|
||||
self._associate_service_filter(tenant, contract, 'arp',
|
||||
'arp', transaction=trs, **attrs)
|
||||
'arp', transaction=trs,
|
||||
**entries['arp'])
|
||||
|
||||
contract = self.name_mapper.l2_policy(
|
||||
context, l2p, prefix=IMPLICIT_PREFIX)
|
||||
@@ -3467,14 +3414,10 @@ class ApicMappingDriver(api.ResourceMappingDriver,
|
||||
|
||||
def _create_tenant_filter(self, rule_name, tenant, entries=None,
|
||||
transaction=None):
|
||||
entries = entries or []
|
||||
x = 0
|
||||
with self.apic_manager.apic.transaction(transaction) as trs:
|
||||
for entry in entries:
|
||||
for k, v in entries.iteritems():
|
||||
self.apic_manager.create_tenant_filter(
|
||||
rule_name, owner=tenant, transaction=trs,
|
||||
entry=apic_manager.CP_ENTRY + '-' + str(x), **entry)
|
||||
x += 1
|
||||
rule_name, owner=tenant, transaction=trs, entry=k, **v)
|
||||
|
||||
def _get_l3p_allocated_subnets(self, context, l3p_id,
|
||||
clean_session=True):
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import copy
|
||||
|
||||
from neutron.common import constants as n_constants
|
||||
|
||||
from gbpservice.neutron.db.grouppolicy import group_policy_mapping_db as gpdb
|
||||
from gbpservice.neutron.services.grouppolicy.common import constants as g_const
|
||||
|
||||
|
||||
ALLOWING_ACTIONS = [g_const.GP_ACTION_ALLOW, g_const.GP_ACTION_REDIRECT]
|
||||
REVERSE_PREFIX = 'reverse-'
|
||||
REVERSIBLE_PROTOCOLS = [n_constants.PROTO_NAME_TCP.lower(),
|
||||
n_constants.PROTO_NAME_UDP.lower(),
|
||||
n_constants.PROTO_NAME_ICMP.lower()]
|
||||
ICMP_REPLY_TYPES = ['echo-rep', 'dst-unreach', 'src-quench', 'time-exceeded']
|
||||
CP_ENTRY = 'os-entry'
|
||||
|
||||
|
||||
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
|
||||
# key and the filter_entry attributes as the value
|
||||
entries = {'forward_rules': None, 'reverse_rules': None}
|
||||
action = context._plugin.get_policy_action(
|
||||
context._plugin_context, context.current['policy_actions'][0])
|
||||
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
|
||||
return entries
|
||||
|
||||
|
||||
def get_arp_filter_entry():
|
||||
return {'etherT': 'arp'}
|
||||
|
||||
|
||||
def get_service_contract_filter_entries():
|
||||
entries = {}
|
||||
# DNS
|
||||
dns_attrs = {'etherT': 'ip',
|
||||
'prot': 'udp',
|
||||
'dToPort': 'dns',
|
||||
'dFromPort': 'dns'}
|
||||
entries['dns'] = dns_attrs
|
||||
r_dns_attrs = {'etherT': 'ip',
|
||||
'prot': 'udp',
|
||||
'sToPort': 'dns',
|
||||
'sFromPort': 'dns'}
|
||||
entries['r-dns'] = r_dns_attrs
|
||||
|
||||
# HTTP
|
||||
http_attrs = {'etherT': 'ip',
|
||||
'prot': 'tcp',
|
||||
'dToPort': 80,
|
||||
'dFromPort': 80}
|
||||
entries['http'] = http_attrs
|
||||
r_http_attrs = {'etherT': 'ip',
|
||||
'prot': 'tcp',
|
||||
'sToPort': 80,
|
||||
'sFromPort': 80}
|
||||
entries['r-http'] = r_http_attrs
|
||||
|
||||
icmp_attrs = {'etherT': 'ip',
|
||||
'prot': 'icmp'}
|
||||
entries['icmp'] = icmp_attrs
|
||||
|
||||
# DHCP
|
||||
dhcp_attrs = {'etherT': 'ip',
|
||||
'prot': 'udp',
|
||||
'dToPort': 68,
|
||||
'dFromPort': 68,
|
||||
'sToPort': 67,
|
||||
'sFromPort': 67}
|
||||
entries['dhcp'] = dhcp_attrs
|
||||
r_dhcp_attrs = {'etherT': 'ip',
|
||||
'prot': 'udp',
|
||||
'dToPort': 67,
|
||||
'dFromPort': 67,
|
||||
'sToPort': 68,
|
||||
'sFromPort': 68}
|
||||
entries['r-dhcp'] = r_dhcp_attrs
|
||||
|
||||
# ARP
|
||||
arp_attrs = get_arp_filter_entry()
|
||||
|
||||
entries['arp'] = arp_attrs
|
||||
return entries
|
||||
|
||||
|
||||
def _get_filter_entry_name(entry_number):
|
||||
return CP_ENTRY + '-' + str(entry_number)
|
||||
@@ -47,3 +47,6 @@ class AIMExtensionDriver(api.ExtensionDriver):
|
||||
|
||||
def extend_policy_target_group_dict(self, session, result):
|
||||
self._pd.extend_policy_target_group_dict(session, result)
|
||||
|
||||
def extend_policy_rule_dict(self, session, result):
|
||||
self._pd.extend_policy_rule_dict(session, result)
|
||||
|
||||
@@ -343,7 +343,6 @@ class GroupPolicyPlugin(group_policy_mapping_db.GroupPolicyMappingDbPlugin):
|
||||
|
||||
def _get_status_from_drivers(self, context, context_name, resource_name,
|
||||
resource_id, resource):
|
||||
result = resource
|
||||
status = resource['status']
|
||||
status_details = resource['status_details']
|
||||
policy_context = getattr(p_context, context_name)(
|
||||
@@ -360,10 +359,12 @@ class GroupPolicyPlugin(group_policy_mapping_db.GroupPolicyMappingDbPlugin):
|
||||
updated_status_details}}
|
||||
session = context.session
|
||||
with session.begin(subtransactions=True):
|
||||
result = getattr(super(GroupPolicyPlugin, self),
|
||||
"update_" + resource_name)(
|
||||
context, _resource['id'], new_status)
|
||||
return result
|
||||
getattr(super(GroupPolicyPlugin, self),
|
||||
"update_" + resource_name)(
|
||||
context, _resource['id'], new_status)
|
||||
resource['status'] = updated_status
|
||||
resource['status_details'] = updated_status_details
|
||||
return resource
|
||||
|
||||
def _get_resource(self, context, resource_name, resource_id,
|
||||
gbp_context_name, fields=None):
|
||||
@@ -412,7 +413,7 @@ class GroupPolicyPlugin(group_policy_mapping_db.GroupPolicyMappingDbPlugin):
|
||||
result)
|
||||
new_filtered_results.append(result)
|
||||
new_filtered_results = new_filtered_results or filtered_results
|
||||
return [self._fields(result, fields) for result in
|
||||
return [self._fields(nfresult, fields) for nfresult in
|
||||
new_filtered_results]
|
||||
|
||||
@resource_registry.tracked_resources(
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
import mock
|
||||
|
||||
from aim.api import resource as aim_resource
|
||||
from aim.api import status as aim_status
|
||||
from aim import context as aim_context
|
||||
from aim.db import model_base as aim_model_base
|
||||
from keystoneclient.v3 import client as ksc_client
|
||||
@@ -27,6 +28,8 @@ from gbpservice.neutron.plugins.ml2plus.drivers.apic_aim import model
|
||||
from gbpservice.neutron.services.grouppolicy.common import (
|
||||
constants as gp_const)
|
||||
from gbpservice.neutron.services.grouppolicy import config
|
||||
from gbpservice.neutron.services.grouppolicy.drivers.cisco.apic import (
|
||||
apic_mapping_lib as alib)
|
||||
from gbpservice.neutron.tests.unit.plugins.ml2plus import (
|
||||
test_apic_aim as test_aim_md)
|
||||
from gbpservice.neutron.tests.unit.services.grouppolicy import (
|
||||
@@ -46,7 +49,12 @@ class AIMBaseTestCase(test_nr_base.CommonNeutronBaseTestCase,
|
||||
def setUp(self, policy_drivers=None, core_plugin=None, ml2_options=None,
|
||||
sc_plugin=None, **kwargs):
|
||||
core_plugin = core_plugin or ML2PLUS_PLUGIN
|
||||
policy_drivers = policy_drivers or ['aim_mapping']
|
||||
# The dummy driver configured here is meant to be the second driver
|
||||
# invoked and helps in rollback testing. We mock the dummy driver
|
||||
# methods to raise an exception and validate that DB operations
|
||||
# performed up until that point (including those in the aim_mapping)
|
||||
# driver are rolled back.
|
||||
policy_drivers = policy_drivers or ['aim_mapping', 'dummy']
|
||||
ml2_opts = ml2_options or {'mechanism_drivers': ['logger', 'apic_aim'],
|
||||
'extension_drivers': ['apic_aim'],
|
||||
'type_drivers': ['opflex', 'local', 'vlan'],
|
||||
@@ -95,14 +103,6 @@ class AIMBaseTestCase(test_nr_base.CommonNeutronBaseTestCase,
|
||||
'aim_mapping'].obj.name_mapper)
|
||||
return self._name_mapper
|
||||
|
||||
|
||||
class TestL2Policy(test_nr_base.TestL2Policy, AIMBaseTestCase):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class TestPolicyTargetGroup(AIMBaseTestCase):
|
||||
|
||||
def _test_aim_resource_status(self, aim_resource_obj, gbp_resource):
|
||||
aim_status = self.aim_mgr.get_status(self._aim_context,
|
||||
aim_resource_obj)
|
||||
@@ -113,6 +113,14 @@ class TestPolicyTargetGroup(AIMBaseTestCase):
|
||||
else:
|
||||
self.assertEqual(gp_const.STATUS_ACTIVE, gbp_resource['status'])
|
||||
|
||||
|
||||
class TestL2Policy(test_nr_base.TestL2Policy, AIMBaseTestCase):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class TestPolicyTargetGroup(AIMBaseTestCase):
|
||||
|
||||
def test_policy_target_group_lifecycle_implicit_l2p(self):
|
||||
ptg = self.create_policy_target_group(
|
||||
name="ptg1")['policy_target_group']
|
||||
@@ -140,11 +148,15 @@ class TestPolicyTargetGroup(AIMBaseTestCase):
|
||||
self.assertEqual(aim_epg_name, aim_epgs[0].name)
|
||||
self.assertEqual(aim_tenant_name, aim_epgs[0].tenant_name)
|
||||
|
||||
self.assertEqual(aim_epgs[0].dn,
|
||||
ptg['apic:distinguished_names']['EndpointGroup'])
|
||||
self._test_aim_resource_status(aim_epgs[0], ptg)
|
||||
self.assertEqual(aim_epgs[0].dn,
|
||||
ptg_show['apic:distinguished_names']['EndpointGroup'])
|
||||
self._test_aim_resource_status(aim_epgs[0], ptg_show)
|
||||
|
||||
# TODO(Sumit): Test update
|
||||
|
||||
self.delete_policy_target_group(ptg_id, expected_res_status=204)
|
||||
self.show_policy_target_group(ptg_id, expected_res_status=404)
|
||||
# Implicitly created subnet should be deleted
|
||||
@@ -165,7 +177,8 @@ class TestPolicyTargetGroup(AIMBaseTestCase):
|
||||
ptg = self.create_policy_target_group(
|
||||
name="ptg1", l2_policy_id=l2p_id)['policy_target_group']
|
||||
ptg_id = ptg['id']
|
||||
self.show_policy_target_group(ptg_id, expected_res_status=200)
|
||||
ptg_show = self.show_policy_target_group(
|
||||
ptg_id, expected_res_status=200)['policy_target_group']
|
||||
self.assertEqual(l2p_id, ptg['l2_policy_id'])
|
||||
self.show_l2_policy(ptg['l2_policy_id'], expected_res_status=200)
|
||||
req = self.new_show_request('subnets', ptg['subnets'][0], fmt=self.fmt)
|
||||
@@ -187,7 +200,13 @@ class TestPolicyTargetGroup(AIMBaseTestCase):
|
||||
self.assertEqual(aim_epg_name, aim_epgs[0].name)
|
||||
self.assertEqual(aim_tenant_name, aim_epgs[0].tenant_name)
|
||||
|
||||
self.assertEqual(aim_epgs[0].dn,
|
||||
ptg['apic:distinguished_names']['EndpointGroup'])
|
||||
self._test_aim_resource_status(aim_epgs[0], ptg)
|
||||
self.assertEqual(aim_epgs[0].dn,
|
||||
ptg_show['apic:distinguished_names']['EndpointGroup'])
|
||||
|
||||
# TODO(Sumit): Test update
|
||||
|
||||
self.delete_policy_target_group(ptg_id, expected_res_status=204)
|
||||
self.show_policy_target_group(ptg_id, expected_res_status=404)
|
||||
@@ -226,11 +245,11 @@ class TestPolicyTargetGroup(AIMBaseTestCase):
|
||||
class TestPolicyTargetGroupRollback(AIMBaseTestCase):
|
||||
|
||||
def test_policy_target_group_create_fail(self):
|
||||
# REVISIT(Sumit): This exception should be raised from the deepest
|
||||
# point. Currently this is the deepest point.
|
||||
orig_func = self._gbp_plugin.policy_driver_manager.policy_drivers[
|
||||
'dummy'].obj.create_policy_target_group_precommit
|
||||
self._gbp_plugin.policy_driver_manager.policy_drivers[
|
||||
'aim_mapping'].obj._validate_and_add_subnet = mock.Mock(
|
||||
side_effect=Exception)
|
||||
'dummy'].obj.create_policy_target_group_precommit = (
|
||||
mock.Mock(side_effect=Exception))
|
||||
self.create_policy_target_group(name="ptg1", expected_res_status=500)
|
||||
self.assertEqual([], self._plugin.get_subnets(self._context))
|
||||
self.assertEqual([], self._plugin.get_networks(self._context))
|
||||
@@ -238,12 +257,15 @@ class TestPolicyTargetGroupRollback(AIMBaseTestCase):
|
||||
self._context))
|
||||
self.assertEqual([], self._gbp_plugin.get_l2_policies(self._context))
|
||||
self.assertEqual([], self._gbp_plugin.get_l3_policies(self._context))
|
||||
# restore mock
|
||||
self._gbp_plugin.policy_driver_manager.policy_drivers[
|
||||
'dummy'].obj.create_policy_target_group_precommit = orig_func
|
||||
|
||||
def test_policy_target_group_update_fail(self):
|
||||
# REVISIT(Sumit): This exception should be raised from the deepest
|
||||
# point. Currently this is the deepest point.
|
||||
orig_func = self._gbp_plugin.policy_driver_manager.policy_drivers[
|
||||
'dummy'].obj.update_policy_target_group_precommit
|
||||
self._gbp_plugin.policy_driver_manager.policy_drivers[
|
||||
'aim_mapping'].obj.update_policy_target_group_precommit = (
|
||||
'dummy'].obj.update_policy_target_group_precommit = (
|
||||
mock.Mock(side_effect=Exception))
|
||||
ptg = self.create_policy_target_group(name="ptg1")
|
||||
ptg_id = ptg['policy_target_group']['id']
|
||||
@@ -253,12 +275,15 @@ class TestPolicyTargetGroupRollback(AIMBaseTestCase):
|
||||
expected_res_status=200)
|
||||
self.assertEqual(ptg['policy_target_group']['name'],
|
||||
new_ptg['policy_target_group']['name'])
|
||||
# restore mock
|
||||
self._gbp_plugin.policy_driver_manager.policy_drivers[
|
||||
'dummy'].obj.update_policy_target_group_precommit = orig_func
|
||||
|
||||
def test_policy_target_group_delete_fail(self):
|
||||
# REVISIT(Sumit): This exception should be raised from the deepest
|
||||
# point. Currently this is the deepest point.
|
||||
orig_func = self._gbp_plugin.policy_driver_manager.policy_drivers[
|
||||
'dummy'].obj.delete_l3_policy_precommit
|
||||
self._gbp_plugin.policy_driver_manager.policy_drivers[
|
||||
'aim_mapping'].obj.delete_l3_policy_precommit = mock.Mock(
|
||||
'dummy'].obj.delete_l3_policy_precommit = mock.Mock(
|
||||
side_effect=Exception)
|
||||
ptg = self.create_policy_target_group(name="ptg1")
|
||||
ptg_id = ptg['policy_target_group']['id']
|
||||
@@ -273,6 +298,9 @@ class TestPolicyTargetGroupRollback(AIMBaseTestCase):
|
||||
self.show_policy_target_group(ptg_id, expected_res_status=200)
|
||||
self.show_l2_policy(l2p_id, expected_res_status=200)
|
||||
self.show_l3_policy(l3p_id, expected_res_status=200)
|
||||
# restore mock
|
||||
self._gbp_plugin.policy_driver_manager.policy_drivers[
|
||||
'dummy'].obj.delete_l3_policy_precommit = orig_func
|
||||
|
||||
|
||||
class TestPolicyTarget(AIMBaseTestCase):
|
||||
@@ -305,10 +333,10 @@ class TestPolicyTarget(AIMBaseTestCase):
|
||||
class TestPolicyTargetRollback(AIMBaseTestCase):
|
||||
|
||||
def test_policy_target_create_fail(self):
|
||||
# REVISIT(Sumit): This exception should be raised from the deepest
|
||||
# point. Currently this is the deepest point.
|
||||
orig_func = self._gbp_plugin.policy_driver_manager.policy_drivers[
|
||||
'dummy'].obj.create_policy_target_precommit
|
||||
self._gbp_plugin.policy_driver_manager.policy_drivers[
|
||||
'aim_mapping'].obj._mark_port_owned = mock.Mock(
|
||||
'dummy'].obj.create_policy_target_precommit = mock.Mock(
|
||||
side_effect=Exception)
|
||||
ptg_id = self.create_policy_target_group(
|
||||
name="ptg1")['policy_target_group']['id']
|
||||
@@ -318,12 +346,15 @@ class TestPolicyTargetRollback(AIMBaseTestCase):
|
||||
self.assertEqual([],
|
||||
self._gbp_plugin.get_policy_targets(self._context))
|
||||
self.assertEqual([], self._plugin.get_ports(self._context))
|
||||
# restore mock
|
||||
self._gbp_plugin.policy_driver_manager.policy_drivers[
|
||||
'dummy'].obj.create_policy_target_precommit = orig_func
|
||||
|
||||
def test_policy_target_update_fail(self):
|
||||
# REVISIT(Sumit): This exception should be raised from the deepest
|
||||
# point. Currently this is the deepest point.
|
||||
orig_func = self._gbp_plugin.policy_driver_manager.policy_drivers[
|
||||
'dummy'].obj.update_policy_target_precommit
|
||||
self._gbp_plugin.policy_driver_manager.policy_drivers[
|
||||
'aim_mapping'].obj.update_policy_target_precommit = mock.Mock(
|
||||
'dummy'].obj.update_policy_target_precommit = mock.Mock(
|
||||
side_effect=Exception)
|
||||
ptg = self.create_policy_target_group(
|
||||
name="ptg1")['policy_target_group']
|
||||
@@ -335,10 +366,16 @@ class TestPolicyTargetRollback(AIMBaseTestCase):
|
||||
name="new name")
|
||||
new_pt = self.show_policy_target(pt_id, expected_res_status=200)
|
||||
self.assertEqual(pt['name'], new_pt['policy_target']['name'])
|
||||
# restore mock
|
||||
self._gbp_plugin.policy_driver_manager.policy_drivers[
|
||||
'dummy'].obj.update_policy_target_precommit = orig_func
|
||||
|
||||
def test_policy_target_delete_fail(self):
|
||||
# REVISIT(Sumit): This exception should be raised from the deepest
|
||||
# point. Currently this is the deepest point.
|
||||
orig_func = self._gbp_plugin.policy_driver_manager.policy_drivers[
|
||||
'dummy'].obj.delete_policy_target_precommit
|
||||
self._gbp_plugin.policy_driver_manager.policy_drivers[
|
||||
'dummy'].obj.delete_policy_target_precommit = mock.Mock(
|
||||
side_effect=Exception)
|
||||
self._gbp_plugin.policy_driver_manager.policy_drivers[
|
||||
'aim_mapping'].obj._delete_port = mock.Mock(
|
||||
side_effect=Exception)
|
||||
@@ -356,12 +393,97 @@ class TestPolicyTargetRollback(AIMBaseTestCase):
|
||||
req = self.new_show_request('ports', port_id, fmt=self.fmt)
|
||||
res = self.deserialize(self.fmt, req.get_response(self.api))
|
||||
self.assertIsNotNone(res['port']['id'])
|
||||
# restore mock
|
||||
self._gbp_plugin.policy_driver_manager.policy_drivers[
|
||||
'dummy'].obj.update_policy_target_precommit = orig_func
|
||||
|
||||
|
||||
class TestPolicyRule(AIMBaseTestCase):
|
||||
class TestAIMStatus(AIMBaseTestCase):
|
||||
|
||||
def _test_policy_rule_lifecycle(self):
|
||||
# TODO(Sumit): Enable this test when the AIM driver is ready
|
||||
def test_status_merging(self):
|
||||
aim_driver = self._gbp_plugin.policy_driver_manager.policy_drivers[
|
||||
'aim_mapping'].obj
|
||||
|
||||
def mock_get_aim_status(aim_context, aim_resource):
|
||||
astatus = aim_status.AciStatus()
|
||||
if aim_resource['status'] == '':
|
||||
return
|
||||
elif aim_resource['status'] == 'build':
|
||||
astatus.sync_status = aim_status.AciStatus.SYNC_PENDING
|
||||
elif aim_resource['status'] == 'error':
|
||||
astatus.sync_status = aim_status.AciStatus.SYNC_FAILED
|
||||
else:
|
||||
astatus.sync_status = aim_status.AciStatus.SYNCED
|
||||
return astatus
|
||||
|
||||
orig_get_status = self.aim_mgr.get_status
|
||||
self.aim_mgr.get_status = mock_get_aim_status
|
||||
|
||||
aim_active = {'status': 'active'}
|
||||
aim_objs_active = [aim_active, aim_active, aim_active]
|
||||
mstatus = aim_driver._merge_aim_status(self._neutron_context.session,
|
||||
aim_objs_active)
|
||||
self.assertEqual(gp_const.STATUS_ACTIVE, mstatus)
|
||||
|
||||
aim_build = {'status': 'build'}
|
||||
aim_none = {'status': ''}
|
||||
aim_objs_build = [aim_active, aim_active, aim_build]
|
||||
mstatus = aim_driver._merge_aim_status(self._neutron_context.session,
|
||||
aim_objs_build)
|
||||
self.assertEqual(gp_const.STATUS_BUILD, mstatus)
|
||||
aim_objs_build = [aim_active, aim_active, aim_none]
|
||||
mstatus = aim_driver._merge_aim_status(self._neutron_context.session,
|
||||
aim_objs_build)
|
||||
self.assertEqual(gp_const.STATUS_BUILD, mstatus)
|
||||
|
||||
aim_error = {'status': 'error'}
|
||||
aim_objs_error = [aim_active, aim_build, aim_error]
|
||||
mstatus = aim_driver._merge_aim_status(self._neutron_context.session,
|
||||
aim_objs_error)
|
||||
self.assertEqual(gp_const.STATUS_ERROR, mstatus)
|
||||
|
||||
self.aim_mgr.get_status = orig_get_status
|
||||
|
||||
|
||||
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]:
|
||||
aim_filters = self.aim_mgr.find(
|
||||
self._aim_context, aim_resource.Filter, name=filter_name)
|
||||
aim_obj_list.append(aim_filters[0])
|
||||
self.assertEqual(1, len(aim_filters))
|
||||
self.assertEqual(filter_name, aim_filters[0].name)
|
||||
self.assertEqual(aim_tenant_name, aim_filters[0].tenant_name)
|
||||
aim_filter_entries = self.aim_mgr.find(
|
||||
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.assertEqual('os-entry-0', aim_filter_entries[0].name)
|
||||
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])
|
||||
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'])
|
||||
|
||||
|
||||
class TestPolicyRule(TestPolicyRuleBase):
|
||||
|
||||
def test_policy_rule_lifecycle(self):
|
||||
action1 = self.create_policy_action(
|
||||
action_type='redirect')['policy_action']
|
||||
classifier = self.create_policy_classifier(
|
||||
@@ -372,21 +494,134 @@ class TestPolicyRule(AIMBaseTestCase):
|
||||
name="pr1", policy_classifier_id=classifier['id'],
|
||||
policy_actions=[action1['id']])['policy_rule']
|
||||
pr_id = pr['id']
|
||||
pr_name = pr['name']
|
||||
self.show_policy_rule(pr_id, expected_res_status=200)
|
||||
|
||||
tenant = pr['tenant_id']
|
||||
pr_id = pr['id']
|
||||
pr_name = pr['name']
|
||||
rn = self._aim_mapper.tenant_filter(tenant, pr_id, name=pr_name)
|
||||
aim_pr = self.aim_mgr.find(
|
||||
self._aim_context, aim_resource.TenantFilter, rn=rn)
|
||||
self.assertEqual(1, len(aim_pr))
|
||||
self.assertEqual(rn, aim_pr[0].rn)
|
||||
self.assertEqual(tenant, aim_pr[0].tenant_rn)
|
||||
aim_filter_name = str(self.name_mapper.policy_rule(
|
||||
self._neutron_context.session, pr_id, pr_name))
|
||||
aim_reverse_filter_name = str(self.name_mapper.policy_rule(
|
||||
self._neutron_context.session, pr_id, pr_name,
|
||||
prefix=alib.REVERSE_PREFIX))
|
||||
aim_tenant_name = str(self.name_mapper.tenant(
|
||||
self._neutron_context.session, self._tenant_id))
|
||||
self._test_policy_rule_create_update_result(
|
||||
aim_tenant_name, aim_filter_name, aim_reverse_filter_name, 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, pr_name))
|
||||
aim_reverse_filter_name = str(self.name_mapper.policy_rule(
|
||||
self._neutron_context.session, pr_id, pr_name,
|
||||
prefix=alib.REVERSE_PREFIX))
|
||||
self._test_policy_rule_create_update_result(
|
||||
aim_tenant_name, aim_filter_name, aim_reverse_filter_name, new_pr)
|
||||
|
||||
self.delete_policy_rule(pr_id, expected_res_status=204)
|
||||
self.show_policy_rule(pr_id, expected_res_status=404)
|
||||
|
||||
aim_pr = self.aim_mgr.find(
|
||||
self._aim_context, aim_resource.TenantFilter, rn=rn)
|
||||
self.assertEqual(0, len(aim_pr))
|
||||
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 TestPolicyRuleRollback(TestPolicyRuleBase):
|
||||
|
||||
def test_policy_rule_create_fail(self):
|
||||
orig_func = self._gbp_plugin.policy_driver_manager.policy_drivers[
|
||||
'dummy'].obj.create_policy_rule_precommit
|
||||
self._gbp_plugin.policy_driver_manager.policy_drivers[
|
||||
'dummy'].obj.create_policy_rule_precommit = mock.Mock(
|
||||
side_effect=Exception)
|
||||
action1 = self.create_policy_action(
|
||||
action_type='redirect')['policy_action']
|
||||
classifier = self.create_policy_classifier(
|
||||
protocol='TCP', port_range="22",
|
||||
direction='bi')['policy_classifier']
|
||||
|
||||
self.create_policy_rule(
|
||||
name="pr1", policy_classifier_id=classifier['id'],
|
||||
policy_actions=[action1['id']], expected_res_status=500)
|
||||
|
||||
self.assertEqual([],
|
||||
self._gbp_plugin.get_policy_rules(self._context))
|
||||
aim_filters = self.aim_mgr.find(
|
||||
self._aim_context, aim_resource.Filter)
|
||||
self.assertEqual(0, len(aim_filters))
|
||||
aim_filter_entries = self.aim_mgr.find(
|
||||
self._aim_context, aim_resource.FilterEntry)
|
||||
self.assertEqual(0, len(aim_filter_entries))
|
||||
# restore mock
|
||||
self._gbp_plugin.policy_driver_manager.policy_drivers[
|
||||
'dummy'].obj.create_policy_rule_precommit = orig_func
|
||||
|
||||
def test_policy_rule_update_fail(self):
|
||||
orig_func = self._gbp_plugin.policy_driver_manager.policy_drivers[
|
||||
'dummy'].obj.update_policy_rule_precommit
|
||||
self._gbp_plugin.policy_driver_manager.policy_drivers[
|
||||
'dummy'].obj.update_policy_rule_precommit = mock.Mock(
|
||||
side_effect=Exception)
|
||||
action1 = self.create_policy_action(
|
||||
action_type='redirect')['policy_action']
|
||||
classifier = self.create_policy_classifier(
|
||||
protocol='TCP', port_range="22",
|
||||
direction='bi')['policy_classifier']
|
||||
|
||||
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'], pr['name']))
|
||||
aim_reverse_filter_name = str(self.name_mapper.policy_rule(
|
||||
self._neutron_context.session, pr['id'], pr['name'],
|
||||
prefix=alib.REVERSE_PREFIX))
|
||||
|
||||
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))
|
||||
|
||||
# restore mock
|
||||
self._gbp_plugin.policy_driver_manager.policy_drivers[
|
||||
'dummy'].obj.create_policy_rule_precommit = orig_func
|
||||
|
||||
def test_policy_rule_delete_fail(self):
|
||||
orig_func = self._gbp_plugin.policy_driver_manager.policy_drivers[
|
||||
'dummy'].obj.delete_policy_rule_precommit
|
||||
self._gbp_plugin.policy_driver_manager.policy_drivers[
|
||||
'dummy'].obj.delete_policy_rule_precommit = mock.Mock(
|
||||
side_effect=Exception)
|
||||
action1 = self.create_policy_action(
|
||||
action_type='redirect')['policy_action']
|
||||
classifier = self.create_policy_classifier(
|
||||
protocol='TCP', port_range="22",
|
||||
direction='bi')['policy_classifier']
|
||||
|
||||
pr = self.create_policy_rule(
|
||||
name="pr1", policy_classifier_id=classifier['id'],
|
||||
policy_actions=[action1['id']])['policy_rule']
|
||||
pr_id = pr['id']
|
||||
pr_name = pr['name']
|
||||
|
||||
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, pr_name))
|
||||
aim_reverse_filter_name = str(self.name_mapper.policy_rule(
|
||||
self._neutron_context.session, pr_id, pr_name,
|
||||
prefix=alib.REVERSE_PREFIX))
|
||||
aim_tenant_name = str(self.name_mapper.tenant(
|
||||
self._neutron_context.session, self._tenant_id))
|
||||
self._test_policy_rule_create_update_result(
|
||||
aim_tenant_name, aim_filter_name, aim_reverse_filter_name, pr)
|
||||
|
||||
# restore mock
|
||||
self._gbp_plugin.policy_driver_manager.policy_drivers[
|
||||
'dummy'].obj.delete_policy_rule_precommit = orig_func
|
||||
|
||||
@@ -41,6 +41,8 @@ from gbpservice.neutron.services.grouppolicy import (
|
||||
from gbpservice.neutron.services.grouppolicy import config
|
||||
from gbpservice.neutron.services.grouppolicy.drivers.cisco.apic import (
|
||||
apic_mapping as amap)
|
||||
from gbpservice.neutron.services.grouppolicy.drivers.cisco.apic import (
|
||||
apic_mapping_lib as alib)
|
||||
from gbpservice.neutron.services.l3_router import l3_apic
|
||||
from gbpservice.neutron.tests.unit.services.grouppolicy import (
|
||||
test_resource_mapping as test_rmd)
|
||||
@@ -3369,7 +3371,7 @@ class TestPolicyRuleSet(ApicMappingTestCase):
|
||||
owner=ctr['tenant_id'], transaction=mock.ANY,
|
||||
unset=False, rule_owner=rule_owner),
|
||||
mock.call(ctr['id'], ctr['id'],
|
||||
amap.REVERSE_PREFIX + rules[out]['id'],
|
||||
alib.REVERSE_PREFIX + rules[out]['id'],
|
||||
owner=ctr['tenant_id'], transaction=mock.ANY,
|
||||
unset=False, rule_owner=rule_owner)]
|
||||
self._check_call_list(
|
||||
@@ -3381,7 +3383,7 @@ class TestPolicyRuleSet(ApicMappingTestCase):
|
||||
owner=ctr['tenant_id'], transaction=mock.ANY,
|
||||
unset=False, rule_owner=rule_owner),
|
||||
mock.call(ctr['id'], ctr['id'],
|
||||
amap.REVERSE_PREFIX + rules[in_d]['id'],
|
||||
alib.REVERSE_PREFIX + rules[in_d]['id'],
|
||||
owner=ctr['tenant_id'], transaction=mock.ANY,
|
||||
unset=False, rule_owner=rule_owner)]
|
||||
self._check_call_list(
|
||||
@@ -3401,11 +3403,11 @@ class TestPolicyRuleSet(ApicMappingTestCase):
|
||||
transaction=mock.ANY, unset=False,
|
||||
rule_owner=rule_owner)
|
||||
mgr.manage_contract_subject_in_filter.call_happened_with(
|
||||
ctr['id'], ctr['id'], amap.REVERSE_PREFIX + rules[bi]['id'],
|
||||
ctr['id'], ctr['id'], alib.REVERSE_PREFIX + rules[bi]['id'],
|
||||
owner=ctr['tenant_id'], transaction=mock.ANY, unset=False,
|
||||
rule_owner=rule_owner)
|
||||
mgr.manage_contract_subject_out_filter.call_happened_with(
|
||||
ctr['id'], ctr['id'], amap.REVERSE_PREFIX + rules[bi]['id'],
|
||||
ctr['id'], ctr['id'], alib.REVERSE_PREFIX + rules[bi]['id'],
|
||||
owner=ctr['tenant_id'], transaction=mock.ANY, unset=False,
|
||||
rule_owner=rule_owner)
|
||||
|
||||
@@ -3524,13 +3526,13 @@ class TestPolicyRule(ApicMappingTestCase):
|
||||
mock.call(pr['id'], owner=tenant, entry='os-entry-0', etherT='ip',
|
||||
prot='tcp', dToPort=88, dFromPort=88,
|
||||
transaction=mock.ANY),
|
||||
mock.call(amap.REVERSE_PREFIX + pr['id'], owner=tenant,
|
||||
mock.call(alib.REVERSE_PREFIX + pr['id'], owner=tenant,
|
||||
entry='os-entry-0', etherT='ip', prot='tcp', sToPort=88,
|
||||
sFromPort=88, tcpRules='est', transaction=mock.ANY),
|
||||
mock.call(pr1['id'], owner=tenant, entry='os-entry-0',
|
||||
etherT='ip', prot='udp', dToPort=53, dFromPort=53,
|
||||
transaction=mock.ANY),
|
||||
mock.call(amap.REVERSE_PREFIX + pr1['id'], owner=tenant,
|
||||
mock.call(alib.REVERSE_PREFIX + pr1['id'], owner=tenant,
|
||||
entry='os-entry-0', etherT='ip', prot='udp', sToPort=53,
|
||||
sFromPort=53, transaction=mock.ANY),
|
||||
mock.call(pr2['id'], owner=tenant, entry='os-entry-0',
|
||||
@@ -3561,7 +3563,7 @@ class TestPolicyRule(ApicMappingTestCase):
|
||||
mgr = self.driver.apic_manager
|
||||
expected_calls = [
|
||||
mock.call(pr['id'], owner=tenant, transaction=mock.ANY),
|
||||
mock.call(amap.REVERSE_PREFIX + pr['id'], owner=tenant,
|
||||
mock.call(alib.REVERSE_PREFIX + pr['id'], owner=tenant,
|
||||
transaction=mock.ANY)]
|
||||
self._check_call_list(
|
||||
expected_calls, mgr.delete_tenant_filter.call_args_list)
|
||||
@@ -3570,7 +3572,7 @@ class TestPolicyRule(ApicMappingTestCase):
|
||||
self.delete_policy_rule(pr1['id'], expected_res_status=204)
|
||||
expected_calls = [
|
||||
mock.call(pr1['id'], owner=tenant, transaction=mock.ANY),
|
||||
mock.call(amap.REVERSE_PREFIX + pr1['id'], owner=tenant,
|
||||
mock.call(alib.REVERSE_PREFIX + pr1['id'], owner=tenant,
|
||||
transaction=mock.ANY)]
|
||||
self._check_call_list(
|
||||
expected_calls, mgr.delete_tenant_filter.call_args_list)
|
||||
@@ -3611,10 +3613,10 @@ class TestPolicyRule(ApicMappingTestCase):
|
||||
entry='os-entry-0', transaction=mock.ANY),
|
||||
mock.call(pr2['id'], owner='test-tenant', etherT='ip', prot='udp',
|
||||
entry='os-entry-0', transaction=mock.ANY),
|
||||
mock.call(amap.REVERSE_PREFIX + pr1['id'], owner='common',
|
||||
mock.call(alib.REVERSE_PREFIX + pr1['id'], owner='common',
|
||||
etherT='ip', prot='udp', entry='os-entry-0',
|
||||
transaction=mock.ANY),
|
||||
mock.call(amap.REVERSE_PREFIX + pr2['id'], owner='test-tenant',
|
||||
mock.call(alib.REVERSE_PREFIX + pr2['id'], owner='test-tenant',
|
||||
etherT='ip', prot='udp', entry='os-entry-0',
|
||||
transaction=mock.ANY)]
|
||||
self._check_call_list(
|
||||
@@ -3622,9 +3624,9 @@ class TestPolicyRule(ApicMappingTestCase):
|
||||
expected_calls = [
|
||||
mock.call(pr1['id'], owner='common', transaction=mock.ANY),
|
||||
mock.call(pr2['id'], owner='test-tenant', transaction=mock.ANY),
|
||||
mock.call(amap.REVERSE_PREFIX + pr1['id'], owner='common',
|
||||
mock.call(alib.REVERSE_PREFIX + pr1['id'], owner='common',
|
||||
transaction=mock.ANY),
|
||||
mock.call(amap.REVERSE_PREFIX + pr2['id'], owner='test-tenant',
|
||||
mock.call(alib.REVERSE_PREFIX + pr2['id'], owner='test-tenant',
|
||||
transaction=mock.ANY)]
|
||||
self._check_call_list(
|
||||
expected_calls, mgr.delete_tenant_filter.call_args_list)
|
||||
@@ -3645,9 +3647,9 @@ class TestPolicyRule(ApicMappingTestCase):
|
||||
expected_calls = [
|
||||
mock.call(pr1['id'], owner='common', transaction=mock.ANY),
|
||||
mock.call(pr2['id'], owner='test-tenant', transaction=mock.ANY),
|
||||
mock.call(amap.REVERSE_PREFIX + pr1['id'], owner='common',
|
||||
mock.call(alib.REVERSE_PREFIX + pr1['id'], owner='common',
|
||||
transaction=mock.ANY),
|
||||
mock.call(amap.REVERSE_PREFIX + pr2['id'], owner='test-tenant',
|
||||
mock.call(alib.REVERSE_PREFIX + pr2['id'], owner='test-tenant',
|
||||
transaction=mock.ANY)]
|
||||
self._check_call_list(
|
||||
expected_calls, mgr.delete_tenant_filter.call_args_list)
|
||||
@@ -3663,9 +3665,9 @@ class TestPolicyRule(ApicMappingTestCase):
|
||||
expected_calls = [
|
||||
mock.call(pr1['id'], owner='common', transaction=mock.ANY),
|
||||
mock.call(pr2['id'], owner='test-tenant', transaction=mock.ANY),
|
||||
mock.call(amap.REVERSE_PREFIX + pr1['id'], owner='common',
|
||||
mock.call(alib.REVERSE_PREFIX + pr1['id'], owner='common',
|
||||
transaction=mock.ANY),
|
||||
mock.call(amap.REVERSE_PREFIX + pr2['id'], owner='test-tenant',
|
||||
mock.call(alib.REVERSE_PREFIX + pr2['id'], owner='test-tenant',
|
||||
transaction=mock.ANY)]
|
||||
self._check_call_list(
|
||||
expected_calls, mgr.delete_tenant_filter.call_args_list)
|
||||
@@ -3674,10 +3676,10 @@ class TestPolicyRule(ApicMappingTestCase):
|
||||
entry='os-entry-0', transaction=mock.ANY),
|
||||
mock.call(pr2['id'], owner='test-tenant', etherT='ip', prot='tcp',
|
||||
entry='os-entry-0', transaction=mock.ANY),
|
||||
mock.call(amap.REVERSE_PREFIX + pr1['id'], owner='common',
|
||||
mock.call(alib.REVERSE_PREFIX + pr1['id'], owner='common',
|
||||
etherT='ip', prot='tcp', tcpRules='est',
|
||||
entry='os-entry-0', transaction=mock.ANY),
|
||||
mock.call(amap.REVERSE_PREFIX + pr2['id'], owner='test-tenant',
|
||||
mock.call(alib.REVERSE_PREFIX + pr2['id'], owner='test-tenant',
|
||||
etherT='ip', prot='tcp', tcpRules='est',
|
||||
entry='os-entry-0', transaction=mock.ANY)]
|
||||
self._check_call_list(
|
||||
@@ -3706,13 +3708,13 @@ class TestPolicyRule(ApicMappingTestCase):
|
||||
mgr.manage_contract_subject_in_filter.call_args_list)
|
||||
# SET Reverse PR1 and PR2 OUT
|
||||
expected_calls = [
|
||||
mock.call(prs1['id'], prs1['id'], amap.REVERSE_PREFIX + pr1['id'],
|
||||
mock.call(prs1['id'], prs1['id'], alib.REVERSE_PREFIX + pr1['id'],
|
||||
owner='test-tenant', transaction=mock.ANY, unset=False,
|
||||
rule_owner='common'),
|
||||
mock.call(prs2['id'], prs2['id'], amap.REVERSE_PREFIX + pr1['id'],
|
||||
mock.call(prs2['id'], prs2['id'], alib.REVERSE_PREFIX + pr1['id'],
|
||||
owner='test-tenant', transaction=mock.ANY, unset=False,
|
||||
rule_owner='common'),
|
||||
mock.call(prs2['id'], prs2['id'], amap.REVERSE_PREFIX + pr2['id'],
|
||||
mock.call(prs2['id'], prs2['id'], alib.REVERSE_PREFIX + pr2['id'],
|
||||
owner='test-tenant', transaction=mock.ANY, unset=False,
|
||||
rule_owner='test-tenant')
|
||||
]
|
||||
@@ -3728,23 +3730,23 @@ class TestPolicyRule(ApicMappingTestCase):
|
||||
expected_calls = [
|
||||
mock.call(pr['id'], owner=tenant, entry='os-entry-0', etherT='ip',
|
||||
prot='icmp', transaction=mock.ANY),
|
||||
mock.call(amap.REVERSE_PREFIX + pr['id'], owner=tenant,
|
||||
mock.call(alib.REVERSE_PREFIX + pr['id'], owner=tenant,
|
||||
entry=mock.ANY, etherT='ip', icmpv4T='echo-rep',
|
||||
prot='icmp', transaction=mock.ANY),
|
||||
mock.call(amap.REVERSE_PREFIX + pr['id'], owner=tenant,
|
||||
mock.call(alib.REVERSE_PREFIX + pr['id'], owner=tenant,
|
||||
entry=mock.ANY, etherT='ip', icmpv4T='dst-unreach',
|
||||
prot='icmp', transaction=mock.ANY),
|
||||
mock.call(amap.REVERSE_PREFIX + pr['id'], owner=tenant,
|
||||
mock.call(alib.REVERSE_PREFIX + pr['id'], owner=tenant,
|
||||
entry=mock.ANY, etherT='ip', icmpv4T='src-quench',
|
||||
prot='icmp', transaction=mock.ANY),
|
||||
mock.call(amap.REVERSE_PREFIX + pr['id'], owner=tenant,
|
||||
mock.call(alib.REVERSE_PREFIX + pr['id'], owner=tenant,
|
||||
entry=mock.ANY, etherT='ip', icmpv4T='time-exceeded',
|
||||
prot='icmp', transaction=mock.ANY)]
|
||||
# verify that entry is always different
|
||||
found = set()
|
||||
for call in mgr.create_tenant_filter.call_args_list:
|
||||
# Only for reverse filters
|
||||
if call[0][0].startswith(amap.REVERSE_PREFIX):
|
||||
if call[0][0].startswith(alib.REVERSE_PREFIX):
|
||||
self.assertFalse(call[1]['entry'] in found)
|
||||
found.add(call[1]['entry'])
|
||||
|
||||
|
||||
@@ -104,14 +104,17 @@ class TestL2PolicyRollback(CommonNeutronBaseTestCase):
|
||||
'GROUP_POLICY'].policy_driver_manager.policy_drivers['dummy'].obj
|
||||
|
||||
def test_l2_policy_create_fail(self):
|
||||
orig_func = self.dummy_driver.create_l2_policy_precommit
|
||||
self.dummy_driver.create_l2_policy_precommit = mock.Mock(
|
||||
side_effect=Exception)
|
||||
self.create_l2_policy(name="l2p1", expected_res_status=500)
|
||||
self.assertEqual([], self._plugin.get_networks(self._context))
|
||||
self.assertEqual([], self._gbp_plugin.get_l2_policies(self._context))
|
||||
self.assertEqual([], self._gbp_plugin.get_l3_policies(self._context))
|
||||
self.dummy_driver.create_l2_policy_precommit = orig_func
|
||||
|
||||
def test_l2_policy_update_fail(self):
|
||||
orig_func = self.dummy_driver.update_l2_policy_precommit
|
||||
self.dummy_driver.update_l2_policy_precommit = mock.Mock(
|
||||
side_effect=Exception)
|
||||
l2p = self.create_l2_policy(name="l2p1")
|
||||
@@ -121,8 +124,10 @@ class TestL2PolicyRollback(CommonNeutronBaseTestCase):
|
||||
new_l2p = self.show_l2_policy(l2p_id, expected_res_status=200)
|
||||
self.assertEqual(l2p['l2_policy']['name'],
|
||||
new_l2p['l2_policy']['name'])
|
||||
self.dummy_driver.update_l2_policy_precommit = orig_func
|
||||
|
||||
def test_l2_policy_delete_fail(self):
|
||||
orig_func = self.dummy_driver.delete_l2_policy_precommit
|
||||
self.dummy_driver.delete_l2_policy_precommit = mock.Mock(
|
||||
side_effect=Exception)
|
||||
l2p = self.create_l2_policy(name="l2p1")
|
||||
@@ -135,3 +140,4 @@ class TestL2PolicyRollback(CommonNeutronBaseTestCase):
|
||||
self.assertIsNotNone(res['network']['id'])
|
||||
self.show_l3_policy(l3p_id, expected_res_status=200)
|
||||
self.show_l2_policy(l2p_id, expected_res_status=200)
|
||||
self.dummy_driver.delete_l2_policy_precommit = orig_func
|
||||
|
||||
Reference in New Issue
Block a user