Merge "NSX|P: Support bulk subnet create"
This commit is contained in:
commit
f1f4f1abe7
@ -1529,6 +1529,101 @@ class NsxPluginV3Base(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
context, created_subnet['id'])
|
||||
return created_subnet
|
||||
|
||||
def _create_bulk_with_callback(self, resource, context, request_items,
|
||||
post_create_func=None, rollback_func=None):
|
||||
# This is a copy of the _create_bulk() in db_base_plugin_v2.py,
|
||||
# but extended with user-provided callback functions.
|
||||
objects = []
|
||||
collection = "%ss" % resource
|
||||
items = request_items[collection]
|
||||
try:
|
||||
with db_api.CONTEXT_WRITER.using(context):
|
||||
for item in items:
|
||||
obj_creator = getattr(self, 'create_%s' % resource)
|
||||
obj = obj_creator(context, item)
|
||||
objects.append(obj)
|
||||
if post_create_func:
|
||||
# The user-provided post_create function is called
|
||||
# after a new object is created.
|
||||
post_create_func(obj)
|
||||
except Exception:
|
||||
if rollback_func:
|
||||
# The user-provided rollback function is called when an
|
||||
# exception occurred.
|
||||
for obj in objects:
|
||||
rollback_func(obj)
|
||||
|
||||
# Note that the session.rollback() function is called here.
|
||||
# session.rollback() will invoke transaction.rollback() on
|
||||
# the transaction this session maintains. The latter will
|
||||
# deactive the transaction and clear the session's cache.
|
||||
#
|
||||
# But depending on where the exception occurred,
|
||||
# transaction.rollback() may have already been called
|
||||
# internally before reaching here.
|
||||
#
|
||||
# For example, if the exception happened under a
|
||||
# "with session.begin(subtransactions=True):" statement
|
||||
# anywhere in the middle of processing obj_creator(),
|
||||
# transaction.__exit__() will invoke transaction.rollback().
|
||||
# Thus when the exception reaches here, the session's cache
|
||||
# is already empty.
|
||||
context.session.rollback()
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.error("An exception occurred while creating "
|
||||
"the %(resource)s:%(item)s",
|
||||
{'resource': resource, 'item': item})
|
||||
return objects
|
||||
|
||||
def _post_create_subnet(self, context, subnet):
|
||||
LOG.debug("Collect native DHCP entries for network %s",
|
||||
subnet['network_id'])
|
||||
dhcp_service = nsx_db.get_nsx_service_binding(
|
||||
context.session, subnet['network_id'], nsxlib_consts.SERVICE_DHCP)
|
||||
if dhcp_service:
|
||||
_net_id, nsx_port_id = nsx_db.get_nsx_switch_and_port_id(
|
||||
context.session, dhcp_service['port_id'])
|
||||
return {'nsx_port_id': nsx_port_id,
|
||||
'nsx_service_id': dhcp_service['nsx_service_id']}
|
||||
|
||||
def _rollback_subnet(self, subnet, dhcp_info):
|
||||
LOG.debug("Rollback native DHCP entries for network %s",
|
||||
subnet['network_id'])
|
||||
if dhcp_info and self.nsxlib:
|
||||
try:
|
||||
self.nsxlib.logical_port.delete(dhcp_info['nsx_port_id'])
|
||||
except Exception as e:
|
||||
LOG.error("Failed to delete logical port %(id)s "
|
||||
"during rollback. Exception: %(e)s",
|
||||
{'id': dhcp_info['nsx_port_id'], 'e': e})
|
||||
try:
|
||||
self.nsxlib.dhcp_server.delete(dhcp_info['nsx_service_id'])
|
||||
except Exception as e:
|
||||
LOG.error("Failed to delete logical DHCP server %(id)s "
|
||||
"during rollback. Exception: %(e)s",
|
||||
{'id': dhcp_info['nsx_service_id'], 'e': e})
|
||||
|
||||
def create_subnet_bulk(self, context, subnets):
|
||||
# Maintain a local cache here because when the rollback function
|
||||
# is called, the cache in the session may have already been cleared.
|
||||
_subnet_dhcp_info = {}
|
||||
|
||||
def _post_create(subnet):
|
||||
if subnet['enable_dhcp']:
|
||||
_subnet_dhcp_info[subnet['id']] = self._post_create_subnet(
|
||||
context, subnet)
|
||||
|
||||
def _rollback(subnet):
|
||||
if subnet['enable_dhcp'] and subnet['id'] in _subnet_dhcp_info:
|
||||
self._rollback_subnet(subnet, _subnet_dhcp_info[subnet['id']])
|
||||
del _subnet_dhcp_info[subnet['id']]
|
||||
|
||||
if self._has_native_dhcp_metadata():
|
||||
return self._create_bulk_with_callback('subnet', context, subnets,
|
||||
_post_create, _rollback)
|
||||
else:
|
||||
return self._create_bulk('subnet', context, subnets)
|
||||
|
||||
def _get_neutron_net_ids_by_nsx_id(self, context, nsx_id):
|
||||
"""Should be implemented by each plugin"""
|
||||
pass
|
||||
|
@ -1280,101 +1280,6 @@ class NsxV3Plugin(nsx_plugin_common.NsxPluginV3Base,
|
||||
LOG.warning("Failed to update network %(id)s dhcp server on "
|
||||
"the NSX: %(e)s", {'id': network['id'], 'e': e})
|
||||
|
||||
def _create_bulk_with_callback(self, resource, context, request_items,
|
||||
post_create_func=None, rollback_func=None):
|
||||
# This is a copy of the _create_bulk() in db_base_plugin_v2.py,
|
||||
# but extended with user-provided callback functions.
|
||||
objects = []
|
||||
collection = "%ss" % resource
|
||||
items = request_items[collection]
|
||||
try:
|
||||
with db_api.CONTEXT_WRITER.using(context):
|
||||
for item in items:
|
||||
obj_creator = getattr(self, 'create_%s' % resource)
|
||||
obj = obj_creator(context, item)
|
||||
objects.append(obj)
|
||||
if post_create_func:
|
||||
# The user-provided post_create function is called
|
||||
# after a new object is created.
|
||||
post_create_func(obj)
|
||||
except Exception:
|
||||
if rollback_func:
|
||||
# The user-provided rollback function is called when an
|
||||
# exception occurred.
|
||||
for obj in objects:
|
||||
rollback_func(obj)
|
||||
|
||||
# Note that the session.rollback() function is called here.
|
||||
# session.rollback() will invoke transaction.rollback() on
|
||||
# the transaction this session maintains. The latter will
|
||||
# deactive the transaction and clear the session's cache.
|
||||
#
|
||||
# But depending on where the exception occurred,
|
||||
# transaction.rollback() may have already been called
|
||||
# internally before reaching here.
|
||||
#
|
||||
# For example, if the exception happened under a
|
||||
# "with session.begin(subtransactions=True):" statement
|
||||
# anywhere in the middle of processing obj_creator(),
|
||||
# transaction.__exit__() will invoke transaction.rollback().
|
||||
# Thus when the exception reaches here, the session's cache
|
||||
# is already empty.
|
||||
context.session.rollback()
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.error("An exception occurred while creating "
|
||||
"the %(resource)s:%(item)s",
|
||||
{'resource': resource, 'item': item})
|
||||
return objects
|
||||
|
||||
def _post_create_subnet(self, context, subnet):
|
||||
LOG.debug("Collect native DHCP entries for network %s",
|
||||
subnet['network_id'])
|
||||
dhcp_service = nsx_db.get_nsx_service_binding(
|
||||
context.session, subnet['network_id'], nsxlib_consts.SERVICE_DHCP)
|
||||
if dhcp_service:
|
||||
_net_id, nsx_port_id = nsx_db.get_nsx_switch_and_port_id(
|
||||
context.session, dhcp_service['port_id'])
|
||||
return {'nsx_port_id': nsx_port_id,
|
||||
'nsx_service_id': dhcp_service['nsx_service_id']}
|
||||
|
||||
def _rollback_subnet(self, subnet, dhcp_info):
|
||||
LOG.debug("Rollback native DHCP entries for network %s",
|
||||
subnet['network_id'])
|
||||
if dhcp_info:
|
||||
try:
|
||||
self.nsxlib.logical_port.delete(dhcp_info['nsx_port_id'])
|
||||
except Exception as e:
|
||||
LOG.error("Failed to delete logical port %(id)s "
|
||||
"during rollback. Exception: %(e)s",
|
||||
{'id': dhcp_info['nsx_port_id'], 'e': e})
|
||||
try:
|
||||
self.nsxlib.dhcp_server.delete(dhcp_info['nsx_service_id'])
|
||||
except Exception as e:
|
||||
LOG.error("Failed to delete logical DHCP server %(id)s "
|
||||
"during rollback. Exception: %(e)s",
|
||||
{'id': dhcp_info['nsx_service_id'], 'e': e})
|
||||
|
||||
def create_subnet_bulk(self, context, subnets):
|
||||
# Maintain a local cache here because when the rollback function
|
||||
# is called, the cache in the session may have already been cleared.
|
||||
_subnet_dhcp_info = {}
|
||||
|
||||
def _post_create(subnet):
|
||||
if subnet['enable_dhcp']:
|
||||
_subnet_dhcp_info[subnet['id']] = self._post_create_subnet(
|
||||
context, subnet)
|
||||
|
||||
def _rollback(subnet):
|
||||
if subnet['enable_dhcp'] and subnet['id'] in _subnet_dhcp_info:
|
||||
self._rollback_subnet(subnet, _subnet_dhcp_info[subnet['id']])
|
||||
del _subnet_dhcp_info[subnet['id']]
|
||||
|
||||
if cfg.CONF.nsx_v3.native_dhcp_metadata:
|
||||
return self._create_bulk_with_callback('subnet', context, subnets,
|
||||
_post_create, _rollback)
|
||||
else:
|
||||
return self._create_bulk('subnet', context, subnets)
|
||||
|
||||
def create_subnet(self, context, subnet):
|
||||
self._validate_host_routes_input(subnet)
|
||||
# TODO(berlin): public external subnet announcement
|
||||
|
@ -206,8 +206,6 @@ class NsxNativeDhcpTestCase(test_plugin.NsxPPluginTestCaseMixin):
|
||||
True)
|
||||
|
||||
def test_dhcp_service_with_create_dhcp_subnet_bulk(self):
|
||||
# TODO(asarfaty) Enable this test once create_subnet_bulk is supported
|
||||
return
|
||||
# Test if DHCP service is enabled on all networks after a
|
||||
# create_subnet_bulk operation.
|
||||
with self.network() as network1, self.network() as network2:
|
||||
@ -239,8 +237,6 @@ class NsxNativeDhcpTestCase(test_plugin.NsxPPluginTestCaseMixin):
|
||||
self.assertTrue(dhcp_service)
|
||||
|
||||
def test_dhcp_service_with_create_dhcp_subnet_bulk_failure(self):
|
||||
# TODO(asarfaty) Enable this test once create_subnet_bulk is supported
|
||||
return
|
||||
# Test if user-provided rollback function is invoked when
|
||||
# exception occurred during a create_subnet_bulk operation.
|
||||
with self.network() as network1, self.network() as network2:
|
||||
|
@ -836,7 +836,6 @@ class NsxPTestPorts(test_db_base_plugin_v2.TestPortsV2,
|
||||
|
||||
class NsxPTestSubnets(test_db_base_plugin_v2.TestSubnetsV2,
|
||||
NsxPPluginTestCaseMixin):
|
||||
# TODO(asarfaty) add NsxNativeDhcpTestCase tests here too
|
||||
def setUp(self, plugin=PLUGIN_NAME, ext_mgr=None):
|
||||
super(NsxPTestSubnets, self).setUp(plugin=plugin, ext_mgr=ext_mgr)
|
||||
self.disable_dhcp = False
|
||||
|
Loading…
x
Reference in New Issue
Block a user