summaryrefslogtreecommitdiff
path: root/openstackclient/volume/v2/volume_backup.py
diff options
context:
space:
mode:
authorSean McGinnis <sean.mcginnis@gmail.com>2018-10-23 11:34:07 -0500
committerDean Troyer <dtroyer@gmail.com>2019-05-20 14:05:18 -0500
commite76e10c0bac9cf87c564a7f0201df189f7cd8b52 (patch)
tree08ef97c0f31040490fe0dac26e569cf16903a83c /openstackclient/volume/v2/volume_backup.py
parent5a0fc68a87d1c9733c1dd5bb6f68b2e518fe2105 (diff)
downloadpython-openstackclient-e76e10c0bac9cf87c564a7f0201df189f7cd8b52.tar.gz
Remove deprecated volume commands and args
The following were deprecated over two years ago and can now be removed: * Remove ``backup`` commands in favor of ``volume backup`` * Remove ``snapshot`` commands in favor of ``volume snapshot`` * Remove ``volume create`` options ``--project``, ``--user`` and ``--multi-attach`` * Use of an auth-key positional argument in volume transfers * ``volume transfer request`` no longer accepts 'auth_key' as a positional arg, ``--auth-key`` is now required Internal (non-user-visible) * Rename backup.py to volume_backup.py for Volume v1 and v2, update tests These are backwards incompatible changes and will require a major version bump after they are merged. Change-Id: I94aa7a9824e44f9585ffb45e5e7637b9588539b4 Signed-off-by: Sean McGinnis <sean.mcginnis@gmail.com> Signed-off-by: Dean Troyer <dtroyer@gmail.com>
Diffstat (limited to 'openstackclient/volume/v2/volume_backup.py')
-rw-r--r--openstackclient/volume/v2/volume_backup.py355
1 files changed, 355 insertions, 0 deletions
diff --git a/openstackclient/volume/v2/volume_backup.py b/openstackclient/volume/v2/volume_backup.py
new file mode 100644
index 00000000..1d2b0cde
--- /dev/null
+++ b/openstackclient/volume/v2/volume_backup.py
@@ -0,0 +1,355 @@
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+
+"""Volume v2 Backup action implementations"""
+
+import copy
+import logging
+
+from osc_lib.cli import parseractions
+from osc_lib.command import command
+from osc_lib import exceptions
+from osc_lib import utils
+import six
+
+from openstackclient.i18n import _
+
+
+LOG = logging.getLogger(__name__)
+
+
+class CreateVolumeBackup(command.ShowOne):
+ _description = _("Create new volume backup")
+
+ def get_parser(self, prog_name):
+ parser = super(CreateVolumeBackup, self).get_parser(prog_name)
+ parser.add_argument(
+ "volume",
+ metavar="<volume>",
+ help=_("Volume to backup (name or ID)")
+ )
+ parser.add_argument(
+ "--name",
+ metavar="<name>",
+ help=_("Name of the backup")
+ )
+ parser.add_argument(
+ "--description",
+ metavar="<description>",
+ help=_("Description of the backup")
+ )
+ parser.add_argument(
+ "--container",
+ metavar="<container>",
+ help=_("Optional backup container name")
+ )
+ parser.add_argument(
+ "--snapshot",
+ metavar="<snapshot>",
+ help=_("Snapshot to backup (name or ID)")
+ )
+ parser.add_argument(
+ '--force',
+ action='store_true',
+ default=False,
+ help=_("Allow to back up an in-use volume")
+ )
+ parser.add_argument(
+ '--incremental',
+ action='store_true',
+ default=False,
+ help=_("Perform an incremental backup")
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ volume_client = self.app.client_manager.volume
+ volume_id = utils.find_resource(
+ volume_client.volumes, parsed_args.volume).id
+ snapshot_id = None
+ if parsed_args.snapshot:
+ snapshot_id = utils.find_resource(
+ volume_client.volume_snapshots, parsed_args.snapshot).id
+ backup = volume_client.backups.create(
+ volume_id,
+ container=parsed_args.container,
+ name=parsed_args.name,
+ description=parsed_args.description,
+ force=parsed_args.force,
+ incremental=parsed_args.incremental,
+ snapshot_id=snapshot_id,
+ )
+ backup._info.pop("links", None)
+ return zip(*sorted(six.iteritems(backup._info)))
+
+
+class DeleteVolumeBackup(command.Command):
+ _description = _("Delete volume backup(s)")
+
+ def get_parser(self, prog_name):
+ parser = super(DeleteVolumeBackup, self).get_parser(prog_name)
+ parser.add_argument(
+ "backups",
+ metavar="<backup>",
+ nargs="+",
+ help=_("Backup(s) to delete (name or ID)")
+ )
+ parser.add_argument(
+ '--force',
+ action='store_true',
+ default=False,
+ help=_("Allow delete in state other than error or available")
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ volume_client = self.app.client_manager.volume
+ result = 0
+
+ for i in parsed_args.backups:
+ try:
+ backup_id = utils.find_resource(
+ volume_client.backups, i).id
+ volume_client.backups.delete(backup_id, parsed_args.force)
+ except Exception as e:
+ result += 1
+ LOG.error(_("Failed to delete backup with "
+ "name or ID '%(backup)s': %(e)s")
+ % {'backup': i, 'e': e})
+
+ if result > 0:
+ total = len(parsed_args.backups)
+ msg = (_("%(result)s of %(total)s backups failed "
+ "to delete.") % {'result': result, 'total': total})
+ raise exceptions.CommandError(msg)
+
+
+class ListVolumeBackup(command.Lister):
+ _description = _("List volume backups")
+
+ def get_parser(self, prog_name):
+ parser = super(ListVolumeBackup, self).get_parser(prog_name)
+ parser.add_argument(
+ "--long",
+ action="store_true",
+ default=False,
+ help=_("List additional fields in output")
+ )
+ parser.add_argument(
+ "--name",
+ metavar="<name>",
+ help=_("Filters results by the backup name")
+ )
+ parser.add_argument(
+ "--status",
+ metavar="<status>",
+ choices=['creating', 'available', 'deleting',
+ 'error', 'restoring', 'error_restoring'],
+ help=_("Filters results by the backup status "
+ "('creating', 'available', 'deleting', "
+ "'error', 'restoring' or 'error_restoring')")
+ )
+ parser.add_argument(
+ "--volume",
+ metavar="<volume>",
+ help=_("Filters results by the volume which they "
+ "backup (name or ID)")
+ )
+ parser.add_argument(
+ '--marker',
+ metavar='<volume-backup>',
+ help=_('The last backup of the previous page (name or ID)'),
+ )
+ parser.add_argument(
+ '--limit',
+ type=int,
+ action=parseractions.NonNegativeAction,
+ metavar='<num-backups>',
+ help=_('Maximum number of backups to display'),
+ )
+ parser.add_argument(
+ '--all-projects',
+ action='store_true',
+ default=False,
+ help=_('Include all projects (admin only)'),
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ volume_client = self.app.client_manager.volume
+
+ def _format_volume_id(volume_id):
+ """Return a volume name if available
+
+ :param volume_id: a volume ID
+ :rtype: either the volume ID or name
+ """
+
+ volume = volume_id
+ if volume_id in volume_cache.keys():
+ volume = volume_cache[volume_id].name
+ return volume
+
+ if parsed_args.long:
+ columns = ['ID', 'Name', 'Description', 'Status', 'Size',
+ 'Availability Zone', 'Volume ID', 'Container']
+ column_headers = copy.deepcopy(columns)
+ column_headers[6] = 'Volume'
+ else:
+ columns = ['ID', 'Name', 'Description', 'Status', 'Size']
+ column_headers = columns
+
+ # Cache the volume list
+ volume_cache = {}
+ try:
+ for s in volume_client.volumes.list():
+ volume_cache[s.id] = s
+ except Exception:
+ # Just forget it if there's any trouble
+ pass
+
+ filter_volume_id = None
+ if parsed_args.volume:
+ filter_volume_id = utils.find_resource(volume_client.volumes,
+ parsed_args.volume).id
+ marker_backup_id = None
+ if parsed_args.marker:
+ marker_backup_id = utils.find_resource(volume_client.backups,
+ parsed_args.marker).id
+ search_opts = {
+ 'name': parsed_args.name,
+ 'status': parsed_args.status,
+ 'volume_id': filter_volume_id,
+ 'all_tenants': parsed_args.all_projects,
+ }
+ data = volume_client.backups.list(
+ search_opts=search_opts,
+ marker=marker_backup_id,
+ limit=parsed_args.limit,
+ )
+
+ return (column_headers,
+ (utils.get_item_properties(
+ s, columns,
+ formatters={'Volume ID': _format_volume_id},
+ ) for s in data))
+
+
+class RestoreVolumeBackup(command.ShowOne):
+ _description = _("Restore volume backup")
+
+ def get_parser(self, prog_name):
+ parser = super(RestoreVolumeBackup, self).get_parser(prog_name)
+ parser.add_argument(
+ "backup",
+ metavar="<backup>",
+ help=_("Backup to restore (name or ID)")
+ )
+ parser.add_argument(
+ "volume",
+ metavar="<volume>",
+ help=_("Volume to restore to (name or ID)")
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ volume_client = self.app.client_manager.volume
+ backup = utils.find_resource(volume_client.backups, parsed_args.backup)
+ destination_volume = utils.find_resource(volume_client.volumes,
+ parsed_args.volume)
+ backup = volume_client.restores.restore(backup.id,
+ destination_volume.id)
+ return zip(*sorted(six.iteritems(backup._info)))
+
+
+class SetVolumeBackup(command.Command):
+ _description = _("Set volume backup properties")
+
+ def get_parser(self, prog_name):
+ parser = super(SetVolumeBackup, self).get_parser(prog_name)
+ parser.add_argument(
+ "backup",
+ metavar="<backup>",
+ help=_("Backup to modify (name or ID)")
+ )
+ parser.add_argument(
+ '--name',
+ metavar='<name>',
+ help=_('New backup name')
+ )
+ parser.add_argument(
+ '--description',
+ metavar='<description>',
+ help=_('New backup description')
+ )
+ parser.add_argument(
+ '--state',
+ metavar='<state>',
+ choices=['available', 'error'],
+ help=_('New backup state ("available" or "error") (admin only) '
+ '(This option simply changes the state of the backup '
+ 'in the database with no regard to actual status, '
+ 'exercise caution when using)'),
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ volume_client = self.app.client_manager.volume
+ backup = utils.find_resource(volume_client.backups,
+ parsed_args.backup)
+ result = 0
+ if parsed_args.state:
+ try:
+ volume_client.backups.reset_state(
+ backup.id, parsed_args.state)
+ except Exception as e:
+ LOG.error(_("Failed to set backup state: %s"), e)
+ result += 1
+
+ kwargs = {}
+ if parsed_args.name:
+ kwargs['name'] = parsed_args.name
+ if parsed_args.description:
+ kwargs['description'] = parsed_args.description
+ if kwargs:
+ try:
+ volume_client.backups.update(backup.id, **kwargs)
+ except Exception as e:
+ LOG.error(_("Failed to update backup name "
+ "or description: %s"), e)
+ result += 1
+
+ if result > 0:
+ raise exceptions.CommandError(_("One or more of the "
+ "set operations failed"))
+
+
+class ShowVolumeBackup(command.ShowOne):
+ _description = _("Display volume backup details")
+
+ def get_parser(self, prog_name):
+ parser = super(ShowVolumeBackup, self).get_parser(prog_name)
+ parser.add_argument(
+ "backup",
+ metavar="<backup>",
+ help=_("Backup to display (name or ID)")
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ volume_client = self.app.client_manager.volume
+ backup = utils.find_resource(volume_client.backups,
+ parsed_args.backup)
+ backup._info.pop("links", None)
+ return zip(*sorted(six.iteritems(backup._info)))