Merge "l3_db: refactor L3_NAT_DB_mixin"

This commit is contained in:
Jenkins 2014-08-08 07:16:20 +00:00 committed by Gerrit Code Review
commit 0229ab0ae8
4 changed files with 180 additions and 87 deletions

View File

@ -51,11 +51,11 @@ class RouterRoute(model_base.BASEV2, models_v2.Route):
cascade='delete')) cascade='delete'))
class ExtraRoute_db_mixin(l3_db.L3_NAT_db_mixin): class ExtraRoute_dbonly_mixin(l3_db.L3_NAT_dbonly_mixin):
"""Mixin class to support extra route configuration on router.""" """Mixin class to support extra route configuration on router."""
def _extend_router_dict_extraroute(self, router_res, router_db): def _extend_router_dict_extraroute(self, router_res, router_db):
router_res['routes'] = (ExtraRoute_db_mixin. router_res['routes'] = (ExtraRoute_dbonly_mixin.
_make_extra_route_list( _make_extra_route_list(
router_db['route_list'] router_db['route_list']
)) ))
@ -71,7 +71,7 @@ class ExtraRoute_db_mixin(l3_db.L3_NAT_db_mixin):
if 'routes' in r: if 'routes' in r:
self._update_extra_routes(context, router_db, r['routes']) self._update_extra_routes(context, router_db, r['routes'])
routes = self._get_extra_routes_by_router_id(context, id) routes = self._get_extra_routes_by_router_id(context, id)
router_updated = super(ExtraRoute_db_mixin, self).update_router( router_updated = super(ExtraRoute_dbonly_mixin, self).update_router(
context, id, router) context, id, router)
router_updated['routes'] = routes router_updated['routes'] = routes
@ -159,7 +159,7 @@ class ExtraRoute_db_mixin(l3_db.L3_NAT_db_mixin):
def get_router(self, context, id, fields=None): def get_router(self, context, id, fields=None):
with context.session.begin(subtransactions=True): with context.session.begin(subtransactions=True):
router = super(ExtraRoute_db_mixin, self).get_router( router = super(ExtraRoute_dbonly_mixin, self).get_router(
context, id, fields) context, id, fields)
return router return router
@ -167,14 +167,15 @@ class ExtraRoute_db_mixin(l3_db.L3_NAT_db_mixin):
sorts=None, limit=None, marker=None, sorts=None, limit=None, marker=None,
page_reverse=False): page_reverse=False):
with context.session.begin(subtransactions=True): with context.session.begin(subtransactions=True):
routers = super(ExtraRoute_db_mixin, self).get_routers( routers = super(ExtraRoute_dbonly_mixin, self).get_routers(
context, filters, fields, sorts=sorts, limit=limit, context, filters, fields, sorts=sorts, limit=limit,
marker=marker, page_reverse=page_reverse) marker=marker, page_reverse=page_reverse)
return routers return routers
def _confirm_router_interface_not_in_use(self, context, router_id, def _confirm_router_interface_not_in_use(self, context, router_id,
subnet_id): subnet_id):
super(ExtraRoute_db_mixin, self)._confirm_router_interface_not_in_use( super(ExtraRoute_dbonly_mixin,
self)._confirm_router_interface_not_in_use(
context, router_id, subnet_id) context, router_id, subnet_id)
subnet_db = self._core_plugin._get_subnet(context, subnet_id) subnet_db = self._core_plugin._get_subnet(context, subnet_id)
subnet_cidr = netaddr.IPNetwork(subnet_db['cidr']) subnet_cidr = netaddr.IPNetwork(subnet_db['cidr'])
@ -183,3 +184,8 @@ class ExtraRoute_db_mixin(l3_db.L3_NAT_db_mixin):
if netaddr.all_matching_cidrs(route['nexthop'], [subnet_cidr]): if netaddr.all_matching_cidrs(route['nexthop'], [subnet_cidr]):
raise extraroute.RouterInterfaceInUseByRoute( raise extraroute.RouterInterfaceInUseByRoute(
router_id=router_id, subnet_id=subnet_id) router_id=router_id, subnet_id=subnet_id)
class ExtraRoute_db_mixin(ExtraRoute_dbonly_mixin, l3_db.L3_NAT_db_mixin):
"""Mixin class to support extra route configuration on router with rpc."""
pass

View File

@ -78,7 +78,7 @@ class FloatingIP(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
status = sa.Column(sa.String(16)) status = sa.Column(sa.String(16))
class L3_NAT_db_mixin(l3.RouterPluginBase): class L3_NAT_dbonly_mixin(l3.RouterPluginBase):
"""Mixin class to add L3/NAT router methods to db_base_plugin_v2.""" """Mixin class to add L3/NAT router methods to db_base_plugin_v2."""
router_device_owners = ( router_device_owners = (
@ -87,16 +87,6 @@ class L3_NAT_db_mixin(l3.RouterPluginBase):
DEVICE_OWNER_FLOATINGIP DEVICE_OWNER_FLOATINGIP
) )
@property
def l3_rpc_notifier(self):
if not hasattr(self, '_l3_rpc_notifier'):
self._l3_rpc_notifier = l3_rpc_agent_api.L3AgentNotifyAPI()
return self._l3_rpc_notifier
@l3_rpc_notifier.setter
def l3_rpc_notifier(self, value):
self._l3_rpc_notifier = value
@property @property
def _core_plugin(self): def _core_plugin(self):
return manager.NeutronManager.get_plugin() return manager.NeutronManager.get_plugin()
@ -169,17 +159,13 @@ class L3_NAT_db_mixin(l3.RouterPluginBase):
if gw_info != attributes.ATTR_NOT_SPECIFIED: if gw_info != attributes.ATTR_NOT_SPECIFIED:
candidates = self._check_router_needs_rescheduling( candidates = self._check_router_needs_rescheduling(
context, id, gw_info) context, id, gw_info)
payload = {'gw_exists': True}
else: else:
candidates = None candidates = None
payload = {'gw_exists': False}
router_db = self._update_router_db(context, id, r, gw_info) router_db = self._update_router_db(context, id, r, gw_info)
if candidates: if candidates:
l3_plugin = manager.NeutronManager.get_service_plugins().get( l3_plugin = manager.NeutronManager.get_service_plugins().get(
constants.L3_ROUTER_NAT) constants.L3_ROUTER_NAT)
l3_plugin.reschedule_router(context, id, candidates) l3_plugin.reschedule_router(context, id, candidates)
self.l3_rpc_notifier.routers_updated(context, [router_db['id']],
None, payload)
return self._make_router_dict(router_db) return self._make_router_dict(router_db)
def _check_router_needs_rescheduling(self, context, router_id, gw_info): def _check_router_needs_rescheduling(self, context, router_id, gw_info):
@ -357,8 +343,6 @@ class L3_NAT_db_mixin(l3.RouterPluginBase):
self._core_plugin._delete_port(context.elevated(), self._core_plugin._delete_port(context.elevated(),
ports[0]['id']) ports[0]['id'])
self.l3_rpc_notifier.router_deleted(context, id)
def get_router(self, context, id, fields=None): def get_router(self, context, id, fields=None):
router = self._get_router(context, id) router = self._get_router(context, id)
return self._make_router_dict(router, fields) return self._make_router_dict(router, fields)
@ -469,23 +453,15 @@ class L3_NAT_db_mixin(l3.RouterPluginBase):
'device_owner': owner, 'device_owner': owner,
'name': ''}}) 'name': ''}})
def notify_router_interface_action( @staticmethod
self, context, router_id, tenant_id, port_id, subnet_id, action): def _make_router_interface_info(
l3_method = '%s_router_interface' % action router_id, tenant_id, port_id, subnet_id):
self.l3_rpc_notifier.routers_updated(context, [router_id], return {
l3_method, {'subnet_id': subnet_id})
mapping = {'add': 'create', 'remove': 'delete'}
info = {
'id': router_id, 'id': router_id,
'tenant_id': tenant_id, 'tenant_id': tenant_id,
'port_id': port_id, 'port_id': port_id,
'subnet_id': subnet_id 'subnet_id': subnet_id
} }
notifier = n_rpc.get_notifier('network')
router_event = 'router.interface.%s' % mapping[action]
notifier.info(context, router_event, {'router_interface': info})
return info
def add_router_interface(self, context, router_id, interface_info): def add_router_interface(self, context, router_id, interface_info):
add_by_port, add_by_sub = self._validate_interface_info(interface_info) add_by_port, add_by_sub = self._validate_interface_info(interface_info)
@ -498,9 +474,9 @@ class L3_NAT_db_mixin(l3.RouterPluginBase):
port = self._add_interface_by_subnet( port = self._add_interface_by_subnet(
context, router_id, interface_info['subnet_id'], device_owner) context, router_id, interface_info['subnet_id'], device_owner)
return self.notify_router_interface_action( return self._make_router_interface_info(
context, router_id, port['tenant_id'], port['id'], router_id, port['tenant_id'], port['id'],
port['fixed_ips'][0]['subnet_id'], 'add') port['fixed_ips'][0]['subnet_id'])
def _confirm_router_interface_not_in_use(self, context, router_id, def _confirm_router_interface_not_in_use(self, context, router_id,
subnet_id): subnet_id):
@ -568,9 +544,8 @@ class L3_NAT_db_mixin(l3.RouterPluginBase):
port, subnet = self._remove_interface_by_subnet( port, subnet = self._remove_interface_by_subnet(
context, router_id, subnet_id, device_owner) context, router_id, subnet_id, device_owner)
return self.notify_router_interface_action( return self._make_router_interface_info(router_id, port['tenant_id'],
context, router_id, port['tenant_id'], port['id'], port['id'], subnet['id'])
subnet['id'], 'remove')
def _get_floatingip(self, context, id): def _get_floatingip(self, context, id):
try: try:
@ -739,9 +714,8 @@ class L3_NAT_db_mixin(l3.RouterPluginBase):
'router_id': router_id, 'router_id': router_id,
'last_known_router_id': previous_router_id}) 'last_known_router_id': previous_router_id})
def create_floatingip( def create_floatingip(self, context, floatingip,
self, context, floatingip, initial_status=l3_constants.FLOATINGIP_STATUS_ACTIVE):
initial_status=l3_constants.FLOATINGIP_STATUS_ACTIVE):
fip = floatingip['floatingip'] fip = floatingip['floatingip']
tenant_id = self._get_tenant_id_for_create(context, fip) tenant_id = self._get_tenant_id_for_create(context, fip)
fip_id = uuidutils.generate_uuid() fip_id = uuidutils.generate_uuid()
@ -785,34 +759,30 @@ class L3_NAT_db_mixin(l3.RouterPluginBase):
floatingip_db, external_port) floatingip_db, external_port)
context.session.add(floatingip_db) context.session.add(floatingip_db)
router_id = floatingip_db['router_id']
if router_id:
self.l3_rpc_notifier.routers_updated(
context, [router_id],
'create_floatingip', {})
return self._make_floatingip_dict(floatingip_db) return self._make_floatingip_dict(floatingip_db)
def update_floatingip(self, context, id, floatingip): def _update_floatingip(self, context, id, floatingip):
fip = floatingip['floatingip'] fip = floatingip['floatingip']
with context.session.begin(subtransactions=True): with context.session.begin(subtransactions=True):
floatingip_db = self._get_floatingip(context, id) floatingip_db = self._get_floatingip(context, id)
old_floatingip = self._make_floatingip_dict(floatingip_db)
fip['tenant_id'] = floatingip_db['tenant_id'] fip['tenant_id'] = floatingip_db['tenant_id']
fip['id'] = id fip['id'] = id
fip_port_id = floatingip_db['floating_port_id'] fip_port_id = floatingip_db['floating_port_id']
before_router_id = floatingip_db['router_id']
self._update_fip_assoc(context, fip, floatingip_db, self._update_fip_assoc(context, fip, floatingip_db,
self._core_plugin.get_port( self._core_plugin.get_port(
context.elevated(), fip_port_id)) context.elevated(), fip_port_id))
router_ids = [] return old_floatingip, self._make_floatingip_dict(floatingip_db)
if before_router_id:
router_ids.append(before_router_id) def _floatingips_to_router_ids(self, floatingips):
router_id = floatingip_db['router_id'] return list(set([floatingip['router_id']
if router_id and router_id != before_router_id: for floatingip in floatingips
router_ids.append(router_id) if floatingip['router_id']]))
if router_ids:
self.l3_rpc_notifier.routers_updated( def update_floatingip(self, context, id, floatingip):
context, router_ids, 'update_floatingip', {}) _old_floatingip, floatingip = self._update_floatingip(
return self._make_floatingip_dict(floatingip_db) context, id, floatingip)
return floatingip
def update_floatingip_status(self, context, floatingip_id, status): def update_floatingip_status(self, context, floatingip_id, status):
"""Update operational status for floating IP in neutron DB.""" """Update operational status for floating IP in neutron DB."""
@ -820,7 +790,7 @@ class L3_NAT_db_mixin(l3.RouterPluginBase):
FloatingIP.id == floatingip_id) FloatingIP.id == floatingip_id)
fip_query.update({'status': status}, synchronize_session=False) fip_query.update({'status': status}, synchronize_session=False)
def delete_floatingip(self, context, id): def _delete_floatingip(self, context, id):
floatingip = self._get_floatingip(context, id) floatingip = self._get_floatingip(context, id)
router_id = floatingip['router_id'] router_id = floatingip['router_id']
with context.session.begin(subtransactions=True): with context.session.begin(subtransactions=True):
@ -828,10 +798,10 @@ class L3_NAT_db_mixin(l3.RouterPluginBase):
self._core_plugin.delete_port(context.elevated(), self._core_plugin.delete_port(context.elevated(),
floatingip['floating_port_id'], floatingip['floating_port_id'],
l3_port_check=False) l3_port_check=False)
if router_id: return router_id
self.l3_rpc_notifier.routers_updated(
context, [router_id], def delete_floatingip(self, context, id):
'delete_floatingip', {}) self._delete_floatingip(context, id)
def get_floatingip(self, context, id, fields=None): def get_floatingip(self, context, id, fields=None):
floatingip = self._get_floatingip(context, id) floatingip = self._get_floatingip(context, id)
@ -890,7 +860,7 @@ class L3_NAT_db_mixin(l3.RouterPluginBase):
{'port_id': port_db['id'], {'port_id': port_db['id'],
'port_owner': port_db['device_owner']}) 'port_owner': port_db['device_owner']})
def disassociate_floatingips(self, context, port_id, do_notify=True): def disassociate_floatingips(self, context, port_id):
"""Disassociate all floating IPs linked to specific port. """Disassociate all floating IPs linked to specific port.
@param port_id: ID of the port to disassociate floating IPs. @param port_id: ID of the port to disassociate floating IPs.
@ -908,20 +878,8 @@ class L3_NAT_db_mixin(l3.RouterPluginBase):
floating_ip.update({'fixed_port_id': None, floating_ip.update({'fixed_port_id': None,
'fixed_ip_address': None, 'fixed_ip_address': None,
'router_id': None}) 'router_id': None})
if do_notify:
self.notify_routers_updated(context, router_ids)
# since caller assumes that we handled notifications on its
# behalf, return nothing
return
return router_ids return router_ids
def notify_routers_updated(self, context, router_ids):
if router_ids:
self.l3_rpc_notifier.routers_updated(
context, list(router_ids),
'disassociate_floatingips', {})
def _build_routers_list(self, context, routers, gw_ports): def _build_routers_list(self, context, routers, gw_ports):
for router in routers: for router in routers:
gw_port_id = router['gw_port_id'] gw_port_id = router['gw_port_id']
@ -1069,3 +1027,122 @@ class L3_NAT_db_mixin(l3.RouterPluginBase):
self._process_floating_ips(context, routers_dict, floating_ips) self._process_floating_ips(context, routers_dict, floating_ips)
self._process_interfaces(routers_dict, interfaces) self._process_interfaces(routers_dict, interfaces)
return routers_dict.values() return routers_dict.values()
class L3RpcNotifierMixin(object):
"""Mixin class to add rpc notifier attribute to db_base_plugin_v2."""
@property
def l3_rpc_notifier(self):
if not hasattr(self, '_l3_rpc_notifier'):
self._l3_rpc_notifier = l3_rpc_agent_api.L3AgentNotifyAPI()
return self._l3_rpc_notifier
@l3_rpc_notifier.setter
def l3_rpc_notifier(self, value):
self._l3_rpc_notifier = value
def notify_router_updated(self, context, router_id,
operation=None, data=None):
if router_id:
self.l3_rpc_notifier.routers_updated(
context, [router_id], operation, data)
def notify_routers_updated(self, context, router_ids,
operation=None, data=None):
if router_ids:
self.l3_rpc_notifier.routers_updated(
context, router_ids, operation, data)
def notify_router_deleted(self, context, router_id):
self.l3_rpc_notifier.router_deleted(context, router_id)
class L3_NAT_db_mixin(L3_NAT_dbonly_mixin, L3RpcNotifierMixin):
"""Mixin class to add rpc notifier methods to db_base_plugin_v2."""
def update_router(self, context, id, router):
r = router['router']
payload = {'gw_exists':
r.get(EXTERNAL_GW_INFO, attributes.ATTR_NOT_SPECIFIED) !=
attributes.ATTR_NOT_SPECIFIED}
router_dict = super(L3_NAT_db_mixin, self).update_router(context,
id, router)
self.notify_router_updated(context, router_dict['id'], None, payload)
return router_dict
def delete_router(self, context, id):
super(L3_NAT_db_mixin, self).delete_router(context, id)
self.notify_router_deleted(context, id)
def notify_router_interface_action(
self, context, router_interface_info, action):
l3_method = '%s_router_interface' % action
super(L3_NAT_db_mixin, self).notify_routers_updated(
context, [router_interface_info['id']], l3_method,
{'subnet_id': router_interface_info['subnet_id']})
mapping = {'add': 'create', 'remove': 'delete'}
notifier = n_rpc.get_notifier('network')
router_event = 'router.interface.%s' % mapping[action]
notifier.info(context, router_event,
{'router_interface': router_interface_info})
def add_router_interface(self, context, router_id, interface_info):
router_interface_info = super(
L3_NAT_db_mixin, self).add_router_interface(
context, router_id, interface_info)
self.notify_router_interface_action(
context, router_interface_info, 'add')
return router_interface_info
def remove_router_interface(self, context, router_id, interface_info):
router_interface_info = super(
L3_NAT_db_mixin, self).remove_router_interface(
context, router_id, interface_info)
self.notify_router_interface_action(
context, router_interface_info, 'remove')
return router_interface_info
def create_floatingip(self, context, floatingip,
initial_status=l3_constants.FLOATINGIP_STATUS_ACTIVE):
floatingip_dict = super(L3_NAT_db_mixin, self).create_floatingip(
context, floatingip, initial_status)
router_id = floatingip_dict['router_id']
self.notify_router_updated(context, router_id, 'create_floatingip', {})
return floatingip_dict
def update_floatingip(self, context, id, floatingip):
old_floatingip, floatingip = self._update_floatingip(
context, id, floatingip)
router_ids = self._floatingips_to_router_ids(
[old_floatingip, floatingip])
super(L3_NAT_db_mixin, self).notify_routers_updated(
context, router_ids, 'update_floatingip', {})
return floatingip
def delete_floatingip(self, context, id):
router_id = self._delete_floatingip(context, id)
self.notify_router_updated(context, router_id, 'delete_floatingip', {})
def disassociate_floatingips(self, context, port_id, do_notify=True):
"""Disassociate all floating IPs linked to specific port.
@param port_id: ID of the port to disassociate floating IPs.
@param do_notify: whether we should notify routers right away.
@return: set of router-ids that require notification updates
if do_notify is False, otherwise None.
"""
router_ids = super(L3_NAT_db_mixin, self).disassociate_floatingips(
context, port_id)
if do_notify:
self.notify_routers_updated(context, router_ids)
# since caller assumes that we handled notifications on its
# behalf, return nothing
return
return router_ids
def notify_routers_updated(self, context, router_ids):
super(L3_NAT_db_mixin, self).notify_routers_updated(
context, list(router_ids), 'disassociate_floatingips', {})

View File

@ -180,9 +180,12 @@ class L3_NAT_with_dvr_db_mixin(l3_db.L3_NAT_db_mixin,
context.elevated(), router_id, port['network_id'], context.elevated(), router_id, port['network_id'],
port['fixed_ips'][0]['subnet_id']) port['fixed_ips'][0]['subnet_id'])
return self.notify_router_interface_action( router_interface_info = self._make_router_interface_info(
context, router_id, port['tenant_id'], port['id'], router_id, port['tenant_id'], port['id'],
port['fixed_ips'][0]['subnet_id'], 'add') port['fixed_ips'][0]['subnet_id'])
self.notify_router_interface_action(
context, router_interface_info, 'add')
return router_interface_info
def remove_router_interface(self, context, router_id, interface_info): def remove_router_interface(self, context, router_id, interface_info):
if not interface_info: if not interface_info:
@ -205,9 +208,12 @@ class L3_NAT_with_dvr_db_mixin(l3_db.L3_NAT_db_mixin,
self.delete_csnat_router_interface_ports( self.delete_csnat_router_interface_ports(
context.elevated(), router, subnet_id=subnet_id) context.elevated(), router, subnet_id=subnet_id)
return self.notify_router_interface_action( router_interface_info = self._make_router_interface_info(
context, router_id, port['tenant_id'], port['id'], router_id, port['tenant_id'], port['id'],
subnet['id'], 'remove') port['fixed_ips'][0]['subnet_id'])
self.notify_router_interface_action(
context, router_interface_info, 'remove')
return router_interface_info
def get_snat_sync_interfaces(self, context, router_ids): def get_snat_sync_interfaces(self, context, router_ids):
"""Query router interfaces that relate to list of router_ids.""" """Query router interfaces that relate to list of router_ids."""

View File

@ -31,7 +31,7 @@ setattr(l3_db.Router, 'enable_snat',
nullable=False)) nullable=False))
class L3_NAT_db_mixin(l3_db.L3_NAT_db_mixin): class L3_NAT_dbonly_mixin(l3_db.L3_NAT_dbonly_mixin):
"""Mixin class to add configurable gateway modes.""" """Mixin class to add configurable gateway modes."""
# Register dict extend functions for ports and networks # Register dict extend functions for ports and networks
@ -56,7 +56,7 @@ class L3_NAT_db_mixin(l3_db.L3_NAT_db_mixin):
router.enable_snat = enable_snat router.enable_snat = enable_snat
# Calls superclass, pass router db object for avoiding re-loading # Calls superclass, pass router db object for avoiding re-loading
super(L3_NAT_db_mixin, self)._update_router_gw_info( super(L3_NAT_dbonly_mixin, self)._update_router_gw_info(
context, router_id, info, router=router) context, router_id, info, router=router)
# Returning the router might come back useful if this # Returning the router might come back useful if this
# method is overridden in child classes # method is overridden in child classes
@ -70,3 +70,7 @@ class L3_NAT_db_mixin(l3_db.L3_NAT_db_mixin):
# Add enable_snat key # Add enable_snat key
rtr['enable_snat'] = rtr[EXTERNAL_GW_INFO]['enable_snat'] rtr['enable_snat'] = rtr[EXTERNAL_GW_INFO]['enable_snat']
return routers return routers
class L3_NAT_db_mixin(L3_NAT_dbonly_mixin, l3_db.L3_NAT_db_mixin):
pass