From c3b2c2a9a22bac5cf17813c589444d3abebaa23b Mon Sep 17 00:00:00 2001 From: Wojciech Dec Date: Tue, 16 Aug 2016 19:27:01 +0200 Subject: Adding Mitaka networking-old module with the ODL topology based port binding resolution mechanism from https://review.openstack.org/333186 Change-Id: I10d400aac9bb639c146527f0f93e6925cb74d9de Signed-off-by: Wojciech Dec --- networking-odl/networking_odl/l3/l3_odl_v2.py | 206 ++++++++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 networking-odl/networking_odl/l3/l3_odl_v2.py (limited to 'networking-odl/networking_odl/l3/l3_odl_v2.py') diff --git a/networking-odl/networking_odl/l3/l3_odl_v2.py b/networking-odl/networking_odl/l3/l3_odl_v2.py new file mode 100644 index 0000000..2732ea6 --- /dev/null +++ b/networking-odl/networking_odl/l3/l3_odl_v2.py @@ -0,0 +1,206 @@ +# Copyright (c) 2016 OpenStack Foundation +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +from oslo_log import log as logging + +from neutron.db import api as db_api +from neutron.db import common_db_mixin +from neutron.db import extraroute_db +from neutron.db import l3_agentschedulers_db +from neutron.db import l3_dvr_db +from neutron.db import l3_gwmode_db +from neutron.plugins.common import constants +from neutron_lib import constants as q_const + +from networking_odl.common import config # noqa +from networking_odl.common import constants as odl_const +from networking_odl.db import db +from networking_odl.journal import journal + +LOG = logging.getLogger(__name__) + + +class OpenDaylightL3RouterPlugin( + common_db_mixin.CommonDbMixin, + extraroute_db.ExtraRoute_db_mixin, + l3_dvr_db.L3_NAT_with_dvr_db_mixin, + l3_gwmode_db.L3_NAT_db_mixin, + l3_agentschedulers_db.L3AgentSchedulerDbMixin): + + """Implementation of the OpenDaylight L3 Router Service Plugin. + + This class implements a L3 service plugin that provides + router and floatingip resources and manages associated + request/response. + """ + supported_extension_aliases = ["dvr", "router", "ext-gw-mode", + "extraroute"] + + def __init__(self): + super(OpenDaylightL3RouterPlugin, self).__init__() + + # TODO(rcurran): Continue investigation into how many journal threads + # to run per neutron controller deployment. + self.journal = journal.OpendaylightJournalThread() + + def get_plugin_type(self): + return constants.L3_ROUTER_NAT + + def get_plugin_description(self): + """Returns string description of the plugin.""" + return ("L3 Router Service Plugin for basic L3 forwarding " + "using OpenDaylight.") + + @journal.call_thread_on_end + def create_router(self, context, router): + session = db_api.get_session() + with session.begin(subtransactions=True): + router_dict = super( + OpenDaylightL3RouterPlugin, self).create_router(context, + router) + db.create_pending_row(context.session, odl_const.ODL_ROUTER, + router_dict['id'], odl_const.ODL_CREATE, + router_dict) + return router_dict + + @journal.call_thread_on_end + def update_router(self, context, router_id, router): + session = db_api.get_session() + with session.begin(subtransactions=True): + router_dict = super( + OpenDaylightL3RouterPlugin, self).update_router( + context, router_id, router) + db.create_pending_row(context.session, odl_const.ODL_ROUTER, + router_id, odl_const.ODL_UPDATE, router_dict) + return router_dict + + @journal.call_thread_on_end + def delete_router(self, context, router_id): + session = db_api.get_session() + router_dict = self.get_router(context, router_id) + dependency_list = [router_dict['gw_port_id']] + with session.begin(subtransactions=True): + super(OpenDaylightL3RouterPlugin, self).delete_router(context, + router_id) + db.create_pending_row(context.session, odl_const.ODL_ROUTER, + router_id, odl_const.ODL_DELETE, + dependency_list) + + @journal.call_thread_on_end + def create_floatingip(self, context, floatingip, + initial_status=q_const.FLOATINGIP_STATUS_ACTIVE): + session = db_api.get_session() + with session.begin(subtransactions=True): + fip_dict = super( + OpenDaylightL3RouterPlugin, self).create_floatingip( + context, floatingip, initial_status) + db.create_pending_row(context.session, odl_const.ODL_FLOATINGIP, + fip_dict['id'], odl_const.ODL_CREATE, + fip_dict) + return fip_dict + + @journal.call_thread_on_end + def update_floatingip(self, context, floatingip_id, floatingip): + session = db_api.get_session() + with session.begin(subtransactions=True): + fip_dict = super( + OpenDaylightL3RouterPlugin, self).update_floatingip( + context, floatingip_id, floatingip) + + # Update status based on association + if fip_dict.get('port_id') is None: + fip_dict['status'] = q_const.FLOATINGIP_STATUS_DOWN + else: + fip_dict['status'] = q_const.FLOATINGIP_STATUS_ACTIVE + self.update_floatingip_status(context, floatingip_id, + fip_dict['status']) + + db.create_pending_row(context.session, odl_const.ODL_FLOATINGIP, + floatingip_id, odl_const.ODL_UPDATE, + fip_dict) + return fip_dict + + @journal.call_thread_on_end + def delete_floatingip(self, context, floatingip_id): + session = db_api.get_session() + floatingip_dict = self.get_floatingip(context, floatingip_id) + dependency_list = [floatingip_dict['router_id']] + dependency_list.append(floatingip_dict['floating_network_id']) + with session.begin(subtransactions=True): + super(OpenDaylightL3RouterPlugin, self).delete_floatingip( + context, floatingip_id) + db.create_pending_row(context.session, odl_const.ODL_FLOATINGIP, + floatingip_id, odl_const.ODL_DELETE, + dependency_list) + + @journal.call_thread_on_end + def add_router_interface(self, context, router_id, interface_info): + session = db_api.get_session() + with session.begin(subtransactions=True): + new_router = super( + OpenDaylightL3RouterPlugin, self).add_router_interface( + context, router_id, interface_info) + router_dict = self._generate_router_dict(router_id, interface_info, + new_router) + db.create_pending_row(context.session, odl_const.ODL_ROUTER_INTF, + odl_const.ODL_UUID_NOT_USED, + odl_const.ODL_ADD, router_dict) + return new_router + + @journal.call_thread_on_end + def remove_router_interface(self, context, router_id, interface_info): + session = db_api.get_session() + with session.begin(subtransactions=True): + new_router = super( + OpenDaylightL3RouterPlugin, self).remove_router_interface( + context, router_id, interface_info) + router_dict = self._generate_router_dict(router_id, interface_info, + new_router) + db.create_pending_row(context.session, odl_const.ODL_ROUTER_INTF, + odl_const.ODL_UUID_NOT_USED, + odl_const.ODL_REMOVE, router_dict) + return new_router + + def _generate_router_dict(self, router_id, interface_info, new_router): + # Get network info for the subnet that is being added to the router. + # Check if the interface information is by port-id or subnet-id. + add_by_port, add_by_sub = self._validate_interface_info(interface_info) + if add_by_sub: + _port_id = new_router['port_id'] + _subnet_id = interface_info['subnet_id'] + elif add_by_port: + _port_id = interface_info['port_id'] + _subnet_id = new_router['subnet_id'] + + router_dict = {'subnet_id': _subnet_id, + 'port_id': _port_id, + 'id': router_id, + 'tenant_id': new_router['tenant_id']} + + return router_dict + + dvr_deletens_if_no_port_warned = False + + def dvr_deletens_if_no_port(self, context, port_id): + # TODO(yamahata): implement this method or delete this logging + # For now, this is defined to avoid attribute exception + # Since ODL L3 does not create namespaces, this is always going to + # be a noop. When it is confirmed, delete this comment and logging + if not self.dvr_deletens_if_no_port_warned: + LOG.debug('dvr is not suported yet. ' + 'this method needs to be implemented') + self.dvr_deletens_if_no_port_warned = True + return [] -- cgit 1.2.3-korg