Add support for volume snapshot v2 command
openstack snapshot create openstack snapshot set openstack snapshot unset openstack snapshot list Implements: blueprint volume-v2 Change-Id: Ia1d9f4426baa0099281a9931f4eec99ebe1969b1
This commit is contained in:
		@@ -12,6 +12,7 @@
 | 
			
		||||
#   under the License.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
import copy
 | 
			
		||||
import mock
 | 
			
		||||
 | 
			
		||||
from openstackclient.tests import fakes
 | 
			
		||||
@@ -62,11 +63,17 @@ SNAPSHOT = {
 | 
			
		||||
    "name": snapshot_name,
 | 
			
		||||
    "description": snapshot_description,
 | 
			
		||||
    "size": snapshot_size,
 | 
			
		||||
    "metadata": snapshot_metadata
 | 
			
		||||
    "status": "available",
 | 
			
		||||
    "metadata": snapshot_metadata,
 | 
			
		||||
    "created_at": "2015-06-03T18:49:19.000000",
 | 
			
		||||
    "volume_id": volume_name
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SNAPSHOT_columns = tuple(sorted(SNAPSHOT))
 | 
			
		||||
SNAPSHOT_data = tuple((SNAPSHOT[x] for x in sorted(SNAPSHOT)))
 | 
			
		||||
EXPECTED_SNAPSHOT = copy.deepcopy(SNAPSHOT)
 | 
			
		||||
EXPECTED_SNAPSHOT.pop("metadata")
 | 
			
		||||
EXPECTED_SNAPSHOT['properties'] = "foo='bar'"
 | 
			
		||||
SNAPSHOT_columns = tuple(sorted(EXPECTED_SNAPSHOT))
 | 
			
		||||
SNAPSHOT_data = tuple((EXPECTED_SNAPSHOT[x]
 | 
			
		||||
                       for x in sorted(EXPECTED_SNAPSHOT)))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
type_id = "5520dc9e-6f9b-4378-a719-729911c0f407"
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,53 @@ class TestSnapshot(volume_fakes.TestVolume):
 | 
			
		||||
 | 
			
		||||
        self.snapshots_mock = self.app.client_manager.volume.volume_snapshots
 | 
			
		||||
        self.snapshots_mock.reset_mock()
 | 
			
		||||
        self.volumes_mock = self.app.client_manager.volume.volumes
 | 
			
		||||
        self.volumes_mock.reset_mock()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestSnapshotCreate(TestSnapshot):
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        super(TestSnapshotCreate, self).setUp()
 | 
			
		||||
 | 
			
		||||
        self.volumes_mock.get.return_value = fakes.FakeResource(
 | 
			
		||||
            None,
 | 
			
		||||
            copy.deepcopy(volume_fakes.VOLUME),
 | 
			
		||||
            loaded=True
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        self.snapshots_mock.create.return_value = fakes.FakeResource(
 | 
			
		||||
            None,
 | 
			
		||||
            copy.deepcopy(volume_fakes.SNAPSHOT),
 | 
			
		||||
            loaded=True
 | 
			
		||||
        )
 | 
			
		||||
        # Get the command object to test
 | 
			
		||||
        self.cmd = snapshot.CreateSnapshot(self.app, None)
 | 
			
		||||
 | 
			
		||||
    def test_snapshot_create(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            volume_fakes.volume_id,
 | 
			
		||||
            "--name", volume_fakes.snapshot_name,
 | 
			
		||||
            "--description", volume_fakes.snapshot_description,
 | 
			
		||||
            "--force"
 | 
			
		||||
        ]
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ("volume", volume_fakes.volume_id),
 | 
			
		||||
            ("name", volume_fakes.snapshot_name),
 | 
			
		||||
            ("description", volume_fakes.snapshot_description),
 | 
			
		||||
            ("force", True)
 | 
			
		||||
        ]
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        columns, data = self.cmd.take_action(parsed_args)
 | 
			
		||||
 | 
			
		||||
        self.snapshots_mock.create.assert_called_with(
 | 
			
		||||
            volume_fakes.volume_id,
 | 
			
		||||
            force=True,
 | 
			
		||||
            name=volume_fakes.snapshot_name,
 | 
			
		||||
            description=volume_fakes.snapshot_description
 | 
			
		||||
        )
 | 
			
		||||
        self.assertEqual(columns, volume_fakes.SNAPSHOT_columns)
 | 
			
		||||
        self.assertEqual(data, volume_fakes.SNAPSHOT_data)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestSnapshotShow(TestSnapshot):
 | 
			
		||||
@@ -80,3 +127,139 @@ class TestSnapshotDelete(TestSnapshot):
 | 
			
		||||
 | 
			
		||||
        self.cmd.take_action(parsed_args)
 | 
			
		||||
        self.snapshots_mock.delete.assert_called_with(volume_fakes.snapshot_id)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestSnapshotSet(TestSnapshot):
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        super(TestSnapshotSet, self).setUp()
 | 
			
		||||
 | 
			
		||||
        self.snapshots_mock.get.return_value = fakes.FakeResource(
 | 
			
		||||
            None,
 | 
			
		||||
            copy.deepcopy(volume_fakes.SNAPSHOT),
 | 
			
		||||
            loaded=True
 | 
			
		||||
        )
 | 
			
		||||
        self.snapshots_mock.set_metadata.return_value = None
 | 
			
		||||
        self.snapshots_mock.update.return_value = None
 | 
			
		||||
        # Get the command object to mock
 | 
			
		||||
        self.cmd = snapshot.SetSnapshot(self.app, None)
 | 
			
		||||
 | 
			
		||||
    def test_snapshot_set(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            volume_fakes.snapshot_id,
 | 
			
		||||
            "--name", "new_snapshot",
 | 
			
		||||
            "--property", "x=y",
 | 
			
		||||
            "--property", "foo=foo"
 | 
			
		||||
        ]
 | 
			
		||||
        new_property = {"x": "y", "foo": "foo"}
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ("snapshot", volume_fakes.snapshot_id),
 | 
			
		||||
            ("name", "new_snapshot"),
 | 
			
		||||
            ("property", new_property)
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
        kwargs = {
 | 
			
		||||
            "name": "new_snapshot",
 | 
			
		||||
        }
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
        self.cmd.take_action(parsed_args)
 | 
			
		||||
 | 
			
		||||
        self.snapshots_mock.update.assert_called_with(
 | 
			
		||||
            volume_fakes.snapshot_id, **kwargs)
 | 
			
		||||
        self.snapshots_mock.set_metadata.assert_called_with(
 | 
			
		||||
            volume_fakes.snapshot_id, new_property
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestSnapshotUnset(TestSnapshot):
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        super(TestSnapshotUnset, self).setUp()
 | 
			
		||||
 | 
			
		||||
        self.snapshots_mock.get.return_value = fakes.FakeResource(
 | 
			
		||||
            None,
 | 
			
		||||
            copy.deepcopy(volume_fakes.SNAPSHOT),
 | 
			
		||||
            loaded=True
 | 
			
		||||
        )
 | 
			
		||||
        self.snapshots_mock.delete_metadata.return_value = None
 | 
			
		||||
        # Get the command object to mock
 | 
			
		||||
        self.cmd = snapshot.UnsetSnapshot(self.app, None)
 | 
			
		||||
 | 
			
		||||
    def test_snapshot_unset(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            volume_fakes.snapshot_id,
 | 
			
		||||
            "--property", "foo"
 | 
			
		||||
        ]
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ("snapshot", volume_fakes.snapshot_id),
 | 
			
		||||
            ("property", ["foo"])
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
        self.cmd.take_action(parsed_args)
 | 
			
		||||
 | 
			
		||||
        self.snapshots_mock.delete_metadata.assert_called_with(
 | 
			
		||||
            volume_fakes.snapshot_id, ["foo"]
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestSnapshotList(TestSnapshot):
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        super(TestSnapshotList, self).setUp()
 | 
			
		||||
 | 
			
		||||
        self.volumes_mock.list.return_value = [
 | 
			
		||||
            fakes.FakeResource(
 | 
			
		||||
                None,
 | 
			
		||||
                copy.deepcopy(volume_fakes.VOLUME),
 | 
			
		||||
                loaded=True
 | 
			
		||||
            )
 | 
			
		||||
        ]
 | 
			
		||||
        self.snapshots_mock.list.return_value = [
 | 
			
		||||
            fakes.FakeResource(
 | 
			
		||||
                None,
 | 
			
		||||
                copy.deepcopy(volume_fakes.SNAPSHOT),
 | 
			
		||||
                loaded=True
 | 
			
		||||
            )
 | 
			
		||||
        ]
 | 
			
		||||
        # Get the command to test
 | 
			
		||||
        self.cmd = snapshot.ListSnapshot(self.app, None)
 | 
			
		||||
 | 
			
		||||
    def test_snapshot_list_without_options(self):
 | 
			
		||||
        arglist = []
 | 
			
		||||
        verifylist = [
 | 
			
		||||
            ("long", False)
 | 
			
		||||
        ]
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        columns, data = self.cmd.take_action(parsed_args)
 | 
			
		||||
        collist = ["ID", "Name", "Description", "Status", "Size"]
 | 
			
		||||
        self.assertEqual(collist, columns)
 | 
			
		||||
        datalist = ((
 | 
			
		||||
            volume_fakes.snapshot_id,
 | 
			
		||||
            volume_fakes.snapshot_name,
 | 
			
		||||
            volume_fakes.snapshot_description,
 | 
			
		||||
            "available",
 | 
			
		||||
            volume_fakes.snapshot_size
 | 
			
		||||
            ),)
 | 
			
		||||
        self.assertEqual(datalist, tuple(data))
 | 
			
		||||
 | 
			
		||||
    def test_snapshot_list_with_options(self):
 | 
			
		||||
        arglist = ["--long"]
 | 
			
		||||
        verifylist = [("long", True)]
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        columns, data = self.cmd.take_action(parsed_args)
 | 
			
		||||
 | 
			
		||||
        collist = ["ID", "Name", "Description", "Status", "Size", "Created At",
 | 
			
		||||
                   "Volume", "Properties"]
 | 
			
		||||
        self.assertEqual(collist, columns)
 | 
			
		||||
 | 
			
		||||
        datalist = ((
 | 
			
		||||
            volume_fakes.snapshot_id,
 | 
			
		||||
            volume_fakes.snapshot_name,
 | 
			
		||||
            volume_fakes.snapshot_description,
 | 
			
		||||
            "available",
 | 
			
		||||
            volume_fakes.snapshot_size,
 | 
			
		||||
            "2015-06-03T18:49:19.000000",
 | 
			
		||||
            volume_fakes.volume_name,
 | 
			
		||||
            volume_fakes.EXPECTED_SNAPSHOT.get("properties")
 | 
			
		||||
        ),)
 | 
			
		||||
        self.assertEqual(datalist, tuple(data))
 | 
			
		||||
 
 | 
			
		||||
@@ -14,15 +14,67 @@
 | 
			
		||||
 | 
			
		||||
"""Volume v2 snapshot action implementations"""
 | 
			
		||||
 | 
			
		||||
import copy
 | 
			
		||||
import logging
 | 
			
		||||
 | 
			
		||||
from cliff import command
 | 
			
		||||
from cliff import lister
 | 
			
		||||
from cliff import show
 | 
			
		||||
import six
 | 
			
		||||
 | 
			
		||||
from openstackclient.common import parseractions
 | 
			
		||||
from openstackclient.common import utils
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CreateSnapshot(show.ShowOne):
 | 
			
		||||
    """Create new snapshot"""
 | 
			
		||||
 | 
			
		||||
    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="Volume to snapshot (name or ID)"
 | 
			
		||||
        )
 | 
			
		||||
        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,
 | 
			
		||||
            force=parsed_args.force,
 | 
			
		||||
            name=parsed_args.name,
 | 
			
		||||
            description=parsed_args.description
 | 
			
		||||
        )
 | 
			
		||||
        snapshot._info.update(
 | 
			
		||||
            {'properties': utils.format_dict(snapshot._info.pop('metadata'))}
 | 
			
		||||
        )
 | 
			
		||||
        return zip(*sorted(six.iteritems(snapshot._info)))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DeleteSnapshot(command.Command):
 | 
			
		||||
    """Delete volume snapshot(s)"""
 | 
			
		||||
 | 
			
		||||
@@ -34,7 +86,7 @@ class DeleteSnapshot(command.Command):
 | 
			
		||||
            "snapshots",
 | 
			
		||||
            metavar="<snapshot>",
 | 
			
		||||
            nargs="+",
 | 
			
		||||
            help="Snapsho(s) to delete (name or ID)"
 | 
			
		||||
            help="Snapshot(s) to delete (name or ID)"
 | 
			
		||||
        )
 | 
			
		||||
        return parser
 | 
			
		||||
 | 
			
		||||
@@ -48,6 +100,115 @@ class DeleteSnapshot(command.Command):
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ListSnapshot(lister.Lister):
 | 
			
		||||
    """List snapshots"""
 | 
			
		||||
 | 
			
		||||
    log = logging.getLogger(__name__ + ".ListSnapshot")
 | 
			
		||||
 | 
			
		||||
    def get_parser(self, prog_name):
 | 
			
		||||
        parser = super(ListSnapshot, self).get_parser(prog_name)
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--long',
 | 
			
		||||
            action='store_true',
 | 
			
		||||
            default=False,
 | 
			
		||||
            help='List additional fields in output',
 | 
			
		||||
        )
 | 
			
		||||
        return parser
 | 
			
		||||
 | 
			
		||||
    def take_action(self, parsed_args):
 | 
			
		||||
        self.log.debug("take_action: (%s)", parsed_args)
 | 
			
		||||
 | 
			
		||||
        def _format_volume_id(volume_id):
 | 
			
		||||
            """Return a volume name if available
 | 
			
		||||
 | 
			
		||||
            :param volume_id: a volume ID
 | 
			
		||||
            :rtype: either the volume ID or name
 | 
			
		||||
            """
 | 
			
		||||
 | 
			
		||||
            volume = volume_id
 | 
			
		||||
            if volume_id in volume_cache.keys():
 | 
			
		||||
                volume = volume_cache[volume_id].name
 | 
			
		||||
            return volume
 | 
			
		||||
 | 
			
		||||
        if parsed_args.long:
 | 
			
		||||
            columns = ['ID', 'Name', 'Description', 'Status',
 | 
			
		||||
                       'Size', 'Created At', 'Volume ID', 'Metadata']
 | 
			
		||||
            column_headers = copy.deepcopy(columns)
 | 
			
		||||
            column_headers[6] = 'Volume'
 | 
			
		||||
            column_headers[7] = 'Properties'
 | 
			
		||||
        else:
 | 
			
		||||
            columns = ['ID', 'Name', 'Description', 'Status', 'Size']
 | 
			
		||||
            column_headers = copy.deepcopy(columns)
 | 
			
		||||
 | 
			
		||||
        # Cache the volume list
 | 
			
		||||
        volume_cache = {}
 | 
			
		||||
        try:
 | 
			
		||||
            for s in self.app.client_manager.volume.volumes.list():
 | 
			
		||||
                volume_cache[s.id] = s
 | 
			
		||||
        except Exception:
 | 
			
		||||
            # Just forget it if there's any trouble
 | 
			
		||||
            pass
 | 
			
		||||
 | 
			
		||||
        data = self.app.client_manager.volume.volume_snapshots.list()
 | 
			
		||||
        return (column_headers,
 | 
			
		||||
                (utils.get_item_properties(
 | 
			
		||||
                    s, columns,
 | 
			
		||||
                    formatters={'Metadata': utils.format_dict,
 | 
			
		||||
                                'Volume ID': _format_volume_id},
 | 
			
		||||
                ) for s in data))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SetSnapshot(command.Command):
 | 
			
		||||
    """Set snapshot properties"""
 | 
			
		||||
 | 
			
		||||
    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='Snapshot to modify (name or ID)')
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--name',
 | 
			
		||||
            metavar='<name>',
 | 
			
		||||
            help='New snapshot name')
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--description',
 | 
			
		||||
            metavar='<description>',
 | 
			
		||||
            help='New snapshot description')
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--property',
 | 
			
		||||
            metavar='<key=value>',
 | 
			
		||||
            action=parseractions.KeyValueAction,
 | 
			
		||||
            help='Property to add/change for this snapshot '
 | 
			
		||||
                 '(repeat option to set multiple properties)',
 | 
			
		||||
        )
 | 
			
		||||
        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['name'] = parsed_args.name
 | 
			
		||||
        if parsed_args.description:
 | 
			
		||||
            kwargs['description'] = parsed_args.description
 | 
			
		||||
 | 
			
		||||
        if not kwargs and not parsed_args.property:
 | 
			
		||||
            self.app.log.error("No changes requested\n")
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        if parsed_args.property:
 | 
			
		||||
            volume_client.volume_snapshots.set_metadata(snapshot.id,
 | 
			
		||||
                                                        parsed_args.property)
 | 
			
		||||
        volume_client.volume_snapshots.update(snapshot.id, **kwargs)
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ShowSnapshot(show.ShowOne):
 | 
			
		||||
    """Display snapshot details"""
 | 
			
		||||
 | 
			
		||||
@@ -67,5 +228,45 @@ class ShowSnapshot(show.ShowOne):
 | 
			
		||||
        volume_client = self.app.client_manager.volume
 | 
			
		||||
        snapshot = utils.find_resource(
 | 
			
		||||
            volume_client.volume_snapshots, parsed_args.snapshot)
 | 
			
		||||
        snapshot = volume_client.volume_snapshots.get(snapshot.id)
 | 
			
		||||
        snapshot._info.update(
 | 
			
		||||
            {'properties': utils.format_dict(snapshot._info.pop('metadata'))}
 | 
			
		||||
        )
 | 
			
		||||
        return zip(*sorted(six.iteritems(snapshot._info)))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UnsetSnapshot(command.Command):
 | 
			
		||||
    """Unset snapshot properties"""
 | 
			
		||||
 | 
			
		||||
    log = logging.getLogger(__name__ + '.UnsetSnapshot')
 | 
			
		||||
 | 
			
		||||
    def get_parser(self, prog_name):
 | 
			
		||||
        parser = super(UnsetSnapshot, self).get_parser(prog_name)
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            'snapshot',
 | 
			
		||||
            metavar='<snapshot>',
 | 
			
		||||
            help='Snapshot to modify (name or ID)',
 | 
			
		||||
        )
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--property',
 | 
			
		||||
            metavar='<key>',
 | 
			
		||||
            action='append',
 | 
			
		||||
            default=[],
 | 
			
		||||
            help='Property to remove from snapshot '
 | 
			
		||||
                 '(repeat to remove multiple values)',
 | 
			
		||||
        )
 | 
			
		||||
        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)
 | 
			
		||||
 | 
			
		||||
        if parsed_args.property:
 | 
			
		||||
            volume_client.volume_snapshots.delete_metadata(
 | 
			
		||||
                snapshot.id,
 | 
			
		||||
                parsed_args.property,
 | 
			
		||||
            )
 | 
			
		||||
        else:
 | 
			
		||||
            self.app.log.error("No changes requested\n")
 | 
			
		||||
        return
 | 
			
		||||
 
 | 
			
		||||
@@ -370,8 +370,12 @@ openstack.volume.v2 =
 | 
			
		||||
    backup_delete = openstackclient.volume.v2.backup:DeleteBackup
 | 
			
		||||
    backup_show = openstackclient.volume.v2.backup:ShowBackup
 | 
			
		||||
 | 
			
		||||
    snapshot_create = openstackclient.volume.v2.snapshot:CreateSnapshot
 | 
			
		||||
    snapshot_delete = openstackclient.volume.v2.snapshot:DeleteSnapshot
 | 
			
		||||
    snapshot_list = openstackclient.volume.v2.snapshot:ListSnapshot
 | 
			
		||||
    snapshot_set = openstackclient.volume.v2.snapshot:SetSnapshot
 | 
			
		||||
    snapshot_show = openstackclient.volume.v2.snapshot:ShowSnapshot
 | 
			
		||||
    snapshot_unset = openstackclient.volume.v2.snapshot:UnsetSnapshot
 | 
			
		||||
 | 
			
		||||
    volume_delete = openstackclient.volume.v2.volume:DeleteVolume
 | 
			
		||||
    volume_show = openstackclient.volume.v2.volume:ShowVolume
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user