From 7072b4f802ff5567f0781f89f360c5be43a7977e Mon Sep 17 00:00:00 2001
From: Steve Martinelli <stevemar@ca.ibm.com>
Date: Fri, 1 Feb 2013 01:12:05 -0600
Subject: [PATCH] Add Cinder API V1 Support

made the changes suggested by dtroyer
added client
modified setup.py entry points
updated pip required
added support for create/delete/list volume types
openstack list type
openstack create type typeName
openstack delete type typeNameOrId

Change-Id: I43655de151582e37f14dc9550151a66db7a009ab
---
 openstackclient/common/clientmanager.py |  2 +
 openstackclient/shell.py                | 11 +++
 openstackclient/volume/__init__.py      | 14 ++++
 openstackclient/volume/client.py        | 45 ++++++++++++
 openstackclient/volume/v1/__init__.py   | 14 ++++
 openstackclient/volume/v1/type.py       | 92 +++++++++++++++++++++++++
 setup.py                                |  5 ++
 tools/pip-requires                      |  1 +
 8 files changed, 184 insertions(+)
 create mode 100644 openstackclient/volume/__init__.py
 create mode 100644 openstackclient/volume/client.py
 create mode 100644 openstackclient/volume/v1/__init__.py
 create mode 100644 openstackclient/volume/v1/type.py

diff --git a/openstackclient/common/clientmanager.py b/openstackclient/common/clientmanager.py
index 830ecde709..a1b838a22e 100644
--- a/openstackclient/common/clientmanager.py
+++ b/openstackclient/common/clientmanager.py
@@ -20,6 +20,7 @@ import logging
 from openstackclient.compute import client as compute_client
 from openstackclient.identity import client as identity_client
 from openstackclient.image import client as image_client
+from openstackclient.volume import client as volume_client
 
 
 LOG = logging.getLogger(__name__)
@@ -43,6 +44,7 @@ class ClientManager(object):
     compute = ClientCache(compute_client.make_client)
     identity = ClientCache(identity_client.make_client)
     image = ClientCache(image_client.make_client)
+    volume = ClientCache(volume_client.make_client)
 
     def __init__(self, token=None, url=None, auth_url=None, tenant_name=None,
                  tenant_id=None, username=None, password=None,
diff --git a/openstackclient/shell.py b/openstackclient/shell.py
index 2654d658d8..ffa0245a79 100644
--- a/openstackclient/shell.py
+++ b/openstackclient/shell.py
@@ -36,6 +36,7 @@ KEYRING_SERVICE = 'openstack'
 DEFAULT_COMPUTE_API_VERSION = '2'
 DEFAULT_IDENTITY_API_VERSION = '2.0'
 DEFAULT_IMAGE_API_VERSION = '1.0'
+DEFAULT_VOLUME_API_VERSION = '1'
 
 
 def env(*vars, **kwargs):
@@ -160,6 +161,15 @@ class OpenStackShell(App):
             help='Image API version, default=' +
                  DEFAULT_IMAGE_API_VERSION +
                  ' (Env: OS_IMAGE_API_VERSION)')
+        parser.add_argument(
+            '--os-volume-api-version',
+            metavar='<volume-api-version>',
+            default=env(
+                'OS_VOLUME_API_VERSION',
+                default=DEFAULT_VOLUME_API_VERSION),
+            help='Volume API version, default=' +
+                 DEFAULT_VOLUME_API_VERSION +
+                 ' (Env: OS_VOLUME_API_VERSION)')
         parser.add_argument(
             '--os-token',
             metavar='<token>',
@@ -293,6 +303,7 @@ class OpenStackShell(App):
             'compute': self.options.os_compute_api_version,
             'identity': self.options.os_identity_api_version,
             'image': self.options.os_image_api_version,
+            'volume': self.options.os_volume_api_version,
         }
 
         # Add the API version-specific commands
diff --git a/openstackclient/volume/__init__.py b/openstackclient/volume/__init__.py
new file mode 100644
index 0000000000..85ac2501b8
--- /dev/null
+++ b/openstackclient/volume/__init__.py
@@ -0,0 +1,14 @@
+#   Copyright 2012-2013 OpenStack, LLC.
+#
+#   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.
+#
diff --git a/openstackclient/volume/client.py b/openstackclient/volume/client.py
new file mode 100644
index 0000000000..c1acff2fe6
--- /dev/null
+++ b/openstackclient/volume/client.py
@@ -0,0 +1,45 @@
+#   Copyright 2012-2013 OpenStack, LLC.
+#
+#   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.
+#
+
+import logging
+
+from openstackclient.common import utils
+
+
+LOG = logging.getLogger(__name__)
+
+API_NAME = "volume"
+API_VERSIONS = {
+    "1": "cinderclient.v1.client.Client"
+}
+
+
+def make_client(instance):
+    """Returns a volume service client."""
+    volume_client = utils.get_client_class(
+        API_NAME,
+        instance._api_version[API_NAME],
+        API_VERSIONS
+    )
+
+    LOG.debug('instantiating volume client')
+    client = volume_client(
+        username=instance._username,
+        api_key=instance._password,
+        project_id=instance._tenant_name,
+        auth_url=instance._auth_url,
+    )
+
+    return client
diff --git a/openstackclient/volume/v1/__init__.py b/openstackclient/volume/v1/__init__.py
new file mode 100644
index 0000000000..85ac2501b8
--- /dev/null
+++ b/openstackclient/volume/v1/__init__.py
@@ -0,0 +1,14 @@
+#   Copyright 2012-2013 OpenStack, LLC.
+#
+#   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.
+#
diff --git a/openstackclient/volume/v1/type.py b/openstackclient/volume/v1/type.py
new file mode 100644
index 0000000000..124f67d844
--- /dev/null
+++ b/openstackclient/volume/v1/type.py
@@ -0,0 +1,92 @@
+#   Copyright 2012-2013 OpenStack, LLC.
+#
+#   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.
+#
+
+"""Volume v1 Type action implementations"""
+
+import logging
+
+from cliff import command
+from cliff import lister
+from cliff import show
+
+from openstackclient.common import utils
+
+
+class CreateType(show.ShowOne):
+    """Create type command"""
+
+    api = 'volume'
+    log = logging.getLogger(__name__ + '.CreateType')
+
+    def get_parser(self, prog_name):
+        parser = super(CreateType, self).get_parser(prog_name)
+        parser.add_argument(
+            'name',
+            metavar='<name>',
+            help='New type name',
+        )
+        return parser
+
+    def take_action(self, parsed_args):
+        self.log.debug('take_action(%s)' % parsed_args)
+        volume_client = self.app.client_manager.volume
+        volume_type = volume_client.volume_types.create(
+            parsed_args.name
+        )
+
+        info = {}
+        info.update(volume_type._info)
+        return zip(*sorted(info.iteritems()))
+
+
+class DeleteType(command.Command):
+    """Delete type command"""
+
+    api = 'volume'
+    log = logging.getLogger(__name__ + '.DeleteType')
+
+    def get_parser(self, prog_name):
+        parser = super(DeleteType, self).get_parser(prog_name)
+        parser.add_argument(
+            'type',
+            metavar='<type>',
+            help='Name or ID of type to delete',
+        )
+        return parser
+
+    def take_action(self, parsed_args):
+        self.log.debug('take_action(%s)' % parsed_args)
+        volume_client = self.app.client_manager.volume
+        volume_type = utils.find_resource(
+            volume_client.volume_types, parsed_args.type)
+        volume_client.volume_types.delete(volume_type.id)
+        return
+
+
+class ListType(lister.Lister):
+    """List type command"""
+
+    api = 'volume'
+    log = logging.getLogger(__name__ + '.ListType')
+
+    def take_action(self, parsed_args):
+        self.log.debug('take_action(%s)' % parsed_args)
+        columns = ('ID', 'Name')
+        data = self.app.client_manager.volume.volume_types.list()
+        return (columns,
+                (utils.get_item_properties(
+                    s, columns,
+                    formatters={},
+                ) for s in data))
diff --git a/setup.py b/setup.py
index ffd72f7bce..0eda4b8bb9 100644
--- a/setup.py
+++ b/setup.py
@@ -135,5 +135,10 @@ setuptools.setup(
             'suspend_server=openstackclient.compute.v2.server:SuspendServer',
             'unpause_server=openstackclient.compute.v2.server:UnpauseServer',
         ],
+        'openstack.volume.v1': [
+            'create_type=openstackclient.volume.v1.type:CreateType',
+            'delete_type=openstackclient.volume.v1.type:DeleteType',
+            'list_type=openstackclient.volume.v1.type:ListType',
+        ]
     }
 )
diff --git a/tools/pip-requires b/tools/pip-requires
index af2c56ad64..720413ed74 100644
--- a/tools/pip-requires
+++ b/tools/pip-requires
@@ -4,3 +4,4 @@ pycrypto
 python-glanceclient>=0.5.1
 python-keystoneclient>=0.2,<1.0
 python-novaclient>=2
+python-cinderclient>=1