From eb1ae2e9f23d618069e5eee7abedbd5a049d2878 Mon Sep 17 00:00:00 2001
From: Josh Kearney <josh@jk0.org>
Date: Wed, 26 Dec 2012 14:22:23 -0600
Subject: [PATCH] Adds Glance API v2 support.

Change-Id: Ib0325e62a7e50aa94e852a73f9a2cb95daa8d5f6
---
 openstackclient/common/clientmanager.py |   4 +-
 openstackclient/common/utils.py         |   2 +-
 openstackclient/image/client.py         |  41 +++++++++
 openstackclient/image/v2/__init__.py    |   0
 openstackclient/image/v2/image.py       | 109 ++++++++++++++++++++++++
 setup.py                                |   3 +
 6 files changed, 157 insertions(+), 2 deletions(-)
 create mode 100644 openstackclient/image/client.py
 create mode 100644 openstackclient/image/v2/__init__.py
 create mode 100644 openstackclient/image/v2/image.py

diff --git a/openstackclient/common/clientmanager.py b/openstackclient/common/clientmanager.py
index 0a9f9102d3..73c2e5708c 100644
--- a/openstackclient/common/clientmanager.py
+++ b/openstackclient/common/clientmanager.py
@@ -23,6 +23,7 @@ import logging
 from openstackclient.common import exceptions as exc
 from openstackclient.compute import client as compute_client
 from openstackclient.identity import client as identity_client
+from openstackclient.image import client as image_client
 
 LOG = logging.getLogger(__name__)
 
@@ -46,8 +47,9 @@ class ClientManager(object):
     """Manages access to API clients, including authentication.
     """
 
-    identity = ClientCache(identity_client.make_client)
     compute = ClientCache(compute_client.make_client)
+    identity = ClientCache(identity_client.make_client)
+    image = ClientCache(image_client.make_client)
 
     def __init__(self, token=None, url=None,
                  auth_url=None,
diff --git a/openstackclient/common/utils.py b/openstackclient/common/utils.py
index ea8170bc7a..70555be5fa 100644
--- a/openstackclient/common/utils.py
+++ b/openstackclient/common/utils.py
@@ -125,6 +125,6 @@ def get_client_class(api_name, version, version_map):
     except (KeyError, ValueError):
         msg = "Invalid %s client version '%s'. must be one of: %s" % (
               (api_name, version, ', '.join(version_map.keys())))
-        raise exc.UnsupportedVersion(msg)
+        raise exceptions.UnsupportedVersion(msg)
 
     return import_class(client_path)
diff --git a/openstackclient/image/client.py b/openstackclient/image/client.py
new file mode 100644
index 0000000000..0a7c576e7b
--- /dev/null
+++ b/openstackclient/image/client.py
@@ -0,0 +1,41 @@
+#   Copyright 2012 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 = "image"
+API_VERSIONS = {
+    # FIXME(jk0): Temporary 1.0 -> 2 mapping.
+    "1.0": "glanceclient.v2.client.Client"
+}
+
+
+def make_client(instance):
+    """Returns an image service client."""
+    image_client = utils.get_client_class(
+        API_NAME,
+        instance._api_version[API_NAME],
+        API_VERSIONS
+    )
+
+    if not instance._url:
+        instance._url = instance.get_endpoint_for_service_type(API_NAME)
+
+    return image_client(instance._url, token=instance._token)
diff --git a/openstackclient/image/v2/__init__.py b/openstackclient/image/v2/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/openstackclient/image/v2/image.py b/openstackclient/image/v2/image.py
new file mode 100644
index 0000000000..41520612d6
--- /dev/null
+++ b/openstackclient/image/v2/image.py
@@ -0,0 +1,109 @@
+#   Copyright 2012 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.
+#
+
+"""Image Action Implementations"""
+
+import logging
+
+from cliff import command
+from cliff import lister
+
+from glanceclient.common import utils as gc_utils
+from openstackclient.common import utils
+
+
+class ListImage(lister.Lister):
+    """List image command"""
+
+    api = "image"
+    log = logging.getLogger(__name__ + ".ListImage")
+
+    def get_parser(self, prog_name):
+        parser = super(ListImage, self).get_parser(prog_name)
+        parser.add_argument(
+            "--page-size",
+            metavar="<size>",
+            help="Number of images to request in each paginated request.",
+            )
+        return parser
+
+    def take_action(self, parsed_args):
+        self.log.debug("take_action(%s)" % parsed_args)
+        image_client = self.app.client_manager.image
+
+        kwargs = {}
+        if parsed_args.page_size is not None:
+            kwargs["page_size"] = parsed_args.page_size
+
+        data = image_client.images.list(**kwargs)
+        columns = ["ID", "Name"]
+
+        return (columns,
+                (utils.get_item_properties(
+                    s, columns,
+                    ) for s in data),
+                )
+
+
+class SaveImage(command.Command):
+    """Save image command"""
+
+    api = "image"
+    log = logging.getLogger(__name__ + ".SaveImage")
+
+    def get_parser(self, prog_name):
+        parser = super(SaveImage, self).get_parser(prog_name)
+        parser.add_argument(
+            "--file",
+            metavar="<file>",
+            help="Local file to save downloaded image data to. "
+                "If this is not specified the image data will be "
+                "written to stdout.",
+            )
+        parser.add_argument(
+            "id",
+            metavar="<image_id>",
+            help="ID of image to describe.",
+            )
+        return parser
+
+    def take_action(self, parsed_args):
+        self.log.debug("take_action(%s)" % parsed_args)
+        image_client = self.app.client_manager.image
+
+        data = image_client.images.data(parsed_args.id)
+        gc_utils.save_image(data, parsed_args.file)
+
+
+class ShowImage(command.Command):
+    """Show image command"""
+
+    api = "image"
+    log = logging.getLogger(__name__ + ".ShowImage")
+
+    def get_parser(self, prog_name):
+        parser = super(ShowImage, self).get_parser(prog_name)
+        parser.add_argument(
+            "id",
+            metavar="<image_id>",
+            help="ID of image to describe.",
+            )
+        return parser
+
+    def take_action(self, parsed_args):
+        self.log.debug("take_action(%s)" % parsed_args)
+        image_client = self.app.client_manager.image
+
+        gc_utils.print_dict(image_client.images.get(parsed_args.id))
diff --git a/setup.py b/setup.py
index 7dde53f2bf..df9fefffe7 100644
--- a/setup.py
+++ b/setup.py
@@ -110,6 +110,9 @@ setuptools.setup(
             'set_user=openstackclient.identity.v2_0.user:SetUser',
             'show_user=openstackclient.identity.v2_0.user:ShowUser',
             'list_user-role=openstackclient.identity.v2_0.role:ListUserRole',
+            'list_image=openstackclient.image.v2.image:ListImage',
+            'show_image=openstackclient.image.v2.image:ShowImage',
+            'save_image=openstackclient.image.v2.image:SaveImage',
         ]
     }
 )