Custom Search

Tuesday, November 25, 2014

OpenStack OpenContrail Neutron Development Environment Setup

1)
clone neutron from github
#cd /home/saju/
#git clone https://github.com/openstack/neutron.git
#cd neutron
#git checkout stable/icehouse

2)
Create script to start/stop neutron-server from cloned dir
#vim neutron-server
import sys
from neutron.server import main

if __name__ == "__main__":
    sys.exit(main())

3)
Stop the neutron-server
#sudo service neutron-server stop
OR
#sudo /etc/init.d/neutron-server stop

4)
Start/Stop neutron-server from cloned dir
#sudo python neutron-server --config-file /etc/neutron/neutron.conf --log-file /var/log/neutron/server.log --config-file /etc/neutron/plugins/opencontrail/ContrailPlugin.ini

5)
a)
Copy the folder "neutron/neutron/plugins/opencontrail" from "juno" branch to "icehouse"

b)
Create a dir named "extensions" under /home/saju/neutron/neutron/plugins/opencontrail and create/copy following files
* __init__.py
* Copy the extension file "ipam.py" from /usr/lib/python2.7/dist-packages/neutron_plugin_contrail/extensions/ipam.py

c)
Create a dir named "plugins" under /home/saju/neutron/neutron/plugins/opencontrail and create/copy following files
* __init__.py
* Copy the IPAM plugin file "contrail_plugin_ipam.py" from /usr/lib/python2.7/dist-packages/neutron_plugin_contrail/plugins/opencontrail/contrail_plugin_ipam.py

6)
Config changes
a)
#sudo vim /etc/neutron/plugins/opencontrail/ContrailPlugin.ini
Enable only the IPAM extension
contrail_extensions = ipam:neutron.plugins.opencontrail.plugins.contrail_plugin_ipam.NeutronPluginContrailIpam

b)
#sudo vim /etc/neutron/neutron.conf
core_plugin = neutron.plugins.opencontrail.contrail_plugin.NeutronPluginContrailCoreV2
api_extensions_path = extensions:/home/saju/neutron/neutron/plugins/opencontrail/extensions

7)
Patch for neutron/plugins/opencontrail/contrail_plugin.py

diff --git a/neutron/plugins/opencontrail/contrail_plugin.py b/neutron/plugins/opencontrail/contrail_plugin.py
index 511c684..09576ce 100644
--- a/neutron/plugins/opencontrail/contrail_plugin.py
+++ b/neutron/plugins/opencontrail/contrail_plugin.py
@@ -23,6 +23,7 @@ from neutron.extensions import external_net
 from neutron.extensions import portbindings
 from neutron.extensions import securitygroup
 from neutron import neutron_plugin_base_v2
+from neutron.openstack.common import importutils
 from neutron.openstack.common import jsonutils
 from neutron.openstack.common import log as logging
 from neutron.plugins.opencontrail.common import exceptions as c_exc
@@ -30,14 +31,16 @@ from neutron.plugins.opencontrail.common import exceptions as c_exc

 LOG = logging.getLogger(__name__)

-opencontrail_opts = [
-    cfg.StrOpt('api_server_ip', default='127.0.0.1',
-               help='IP address to connect to opencontrail controller'),
-    cfg.IntOpt('api_server_port', default=8082,
-               help='Port to connect to opencontrail controller'),
-]
+#opencontrail_opts = [
+#    cfg.StrOpt('api_server_ip', default='127.0.0.1',
+#               help='IP address to connect to opencontrail controller'),
+#    cfg.IntOpt('api_server_port', default=8082,
+#               help='Port to connect to opencontrail controller'),
+#    cfg.DictOpt('contrail_extensions', default={},
+#                help='Enable Contrail extensions(policy, ipam)'),
+#]

-cfg.CONF.register_opts(opencontrail_opts, 'CONTRAIL')
+#cfg.CONF.register_opts(opencontrail_opts, 'CONTRAIL')

 CONTRAIL_EXCEPTION_MAP = {
     requests.codes.not_found: c_exc.ContrailNotFoundError,
@@ -49,6 +52,19 @@ CONTRAIL_EXCEPTION_MAP = {
 }


+vnc_opts = [
+    cfg.StrOpt('api_server_ip', default='127.0.0.1',
+               help='IP address to connect to VNC controller'),
+    cfg.StrOpt('api_server_port', default='8082',
+               help='Port to connect to VNC controller'),
+    cfg.DictOpt('contrail_extensions', default={},
+                help='Enable Contrail extensions(policy, ipam)'),
+]
+
+class InvalidContrailExtensionError(exc.ServiceUnavailable):
+    message = _("Invalid Contrail Extension: %(ext_name) %(ext_class)")
+
+
 class NeutronPluginContrailCoreV2(neutron_plugin_base_v2.NeutronPluginBaseV2,
                                   securitygroup.SecurityGroupPluginBase,
                                   portbindings_base.PortBindingBaseMixin,
@@ -56,16 +72,58 @@ class NeutronPluginContrailCoreV2(neutron_plugin_base_v2.NeutronPluginBaseV2,

     supported_extension_aliases = ["security-group", "router",
                                    "port-security", "binding", "agent",
-                                   "quotas", "external-net"]
+                                   "quotas", "external-net", "ipam"]
     PLUGIN_URL_PREFIX = '/neutron'
     __native_bulk_support = False

+    # patch VIF_TYPES
+    portbindings.__dict__['VIF_TYPE_VROUTER'] = 'vrouter'
+    portbindings.VIF_TYPES.append(portbindings.VIF_TYPE_VROUTER)
+
+    def _parse_class_args(self):
+        """Parse the contrailplugin.ini file.
+
+        Opencontrail supports extension such as ipam, policy, these extensions
+        can be configured in the plugin configuration file as shown below.
+        Plugin then loads the specified extensions.
+        contrail_extensions=ipam:,policy:
+        """
+
+        contrail_extensions = cfg.CONF.APISERVER.contrail_extensions
+    print "===contrail_extensions:===", contrail_extensions
+        # If multiple class specified for same extension, last one will win
+        # according to DictOpt behavior
+        for ext_name, ext_class in contrail_extensions.items():
+            try:
+                if not ext_class:
+                    LOG.error(_('Malformed contrail extension...'))
+                    continue
+                self.supported_extension_aliases.append(ext_name)
+                if ext_class == 'None':
+                    continue
+                ext_class = importutils.import_class(ext_class)
+                ext_instance = ext_class()
+                ext_instance.set_core(self)
+                for method in dir(ext_instance):
+                    for prefix in ['get', 'update', 'delete', 'create']:
+                        if method.startswith('%s_' % prefix):
+                            setattr(self, method,
+                                    ext_instance.__getattribute__(method))
+            except Exception:
+                LOG.exception(_("Contrail Backend Error"))
+                # Converting contrail backend error to Neutron Exception
+                raise InvalidContrailExtensionError(
+                    ext_name=ext_name, ext_class=ext_class)
+
+
     def __init__(self):
         """Initialize the plugin class."""

         super(NeutronPluginContrailCoreV2, self).__init__()
         portbindings_base.register_port_dict_function()
-        self.base_binding_dict = self._get_base_binding_dict()
+        #self.base_binding_dict = self._get_base_binding_dict()
+    cfg.CONF.register_opts(vnc_opts, 'APISERVER')
+    self._parse_class_args()

     def _get_base_binding_dict(self):
         """return VIF type and details."""
@@ -88,8 +146,8 @@ class NeutronPluginContrailCoreV2(neutron_plugin_base_v2.NeutronPluginBaseV2,
     def _relay_request(self, url_path, data=None):
         """Send received request to api server."""

-        url = "http://%s:%d%s" % (cfg.CONF.CONTRAIL.api_server_ip,
-                                  cfg.CONF.CONTRAIL.api_server_port,
+        url = "http://%s:%s%s" % (cfg.CONF.APISERVER.api_server_ip,
+                                  cfg.CONF.APISERVER.api_server_port,
                                   url_path)

         return self._request_api_server(

8)
Export credentials


export OS_USERNAME=admin
export OS_PASSWORD=secret123
export OS_TENANT_NAME=demo
export OS_AUTH_URL=http://127.0.0.1:35357/v2.0


9)
Test the CLI command

#neutron ipam-list

2 comments:

  1. 1)
    #git clone https://github.com/openstack/neutron.git
    #git checkout stable/icehouse

    2)
    Goto cloned_neutron_dir
    #cd cloned_neutron_dir

    3)
    Copy the script used to start neutron-server to cloned_neutron_dir
    #cd cloned_neutron_dir
    #sudo cp /usr/bin/neutron-server .

    4)
    #cd cloned_neutron_dir
    #cat neutron-server
    #!/usr/bin/python
    # PBR Generated from u'console_scripts'
    import sys
    from neutron.server import main

    import neutron
    print "loc:===>", neutron.__file__

    if __name__ == "__main__":
    sys.exit(main())

    5)
    Stop the neutron-server
    #sudo service neutron-server stop
    #sudo /etc/init.d/neutron-server stop

    6)
    Start the neutron-server
    #cd cloned_neutron_dir
    #sudo python neutron-server --config-file /etc/neutron/neutron.conf --log-file /var/log/neutron/server.log --config-file /etc/neutron/plugins/opencontrail/ContrailPlugin.ini

    7)
    #sudo vim /etc/neutron/plugins/opencontrail/ContrailPlugin.ini

    7,a)
    * Specify the class of contrail extensions in "contrail_extensions".

    7,a1)
    Production config Example:
    Extension class of "ipam" and "policy".
    contrail_extensions=ipam:neutron_plugin_contrail.plugins.opencontrail.contrail_plugin_ipam.NeutronPluginContrailIpam,policy:neutron_plugin_contrail.plugins.opencontrail.contrail_plugin_policy.NeutronPluginContrailPolicy

    7,a2)
    Development config Example:

    * Option1: comment all "contrail_extensions" from ContrailPlugin.ini
    * Option2 (set only one extension):
    contrail_extensions = ipam:neutron_plugin_contrail.plugins.opencontrail.contrail_plugin_ipam.NeutronPluginContrailIpam

    ReplyDelete
  2. 8)
    #sudo vim /etc/neutron/neutron.conf

    8,a)
    * Specify the class of contrail core plugin in "core_plugin".

    8,a1)
    Production config Example:
    core_plugin = neutron_plugin_contrail.plugins.opencontrail.contrail_plugin.NeutronPluginContrailCoreV2

    8,a2)
    Development config Example:
    * Plugin "opencontrail" not available in "icehouse"
    * Copy the folder neutron/plugins/opencontrail from "juno" to "icehouse"
    * Then change core_plugin config to point to NeutronPluginContrailCoreV2 class.
    core_plugin = neutron.plugins.opencontrail.contrail_plugin.NeutronPluginContrailCoreV2

    8,a2,a)
    Error
    ------
    AttributeError: 'module' object has no attribute 'VIF_TYPE_VROUTER'

    Fix
    ----
    #vim neutron/plugins/opencontrail/contrail_plugin.py
    class NeutronPluginContrailCoreV2(neutron_plugin_base_v2.NeutronPluginBaseV2,
    securitygroup.SecurityGroupPluginBase,
    portbindings_base.PortBindingBaseMixin,
    external_net.External_net):
    # patch VIF_TYPES
    portbindings.__dict__['VIF_TYPE_VROUTER'] = 'vrouter'
    portbindings.VIF_TYPES.append(portbindings.VIF_TYPE_VROUTER)

    http://fosshelp.blogspot.com/2014/11/attributeerror-module-object-has-no.html


    8,b)
    api_extensions_path = extensions:/usr/lib/python2.7/dist-packages/neutron_plugin_contrail/extensions

    8,b1)
    Production config Example:
    api_extensions_path = extensions:/usr/lib/python2.7/dist-packages/neutron_plugin_contrail/extensions

    8,b2)
    Development config Example:
    We need to change it to /home/saju/neutron/neutron/plugins/opencontrail/extensions for development
    api_extensions_path = extensions:/home/saju/neutron/neutron/plugins/opencontrail/extensions

    * Create a directory named "extensions" under /home/saju/neutron/neutron/plugins/opencontrail and create on __init__.py file
    * Copy the extension file "ipam.py" from /usr/lib/python2.7/dist-packages/neutron_plugin_contrail/extensions/ipam.py
    * Extension file (for example "ipam.py") should be there in /home/saju/neutron/neutron/plugins/opencontrail/extensions
    * All extensions defined in the "api_extensions_path" will get load while starting/restarting the "neutron-server" (don't forget to add the name of the extension in class variable "supported_extension_aliases" in the plugin class)
    * Add the name of the extension (for example "ipam") in class variable "supported_extension_aliases" in the plugin class "NeutronPluginContrailCoreV2" to load the plugin and to fix the WARNING "[neutron.api.extensions] Extension ipam not supported by any of loaded plugins" while starting the "neutron-server".
    * http://fosshelp.blogspot.in/2014/11/warning-neutronapiextensions-extension.html

    9)
    Code to load methods from extension and append to core_plugin class "NeutronPluginContrailCoreV2"
    * In ./neutron/plugins/opencontrail/contrail_plugin.py, check the method "_parse_class_args" of class "NeutronPluginContrailCoreV2".

    10)
    Copy IPAM plugin class:

    10,a)
    * Create a directory named "plugins" under /home/saju/neutron/neutron/plugins/opencontrail and create on __init__.py file
    * Copy the IPAM plugin from /usr/lib/python2.7/dist-packages/neutron_plugin_contrail/plugins/opencontrail/contrail_plugin_ipam.py
    #cd /home/saju/neutron/neutron/plugins/opencontrail
    #cp /usr/lib/python2.7/dist-packages/neutron_plugin_contrail/plugins/opencontrail/contrail_plugin_ipam.py .

    10,b)
    Change the path of IPAM plugin class in /etc/neutron/plugins/opencontrail/ContrailPlugin.ini
    #sudo vim /etc/neutron/plugins/opencontrail/ContrailPlugin.ini
    contrail_extensions = ipam:neutron_plugin_contrail.plugins.opencontrail.contrail_plugin_ipam.NeutronPluginContrailIpam
    Change to
    contrail_extensions = ipam:neutron.plugins.opencontrail.plugins.contrail_plugin_ipam.NeutronPluginContrailIpam

    ReplyDelete