Custom Search

Tuesday, November 25, 2014

OpenStack Python Client How to add new CLI command

1)
Clone python-neutronclient
#git clone https://github.com/openstack/python-neutronclient.git
#cd python-neutronclient
#git checkout 2.3.6


2)
Export the 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


3)
Run the CLI command from cloned dir

#python neutron net-list
Success: Working

4)
Try to execute a command which is not implemented yet
#python neutron ipam-list
Error: Unknown command [u'ipam-list']

5)
Create command to class Mapping for our new command "ipam-list"


#vim python-neutronclient/neutronclient/shell.py

* Add the name of the command and class (command to class map) to the COMMAND_V2 dictionary

Example:
--------------
COMMAND_V2 = {
    .... ....
    'ipam-list':None,
}


COMMANDS = {'2.0': COMMAND_V2}


* Then try to run the new command "ipam-list"
#python neutron ipam-list
Error: 'NoneType' object is not callable

6)
Create a file named "ipam.py" under python-neutronclient/neutronclient/neutron/v2_0/ and add following lines

import logging
from neutronclient.neutron.v2_0 import ListCommand

class ListIpam(ListCommand):
    resource = 'ipam'
    log = logging.getLogger(__name__ + '.ListIpam')
    _formatters = {}
    list_columns = ['id', 'name']


7)
Map the command "ipam-list" to new class "ListIpam"


#vim python-neutronclient/neutronclient/shell.py


from neutronclient.neutron.v2_0 import ipam

COMMAND_V2 = {
    .... ....
    'ipam-list':ipam.ListIpam,
}


* Then try to run the command
#python neutron ipam-list
Error: 'Client' object has no attribute 'list_ipams'

8)
Add method in client class
#vim python-neutronclient/neutronclient/v2_0/client.py
This file is responsible to generate REST API requests and send the same requests to your plugin running on neutron-server.
Add following codes

class Client(object):
    .... ....
    ipams_path = "/ipams"
   
    @APIParamsCall
    def list_ipams(self, **_params):
        return self.get(self.ipams_path, params=_params)


* Then try to run the new command
#python neutron ipam-list
Sucess: Working

10)
Diff

10,a)
$ git diff
diff --git a/neutronclient/shell.py b/neutronclient/shell.py
index f1f2e2e..bda3e12 100644
--- a/neutronclient/shell.py
+++ b/neutronclient/shell.py
@@ -61,6 +61,7 @@ from neutronclient.neutron.v2_0.vpn import ikepolicy
 from neutronclient.neutron.v2_0.vpn import ipsec_site_connection
 from neutronclient.neutron.v2_0.vpn import ipsecpolicy
 from neutronclient.neutron.v2_0.vpn import vpnservice
+from neutronclient.neutron.v2_0 import ipam
 from neutronclient.openstack.common.gettextutils import _
 from neutronclient.openstack.common import strutils
 from neutronclient.version import __version__
@@ -277,6 +278,7 @@ COMMAND_V2 = {
     'nec-packet-filter-create': packetfilter.CreatePacketFilter,
     'nec-packet-filter-update': packetfilter.UpdatePacketFilter,
     'nec-packet-filter-delete': packetfilter.DeletePacketFilter,
+    'ipam-list': ipam.ListIpam,
 }

 COMMANDS = {'2.0': COMMAND_V2}
diff --git a/neutronclient/v2_0/client.py b/neutronclient/v2_0/client.py
index a102781..6b2e972 100644
--- a/neutronclient/v2_0/client.py
+++ b/neutronclient/v2_0/client.py
@@ -221,6 +221,7 @@ class Client(object):
     firewall_path = "/fw/firewalls/%s"
     net_partitions_path = "/net-partitions"
     net_partition_path = "/net-partitions/%s"
+    ipams_path = "/ipams"

     # API has no way to report plurals, so we have to hard code them
     EXTED_PLURALS = {'routers': 'router',
@@ -1187,6 +1188,14 @@ class Client(object):
         """Delete the specified packet filter."""
         return self.delete(self.packet_filter_path % packet_filter_id)

+    @APIParamsCall
+    def list_ipams(self, **_params):
+        """
+        Fetches a list of all ipams for a tenant
+        """
+        # Pass filters in "params" argument to do_request
+        return self.get(self.ipams_path, params=_params)
+
     def __init__(self, **kwargs):
         """Initialize a new client for the Neutron v2.0 API."""
         super(Client, self).__init__()
 

10,b)
#cat neutronclient/neutron/v2_0/ipam.py

import logging
from neutronclient.neutron.v2_0 import ListCommand

class ListIpam(ListCommand):
    resource = 'ipam'
    log = logging.getLogger(__name__ + '.ListIpam')
    _formatters = {}
    list_columns = ['id', 'name']


11)
Ref: http://control-that-vm.blogspot.in/2014/06/writing-cli-commands-for-neutronclient.html



3 comments:

  1. Hi it was really helpful but while creating it didnt worked as expected instead i got an error msg like below,

    404 Not Found

    The resource could not be found.

    Can you please help me.

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. Me too getting the same error

    neutron ipam-list
    404 Not Found

    The resource could not be found.

    ReplyDelete