diff options
author | Ashlee Young <ashlee@onosfw.com> | 2015-10-30 09:20:45 -0700 |
---|---|---|
committer | Ashlee Young <ashlee@onosfw.com> | 2015-10-30 09:20:45 -0700 |
commit | 89a574196783f93e32d81244f37f726be11bbf30 (patch) | |
tree | 408c721579d29d49eebf50c78b7f4a8da7a6489e /framework/src/openstack/neutron/plugin/networking-onos/networking-onos/networking_onos/plugins | |
parent | 62bb467ca10e4fd0ca23499953bc7f7f413dee16 (diff) |
New ML2/L3 plugin to support SFC
Change-Id: Ie778a2b2e09a29972e28d70c8eedee407b1d8eb6
Signed-off-by: Ashlee Young <ashlee@onosfw.com>
Diffstat (limited to 'framework/src/openstack/neutron/plugin/networking-onos/networking-onos/networking_onos/plugins')
9 files changed, 442 insertions, 0 deletions
diff --git a/framework/src/openstack/neutron/plugin/networking-onos/networking-onos/networking_onos/plugins/__init__.py b/framework/src/openstack/neutron/plugin/networking-onos/networking-onos/networking_onos/plugins/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/framework/src/openstack/neutron/plugin/networking-onos/networking-onos/networking_onos/plugins/__init__.py diff --git a/framework/src/openstack/neutron/plugin/networking-onos/networking-onos/networking_onos/plugins/l3/README b/framework/src/openstack/neutron/plugin/networking-onos/networking-onos/networking_onos/plugins/l3/README new file mode 100644 index 00000000..04ca224b --- /dev/null +++ b/framework/src/openstack/neutron/plugin/networking-onos/networking-onos/networking_onos/plugins/l3/README @@ -0,0 +1,29 @@ +Open Networking Operating System (ONOS) L3 Plugin +================================================= +ONOS is a carrier grade SDN open operating system designed for +High Availability, scale-out and better performance. + + http://www.onosproject.org/ + +Mode of Working: +================ +networking-onos.plugins.l3 define onos plug-in for supporting neutron's router +functionality. This shim layer makes the communication between ONOS and +Openstack neutron possible via ReST call. +The driver code can be downloaded from: + + https://git.openstack.org/cgit/openstack/networking-onos + +Using ONOS L3 Plugin +==================== +To use ONOS L3 Plugin one should +1. Make sure networking-onos code is downloaded and installed. If doing + mannually then download the code, go inside networking_onos folder + and finally run "sudo python setup.py install" otherwise download the + required package version from "https://pypi.python.org/pypi/networking-onos/" + and install using pip. + +2. Configure ONOS credentials in networking_onos/etc/conf_onos.ini. + +3. Start neutron server mentioning networking_onos/etc/conf_onos.ini as + one of the config-file with ONOS L3 Plugin support. diff --git a/framework/src/openstack/neutron/plugin/networking-onos/networking-onos/networking_onos/plugins/l3/__init__.py b/framework/src/openstack/neutron/plugin/networking-onos/networking-onos/networking_onos/plugins/l3/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/framework/src/openstack/neutron/plugin/networking-onos/networking-onos/networking_onos/plugins/l3/__init__.py diff --git a/framework/src/openstack/neutron/plugin/networking-onos/networking-onos/networking_onos/plugins/l3/driver.py b/framework/src/openstack/neutron/plugin/networking-onos/networking-onos/networking_onos/plugins/l3/driver.py new file mode 100644 index 00000000..2db3ad35 --- /dev/null +++ b/framework/src/openstack/neutron/plugin/networking-onos/networking-onos/networking_onos/plugins/l3/driver.py @@ -0,0 +1,126 @@ +# Copyright (C) 2015 Huawei Technologies India Pvt Ltd. +# 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_config import cfg + +from neutron.api.rpc.agentnotifiers import l3_rpc_agent_api +from neutron.api.rpc.handlers import l3_rpc +from neutron.common import constants as q_const +from neutron.common import rpc as n_rpc +from neutron.common import topics +from neutron.db import db_base_plugin_v2 +from neutron.db import extraroute_db +from neutron.db import l3_agentschedulers_db +from neutron.db import l3_gwmode_db +from neutron.plugins.common import constants + +from networking_onos.common import config # noqa +from networking_onos.plugins.l3 import floating_ip as onos_fip +from networking_onos.plugins.l3 import router as onos_router + + +class ONOSL3Plugin(db_base_plugin_v2.NeutronDbPluginV2, + extraroute_db.ExtraRoute_db_mixin, + l3_gwmode_db.L3_NAT_db_mixin, + l3_agentschedulers_db.L3AgentSchedulerDbMixin, + onos_router.ONOSRouter, + onos_fip.ONOSFloatingIP): + + """Implementation of the ONOS 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 = ["router", "ext-gw-mode", "extraroute"] + + def __init__(self): + self.setup_rpc() + self.onos_path = cfg.CONF.onos.url_path + self.onos_auth = (cfg.CONF.onos.username, cfg.CONF.onos.password) + + def setup_rpc(self): + self.topic = topics.L3PLUGIN + self.conn = n_rpc.create_connection(new=True) + self.agent_notifiers.update( + {q_const.AGENT_TYPE_L3: l3_rpc_agent_api.L3AgentNotifyAPI()}) + self.endpoints = [l3_rpc.L3RpcCallback()] + self.conn.create_consumer(self.topic, self.endpoints, fanout=False) + self.conn.consume_in_threads() + + def get_plugin_type(self): + return constants.L3_ROUTER_NAT + + def get_plugin_description(self): + """returns plug-in description""" + return ("L3 Router Service Plug-in for basic L3 forwarding using ONOS") + + def create_router(self, context, router): + router_dict = super(ONOSL3Plugin, self).create_router(context, router) + self.handle_create_router(router_dict) + return router_dict + + def update_router(self, context, id, router): + router_dict = super(ONOSL3Plugin, self).update_router(context, id, + router) + self.handle_update_router(router_dict, id) + return router_dict + + def delete_router(self, context, id): + super(ONOSL3Plugin, self).delete_router(context, id) + self.handle_delete_router(id) + + def create_floatingip(self, context, floatingip, + initial_status=q_const.FLOATINGIP_STATUS_ACTIVE): + fip_dict = super(ONOSL3Plugin, self).create_floatingip(context, + floatingip, + initial_status) + self.handle_create_floatingip(fip_dict) + return fip_dict + + def update_floatingip(self, context, id, floatingip): + fip_dict = super(ONOSL3Plugin, self).update_floatingip(context, id, + floatingip) + self.handle_update_floatingip(id, fip_dict) + return fip_dict + + def delete_floatingip(self, context, id): + super(ONOSL3Plugin, self).delete_floatingip(context, id) + self.handle_delete_floatingip(id) + + def add_router_interface(self, context, router_id, interface_info): + router = super(ONOSL3Plugin, self).add_router_interface(context, + router_id, + interface_info) + intf_add_type = self._get_intf_add_type(router, interface_info) + self.handle_add_router_interface(router, router_id, + interface_info, intf_add_type) + return router + + def remove_router_interface(self, context, router_id, interface_info): + router = super(ONOSL3Plugin, self).remove_router_interface( + context, router_id, interface_info) + intf_add_type = self._get_intf_add_type(router, interface_info) + self.handle_remove_router_interface(router, router_id, + interface_info, intf_add_type) + return router + + def _get_intf_add_type(self, router_info, intf_info): + add_by_port, add_by_sub = self._validate_interface_info(intf_info) + if add_by_sub: + return onos_router.ADD_INTF_BY_SUBNET + + return onos_router.ADD_INTF_BY_PORT diff --git a/framework/src/openstack/neutron/plugin/networking-onos/networking-onos/networking_onos/plugins/l3/floating_ip.py b/framework/src/openstack/neutron/plugin/networking-onos/networking-onos/networking_onos/plugins/l3/floating_ip.py new file mode 100644 index 00000000..0748724e --- /dev/null +++ b/framework/src/openstack/neutron/plugin/networking-onos/networking-onos/networking_onos/plugins/l3/floating_ip.py @@ -0,0 +1,40 @@ +# Copyright (C) 2015 Huawei Technologies India Pvt Ltd. +# +# 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 networking_onos.common import utils as onos_utils + + +class ONOSFloatingIP(object): + + """Implementation of ONOS L3 Floating IP Service. + + This class sends Neutron's L3 Floating IP messages to ONOS. + """ + def send_floatingip_msg(self, msg_type, entity_path, entity): + onos_utils.send_msg(self.onos_path, self.onos_auth, + msg_type, entity_path, entity) + + def handle_create_floatingip(self, fip_dict): + self.send_floatingip_msg('post', 'floatingips', + {'floatingip': fip_dict}) + + def handle_update_floatingip(self, id, fip_dict): + url_path = 'floatingips' + '/' + id + self.send_floatingip_msg('put', url_path, + {'floatingip': fip_dict}) + + def handle_delete_floatingip(self, id): + url_path = 'floatingips' + '/' + id + self.send_floatingip_msg('delete', url_path, None) diff --git a/framework/src/openstack/neutron/plugin/networking-onos/networking-onos/networking_onos/plugins/l3/router.py b/framework/src/openstack/neutron/plugin/networking-onos/networking-onos/networking_onos/plugins/l3/router.py new file mode 100644 index 00000000..495dacd6 --- /dev/null +++ b/framework/src/openstack/neutron/plugin/networking-onos/networking-onos/networking_onos/plugins/l3/router.py @@ -0,0 +1,74 @@ +# Copyright (C) 2015 Huawei Technologies India Pvt Ltd. +# +# 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 networking_onos.common import utils as onos_utils + +ADD_INTF_BY_PORT = 1 +ADD_INTF_BY_SUBNET = 2 + + +class ONOSRouter(object): + + """Implementation of ONOS L3 Router Service. + + This class sends Neutron's L3 router messages to ONOS. + """ + def send_router_msg(self, msg_type, entity_path, entity): + onos_utils.send_msg(self.onos_path, self.onos_auth, + msg_type, entity_path, entity) + + def handle_create_router(self, router_dict): + self.send_router_msg('post', 'routers', + {'router': router_dict}) + + def handle_update_router(self, router_dict, id): + url_path = 'routers' + '/' + id + resource = router_dict.copy() + onos_utils.safe_delete_from_dict(resource, + ['id', 'tenant_id', 'status']) + self.send_router_msg('put', url_path, {'router': resource}) + + def handle_delete_router(self, id): + url_path = 'routers' + '/' + id + self.send_router_msg('delete', url_path, None) + + def handle_add_router_interface(self, new_router, router_id, + interface_info, intf_add_type): + url_path = 'routers' + '/' + router_id + '/add_router_interface' + router_dict = self._prepare_router_dict(router_id, interface_info, + new_router, intf_add_type) + self.send_router_msg('put', url_path, router_dict) + + def handle_remove_router_interface(self, new_router, router_id, + interface_info, intf_add_type): + url_path = 'routers' + '/' + router_id + '/remove_router_interface' + router_dict = self._prepare_router_dict(router_id, interface_info, + new_router, intf_add_type) + self.send_router_msg('put', url_path, router_dict) + + def _prepare_router_dict(self, router_id, interface_info, + new_router, add_type): + if add_type == ADD_INTF_BY_SUBNET: + _port_id = new_router['port_id'] + _subnet_id = interface_info['subnet_id'] + else: + _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 diff --git a/framework/src/openstack/neutron/plugin/networking-onos/networking-onos/networking_onos/plugins/ml2/README b/framework/src/openstack/neutron/plugin/networking-onos/networking-onos/networking_onos/plugins/ml2/README new file mode 100644 index 00000000..c3c722c8 --- /dev/null +++ b/framework/src/openstack/neutron/plugin/networking-onos/networking-onos/networking_onos/plugins/ml2/README @@ -0,0 +1,33 @@ +Open Networking Operating System (ONOS) ML2 MechanismDriver +========================================================== +ONOS is a carrier grade SDN open operating system designed for +High Availability, scale-out and better performance. + + http://www.onosproject.org/ + +Mode of Working: +================ +The networking-onos project provides a thin layer which makes the +communication between ONOS and OpenStack neutron possible via ReST +call. The driver code can be downloaded from: + + https://git.openstack.org/cgit/openstack/networking-onos + +Using ONOS ML2 MechanismDriver +============================== +To use ONOS ML2 MechanismDriver one should +1. Make sure networking-onos code is downloaded and installed. If doing + mannually then download the code, go inside networking_onos folder + and finally run "sudo python setup.py install" otherwise download the + required package version from "https://pypi.python.org/pypi/networking-onos/" + and install using pip. + +2. Configure ONOS as the required ML2 "mechanism_drivers" in + neutron/plugins/ml2/ml2_conf.ini: + + mechanism_drivers=onos_ml2 + +3. Configure ONOS credentials in networking_onos/etc/conf_onos.ini. + +4. Start neutron server mentioning networking_onos/etc/conf_onos.ini as + one of the config-file. diff --git a/framework/src/openstack/neutron/plugin/networking-onos/networking-onos/networking_onos/plugins/ml2/__init__.py b/framework/src/openstack/neutron/plugin/networking-onos/networking-onos/networking_onos/plugins/ml2/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/framework/src/openstack/neutron/plugin/networking-onos/networking-onos/networking_onos/plugins/ml2/__init__.py diff --git a/framework/src/openstack/neutron/plugin/networking-onos/networking-onos/networking_onos/plugins/ml2/driver.py b/framework/src/openstack/neutron/plugin/networking-onos/networking-onos/networking_onos/plugins/ml2/driver.py new file mode 100644 index 00000000..b78775f4 --- /dev/null +++ b/framework/src/openstack/neutron/plugin/networking-onos/networking-onos/networking_onos/plugins/ml2/driver.py @@ -0,0 +1,140 @@ +# Copyright (c) 2015 Huawei Technologies India Pvt Ltd +# 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_config import cfg +from oslo_log import helpers as log_helpers +from oslo_log import log as logging + +from neutron.common import constants as n_const +from neutron.extensions import portbindings +from neutron.plugins.common import constants +from neutron.plugins.ml2 import driver_api as api + +from networking_onos.common import config # noqa +from networking_onos.common import utils as onos_utils + +LOG = logging.getLogger(__name__) + + +class ONOSMechanismDriver(api.MechanismDriver): + + """Open Networking Operating System ML2 Driver for Neutron. + + Code which makes communication between ONOS and OpenStack Neutron + possible. + """ + def __init__(self): + self.onos_path = cfg.CONF.onos.url_path + self.onos_auth = (cfg.CONF.onos.username, cfg.CONF.onos.password) + self.vif_type = portbindings.VIF_TYPE_OVS + self.vif_details = {portbindings.CAP_PORT_FILTER: True} + + def initialize(self): + # No action required as of now. Can be extended in + # the future if required. + pass + + @log_helpers.log_method_call + def create_network_postcommit(self, context): + entity_path = 'networks' + resource = context.current.copy() + onos_utils.send_msg(self.onos_path, self.onos_auth, 'post', + entity_path, {'network': resource}) + + @log_helpers.log_method_call + def update_network_postcommit(self, context): + entity_path = 'networks/' + context.current['id'] + resource = context.current.copy() + onos_utils.send_msg(self.onos_path, self.onos_auth, 'put', + entity_path, {'network': resource}) + + @log_helpers.log_method_call + def delete_network_postcommit(self, context): + entity_path = 'networks/' + context.current['id'] + onos_utils.send_msg(self.onos_path, self.onos_auth, 'delete', + entity_path) + + @log_helpers.log_method_call + def create_subnet_postcommit(self, context): + entity_path = 'subnets' + resource = context.current.copy() + onos_utils.send_msg(self.onos_path, self.onos_auth, 'post', + entity_path, {'subnet': resource}) + + @log_helpers.log_method_call + def update_subnet_postcommit(self, context): + entity_path = 'subnets/' + context.current['id'] + resource = context.current.copy() + onos_utils.send_msg(self.onos_path, self.onos_auth, 'put', + entity_path, {'subnet': resource}) + + @log_helpers.log_method_call + def delete_subnet_postcommit(self, context): + entity_path = 'subnets/' + context.current['id'] + onos_utils.send_msg(self.onos_path, self.onos_auth, 'delete', + entity_path) + + @log_helpers.log_method_call + def create_port_postcommit(self, context): + entity_path = 'ports' + resource = context.current.copy() + onos_utils.send_msg(self.onos_path, self.onos_auth, 'post', + entity_path, {'port': resource}) + + @log_helpers.log_method_call + def update_port_postcommit(self, context): + entity_path = 'ports/' + context.current['id'] + resource = context.current.copy() + onos_utils.send_msg(self.onos_path, self.onos_auth, 'put', + entity_path, {'port': resource}) + + @log_helpers.log_method_call + def delete_port_postcommit(self, context): + entity_path = 'ports/' + context.current['id'] + onos_utils.send_msg(self.onos_path, self.onos_auth, 'delete', + entity_path) + + @log_helpers.log_method_call + def bind_port(self, context): + """Set port binding data for use with nova.""" + LOG.debug("Attempting to bind port %(port)s on network %(network)s", + {'port': context.current['id'], + 'network': context.network.current['id']}) + # Prepared porting binding data + for segment in context.segments_to_bind: + if self.check_segment(segment): + context.set_binding(segment[api.ID], + self.vif_type, + self.vif_details, + status=n_const.PORT_STATUS_ACTIVE) + LOG.debug("Port bound successful for segment: %s", segment) + return + else: + LOG.debug("Port bound un-successfult for segment ID %(id)s, " + "segment %(seg)s, phys net %(physnet)s, and " + "network type %(nettype)s", + {'id': segment[api.ID], + 'seg': segment[api.SEGMENTATION_ID], + 'physnet': segment[api.PHYSICAL_NETWORK], + 'nettype': segment[api.NETWORK_TYPE]}) + + @log_helpers.log_method_call + def check_segment(self, segment): + """Check whether segment is valid for the ONOS MechanismDriver.""" + + return segment[api.NETWORK_TYPE] in [constants.TYPE_LOCAL, + constants.TYPE_GRE, + constants.TYPE_VXLAN, + constants.TYPE_VLAN] |