diff --git a/cinderclient/tests/v2/fakes.py b/cinderclient/tests/v2/fakes.py index dbb50f2b4..1ece47919 100644 --- a/cinderclient/tests/v2/fakes.py +++ b/cinderclient/tests/v2/fakes.py @@ -296,6 +296,13 @@ class FakeHTTPClient(base_client.HTTPClient): def get_snapshots_5678(self, **kw): return (200, {}, {'snapshot': _stub_snapshot(id='5678')}) + def post_snapshots(self, **kw): + metadata = kw['body']['snapshot'].get('metadata', None) + snapshot = _stub_snapshot(id='1234', volume_id='1234') + if snapshot is not None: + snapshot.update({'metadata': metadata}) + return (202, {}, {'snapshot': snapshot}) + def put_snapshots_1234(self, **kw): snapshot = _stub_snapshot(id='1234') snapshot.update(kw['body']['snapshot']) diff --git a/cinderclient/tests/v2/test_shell.py b/cinderclient/tests/v2/test_shell.py index 696d627db..e962f6e41 100644 --- a/cinderclient/tests/v2/test_shell.py +++ b/cinderclient/tests/v2/test_shell.py @@ -540,3 +540,16 @@ class ShellTest(utils.TestCase): self.run_command('replication-reenable 1234') self.assert_called('POST', '/volumes/1234/action', body={'os-reenable-replica': None}) + + def test_create_snapshot_from_volume_with_metadata(self): + """ + Tests create snapshot with --metadata parameter. + + Checks metadata params are set during create snapshot + when metadata is passed + """ + expected = {'snapshot': {'volume_id': 1234, + 'metadata': {'k1': 'v1', + 'k2': 'v2'}}} + self.run_command('snapshot-create 1234 --metadata k1=v1 k2=v2') + self.assert_called_anytime('POST', '/snapshots', partial_body=expected) diff --git a/cinderclient/v2/shell.py b/cinderclient/v2/shell.py index 41972a1e8..5d96a94ba 100644 --- a/cinderclient/v2/shell.py +++ b/cinderclient/v2/shell.py @@ -578,6 +578,12 @@ def do_snapshot_show(cs, args): help=argparse.SUPPRESS) @utils.arg('--display_description', help=argparse.SUPPRESS) +@utils.arg('--metadata', + type=str, + nargs='*', + metavar='', + help='Snapshot metadata key and value pairs. Default=None.', + default=None) @utils.service_type('volumev2') def do_snapshot_create(cs, args): """Creates a snapshot.""" @@ -587,11 +593,16 @@ def do_snapshot_create(cs, args): if args.display_description is not None: args.description = args.display_description + snapshot_metadata = None + if args.metadata is not None: + snapshot_metadata = _extract_metadata(args) + volume = utils.find_volume(cs, args.volume) snapshot = cs.volume_snapshots.create(volume.id, args.force, args.name, - args.description) + args.description, + metadata=snapshot_metadata) _print_volume_snapshot(snapshot) diff --git a/cinderclient/v2/volume_snapshots.py b/cinderclient/v2/volume_snapshots.py index a398b0eb9..51b611db6 100644 --- a/cinderclient/v2/volume_snapshots.py +++ b/cinderclient/v2/volume_snapshots.py @@ -67,7 +67,7 @@ class SnapshotManager(base.ManagerWithFind): resource_class = Snapshot def create(self, volume_id, force=False, - name=None, description=None): + name=None, description=None, metadata=None): """Creates a snapshot of the given volume. @@ -76,12 +76,20 @@ class SnapshotManager(base.ManagerWithFind): attached to an instance. Default is False. :param name: Name of the snapshot :param description: Description of the snapshot + :param metadata: Metadata of the snapshot :rtype: :class:`Snapshot` """ + + if metadata is None: + snapshot_metadata = {} + else: + snapshot_metadata = metadata + body = {'snapshot': {'volume_id': volume_id, 'force': force, 'name': name, - 'description': description}} + 'description': description, + 'metadata': snapshot_metadata}} return self._create('/snapshots', body, 'snapshot') def get(self, snapshot_id):