commit fc517e598b380133cdc765523a1da7b261273d70
Author: Christos Stavrakakis <cstavr@grnet.gr>
Date:   Tue Feb 4 12:48:41 2014 +0200

    cyclades: Create snapshot-show and fix image-show

diff --git a/snf-cyclades-app/synnefo/plankton/management/commands/image-show.py b/snf-cyclades-app/synnefo/plankton/management/commands/image-show.py
index 231cf17..33332f7 100644
--- a/snf-cyclades-app/synnefo/plankton/management/commands/image-show.py
+++ b/snf-cyclades-app/synnefo/plankton/management/commands/image-show.py
@@ -28,8 +28,10 @@
 # policies, either expressed or implied, of GRNET S.A.
 #
 
+from optparse import make_option
 from django.core.management.base import BaseCommand, CommandError
 
+from synnefo.management import common
 from synnefo.plankton.utils import image_backend
 from snf_django.management import utils
 
@@ -37,19 +39,24 @@ from snf_django.management import utils
 class Command(BaseCommand):
     args = "<image_id>"
     help = "Display available information about an image"
+    option_list = BaseCommand.option_list + (
+        make_option(
+            '--user-id',
+            dest='userid',
+            default=None,
+            help="The UUID of the owner of the image. Required"
+                 " if image is not public"),
+    )
 
+    @common.convert_api_faults
     def handle(self, *args, **options):
 
         if len(args) != 1:
             raise CommandError("Please provide an image ID")
         image_id = args[0]
+        user_id = options["userid"]
 
-        with image_backend(None) as backend:
-            images = backend._list_images(None)
-            try:
-                image = filter(lambda x: x["id"] == image_id, images)[0]
-            except IndexError:
-                raise CommandError("Image not found. Use snf-manage image-list"
-                                   " to get the list of all images.")
+        with image_backend(userid) as backend:
+            image = backend.get_image(image_id)
         utils.pprint_table(out=self.stdout, table=[image.values()],
                            headers=image.keys(), vertical=True)
diff --git a/snf-cyclades-app/synnefo/plankton/utils.py b/snf-cyclades-app/synnefo/plankton/utils.py
index f7d39e0..bb29b9c 100644
--- a/snf-cyclades-app/synnefo/plankton/utils.py
+++ b/snf-cyclades-app/synnefo/plankton/utils.py
@@ -50,9 +50,9 @@ def image_backend(user_id):
     try:
         yield image_backend
     except backend.Forbidden as e:
-        raise faults.Forbidden
-    except backend.ImageNotFound:
-        raise faults.ItemNotFound
+        raise faults.Forbidden("Access forbidden")
+    except backend.ImageNotFound as e:
+        raise faults.ItemNotFound("Not found")
     except backend.InvalidMetadata as e:
         raise faults.BadRequest(str(e))
     except QuotaError as e:
diff --git a/snf-cyclades-app/synnefo/volume/management/commands/snapshot-show.py b/snf-cyclades-app/synnefo/volume/management/commands/snapshot-show.py
new file mode 100644
index 0000000..ede466b
--- /dev/null
+++ b/snf-cyclades-app/synnefo/volume/management/commands/snapshot-show.py
@@ -0,0 +1,63 @@
+# Copyright 2012 GRNET S.A. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+#   1. Redistributions of source code must retain the above copyright
+#      notice, this list of conditions and the following disclaimer.
+#
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# The views and conclusions contained in the software and documentation are
+# those of the authors and should not be interpreted as representing official
+# policies, either expressed or implied, of GRNET S.A.
+#
+
+from django.core.management.base import BaseCommand, CommandError
+from optparse import make_option
+
+from synnefo.management import common
+from synnefo.plankton.utils import image_backend
+from snf_django.management import utils
+
+
+class Command(BaseCommand):
+    args = "<snapshot_id>"
+    help = "Display available information about a snapshot"
+    option_list = BaseCommand.option_list + (
+        make_option(
+            '--user-id',
+            dest='userid',
+            default=None,
+            help="The UUID of the owner of the snapshot. Required"
+                 "if snapshot is not public"),
+    )
+
+    @common.convert_api_faults
+    def handle(self, *args, **options):
+
+        if len(args) != 1:
+            raise CommandError("Please provide a snapshot ID")
+
+        snapshot_id = args[0]
+        user_id = options["userid"]
+
+        with image_backend(userid) as backend:
+            snapshot = backend.get_snapshot(userid, snapshot_id)
+        utils.pprint_table(out=self.stdout, table=[snapshot.values()],
+                           headers=snapshot.keys(), vertical=True)
