Passes the plugin context variable in the ML2 Extension Driver API

Many neutron extensions(like portsecurity) use the plugin_context
variable instead of just the database session. This change
modifies the extension driver api to pass the plugin_context

Change request also modifies the extend_XXX resource api to use the
respective data model(network/subnet/port) passed to it.

Implements: blueprint extensions-in-ml2
Partially Implements: blueprint ml2-ovs-portsecurity
Closes-Bug: 1382448
Change-Id: Icf84615e5fee8b59cbc95ab9b634f1a49f4b56a3
This commit is contained in:
Shweta P 2015-02-03 20:23:31 -05:00 committed by Yalei Wang
parent 10b3a5bc90
commit c027c6cef8
4 changed files with 136 additions and 68 deletions

View File

@ -831,94 +831,95 @@ class ExtensionDriver(object):
"""
pass
def process_create_network(self, session, data, result):
def process_create_network(self, plugin_context, data, result):
"""Process extended attributes for create network.
:param session: database session
:param plugin_context: plugin request context
:param data: dictionary of incoming network data
:param result: network dictionary to extend
Called inside transaction context on session to validate and
persist any extended network attributes defined by this
Called inside transaction context on plugin_context.session to
validate and persist any extended network attributes defined by this
driver. Extended attribute values must also be added to
result.
"""
pass
def process_create_subnet(self, session, data, result):
def process_create_subnet(self, plugin_context, data, result):
"""Process extended attributes for create subnet.
:param session: database session
:param plugin_context: plugin request context
:param data: dictionary of incoming subnet data
:param result: subnet dictionary to extend
Called inside transaction context on session to validate and
persist any extended subnet attributes defined by this
Called inside transaction context on plugin_context.session to
validate and persist any extended subnet attributes defined by this
driver. Extended attribute values must also be added to
result.
"""
pass
def process_create_port(self, session, data, result):
def process_create_port(self, plugin_context, data, result):
"""Process extended attributes for create port.
:param session: database session
:param plugin_context: plugin request context
:param data: dictionary of incoming port data
:param result: port dictionary to extend
Called inside transaction context on session to validate and
persist any extended port attributes defined by this
Called inside transaction context on plugin_context.session to
validate and persist any extended port attributes defined by this
driver. Extended attribute values must also be added to
result.
"""
pass
def process_update_network(self, session, data, result):
def process_update_network(self, plugin_context, data, result):
"""Process extended attributes for update network.
:param session: database session
:param plugin_context: plugin request context
:param data: dictionary of incoming network data
:param result: network dictionary to extend
Called inside transaction context on session to validate and
update any extended network attributes defined by this
Called inside transaction context on plugin_context.session to
validate and update any extended network attributes defined by this
driver. Extended attribute values, whether updated or not,
must also be added to result.
"""
pass
def process_update_subnet(self, session, data, result):
def process_update_subnet(self, plugin_context, data, result):
"""Process extended attributes for update subnet.
:param session: database session
:param plugin_context: plugin request context
:param data: dictionary of incoming subnet data
:param result: subnet dictionary to extend
Called inside transaction context on session to validate and
update any extended subnet attributes defined by this
Called inside transaction context on plugin_context.session to
validate and update any extended subnet attributes defined by this
driver. Extended attribute values, whether updated or not,
must also be added to result.
"""
pass
def process_update_port(self, session, data, result):
def process_update_port(self, plugin_context, data, result):
"""Process extended attributes for update port.
:param session: database session
:param plugin_context: plugin request context
:param data: dictionary of incoming port data
:param result: port dictionary to extend
Called inside transaction context on session to validate and
update any extended port attributes defined by this
Called inside transaction context on plugin_context.session to
validate and update any extended port attributes defined by this
driver. Extended attribute values, whether updated or not,
must also be added to result.
"""
pass
def extend_network_dict(self, session, result):
def extend_network_dict(self, session, base_model, result):
"""Add extended attributes to network dictionary.
:param session: database session
:param base_model: network model data
:param result: network dictionary to extend
Called inside transaction context on session to add any
@ -928,10 +929,11 @@ class ExtensionDriver(object):
"""
pass
def extend_subnet_dict(self, session, result):
def extend_subnet_dict(self, session, base_model, result):
"""Add extended attributes to subnet dictionary.
:param session: database session
:param base_model: subnet model data
:param result: subnet dictionary to extend
Called inside transaction context on session to add any
@ -941,15 +943,16 @@ class ExtensionDriver(object):
"""
pass
def extend_port_dict(self, session, result):
def extend_port_dict(self, session, base_model, result):
"""Add extended attributes to port dictionary.
:param session: database session
:param base_model: port model data
:param result: port dictionary to extend
Called inside transaction context on session to add any
extended attributes defined by this driver to a port
dictionary to be used for mechanism driver calls and/or
returned as the result of a port operation.
dictionary to be used for mechanism driver calls
and/or returned as the result of a port operation.
"""
pass

View File

@ -685,62 +685,64 @@ class ExtensionManager(stevedore.named.NamedExtensionManager):
{'alias': alias, 'drv': driver.name})
return exts
def _call_on_ext_drivers(self, method_name, session, data, result):
def _call_on_ext_drivers(self, method_name, plugin_context, data, result):
"""Helper method for calling a method across all extension drivers."""
for driver in self.ordered_ext_drivers:
try:
getattr(driver.obj, method_name)(session, data, result)
getattr(driver.obj, method_name)(plugin_context, data, result)
except Exception:
LOG.exception(
_LE("Extension driver '%(name)s' failed in %(method)s"),
{'name': driver.name, 'method': method_name}
)
def process_create_network(self, session, data, result):
def process_create_network(self, plugin_context, data, result):
"""Notify all extension drivers during network creation."""
self._call_on_ext_drivers("process_create_network", session, data,
result)
self._call_on_ext_drivers("process_create_network", plugin_context,
data, result)
def process_update_network(self, session, data, result):
def process_update_network(self, plugin_context, data, result):
"""Notify all extension drivers during network update."""
self._call_on_ext_drivers("process_update_network", session, data,
result)
self._call_on_ext_drivers("process_update_network", plugin_context,
data, result)
def process_create_subnet(self, session, data, result):
def process_create_subnet(self, plugin_context, data, result):
"""Notify all extension drivers during subnet creation."""
self._call_on_ext_drivers("process_create_subnet", session, data,
result)
self._call_on_ext_drivers("process_create_subnet", plugin_context,
data, result)
def process_update_subnet(self, session, data, result):
def process_update_subnet(self, plugin_context, data, result):
"""Notify all extension drivers during subnet update."""
self._call_on_ext_drivers("process_update_subnet", session, data,
result)
self._call_on_ext_drivers("process_update_subnet", plugin_context,
data, result)
def process_create_port(self, session, data, result):
def process_create_port(self, plugin_context, data, result):
"""Notify all extension drivers during port creation."""
self._call_on_ext_drivers("process_create_port", session, data, result)
self._call_on_ext_drivers("process_create_port", plugin_context,
data, result)
def process_update_port(self, session, data, result):
def process_update_port(self, plugin_context, data, result):
"""Notify all extension drivers during port update."""
self._call_on_ext_drivers("process_update_port", session, data, result)
self._call_on_ext_drivers("process_update_port", plugin_context,
data, result)
def extend_network_dict(self, session, result):
def extend_network_dict(self, session, base_model, result):
"""Notify all extension drivers to extend network dictionary."""
for driver in self.ordered_ext_drivers:
driver.obj.extend_network_dict(session, result)
driver.obj.extend_network_dict(session, base_model, result)
LOG.info(_LI("Extended network dict for driver '%(drv)s'"),
{'drv': driver.name})
def extend_subnet_dict(self, session, result):
def extend_subnet_dict(self, session, base_model, result):
"""Notify all extension drivers to extend subnet dictionary."""
for driver in self.ordered_ext_drivers:
driver.obj.extend_subnet_dict(session, result)
driver.obj.extend_subnet_dict(session, base_model, result)
LOG.info(_LI("Extended subnet dict for driver '%(drv)s'"),
{'drv': driver.name})
def extend_port_dict(self, session, result):
def extend_port_dict(self, session, base_model, result):
"""Notify all extension drivers to extend port dictionary."""
for driver in self.ordered_ext_drivers:
driver.obj.extend_port_dict(session, result)
driver.obj.extend_port_dict(session, base_model, result)
LOG.info(_LI("Extended port dict for driver '%(drv)s'"),
{'drv': driver.name})

View File

@ -477,17 +477,18 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
def _ml2_md_extend_network_dict(self, result, netdb):
session = db_api.get_session()
with session.begin(subtransactions=True):
self.extension_manager.extend_network_dict(session, result)
self.extension_manager.extend_network_dict(session, netdb, result)
def _ml2_md_extend_port_dict(self, result, portdb):
session = db_api.get_session()
with session.begin(subtransactions=True):
self.extension_manager.extend_port_dict(session, result)
self.extension_manager.extend_port_dict(session, portdb, result)
def _ml2_md_extend_subnet_dict(self, result, subnetdb):
session = db_api.get_session()
with session.begin(subtransactions=True):
self.extension_manager.extend_subnet_dict(session, result)
self.extension_manager.extend_subnet_dict(
session, subnetdb, result)
# Note - The following hook methods have "ml2" in their names so
# that they are not called twice during unit tests due to global
@ -587,7 +588,7 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
with session.begin(subtransactions=True):
self._ensure_default_security_group(context, tenant_id)
result = super(Ml2Plugin, self).create_network(context, network)
self.extension_manager.process_create_network(session, net_data,
self.extension_manager.process_create_network(context, net_data,
result)
self._process_l3_create(context, result, net_data)
net_data['id'] = result['id']
@ -624,8 +625,8 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
updated_network = super(Ml2Plugin, self).update_network(context,
id,
network)
self.extension_manager.process_update_network(session, network,
original_network)
self.extension_manager.process_update_network(context, network,
updated_network)
self._process_l3_update(context, updated_network,
network['network'])
self.type_manager.extend_network_dict_provider(context,
@ -777,7 +778,7 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
session = context.session
with session.begin(subtransactions=True):
result = super(Ml2Plugin, self).create_subnet(context, subnet)
self.extension_manager.process_create_subnet(session, subnet,
self.extension_manager.process_create_subnet(context, subnet,
result)
mech_context = driver_context.SubnetContext(self, context, result)
self.mechanism_manager.create_subnet_precommit(mech_context)
@ -805,8 +806,8 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
original_subnet = super(Ml2Plugin, self).get_subnet(context, id)
updated_subnet = super(Ml2Plugin, self).update_subnet(
context, id, subnet)
self.extension_manager.process_update_subnet(session, subnet,
original_subnet)
self.extension_manager.process_update_subnet(context, subnet,
updated_subnet)
mech_context = driver_context.SubnetContext(
self, context, updated_subnet, original_subnet=original_subnet)
self.mechanism_manager.update_subnet_precommit(mech_context)
@ -913,7 +914,7 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
sgids = self._get_security_groups_on_port(context, port)
dhcp_opts = port['port'].get(edo_ext.EXTRADHCPOPTS, [])
result = super(Ml2Plugin, self).create_port(context, port)
self.extension_manager.process_create_port(session, attrs, result)
self.extension_manager.process_create_port(context, attrs, result)
self._process_port_create_security_group(context, result, sgids)
network = self.get_network(context, result['network_id'])
binding = db.add_port_binding(session, result['id'])
@ -1011,8 +1012,8 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
original_port = self._make_port_dict(port_db)
updated_port = super(Ml2Plugin, self).update_port(context, id,
port)
self.extension_manager.process_update_port(session, attrs,
original_port)
self.extension_manager.process_update_port(context, attrs,
updated_port)
if addr_pair.ADDRESS_PAIRS in port['port']:
need_port_update_notify |= (
self.update_address_pairs_on_port(context, id, port,

View File

@ -29,19 +29,57 @@ class ExtensionDriverTestCase(test_ml2_plugin.Ml2PluginV2TestCase):
def test_network_attr(self):
with self.network() as network:
# Test create network
ent = network['network'].get('network_extension')
self.assertIsNotNone(ent)
# Test list networks
res = self._list('networks')
val = res['networks'][0].get('network_extension')
self.assertEqual('Test_Network_Extension', val)
# Test network update
data = {'network':
{'network_extension': 'Test_Network_Extension_Update'}}
res = self._update('networks', network['network']['id'], data)
val = res['network'].get('network_extension')
self.assertEqual('Test_Network_Extension_Update', val)
def test_subnet_attr(self):
with self.subnet() as subnet:
# Test create subnet
ent = subnet['subnet'].get('subnet_extension')
self.assertIsNotNone(ent)
# Test list subnets
res = self._list('subnets')
val = res['subnets'][0].get('subnet_extension')
self.assertEqual('Test_Subnet_Extension', val)
# Test subnet update
data = {'subnet':
{'subnet_extension': 'Test_Subnet_Extension_Update'}}
res = self._update('subnets', subnet['subnet']['id'], data)
val = res['subnet'].get('subnet_extension')
self.assertEqual('Test_Subnet_Extension_Update', val)
def test_port_attr(self):
with self.port() as port:
# Test create port
ent = port['port'].get('port_extension')
self.assertIsNotNone(ent)
# Test list ports
res = self._list('ports')
val = res['ports'][0].get('port_extension')
self.assertEqual('Test_Port_Extension', val)
# Test port update
data = {'port': {'port_extension': 'Test_Port_Extension_Update'}}
res = self._update('ports', port['port']['id'], data)
val = res['port'].get('port_extension')
self.assertEqual('Test_Port_Extension_Update', val)
class TestExtensionDriver(api.ExtensionDriver):
_supported_extension_alias = 'test_extension'
@ -56,11 +94,35 @@ class TestExtensionDriver(api.ExtensionDriver):
def extension_alias(self):
return self._supported_extension_alias
def process_create_network(self, session, data, result):
def process_create_network(self, plugin_context, data, result):
result['network_extension'] = self.network_extension
def process_create_subnet(self, session, data, result):
def process_create_subnet(self, plugin_context, data, result):
result['subnet_extension'] = self.subnet_extension
def process_create_port(self, session, data, result):
def process_create_port(self, plugin_context, data, result):
result['port_extension'] = self.port_extension
def process_update_network(self, plugin_context, data, result):
self.network_extension = data['network']['network_extension']
result['network_extension'] = self.network_extension
def process_update_subnet(self, plugin_context, data, result):
self.subnet_extension = data['subnet']['subnet_extension']
result['subnet_extension'] = self.subnet_extension
def process_update_port(self, plugin_context, data, result):
self.port_extension = data['port_extension']
result['port_extension'] = self.port_extension
def extend_network_dict(self, session, base_model, result):
if self._supported_extension_alias is 'test_extension':
result['network_extension'] = self.network_extension
def extend_subnet_dict(self, session, base_model, result):
if self._supported_extension_alias is 'test_extension':
result['subnet_extension'] = self.subnet_extension
def extend_port_dict(self, session, base_model, result):
if self._supported_extension_alias is 'test_extension':
result['port_extension'] = self.port_extension