From 0c4929373e04c48638dc3facd47e39933cc9ac49 Mon Sep 17 00:00:00 2001
From: Steve Martinelli <stevemar@ca.ibm.com>
Date: Mon, 4 Mar 2013 22:27:07 -0600
Subject: [PATCH] Add snapshot support for v1 volume

rebase again, and change util to look for display_name too
minor changes and rebase
add create/delete/list/set/show support for snapshot

Change-Id: I80261653fa919555a44ddda07b0a827ccd16e5e0
---
 openstackclient/common/utils.py       |   5 +
 openstackclient/volume/v1/snapshot.py | 183 ++++++++++++++++++++++++++
 setup.py                              |   7 +
 3 files changed, 195 insertions(+)
 create mode 100644 openstackclient/volume/v1/snapshot.py

diff --git a/openstackclient/common/utils.py b/openstackclient/common/utils.py
index 6477285eb0..76532fcb02 100644
--- a/openstackclient/common/utils.py
+++ b/openstackclient/common/utils.py
@@ -46,6 +46,11 @@ def find_resource(manager, name_or_id):
     #                 Eventually this should be pulled from a common set
     #                 of client exceptions.
     except Exception as ex:
+        try:
+            return manager.find(display_name=name_or_id)
+        except:
+            pass
+
         if type(ex).__name__ == 'NotFound':
             msg = "No %s with a name or ID of '%s' exists." % \
                 (manager.resource_class.__name__.lower(), name_or_id)
diff --git a/openstackclient/volume/v1/snapshot.py b/openstackclient/volume/v1/snapshot.py
new file mode 100644
index 0000000000..a4cf86bfd5
--- /dev/null
+++ b/openstackclient/volume/v1/snapshot.py
@@ -0,0 +1,183 @@
+#   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 Snapshot action implementations"""
+
+import logging
+import sys
+
+from cliff import command
+from cliff import lister
+from cliff import show
+
+from openstackclient.common import utils
+
+
+class CreateSnapshot(show.ShowOne):
+    """Create snapshot command"""
+
+    api = 'volume'
+    log = logging.getLogger(__name__ + '.CreateSnapshot')
+
+    def get_parser(self, prog_name):
+        parser = super(CreateSnapshot, self).get_parser(prog_name)
+        parser.add_argument(
+            'volume',
+            metavar='<volume>',
+            help='The name or ID of the volume to snapshot',
+        )
+        parser.add_argument(
+            '--name',
+            metavar='<name>',
+            required=True,
+            help='Name of the snapshot',
+        )
+        parser.add_argument(
+            '--description',
+            metavar='<description>',
+            help='Description of the snapshot',
+        )
+        parser.add_argument(
+            '--force',
+            dest='force',
+            action='store_true',
+            default=False,
+            help='Create a snapshot attached to an instance. Default is False',
+        )
+        return parser
+
+    def take_action(self, parsed_args):
+        self.log.debug('take_action(%s)' % parsed_args)
+        volume_client = self.app.client_manager.volume
+        volume_id = utils.find_resource(volume_client.volumes,
+                                        parsed_args.volume).id
+        snapshot = volume_client.volume_snapshots.create(
+            volume_id,
+            parsed_args.force,
+            parsed_args.name,
+            parsed_args.description
+        )
+
+        return zip(*sorted(snapshot._info.iteritems()))
+
+
+class DeleteSnapshot(command.Command):
+    """Delete snapshot command"""
+
+    api = 'volume'
+    log = logging.getLogger(__name__ + '.DeleteSnapshot')
+
+    def get_parser(self, prog_name):
+        parser = super(DeleteSnapshot, self).get_parser(prog_name)
+        parser.add_argument(
+            'snapshot',
+            metavar='<snapshot>',
+            help='Name or ID of snapshot 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
+        snapshot_id = utils.find_resource(volume_client.volume_snapshots,
+                                          parsed_args.snapshot).id
+        volume_client.volume_snapshots.delete(snapshot_id)
+        return
+
+
+class ListSnapshot(lister.Lister):
+    """List snapshot command"""
+
+    api = 'volume'
+    log = logging.getLogger(__name__ + '.ListSnapshot')
+
+    def take_action(self, parsed_args):
+        self.log.debug('take_action(%s)' % parsed_args)
+        columns = (
+            'ID',
+            'Display Name',
+            'Display Description',
+            'Status',
+            'Size'
+        )
+        data = self.app.client_manager.volume.volume_snapshots.list()
+        return (columns,
+                (utils.get_item_properties(
+                    s, columns,
+                    formatters={},
+                ) for s in data))
+
+
+class SetSnapshot(command.Command):
+    """Set snapshot command"""
+
+    api = 'volume'
+    log = logging.getLogger(__name__ + '.SetSnapshot')
+
+    def get_parser(self, prog_name):
+        parser = super(SetSnapshot, self).get_parser(prog_name)
+        parser.add_argument(
+            'snapshot',
+            metavar='<snapshot>',
+            help='Name or ID of snapshot to change')
+        parser.add_argument(
+            '--name',
+            metavar='<new-snapshot-name>',
+            help='New snapshot name')
+        parser.add_argument(
+            '--description',
+            metavar='<new-snapshot-description>',
+            help='New snapshot description')
+        return parser
+
+    def take_action(self, parsed_args):
+        self.log.debug('take_action(%s)' % parsed_args)
+        volume_client = self.app.client_manager.volume
+        snapshot = utils.find_resource(volume_client.volume_snapshots,
+                                       parsed_args.snapshot)
+        kwargs = {}
+        if parsed_args.name:
+            kwargs['display_name'] = parsed_args.name
+        if parsed_args.description:
+            kwargs['display_description'] = parsed_args.description
+
+        if not kwargs:
+            sys.stdout.write("Snapshot not updated, no arguments present")
+            return
+        snapshot.update(**kwargs)
+        return
+
+
+class ShowSnapshot(show.ShowOne):
+    """Show snapshot command"""
+
+    api = 'volume'
+    log = logging.getLogger(__name__ + '.ShowSnapshot')
+
+    def get_parser(self, prog_name):
+        parser = super(ShowSnapshot, self).get_parser(prog_name)
+        parser.add_argument(
+            'snapshot',
+            metavar='<snapshot>',
+            help='Name or ID of snapshot to display')
+        return parser
+
+    def take_action(self, parsed_args):
+        self.log.debug('take_action(%s)' % parsed_args)
+        volume_client = self.app.client_manager.volume
+        snapshot = utils.find_resource(volume_client.volume_snapshots,
+                                       parsed_args.snapshot)
+
+        return zip(*sorted(snapshot._info.iteritems()))
diff --git a/setup.py b/setup.py
index 922d103bbd..018628aeb8 100644
--- a/setup.py
+++ b/setup.py
@@ -161,6 +161,13 @@ setuptools.setup(
             'list_volume=openstackclient.volume.v1.volume:ListVolume',
             'set_volume=openstackclient.volume.v1.volume:SetVolume',
             'show_volume=openstackclient.volume.v1.volume:ShowVolume',
+            'create_snapshot=' +
+            'openstackclient.volume.v1.snapshot:CreateSnapshot',
+            'delete_snapshot=' +
+            'openstackclient.volume.v1.snapshot:DeleteSnapshot',
+            'list_snapshot=openstackclient.volume.v1.snapshot:ListSnapshot',
+            'set_snapshot=openstackclient.volume.v1.snapshot:SetSnapshot',
+            'show_snapshot=openstackclient.volume.v1.snapshot:ShowSnapshot',
         ]
     }
 )