Merge "Support cross AZ backups"
This commit is contained in:
@@ -1107,6 +1107,19 @@ class ShellTest(utils.TestCase):
|
||||
'metadata': {'foo': 'bar'}, }}
|
||||
self.assert_called('POST', '/backups', body=expected)
|
||||
|
||||
def test_backup_with_az(self):
|
||||
self.run_command('--os-volume-api-version 3.51 backup-create '
|
||||
'--availability-zone AZ2 --name 1234 1234')
|
||||
expected = {'backup': {'volume_id': 1234,
|
||||
'container': None,
|
||||
'name': '1234',
|
||||
'description': None,
|
||||
'incremental': False,
|
||||
'force': False,
|
||||
'snapshot_id': None,
|
||||
'availability_zone': 'AZ2'}}
|
||||
self.assert_called('POST', '/backups', body=expected)
|
||||
|
||||
@mock.patch("cinderclient.utils.print_list")
|
||||
def test_snapshot_list_with_userid(self, mock_print_list):
|
||||
"""Ensure 3.41 provides User ID header."""
|
||||
|
@@ -2332,6 +2332,11 @@ def do_service_get_log(cs, args):
|
||||
default=None,
|
||||
start_version='3.43',
|
||||
help='Metadata key and value pairs. Default=None.')
|
||||
@utils.arg('--availability-zone',
|
||||
default=None,
|
||||
start_version='3.51',
|
||||
help='AZ where the backup should be stored, by default it will be '
|
||||
'the same as the source.')
|
||||
def do_backup_create(cs, args):
|
||||
"""Creates a volume backup."""
|
||||
if args.display_name is not None:
|
||||
@@ -2340,25 +2345,22 @@ def do_backup_create(cs, args):
|
||||
if args.display_description is not None:
|
||||
args.description = args.display_description
|
||||
|
||||
volume = utils.find_volume(cs, args.volume)
|
||||
if hasattr(args, 'metadata') and args.metadata:
|
||||
backup = cs.backups.create(volume.id,
|
||||
args.container,
|
||||
args.name,
|
||||
args.description,
|
||||
args.incremental,
|
||||
args.force,
|
||||
args.snapshot_id,
|
||||
shell_utils.extract_metadata(args))
|
||||
else:
|
||||
backup = cs.backups.create(volume.id,
|
||||
args.container,
|
||||
args.name,
|
||||
args.description,
|
||||
args.incremental,
|
||||
args.force,
|
||||
args.snapshot_id)
|
||||
kwargs = {}
|
||||
if getattr(args, 'metadata', None):
|
||||
kwargs['metadata'] = shell_utils.extract_metadata(args)
|
||||
az = getattr(args, 'availability_zone', None)
|
||||
if az:
|
||||
kwargs['availability_zone'] = az
|
||||
|
||||
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,
|
||||
**kwargs)
|
||||
info = {"volume_id": volume.id}
|
||||
info.update(backup._info)
|
||||
|
||||
|
@@ -57,14 +57,8 @@ class VolumeBackupManager(volume_backups.VolumeBackupManager):
|
||||
the new backup will be based on the snapshot.
|
||||
:rtype: :class:`VolumeBackup`
|
||||
"""
|
||||
body = {'backup': {'volume_id': volume_id,
|
||||
'container': container,
|
||||
'name': name,
|
||||
'description': description,
|
||||
'incremental': incremental,
|
||||
'force': force,
|
||||
'snapshot_id': snapshot_id, }}
|
||||
return self._create('/backups', body, 'backup')
|
||||
return self._create_backup(volume_id, container, name, description,
|
||||
incremental, force, snapshot_id)
|
||||
|
||||
@api_versions.wraps("3.43") # noqa: F811
|
||||
def create(self, volume_id, container=None,
|
||||
@@ -87,12 +81,46 @@ class VolumeBackupManager(volume_backups.VolumeBackupManager):
|
||||
:rtype: :class:`VolumeBackup`
|
||||
"""
|
||||
# pylint: disable=function-redefined
|
||||
return self._create_backup(volume_id, container, name, description,
|
||||
incremental, force, snapshot_id, metadata)
|
||||
|
||||
@api_versions.wraps("3.51") # noqa: F811
|
||||
def create(self, volume_id, container=None, name=None, description=None,
|
||||
incremental=False, force=False, snapshot_id=None, metadata=None,
|
||||
availability_zone=None):
|
||||
return self._create_backup(volume_id, container, name, description,
|
||||
incremental, force, snapshot_id, metadata,
|
||||
availability_zone)
|
||||
|
||||
def _create_backup(self, volume_id, container=None, name=None,
|
||||
description=None, incremental=False, force=False,
|
||||
snapshot_id=None, metadata=None,
|
||||
availability_zone=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
|
||||
:param snapshot_id: The ID of the snapshot to backup. This should
|
||||
be a snapshot of the src volume, when specified,
|
||||
the new backup will be based on the snapshot.
|
||||
:param availability_zone: The AZ where we want the backup stored.
|
||||
:rtype: :class:`VolumeBackup`
|
||||
"""
|
||||
# pylint: disable=function-redefined
|
||||
body = {'backup': {'volume_id': volume_id,
|
||||
'container': container,
|
||||
'name': name,
|
||||
'description': description,
|
||||
'incremental': incremental,
|
||||
'force': force,
|
||||
'snapshot_id': snapshot_id,
|
||||
'metadata': metadata, }}
|
||||
'snapshot_id': snapshot_id, }}
|
||||
if metadata:
|
||||
body['backup']['metadata'] = metadata
|
||||
if availability_zone:
|
||||
body['backup']['availability_zone'] = availability_zone
|
||||
return self._create('/backups', body, 'backup')
|
||||
|
@@ -0,0 +1,5 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Support cross AZ backup creation specifying desired backup service AZ
|
||||
(added in microversion v3.51)
|
Reference in New Issue
Block a user