[aim-mapping] Enable Segmentation Label extension

This patch enables the cisco_apic_gbp_segmentation_label for the
aim_mapping driver.

It is expected that extension driver is configured by being added
to the existing list of extension drivers under:
[group_policy]
extension_drivers=<existing_ext_drivers>,apic_segmentation_label

The segementation_labels attribute is a list of strings. Each string can
be upto 255 characters long. These labels are not interpreted by GBP
but are instead passed downstream by the apic policy driver. It is
assumed that these are defined outside of OpenStack and the backend
system can appropriately interpret them.

The get_gbp_details() RPC call implemented by aim_mapping_rpc (invoked
from the aim_mapping policy driver) will return the segmentation_labels
in its body if the 'segmentation_labels' attribute is populated for the
policy_target.

A CLI option: --segmentation-labels is available provided for the
policy_target create and update operations. This CLI option accepts
a comma separated string as the option value.

Change-Id: I5c6363d0ffc1d5e75eebb995c3c8f10751271cf2
(cherry picked from commit 1a8cdc4abf)
This commit is contained in:
Sumit Naiksatam
2016-10-21 12:12:45 -07:00
parent 042a463881
commit cbf8064ed5
3 changed files with 45 additions and 2 deletions

View File

@@ -85,6 +85,7 @@ class AIMMappingDriver(nrd.CommonNeutronBase, aim_rpc.AIMMappingRPCMixin):
self.db = model.DbModel()
super(AIMMappingDriver, self).initialize()
self._apic_aim_mech_driver = None
self._apic_segmentation_label_driver = None
self.setup_opflex_rpc_listeners()
self._ensure_apic_infra()
@@ -115,6 +116,17 @@ class AIMMappingDriver(nrd.CommonNeutronBase, aim_rpc.AIMMappingRPCMixin):
def name_mapper(self):
return self.aim_mech_driver.name_mapper
@property
def apic_segmentation_label_driver(self):
if not self._apic_segmentation_label_driver:
ext_drivers = self.gbp_plugin.extension_manager.ordered_ext_drivers
for driver in ext_drivers:
if 'apic_segmentation_label' == driver.name:
self._apic_segmentation_label_driver = (
driver.obj)
break
return self._apic_segmentation_label_driver
@log.log_method_call
def ensure_tenant(self, plugin_context, tenant_id):
self.aim_mech_driver.ensure_tenant(plugin_context, tenant_id)
@@ -1215,3 +1227,9 @@ class AIMMappingDriver(nrd.CommonNeutronBase, aim_rpc.AIMMappingRPCMixin):
for pool in subnetpools:
subnets.extend(pool['prefixes'])
return subnets
def _get_segmentation_labels(self, plugin_context, port, details):
pt = self._port_id_to_pt(plugin_context, port['id'])
if self.apic_segmentation_label_driver and pt and (
'segmentation_labels' in pt):
return pt['segmentation_labels']

View File

@@ -158,6 +158,7 @@ class AIMMappingRPCMixin(ha_ip_db.HAIPOwnerDbMixin):
self._add_allowed_address_pairs_details(context, port, details)
self._add_vrf_details(context, details['l3_policy_id'], details)
self._add_extra_details(context, port, details)
self._add_segmentation_label_details(context, port, details)
details.pop('_cache', None)
LOG.debug("Details for port %s : %s" % (port['id'], details))
@@ -214,6 +215,17 @@ class AIMMappingRPCMixin(ha_ip_db.HAIPOwnerDbMixin):
details['vrf_subnets'] = self._get_vrf_subnets(context, vrf_id,
details)
# Child class needs to support:
# - self._get_segmentation_labels(context, port, details)
def _add_segmentation_label_details(self, context, port, details):
# This method needs to define requirements for this Mixin's child
# classes in order to fill the following result parameters:
# - segmentation_labels
# apic_segmentation_label is a GBP driver extension configured
# for the aim_mapping driver
details['segmentation_labels'] = self._get_segmentation_labels(
context, port, details)
def _add_extra_details(self, context, port, details):
# TODO(ivar): Extra details depend on HA and SC implementation
# This method needs to define requirements for this Mixin's child

View File

@@ -25,6 +25,7 @@ from neutron.db import api as db_api
from neutron.notifiers import nova
from neutron.tests.unit.extensions import test_address_scope
from opflexagent import constants as ocst
from oslo_config import cfg
from oslo_utils import uuidutils
import webob.exc
@@ -69,7 +70,7 @@ class AIMBaseTestCase(test_nr_base.CommonNeutronBaseTestCase,
test_ext_base.ExtensionDriverTestBase,
test_aim_md.ApicAimTestMixin,
test_address_scope.AddressScopeTestCase):
_extension_drivers = ['aim_extension']
_extension_drivers = ['aim_extension', 'apic_segmentation_label']
_extension_path = None
def setUp(self, policy_drivers=None, core_plugin=None, ml2_options=None,
@@ -83,6 +84,13 @@ class AIMBaseTestCase(test_nr_base.CommonNeutronBaseTestCase,
# performed up until that point (including those in the aim_mapping)
# driver are rolled back.
policy_drivers = policy_drivers or ['aim_mapping', 'dummy']
if not cfg.CONF.group_policy.extension_drivers:
config.cfg.CONF.set_override(
'extension_drivers', self._extension_drivers,
group='group_policy')
if self._extension_path:
config.cfg.CONF.set_override(
'api_extensions_path', self._extension_path)
self.agent_conf = AGENT_CONF
ml2_opts = ml2_options or {'mechanism_drivers': ['logger', 'apic_aim'],
'extension_drivers': ['apic_aim'],
@@ -1168,13 +1176,18 @@ class TestPolicyTarget(AIMBaseTestCase):
l3_policy_id=l3p['id'])['l2_policy']
ptg = self.create_policy_target_group(
name="ptg1", l2_policy_id=l2p['id'])['policy_target_group']
segmentation_labels = ['label1', 'label2']
pt1 = self.create_policy_target(
policy_target_group_id=ptg['id'])['policy_target']
policy_target_group_id=ptg['id'],
segmentation_labels=segmentation_labels)['policy_target']
self._bind_port_to_host(pt1['port_id'], 'h1')
mapping = self.driver.get_gbp_details(
self._neutron_admin_context, device='tap%s' % pt1['port_id'],
host='h1')
if 'apic_segmentation_label' in self._extension_drivers:
self.assertItemsEqual(segmentation_labels,
mapping['segmentation_labels'])
req_mapping = self.driver.request_endpoint_details(
nctx.get_admin_context(),
request={'device': 'tap%s' % pt1['port_id'], 'host': 'h1',