]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
IBM SDN-VE Plugin decomposition
authormamtap <mamtaprabhu@in.ibm.com>
Wed, 11 Mar 2015 12:43:44 +0000 (05:43 -0700)
committermamtap <mamtaprabhu@in.ibm.com>
Tue, 17 Mar 2015 16:07:43 +0000 (09:07 -0700)
This addresses the changes in ml2 mech-driver
and l3 service plugin to comply with the
core-vendor-decomposition spec

The monolithic sdnve plugin will not be removed with this change
as it is still being used. Once the ml2 plugin is merged and the
older plugin becomes obsolete, it will be removed from the
neutron tree.

Partially-implements: blueprint core-vendor-decomposition
Closes-bug: #1430216
Change-Id: I5bc85a5f0a62b690004d8352b3bc43b9612c213d

doc/source/devref/contribute.rst
neutron/plugins/ml2/drivers/ibm/mechanism_sdnve.py [new file with mode: 0644]
neutron/plugins/ml2/drivers/ibm/requirements.txt [new file with mode: 0644]
neutron/services/l3_router/l3_sdnve.py [new file with mode: 0644]
setup.cfg

index ed18bb2979fb2d18454959e303de27744e7fbaa0..a3183f39ba6ad046db069381afb0aed699039d00 100644 (file)
@@ -406,6 +406,8 @@ The following chart captures the following aspects:
 +-------------------------------+-----------------------+-----------+------------------+---------+--------------+
 | networking-hyperv_            |                       |           |                  |         |              |
 +-------------------------------+-----------------------+-----------+------------------+---------+--------------+
+| networking-ibm_               |         ml2,l3        |    yes    |       no         |   [B]   |     Kilo     |
++-------------------------------+-----------------------+-----------+------------------+---------+--------------+
 | networking-metaplugin_        |         core          |    no     |       no         |   [C]   |     Kilo     |
 +-------------------------------+-----------------------+-----------+------------------+---------+--------------+
 | networking-midonet_           |        core,lb        |    yes    |       yes        |   [C]   |     Kilo     |
@@ -431,6 +433,7 @@ The following chart captures the following aspects:
 | vmware-nsx_                   |         core          |    yes    |       yes        |   [C]   |     Kilo     |
 +-------------------------------+-----------------------+-----------+------------------+---------+--------------+
 
+
 .. _networking-arista:
 
 Arista
@@ -452,6 +455,15 @@ Cisco
 
 .. _networking-hyperv:
 
+
+.. _networking-ibm:
+
+IBM SDNVE
+---------
+
+* Git: https://github.com/stackforge/networking-ibm
+* Launchpad: https://launchpad.net/networking-ibm
+
 .. _networking-metaplugin:
 
 Metaplugin
@@ -525,3 +537,4 @@ VMware
 * Git: https://github.com/stackforge/vmware-nsx
 * Launchpad: https://launchpad.net/vmware-nsx
 * PyPI: https://pypi.python.org/pypi/vmware-nsx
+
diff --git a/neutron/plugins/ml2/drivers/ibm/mechanism_sdnve.py b/neutron/plugins/ml2/drivers/ibm/mechanism_sdnve.py
new file mode 100644 (file)
index 0000000..5b322e6
--- /dev/null
@@ -0,0 +1,106 @@
+# Copyright 2015 IBM Corp.
+#
+# 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 networking_ibm.sdnve.ml2 import sdnve_driver
+from oslo_log import log as logging
+
+from neutron.common import constants as n_const
+from neutron.extensions import portbindings
+from neutron.plugins.ml2 import driver_api as api
+
+LOG = logging.getLogger(__name__)
+
+
+class SdnveMechanismDriver(api.MechanismDriver):
+    """Ml2 Mechanism driver for IBM SDNVE Controller"""
+    def initialize(self):
+        self.vif_type = portbindings.VIF_TYPE_BRIDGE
+        self.vif_details = {portbindings.CAP_PORT_FILTER: False}
+        self.restrict_update_subnet = ['enable_dhcp',
+                                       'gateway_ip',
+                                       'allocation-pool']
+        self.restrict_update_network = ['router:external']
+        self.sdnve_drv = sdnve_driver.SdnveDriver()
+
+    # NETWORK
+    def create_network_precommit(self, context):
+        self.sdnve_drv._pre_create_network(context)
+
+    def create_network_postcommit(self, context):
+        self.sdnve_drv._create_network(context)
+
+    def update_network_precommit(self, context):
+        self.sdnve_drv._pre_update_network(context)
+
+    def update_network_postcommit(self, context):
+        self.sdnve_drv._update_network(context)
+
+    def delete_network_postcommit(self, context):
+        self.sdnve_drv._delete_network(context)
+
+    # SUBNET
+    def create_subnet_precommit(self, context):
+        self.sdnve_drv._pre_create_subnet(context)
+
+    def create_subnet_postcommit(self, context):
+        self.sdnve_drv._create_subnet(context)
+
+    def update_subnet_postcommit(self, context):
+        self.sdnve_drv._update_subnet(context)
+
+    def update_subnet_precommit(self, context):
+        self.sdnve_drv._pre_update_subnet(context)
+
+    def delete_subnet_postcommit(self, context):
+        self.sdnve_drv._delete_subnet(context)
+
+    # PORT
+    def create_port_postcommit(self, context):
+        self.sdnve_drv._create_port(context)
+
+    def create_port_precommit(self, context):
+        self.sdnve_drv._pre_create_port(context)
+
+    def delete_port_precommit(self, context):
+        self.sdnve_drv._pre_delete_port(context)
+
+    def update_port_postcommit(self, context):
+        self.sdnve_drv._update_port(context)
+
+    def delete_port_postcommit(self, context):
+        self.sdnve_drv._delete_port(context)
+
+    def bind_port(self, context):
+        LOG.debug("Attempting to bind port %(port)s on "
+                  "network %(network)s",
+                  {'port': context.current['id'],
+                   'network': context.network.current['id']})
+        for segment in context.network.network_segments:
+            if self.sdnve_drv._check_segment(segment):
+                context.set_binding(segment[api.ID],
+                                    self.vif_type,
+                                    self.vif_details,
+                                    status=n_const.PORT_STATUS_ACTIVE)
+                LOG.debug("Bound using segment: %s", segment)
+                return
+            else:
+                LOG.debug("Refusing to bind port 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]})
diff --git a/neutron/plugins/ml2/drivers/ibm/requirements.txt b/neutron/plugins/ml2/drivers/ibm/requirements.txt
new file mode 100644 (file)
index 0000000..4d5b188
--- /dev/null
@@ -0,0 +1 @@
+networking-ibm
diff --git a/neutron/services/l3_router/l3_sdnve.py b/neutron/services/l3_router/l3_sdnve.py
new file mode 100644 (file)
index 0000000..912644b
--- /dev/null
@@ -0,0 +1,203 @@
+# Copyright 2015 IBM Corp.
+#
+# 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 networking_ibm.sdnve.common import exceptions as sdnve_exc
+from networking_ibm.sdnve.l3plugin import sdnve_l3driver
+from oslo_log import log as logging
+from oslo_utils import excutils
+
+from neutron.common import constants as q_const
+from neutron.common import exceptions as n_exc
+from neutron.db import db_base_plugin_v2
+from neutron.db import extraroute_db
+from neutron.db import l3_gwmode_db
+from neutron.i18n import _LE
+from neutron.plugins.common import constants as l3_constants
+
+
+LOG = logging.getLogger(__name__)
+
+
+class SdnveL3ServicePlugin(db_base_plugin_v2.NeutronDbPluginV2,
+                   extraroute_db.ExtraRoute_db_mixin,
+                   l3_gwmode_db.L3_NAT_db_mixin):
+
+    supported_extension_aliases = ["router", "ext-gw-mode",
+                                   "extraroute"]
+
+    def __init__(self):
+        self.driver = sdnve_l3driver.SdnveL3Driver()
+
+    def get_plugin_type(self):
+        return l3_constants.L3_ROUTER_NAT
+
+    def get_plugin_description(self):
+        """Returns string description of the plugin."""
+        return ("SDNVE Service plugin")
+
+    def create_router(self, context, router):
+        if router['router']['admin_state_up'] is False:
+            router['router']['admin_state_up'] = True
+        with context.session.begin(subtransactions=True):
+            new_router = super(SdnveL3ServicePlugin, self).create_router(
+                context, router)
+        try:
+            self.driver.create_router(context, new_router)
+            return new_router
+        except Exception as e:
+            with excutils.save_and_reraise_exception():
+                LOG.error(_LE("Create router failed in SDN-VE with error %s"),
+                          e)
+                super(SdnveL3ServicePlugin, self).delete_router(
+                    context, new_router['id'])
+
+    def update_router(self, context, id, router):
+        if not router['router'].get('admin_state_up', True):
+            raise n_exc.NotImplementedError(_('admin_state_up=False '
+                                              'routers are not '
+                                              'supported.'))
+        original_router = {}
+        updated_router = {}
+        with context.session.begin(subtransactions=True):
+            original_router = super(SdnveL3ServicePlugin, self).get_router(
+                context, id)
+            updated_router = super(SdnveL3ServicePlugin, self).update_router(
+                context, id, router)
+        try:
+            self.driver.update_router(context, id, original_router, router)
+            return updated_router
+        except Exception as e:
+            LOG.error(_LE("Update router failed in SDN-VE with error %s"),
+                      e)
+
+    def delete_router(self, context, id):
+        with context.session.begin(subtransactions=True):
+            super(SdnveL3ServicePlugin, self).delete_router(context, id)
+        try:
+            self.driver.delete_router(context, id)
+        except Exception as e:
+            LOG.error(_LE("Delete router operation failed in SDN-VE after "
+                          "deleting the router in DB: %s"), e)
+
+    def add_router_interface(self, context, router_id, interface_info):
+        new_interface = super(SdnveL3ServicePlugin, self).add_router_interface(
+            context, router_id, interface_info)
+        request_info = interface_info.copy()
+        request_info['port_id'] = new_interface['port_id']
+        if 'subnet_id' not in interface_info:
+            request_info['subnet_id'] = new_interface['subnet_id']
+        try:
+            self.driver.add_router_interface(context, router_id, request_info)
+            return new_interface
+        except Exception as e:
+            with excutils.save_and_reraise_exception():
+                LOG.error(_LE("Update router-add-interface failed in SDN-VE "
+                              "with error %s"), e)
+                super(SdnveL3ServicePlugin, self).remove_router_interface(
+                    context, router_id, interface_info)
+
+    def _add_router_interface_only(self, context, router_id, interface_info):
+        if interface_info.get('port_id'):
+            try:
+                self.driver._add_router_interface_only(context,
+                                                       router_id,
+                                                       interface_info)
+            except Exception as e:
+                LOG.error(_LE("Add interface in the rollback of a "
+                              "remove_router_interface operation failed %s"),
+                          e)
+
+    def remove_router_interface(self, context, router_id, interface_info):
+        subnet_id = interface_info.get('subnet_id')
+        if not subnet_id:
+            portid = interface_info.get('port_id')
+            if not portid:
+                raise sdnve_exc.BadInputException(msg=_('No port ID'))
+
+            myport = super(SdnveL3ServicePlugin, self).\
+                get_port(context, portid)
+            myfixed_ips = myport.get('fixed_ips')
+            if not myfixed_ips:
+                raise sdnve_exc.BadInputException(msg=_('No fixed IP'))
+            subnet_id = myfixed_ips[0].get('subnet_id')
+            if subnet_id:
+                interface_info['subnet_id'] = subnet_id
+        else:
+            portid = interface_info.get('port_id')
+            if not portid:
+                subnet = super(SdnveL3ServicePlugin, self).\
+                    get_subnet(context, subnet_id)
+                device_filter = {'device_id': [router_id],
+                    'device_owner': [q_const.DEVICE_OWNER_ROUTER_INTF],
+                    'network_id': [subnet['network_id']]}
+                ports = super(SdnveL3ServicePlugin, self).get_ports(context,
+                                                   filters=device_filter)
+                if ports:
+                    portid = ports[0]['id']
+                    interface_info['port_id'] = portid
+        with context.session.begin(subtransactions=True):
+            info = super(SdnveL3ServicePlugin, self).remove_router_interface(
+                        context, router_id, interface_info)
+        try:
+            self.driver.remove_router_interface(context,
+                                                router_id,
+                                                interface_info)
+            return info
+        except Exception as e:
+            with excutils.save_and_reraise_exception():
+                LOG.error(_LE("Update router-remove-interface"
+                          " failed : %s"), e)
+                self._add_router_interface_only(context,
+                                                router_id, interface_info)
+
+    def create_floatingip(self, context, floatingip):
+        with context.session.begin(subtransactions=True):
+            new_floatingip = super(SdnveL3ServicePlugin,
+                self).create_floatingip(context, floatingip)
+        try:
+            self.driver.create_floatingip(context, new_floatingip)
+            return new_floatingip
+        except Exception as e:
+            with excutils.save_and_reraise_exception():
+                LOG.error(_LE("Create floating ip failed with error %s"), e)
+                super(SdnveL3ServicePlugin, self).delete_floatingip(
+                    context, new_floatingip['id'])
+
+    def update_floatingip(self, context, id, floatingip):
+        with context.session.begin(subtransactions=True):
+            original_floatingip = super(
+                SdnveL3ServicePlugin, self).get_floatingip(context, id)
+            updated_floatingip = super(
+                SdnveL3ServicePlugin, self).update_floatingip(
+                    context, id, floatingip)
+        try:
+            self.driver.update_floatingip(context,
+                                          id,
+                                          original_floatingip,
+                                          floatingip)
+            return updated_floatingip
+        except Exception as e:
+            with excutils.save_and_reraise_exception():
+                LOG.error(_LE("Update floating ip failed with error %s"), e)
+                super(SdnveL3ServicePlugin, self).update_floatingip(
+                    context, id, {'floatingip': original_floatingip})
+
+    def delete_floatingip(self, context, id):
+        super(SdnveL3ServicePlugin, self).delete_floatingip(context, id)
+        try:
+            self.driver.delete_floatingip(context, id)
+        except Exception as e:
+            LOG.error(_LE("Delete floatingip failed in SDN-VE: %s"), e)
index 44d7b4c179735a86dd74a9520063a1f06877e7e4..c9e15c28c641ea03d69022c86a63129dfe3e413a 100644 (file)
--- a/setup.cfg
+++ b/setup.cfg
@@ -137,6 +137,7 @@ neutron.service_plugins =
     neutron.services.firewall.fwaas_plugin.FirewallPlugin = neutron_fwaas.services.firewall.fwaas_plugin:FirewallPlugin
     neutron.services.loadbalancer.plugin.LoadBalancerPlugin = neutron_lbaas.services.loadbalancer.plugin:LoadBalancerPlugin
     neutron.services.vpn.plugin.VPNDriverPlugin = neutron_vpnaas.services.vpn.plugin:VPNDriverPlugin
+    ibm_l3 = neutron.services.l3_router.l3_sdnve:SdnveL3ServicePlugin
 neutron.service_providers =
     # These are for backwards compat with Juno firewall service provider configuration values
     neutron.services.firewall.drivers.linux.iptables_fwaas.IptablesFwaasDriver = neutron_fwaas.services.firewall.drivers.linux.iptables_fwaas:IptablesFwaasDriver
@@ -179,6 +180,7 @@ neutron.ml2.mechanism_drivers =
     sriovnicswitch = neutron.plugins.ml2.drivers.mech_sriov.mech_driver:SriovNicSwitchMechanismDriver
     nuage = neutron.plugins.ml2.drivers.mech_nuage.driver:NuageMechanismDriver
     fake_agent = neutron.tests.unit.ml2.drivers.mech_fake_agent:FakeAgentMechanismDriver
+    sdnve = neutron.plugins.ml2.drivers.ibm.mechanism_sdnve:SdnveMechanismDriver
 neutron.ml2.extension_drivers =
     test = neutron.tests.unit.ml2.drivers.ext_test:TestExtensionDriver
     testdb = neutron.tests.unit.ml2.drivers.ext_test:TestDBExtensionDriver