Implement metadata for backup create/update

We have a gap in the micro versions implemented in the cinderclient
and the MAX version being reported by the client.

This patch addresses the missing changes for micro version 3.43
which adds support for metadata for backup create and update.

Change-Id: I14c7205784c53ec3ab0985a4460a88f59de171fb
Partial-Bug: #1715759
This commit is contained in:
j-griffith
2017-09-07 23:51:37 +00:00
committed by John Griffith
parent f447b07490
commit 2255fc99da
3 changed files with 115 additions and 2 deletions

View File

@@ -990,3 +990,11 @@ class ShellTest(utils.TestCase):
self.assertEqual([mock.call(poll_period)] * 2,
mock_time.sleep.call_args_list)
self.assertEqual([mock.call(some_id)] * 2, poll_fn.call_args_list)
def test_backup_with_metadata(self):
cmd = '--os-volume-api-version 3.43 '
cmd += 'backup-create '
cmd += '--metadata foo=bar '
cmd += '1234'
self.run_command(cmd)
self.assert_called('POST', '/backups')

View File

@@ -858,13 +858,19 @@ def do_upload_to_image(cs, args):
args.disk_format))
@api_versions.wraps('3.9')
@api_versions.wraps('3.9', '3.43')
@utils.arg('backup', metavar='<backup>',
help='Name or ID of backup to rename.')
@utils.arg('--name', nargs='?', metavar='<name>',
help='New name for backup.')
@utils.arg('--description', metavar='<description>',
help='Backup description. Default=None.')
@utils.arg('--metadata',
nargs='*',
metavar='<key=value>',
default=None,
help='Metadata key and value pairs. Default=None.',
start_version='3.43')
def do_backup_update(cs, args):
"""Renames a backup."""
kwargs = {}
@@ -875,6 +881,10 @@ def do_backup_update(cs, args):
if args.description is not None:
kwargs['description'] = args.description
if cs.api_version >= api_versions.APIVersion("3.43"):
if args.metadata is not None:
kwargs['metadata'] = args.metadata
if not kwargs:
msg = 'Must supply either name or description.'
raise exceptions.ClientException(code=1, message=msg)
@@ -2005,3 +2015,68 @@ def do_service_get_log(cs, args):
args.prefix)
columns = ('Binary', 'Host', 'Prefix', 'Level')
utils.print_list(log_levels, columns)
@api_versions.wraps('3.43')
@utils.arg('volume', metavar='<volume>',
help='Name or ID of volume to backup.')
@utils.arg('--container', metavar='<container>',
default=None,
help='Backup container name. Default=None.')
@utils.arg('--display-name',
help=argparse.SUPPRESS)
@utils.arg('--name', metavar='<name>',
default=None,
help='Backup name. Default=None.')
@utils.arg('--display-description',
help=argparse.SUPPRESS)
@utils.arg('--description',
metavar='<description>',
default=None,
help='Backup description. Default=None.')
@utils.arg('--incremental',
action='store_true',
help='Incremental backup. Default=False.',
default=False)
@utils.arg('--force',
action='store_true',
help='Allows or disallows backup of a volume '
'when the volume is attached to an instance. '
'If set to True, backs up the volume whether '
'its status is "available" or "in-use". The backup '
'of an "in-use" volume means your data is crash '
'consistent. Default=False.',
default=False)
@utils.arg('--snapshot-id',
metavar='<snapshot-id>',
default=None,
help='ID of snapshot to backup. Default=None.')
@utils.arg('--metadata',
nargs='*',
metavar='<key=value>',
default=None,
help='Metadata key and value pairs. Default=None.')
def do_backup_create(cs, args):
"""Creates a volume backup."""
if args.display_name is not None:
args.name = args.display_name
if args.display_description is not None:
args.description = args.display_description
volume = utils.find_volume(cs, args.volume)
backup = cs.backups.create(volume.id,
args.container,
args.name,
args.description,
args.incremental,
args.force,
args.snapshot_id,
args.metadata)
info = {"volume_id": volume.id}
info.update(backup._info)
if 'links' in info:
info.pop('links')
utils.print_dict(info)

View File

@@ -26,15 +26,45 @@ VolumeBackup = volume_backups.VolumeBackup
class VolumeBackupManager(volume_backups.VolumeBackupManager):
@api_versions.wraps("3.9")
@api_versions.wraps("3.9", "3.43")
def update(self, backup, **kwargs):
"""Update the name or description for a backup.
:param backup: The :class:`Backup` to update.
"""
# NOTE(jdg): Placing 3.43 in versions.wraps above for clarity,
# but it's irrelevant as this just uses the kwargs, should we
# remove that?
if not kwargs:
return
body = {"backup": kwargs}
return self._update("/backups/%s" % base.getid(backup), body)
@api_versions.wraps("3.43")
def create(self, volume_id, container=None,
name=None, description=None,
incremental=False, force=False,
snapshot_id=None,
metadata=None):
"""Creates a volume backup.
:param volume_id: The ID of the volume to backup.
:param container: The name of the backup service container.
:param name: The name of the backup.
:param description: The description of the backup.
:param incremental: Incremental backup.
:param force: If True, allows an in-use volume to be backed up.
:param metadata: Key Value pairs
:rtype: :class:`VolumeBackup`
"""
body = {'backup': {'volume_id': volume_id,
'container': container,
'name': name,
'description': description,
'incremental': incremental,
'force': force,
'snapshot_id': snapshot_id,
'metadata': metadata, }}
return self._create('/backups', body, 'backup')