diff --git a/releasenotes/notes/incremental_backup-c18804d6277adf62.yaml b/releasenotes/notes/incremental_backup-c18804d6277adf62.yaml new file mode 100644 index 00000000..24cc6910 --- /dev/null +++ b/releasenotes/notes/incremental_backup-c18804d6277adf62.yaml @@ -0,0 +1,6 @@ +features: + - The --incremental flag for backup-create will + add the abiility to create incremental backup based + on last full or incremental backup. If no full or + incremental backup exists a new full backup will + be created. diff --git a/troveclient/tests/test_backups.py b/troveclient/tests/test_backups.py index f6401a04..85fb043d 100644 --- a/troveclient/tests/test_backups.py +++ b/troveclient/tests/test_backups.py @@ -55,7 +55,7 @@ class BackupManagerTest(testtools.TestCase): def test_create(self): create_mock = mock.Mock() self.backups._create = create_mock - args = {'name': 'test_backup', 'instance': '1'} + args = {'name': 'test_backup', 'instance': '1', 'incremental': False} body = {'backup': args} self.backups.create(**args) create_mock.assert_called_with('/backups', body, 'backup') @@ -63,7 +63,8 @@ class BackupManagerTest(testtools.TestCase): def test_create_description(self): create_mock = mock.Mock() self.backups._create = create_mock - args = {'name': 'test_backup', 'instance': '1', 'description': 'foo'} + args = {'name': 'test_backup', 'instance': '1', 'description': 'foo', + 'incremental': False} body = {'backup': args} self.backups.create(**args) create_mock.assert_called_with('/backups', body, 'backup') @@ -71,7 +72,8 @@ class BackupManagerTest(testtools.TestCase): def test_create_with_instance_obj(self): create_mock = mock.Mock() self.backups._create = create_mock - args = {'name': 'test_backup', 'instance': self.instance_with_id.id} + args = {'name': 'test_backup', 'instance': self.instance_with_id.id, + 'incremental': False} body = {'backup': args} self.backups.create('test_backup', self.instance_with_id) create_mock.assert_called_with('/backups', body, 'backup') @@ -79,7 +81,16 @@ class BackupManagerTest(testtools.TestCase): def test_create_incremental(self): create_mock = mock.Mock() self.backups._create = create_mock - args = {'name': 'test_backup', 'instance': '1', 'parent_id': 'foo'} + args = {'name': 'test_backup', 'instance': '1', 'parent_id': 'foo', + 'incremental': False} + body = {'backup': args} + self.backups.create(**args) + create_mock.assert_called_with('/backups', body, 'backup') + + def test_create_incremental_2(self): + create_mock = mock.Mock() + self.backups._create = create_mock + args = {'name': 'test_backup', 'instance': '1', 'incremental': True} body = {'backup': args} self.backups.create(**args) create_mock.assert_called_with('/backups', body, 'backup') @@ -88,7 +99,7 @@ class BackupManagerTest(testtools.TestCase): create_mock = mock.Mock() self.backups._create = create_mock args = {'name': 'test_backup', 'instance': 'foo', - 'backup': '1'} + 'backup': '1', 'incremental': False} body = {'backup': args} self.backups.create(**args) create_mock.assert_called_with('/backups', body, 'backup') diff --git a/troveclient/tests/test_v1_shell.py b/troveclient/tests/test_v1_shell.py index fafa2925..660b7890 100644 --- a/troveclient/tests/test_v1_shell.py +++ b/troveclient/tests/test_v1_shell.py @@ -767,7 +767,8 @@ class ShellTest(utils.TestCase): 'POST', '/backups', {'backup': { 'instance': '1234', - 'name': 'bkp_1' + 'name': 'bkp_1', + 'incremental': False }}) def test_backup_copy(self): @@ -776,6 +777,7 @@ class ShellTest(utils.TestCase): 'POST', '/backups', {'backup': { 'name': 'new_bkp', + 'incremental': False, 'backup': {'region': None, 'id': 'bk-1234'} }}) diff --git a/troveclient/v1/backups.py b/troveclient/v1/backups.py index 3062f7ff..d0ac6733 100644 --- a/troveclient/v1/backups.py +++ b/troveclient/v1/backups.py @@ -51,18 +51,21 @@ class Backups(base.ManagerWithFind): query_strings) def create(self, name, instance, description=None, parent_id=None, - backup=None,): + backup=None, incremental=False): """Create a new backup from the given instance. :param name: name for backup. :param instance: instance to backup. :param description: (optional). :param parent_id: base for incremental backup (optional). + :param incremental: flag to indicate incremental backup based on + last backup :returns: :class:`Backups` """ body = { "backup": { - "name": name + "name": name, + "incremental": int(incremental) } } diff --git a/troveclient/v1/shell.py b/troveclient/v1/shell.py index 7741f4be..7df77494 100644 --- a/troveclient/v1/shell.py +++ b/troveclient/v1/shell.py @@ -943,13 +943,18 @@ def do_backup_delete(cs, args): @utils.arg('--parent', metavar='', default=None, help='Optional ID of the parent backup to perform an' ' incremental backup from.') +@utils.arg('--incremental', action='store_true', default=False, + help='Create an incremental backup based on the last' + ' full or incremental backup. It will create a' + ' full backup if no existing backup found.') @utils.service_type('database') def do_backup_create(cs, args): """Creates a backup of an instance.""" instance = _find_instance(cs, args.instance) backup = cs.backups.create(args.name, instance, description=args.description, - parent_id=args.parent) + parent_id=args.parent, + incremental=args.incremental) _print_object(backup)