Ability to pass metadata during snapshot create

Metadata as a parameter is supported by the underlying cinder driver.
This is not exposed by the python client. It is helpful to store additional information
for snapshots and can be used for decision within cinder driver during snapshot creation.
Similar functionality exists for volume creation in cinder client and cinder driver.
Updating cli(shell) to accomodate the new metadata parameter
Adding above change for v2

Change-Id: I002221efea1b9994da4a8d200544a88b0ed26277
Closes-Bug: #1341424
This commit is contained in:
Subhadeep De
2014-05-23 05:03:24 -07:00
parent 4162c9ff5c
commit 4a7014a46e
4 changed files with 42 additions and 3 deletions

View File

@@ -270,6 +270,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'])

View File

@@ -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)

View File

@@ -562,6 +562,12 @@ def do_snapshot_show(cs, args):
help=argparse.SUPPRESS)
@utils.arg('--display_description',
help=argparse.SUPPRESS)
@utils.arg('--metadata',
type=str,
nargs='*',
metavar='<key=value>',
help='Snapshot metadata key and value pairs. Default=None.',
default=None)
@utils.service_type('volumev2')
def do_snapshot_create(cs, args):
"""Creates a snapshot."""
@@ -571,11 +577,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)

View File

@@ -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):