@ -126,8 +126,6 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
self . type_manager . initialize ( )
self . extension_manager . initialize ( )
self . mechanism_manager . initialize ( )
# bulk support depends on the underlying drivers
self . __native_bulk_support = self . mechanism_manager . native_bulk_support
self . _setup_rpc ( )
@ -485,10 +483,59 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
segment [ api . SEGMENTATION_ID ] ,
segment [ api . PHYSICAL_NETWORK ] )
# TODO(apech): Need to override bulk operations
def _delete_objects ( self , context , resource , objects ) :
delete_op = getattr ( self , ' delete_ %s ' % resource )
for obj in objects :
try :
delete_op ( context , obj [ ' result ' ] [ ' id ' ] )
except KeyError :
LOG . exception ( _LE ( " Could not find %s to delete. " ) ,
resource )
except Exception :
LOG . exception ( _LE ( " Could not delete %(res)s %(id)s . " ) ,
{ ' res ' : resource ,
' id ' : obj [ ' result ' ] [ ' id ' ] } )
def _create_bulk_ml2 ( self , resource , context , request_items ) :
objects = [ ]
collection = " %s s " % resource
items = request_items [ collection ]
try :
with context . session . begin ( subtransactions = True ) :
obj_creator = getattr ( self , ' _create_ %s _db ' % resource )
for item in items :
attrs = item [ resource ]
result , mech_context = obj_creator ( context , item )
objects . append ( { ' mech_context ' : mech_context ,
' result ' : result ,
' attributes ' : attrs } )
except Exception :
with excutils . save_and_reraise_exception ( ) :
LOG . exception ( _LE ( " An exception occurred while creating "
" the %(resource)s : %(item)s " ) ,
{ ' resource ' : resource , ' item ' : item } )
def create_network ( self , context , network ) :
net_data = network [ ' network ' ]
try :
postcommit_op = getattr ( self . mechanism_manager ,
' create_ %s _postcommit ' % resource )
for obj in objects :
postcommit_op ( obj [ ' mech_context ' ] )
return objects
except ml2_exc . MechanismDriverError :
with excutils . save_and_reraise_exception ( ) :
resource_ids = [ res [ ' result ' ] [ ' id ' ] for res in objects ]
LOG . exception ( _LE ( " mechanism_manager.create_ %(res)s "
" _postcommit failed for %(res)s : "
" ' %(failed_id)s ' . Deleting "
" %(res)s s %(resource_ids)s " ) ,
{ ' res ' : resource ,
' failed_id ' : obj [ ' result ' ] [ ' id ' ] ,
' resource_ids ' : ' , ' . join ( resource_ids ) } )
self . _delete_objects ( context , resource , objects )
def _create_network_db ( self , context , network ) :
net_data = network [ attributes . NETWORK ]
tenant_id = self . _get_tenant_id_for_create ( context , net_data )
session = context . session
with session . begin ( subtransactions = True ) :
@ -504,7 +551,10 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
mech_context = driver_context . NetworkContext ( self , context ,
result )
self . mechanism_manager . create_network_precommit ( mech_context )
return result , mech_context
def create_network ( self , context , network ) :
result , mech_context = self . _create_network_db ( context , network )
try :
self . mechanism_manager . create_network_postcommit ( mech_context )
except ml2_exc . MechanismDriverError :
@ -512,8 +562,13 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
LOG . error ( _LE ( " mechanism_manager.create_network_postcommit "
" failed, deleting network ' %s ' " ) , result [ ' id ' ] )
self . delete_network ( context , result [ ' id ' ] )
return result
def create_network_bulk ( self , context , networks ) :
objects = self . _create_bulk_ml2 ( attributes . NETWORK , context , networks )
return [ obj [ ' result ' ] for obj in objects ]
def update_network ( self , context , id , network ) :
provider . _raise_if_updates_provider_attributes ( network [ ' network ' ] )
@ -661,7 +716,7 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
" failed " ) )
self . notifier . network_delete ( context , id )
def create_subnet ( self , context , subnet ) :
def _ create_subnet_db ( self , context , subnet ) :
session = context . session
with session . begin ( subtransactions = True ) :
result = super ( Ml2Plugin , self ) . create_subnet ( context , subnet )
@ -670,6 +725,10 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
mech_context = driver_context . SubnetContext ( self , context , result )
self . mechanism_manager . create_subnet_precommit ( mech_context )
return result , mech_context
def create_subnet ( self , context , subnet ) :
result , mech_context = self . _create_subnet_db ( context , subnet )
try :
self . mechanism_manager . create_subnet_postcommit ( mech_context )
except ml2_exc . MechanismDriverError :
@ -679,6 +738,10 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
self . delete_subnet ( context , result [ ' id ' ] )
return result
def create_subnet_bulk ( self , context , subnets ) :
objects = self . _create_bulk_ml2 ( attributes . SUBNET , context , subnets )
return [ obj [ ' result ' ] for obj in objects ]
def update_subnet ( self , context , id , subnet ) :
session = context . session
with session . begin ( subtransactions = True ) :
@ -780,8 +843,8 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
# the fact that an error occurred.
LOG . error ( _LE ( " mechanism_manager.delete_subnet_postcommit failed " ) )
def create_port ( self , context , port ) :
attrs = port [ ' port ' ]
def _ create_port_db ( self , context , port ) :
attrs = port [ attributes . PORT ]
attrs [ ' status ' ] = const . PORT_STATUS_DOWN
session = context . session
@ -796,7 +859,7 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
binding = db . add_port_binding ( session , result [ ' id ' ] )
mech_context = driver_context . PortContext ( self , context , result ,
network , binding )
new_host_port = self . _get_host_port_if_changed ( mech_context , attrs )
self . _process_port_binding ( mech_context , attrs )
result [ addr_pair . ADDRESS_PAIRS ] = (
@ -807,7 +870,12 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
dhcp_opts )
self . mechanism_manager . create_port_precommit ( mech_context )
# Notification must be sent after the above transaction is complete
return result , mech_context
def create_port ( self , context , port ) :
attrs = port [ ' port ' ]
result , mech_context = self . _create_port_db ( context , port )
new_host_port = self . _get_host_port_if_changed ( mech_context , attrs )
self . _notify_l3_agent_new_port ( context , new_host_port )
try :
@ -831,6 +899,35 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
self . delete_port ( context , result [ ' id ' ] )
return bound_context . _port
def create_port_bulk ( self , context , ports ) :
objects = self . _create_bulk_ml2 ( attributes . PORT , context , ports )
for obj in objects :
# REVISIT(rkukura): Is there any point in calling this before
# a binding has been successfully established?
# TODO(banix): Use a single notification for all objects
self . notify_security_groups_member_updated ( context ,
obj [ ' result ' ] )
attrs = obj [ ' attributes ' ]
if attrs and attrs . get ( portbindings . HOST_ID ) :
new_host_port = self . _get_host_port_if_changed (
obj [ ' mech_context ' ] , attrs )
self . _notify_l3_agent_new_port ( context , new_host_port )
try :
for obj in objects :
obj [ ' bound_context ' ] = self . _bind_port_if_needed (
obj [ ' mech_context ' ] )
return [ obj [ ' bound_context ' ] . _port for obj in objects ]
except ml2_exc . MechanismDriverError :
with excutils . save_and_reraise_exception ( ) :
resource_ids = [ res [ ' result ' ] [ ' id ' ] for res in objects ]
LOG . error ( _LE ( " _bind_port_if_needed failed. "
" Deleting all ports from create bulk ' %s ' " ) ,
resource_ids )
self . _delete_objects ( context , ' port ' , objects )
def update_port ( self , context , id , port ) :
attrs = port [ ' port ' ]
need_port_update_notify = False