7a15a2a1ae
Added support for display count info in share snapshot list and detail APIs: 1. /v2/snapshots?with_count=True 2. /v2/snapshots/detail?with_count=True Microversion upgraded to 2.79 Related-Bug: #2024556 Depends-On: I37d8ca9022e2ea2c107c6695e20e951d7950043a Change-Id: I230c2195c414eec28ebc5e5e9714726731307a95
886 lines
30 KiB
Python
886 lines
30 KiB
Python
# 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.
|
|
|
|
import logging
|
|
|
|
from osc_lib.cli import format_columns
|
|
from osc_lib.cli import parseractions
|
|
from osc_lib.command import command
|
|
from osc_lib import exceptions
|
|
from osc_lib import utils
|
|
|
|
from manilaclient import api_versions
|
|
from manilaclient.common._i18n import _
|
|
from manilaclient.common import cliutils
|
|
from manilaclient.osc import utils as oscutils
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
class CreateShareSnapshot(command.ShowOne):
|
|
"""Create a share snapshot."""
|
|
_description = _(
|
|
"Create a snapshot of the given share")
|
|
|
|
def get_parser(self, prog_name):
|
|
parser = super(CreateShareSnapshot, self).get_parser(prog_name)
|
|
parser.add_argument(
|
|
"share",
|
|
metavar="<share>",
|
|
help=_("Name or ID of the share to create snapshot of")
|
|
)
|
|
parser.add_argument(
|
|
"--force",
|
|
action='store_true',
|
|
default=False,
|
|
help=_("Optional flag to indicate whether to snapshot "
|
|
"a share even if it's busy. (Default=False)")
|
|
)
|
|
parser.add_argument(
|
|
"--name",
|
|
metavar="<name>",
|
|
default=None,
|
|
help=_("Add a name to the snapshot (Optional).")
|
|
)
|
|
parser.add_argument(
|
|
"--description",
|
|
metavar="<description>",
|
|
default=None,
|
|
help=_("Add a description to the snapshot (Optional).")
|
|
)
|
|
parser.add_argument(
|
|
'--wait',
|
|
action='store_true',
|
|
default=False,
|
|
help=_('Wait for share snapshot creation')
|
|
)
|
|
parser.add_argument(
|
|
"--property",
|
|
metavar="<key=value>",
|
|
default={},
|
|
action=parseractions.KeyValueAction,
|
|
help=_("Set a property to this snapshot "
|
|
"(repeat option to set multiple properties)."
|
|
"Available only for microversion >= 2.73"),
|
|
)
|
|
return parser
|
|
|
|
def take_action(self, parsed_args):
|
|
share_client = self.app.client_manager.share
|
|
|
|
share = utils.find_resource(share_client.shares,
|
|
parsed_args.share)
|
|
|
|
if share_client.api_version >= api_versions.APIVersion("2.73"):
|
|
property = parsed_args.property or {}
|
|
elif parsed_args.property:
|
|
raise exceptions.CommandError(
|
|
"Setting metadtaa is only available with manila API version "
|
|
">= 2.73")
|
|
|
|
share_snapshot = share_client.share_snapshots.create(
|
|
share=share,
|
|
force=parsed_args.force,
|
|
name=parsed_args.name or None,
|
|
description=parsed_args.description or None,
|
|
metadata=property
|
|
)
|
|
if parsed_args.wait:
|
|
if not utils.wait_for_status(
|
|
status_f=share_client.share_snapshots.get,
|
|
res_id=share_snapshot.id,
|
|
success_status=['available']
|
|
):
|
|
LOG.error(_("ERROR: Share snapshot is in error state."))
|
|
|
|
share_snapshot = utils.find_resource(
|
|
share_client.share_snapshots,
|
|
share_snapshot.id)
|
|
share_snapshot._info.pop('links', None)
|
|
|
|
return self.dict2columns(share_snapshot._info)
|
|
|
|
|
|
class DeleteShareSnapshot(command.Command):
|
|
"""Delete one or more share snapshots"""
|
|
_description = _(
|
|
"Delete one or more share snapshots")
|
|
|
|
def get_parser(self, prog_name):
|
|
parser = super(DeleteShareSnapshot, self).get_parser(prog_name)
|
|
parser.add_argument(
|
|
"snapshot",
|
|
metavar="<snapshot>",
|
|
nargs="+",
|
|
help=_("Name or ID of the snapshot(s) to delete")
|
|
)
|
|
parser.add_argument(
|
|
"--force",
|
|
action='store_true',
|
|
default=False,
|
|
help=_("Delete the snapshot(s) ignoring the current state.")
|
|
)
|
|
parser.add_argument(
|
|
"--wait",
|
|
action='store_true',
|
|
default=False,
|
|
help=_("Wait for share snapshot deletion")
|
|
)
|
|
return parser
|
|
|
|
def take_action(self, parsed_args):
|
|
share_client = self.app.client_manager.share
|
|
result = 0
|
|
|
|
for snapshot in parsed_args.snapshot:
|
|
try:
|
|
snapshot_obj = utils.find_resource(
|
|
share_client.share_snapshots,
|
|
snapshot)
|
|
if parsed_args.force:
|
|
share_client.share_snapshots.force_delete(
|
|
snapshot_obj)
|
|
else:
|
|
share_client.share_snapshots.delete(
|
|
snapshot_obj)
|
|
if parsed_args.wait:
|
|
if not utils.wait_for_delete(
|
|
manager=share_client.share_snapshots,
|
|
res_id=snapshot_obj.id):
|
|
result += 1
|
|
except Exception as e:
|
|
result += 1
|
|
LOG.error(_(
|
|
"Failed to delete snapshot with "
|
|
"name or ID '%(snapshot)s': %(e)s"),
|
|
{'snapshot': snapshot, 'e': e})
|
|
|
|
if result > 0:
|
|
total = len(parsed_args.snapshot)
|
|
msg = (_("%(result)s of %(total)s snapshots failed "
|
|
"to delete.") % {'result': result, 'total': total})
|
|
raise exceptions.CommandError(msg)
|
|
|
|
|
|
class ShowShareSnapshot(command.ShowOne):
|
|
"""Display a share snapshot"""
|
|
_description = _(
|
|
"Show details about a share snapshot")
|
|
|
|
def get_parser(self, prog_name):
|
|
parser = super(ShowShareSnapshot, self).get_parser(prog_name)
|
|
parser.add_argument(
|
|
"snapshot",
|
|
metavar="<snapshot>",
|
|
help=_("Name or ID of the snapshot to display")
|
|
)
|
|
return parser
|
|
|
|
def take_action(self, parsed_args):
|
|
share_client = self.app.client_manager.share
|
|
|
|
share_snapshot = utils.find_resource(
|
|
share_client.share_snapshots,
|
|
parsed_args.snapshot)
|
|
|
|
export_locations = (
|
|
share_client.share_snapshot_export_locations.list(
|
|
share_snapshot))
|
|
|
|
locations = []
|
|
for location in export_locations:
|
|
location._info.pop('links', None)
|
|
locations.append(location._info)
|
|
|
|
if parsed_args.formatter == 'table':
|
|
locations = cliutils.convert_dict_list_to_string(
|
|
locations)
|
|
|
|
data = share_snapshot._info
|
|
data['export_locations'] = locations
|
|
# Special mapping for columns to make the output easier to read:
|
|
# 'metadata' --> 'properties'
|
|
data.update(
|
|
{
|
|
'properties':
|
|
format_columns.DictColumn(data.pop('metadata', {})),
|
|
},
|
|
)
|
|
data.pop('links', None)
|
|
|
|
return self.dict2columns(data)
|
|
|
|
|
|
class SetShareSnapshot(command.Command):
|
|
"""Set share snapshot properties."""
|
|
_description = _("Set share snapshot properties")
|
|
|
|
def get_parser(self, prog_name):
|
|
parser = super(SetShareSnapshot, self).get_parser(prog_name)
|
|
parser.add_argument(
|
|
"snapshot",
|
|
metavar="<snapshot>",
|
|
help=_('Name or ID of the snapshot to set a property for')
|
|
)
|
|
parser.add_argument(
|
|
"--name",
|
|
metavar="<name>",
|
|
default=None,
|
|
help=_("Set a name to the snapshot.")
|
|
)
|
|
parser.add_argument(
|
|
"--description",
|
|
metavar="<description>",
|
|
default=None,
|
|
help=_("Set a description to the snapshot.")
|
|
)
|
|
parser.add_argument(
|
|
"--status",
|
|
metavar="<status>",
|
|
choices=['available', 'error', 'creating', 'deleting',
|
|
'manage_starting', 'manage_error',
|
|
'unmanage_starting', 'unmanage_error',
|
|
'error_deleting'],
|
|
help=_("Assign a status to the snapshot (Admin only). "
|
|
"Options include : available, error, creating, "
|
|
"deleting, manage_starting, manage_error, "
|
|
"unmanage_starting, unmanage_error, error_deleting.")
|
|
)
|
|
parser.add_argument(
|
|
"--property",
|
|
metavar="<key=value>",
|
|
default={},
|
|
action=parseractions.KeyValueAction,
|
|
help=_("Set a property to this snapshot "
|
|
"(repeat option to set multiple properties)"),
|
|
)
|
|
return parser
|
|
|
|
def take_action(self, parsed_args):
|
|
share_client = self.app.client_manager.share
|
|
result = 0
|
|
|
|
share_snapshot = utils.find_resource(
|
|
share_client.share_snapshots,
|
|
parsed_args.snapshot)
|
|
|
|
kwargs = {}
|
|
|
|
if parsed_args.name is not None:
|
|
kwargs['display_name'] = parsed_args.name
|
|
if parsed_args.description is not None:
|
|
kwargs['display_description'] = parsed_args.description
|
|
|
|
try:
|
|
share_client.share_snapshots.update(
|
|
share_snapshot,
|
|
**kwargs
|
|
)
|
|
except Exception as e:
|
|
result += 1
|
|
LOG.error(_(
|
|
"Failed to set share snapshot properties "
|
|
"'%(properties)s': %(exception)s"),
|
|
{'properties': kwargs,
|
|
'exception': e})
|
|
|
|
if parsed_args.status:
|
|
try:
|
|
share_client.share_snapshots.reset_state(
|
|
share_snapshot,
|
|
parsed_args.status
|
|
)
|
|
except Exception as e:
|
|
result += 1
|
|
LOG.error(_(
|
|
"Failed to update snapshot status to "
|
|
"'%(status)s': %(e)s"),
|
|
{'status': parsed_args.status, 'e': e})
|
|
if parsed_args.property:
|
|
try:
|
|
share_snapshot.set_metadata(parsed_args.property)
|
|
except Exception as e:
|
|
LOG.error(_("Failed to set share snapshot properties "
|
|
"'%(properties)s': %(exception)s"),
|
|
{'properties': parsed_args.property,
|
|
'exception': e})
|
|
result += 1
|
|
if result > 0:
|
|
raise exceptions.CommandError(_("One or more of the "
|
|
"set operations failed"))
|
|
|
|
|
|
class UnsetShareSnapshot(command.Command):
|
|
"""Unset a share snapshot property."""
|
|
_description = _("Unset a share snapshot property")
|
|
|
|
def get_parser(self, prog_name):
|
|
parser = super(UnsetShareSnapshot, self).get_parser(prog_name)
|
|
parser.add_argument(
|
|
"snapshot",
|
|
metavar="<snapshot>",
|
|
help=_("Name or ID of the snapshot to set a property for")
|
|
)
|
|
parser.add_argument(
|
|
"--name",
|
|
action='store_true',
|
|
help=_("Unset snapshot name."),
|
|
)
|
|
parser.add_argument(
|
|
"--description",
|
|
action='store_true',
|
|
help=_("Unset snapshot description."),
|
|
)
|
|
parser.add_argument(
|
|
'--property',
|
|
metavar='<key>',
|
|
action='append',
|
|
help=_('Remove a property from snapshot '
|
|
'(repeat option to remove multiple properties)'),
|
|
)
|
|
return parser
|
|
|
|
def take_action(self, parsed_args):
|
|
share_client = self.app.client_manager.share
|
|
|
|
share_snapshot = utils.find_resource(
|
|
share_client.share_snapshots,
|
|
parsed_args.snapshot)
|
|
|
|
kwargs = {}
|
|
if parsed_args.name:
|
|
kwargs['display_name'] = None
|
|
if parsed_args.description:
|
|
kwargs['display_description'] = None
|
|
if kwargs:
|
|
try:
|
|
share_client.share_snapshots.update(
|
|
share_snapshot,
|
|
**kwargs
|
|
)
|
|
except Exception as e:
|
|
raise exceptions.CommandError(_(
|
|
"Failed to unset snapshot display name "
|
|
"or display description : %s" % e))
|
|
if parsed_args.property:
|
|
for key in parsed_args.property:
|
|
try:
|
|
share_snapshot.delete_metadata([key])
|
|
except Exception as e:
|
|
raise exceptions.CommandError(_(
|
|
"Failed to unset snapshot property "
|
|
"'%(key)s': %(e)s"),
|
|
{'key': key, 'e': e})
|
|
|
|
|
|
class ListShareSnapshot(command.Lister):
|
|
"""List snapshots."""
|
|
_description = _("List snapshots")
|
|
|
|
def get_parser(self, prog_name):
|
|
parser = super(ListShareSnapshot, self).get_parser(prog_name)
|
|
parser.add_argument(
|
|
"--all-projects",
|
|
action='store_true',
|
|
default=False,
|
|
help=_("Display snapshots from all projects (Admin only).")
|
|
)
|
|
parser.add_argument(
|
|
"--name",
|
|
metavar="<name>",
|
|
default=None,
|
|
help=_("Filter results by name.")
|
|
)
|
|
parser.add_argument(
|
|
'--description',
|
|
metavar="<description>",
|
|
default=None,
|
|
help=_("Filter results by description. Available only for "
|
|
"microversion >= 2.36.")
|
|
)
|
|
parser.add_argument(
|
|
'--status',
|
|
metavar="<status>",
|
|
default=None,
|
|
help=_('Filter results by status')
|
|
)
|
|
parser.add_argument(
|
|
'--share',
|
|
metavar='<share>',
|
|
default=None,
|
|
help=_('Name or ID of a share to filter results by.')
|
|
)
|
|
parser.add_argument(
|
|
'--usage',
|
|
metavar='<usage>',
|
|
default=None,
|
|
choices=['used', 'unused'],
|
|
help=_("Option to filter snapshots by usage.")
|
|
)
|
|
parser.add_argument(
|
|
"--limit",
|
|
metavar="<num-snapshots>",
|
|
type=int,
|
|
default=None,
|
|
action=parseractions.NonNegativeAction,
|
|
help=_("Limit the number of snapshots returned")
|
|
)
|
|
parser.add_argument(
|
|
"--marker",
|
|
metavar="<snapshot>",
|
|
help=_("The last share ID of the previous page")
|
|
)
|
|
parser.add_argument(
|
|
'--sort',
|
|
metavar="<key>[:<direction>]",
|
|
default='name:asc',
|
|
help=_("Sort output by selected keys and directions(asc or desc) "
|
|
"(default: name:asc), multiple keys and directions can be "
|
|
"specified separated by comma")
|
|
)
|
|
parser.add_argument(
|
|
"--name~",
|
|
metavar="<name~>",
|
|
default=None,
|
|
help=_("Filter results matching a share snapshot name pattern. "
|
|
"Available only for microversion >= 2.36.")
|
|
)
|
|
parser.add_argument(
|
|
'--description~',
|
|
metavar="<description~>",
|
|
default=None,
|
|
help=_("Filter results matching a share snapshot description "
|
|
"pattern. Available only for microversion >= 2.36.")
|
|
)
|
|
parser.add_argument(
|
|
'--detail',
|
|
action='store_true',
|
|
default=False,
|
|
help=_("List share snapshots with details")
|
|
)
|
|
parser.add_argument(
|
|
'--property',
|
|
metavar='<key=value>',
|
|
action=parseractions.KeyValueAction,
|
|
help=_('Filter snapshots having a given metadata key=value '
|
|
'property. (repeat option to filter by multiple '
|
|
'properties)'),
|
|
)
|
|
parser.add_argument(
|
|
'--count',
|
|
action='store_true',
|
|
default=False,
|
|
help=_("The total count of share snapshots before pagination is "
|
|
"applied. This parameter is useful when applying "
|
|
"pagination parameters '--limit' and '--offset'. Available "
|
|
"only for microversion >= 2.79.")
|
|
)
|
|
|
|
return parser
|
|
|
|
def take_action(self, parsed_args):
|
|
share_client = self.app.client_manager.share
|
|
|
|
share_id = None
|
|
if parsed_args.share:
|
|
share_id = utils.find_resource(share_client.shares,
|
|
parsed_args.share).id
|
|
columns = ['ID', 'Name']
|
|
|
|
search_opts = {
|
|
'offset': parsed_args.marker,
|
|
'limit': parsed_args.limit,
|
|
'all_tenants': parsed_args.all_projects,
|
|
'name': parsed_args.name,
|
|
'status': parsed_args.status,
|
|
'share_id': share_id,
|
|
'usage': parsed_args.usage,
|
|
'metadata': oscutils.extract_key_value_options(
|
|
parsed_args.property),
|
|
}
|
|
|
|
if share_client.api_version >= api_versions.APIVersion("2.36"):
|
|
search_opts['name~'] = getattr(parsed_args, 'name~')
|
|
search_opts['description~'] = getattr(parsed_args, 'description~')
|
|
search_opts['description'] = parsed_args.description
|
|
elif (parsed_args.description or getattr(parsed_args, 'name~') or
|
|
getattr(parsed_args, 'description~')):
|
|
raise exceptions.CommandError(
|
|
"Pattern based filtering (name~, description~ and description)"
|
|
" is only available with manila API version >= 2.36")
|
|
|
|
if parsed_args.count:
|
|
if share_client.api_version < api_versions.APIVersion("2.79"):
|
|
raise exceptions.CommandError(
|
|
"Displaying total number of share snapshots is only "
|
|
"available with manila API version >= 2.79")
|
|
if parsed_args.formatter != 'table':
|
|
raise exceptions.CommandError(
|
|
"Count can only be printed when using '--format table'")
|
|
|
|
if parsed_args.detail:
|
|
columns.extend([
|
|
'Status',
|
|
'Description',
|
|
'Created At',
|
|
'Size',
|
|
'Share ID',
|
|
'Share Proto',
|
|
'Share Size',
|
|
'User ID'
|
|
])
|
|
|
|
if parsed_args.all_projects:
|
|
columns.append('Project ID')
|
|
|
|
total_count = 0
|
|
if parsed_args.count:
|
|
search_opts['with_count'] = True
|
|
snapshots, total_count = share_client.share_snapshots.list(
|
|
search_opts=search_opts)
|
|
else:
|
|
snapshots = share_client.share_snapshots.list(
|
|
search_opts=search_opts)
|
|
|
|
snapshots = utils.sort_items(snapshots, parsed_args.sort, str)
|
|
|
|
if parsed_args.count:
|
|
print("Total number of snapshots: %s" % total_count)
|
|
return (columns,
|
|
(utils.get_item_properties(s, columns) for s in snapshots))
|
|
|
|
|
|
class AdoptShareSnapshot(command.ShowOne):
|
|
"""Adopt a share snapshot not handled by Manila (Admin only)."""
|
|
|
|
_description = _("Adopt a share snapshot")
|
|
|
|
def get_parser(self, prog_name):
|
|
parser = super(AdoptShareSnapshot, self).get_parser(prog_name)
|
|
parser.add_argument(
|
|
"share",
|
|
metavar="<share>",
|
|
help=_("Name or ID of the share that owns the snapshot "
|
|
"to be adopted.")
|
|
)
|
|
parser.add_argument(
|
|
"provider_location",
|
|
metavar="<provider-location>",
|
|
help=_("Provider location of the snapshot on the backend.")
|
|
)
|
|
parser.add_argument(
|
|
"--name",
|
|
metavar="<name>",
|
|
default=None,
|
|
help=_("Optional snapshot name (Default=None).")
|
|
)
|
|
parser.add_argument(
|
|
"--description",
|
|
metavar="<description>",
|
|
default=None,
|
|
help=_("Optional snapshot description (Default=None).")
|
|
)
|
|
parser.add_argument(
|
|
"--driver-option",
|
|
metavar="<key=value>",
|
|
default={},
|
|
action=parseractions.KeyValueAction,
|
|
help=_(
|
|
"Set driver options as key=value pairs."
|
|
"(repeat option to set multiple key=value pairs)")
|
|
)
|
|
parser.add_argument(
|
|
"--wait",
|
|
action='store_true',
|
|
help=_("Wait until share snapshot is adopted")
|
|
)
|
|
return parser
|
|
|
|
def take_action(self, parsed_args):
|
|
share_client = self.app.client_manager.share
|
|
|
|
share = utils.find_resource(share_client.shares,
|
|
parsed_args.share)
|
|
|
|
snapshot = share_client.share_snapshots.manage(
|
|
share=share,
|
|
provider_location=parsed_args.provider_location,
|
|
driver_options=parsed_args.driver_option,
|
|
name=parsed_args.name,
|
|
description=parsed_args.description
|
|
)
|
|
|
|
if parsed_args.wait:
|
|
if not utils.wait_for_status(
|
|
status_f=share_client.share_snapshots.get,
|
|
res_id=snapshot.id,
|
|
success_status=['available'],
|
|
error_status=['manage_error', 'error']
|
|
):
|
|
LOG.error(_("ERROR: Share snapshot is in error state."))
|
|
|
|
snapshot = utils.find_resource(share_client.share_snapshots,
|
|
snapshot.id)
|
|
|
|
snapshot._info.pop('links', None)
|
|
|
|
return self.dict2columns(snapshot._info)
|
|
|
|
|
|
class AbandonShareSnapshot(command.Command):
|
|
"""Abandon one or more share snapshots (Admin only)."""
|
|
|
|
_description = _("Abandon share snapshot(s)")
|
|
|
|
def get_parser(self, prog_name):
|
|
parser = super(AbandonShareSnapshot, self).get_parser(prog_name)
|
|
parser.add_argument(
|
|
"snapshot",
|
|
metavar="<snapshot>",
|
|
nargs='+',
|
|
help=_("Name or ID of the snapshot(s) to be abandoned.")
|
|
)
|
|
parser.add_argument(
|
|
"--wait",
|
|
action='store_true',
|
|
help=_("Wait until share snapshot is abandoned")
|
|
)
|
|
return parser
|
|
|
|
def take_action(self, parsed_args):
|
|
share_client = self.app.client_manager.share
|
|
result = 0
|
|
|
|
for snapshot in parsed_args.snapshot:
|
|
snapshot_obj = utils.find_resource(
|
|
share_client.share_snapshots,
|
|
snapshot)
|
|
try:
|
|
share_client.share_snapshots.unmanage(snapshot_obj)
|
|
if parsed_args.wait:
|
|
if not utils.wait_for_delete(
|
|
manager=share_client.share_snapshots,
|
|
res_id=snapshot_obj.id):
|
|
result += 1
|
|
except Exception as e:
|
|
result += 1
|
|
LOG.error(_(
|
|
"Failed to abandon share snapshot with "
|
|
"name or ID '%(snapshot)s': %(e)s"),
|
|
{'snapshot': snapshot, 'e': e})
|
|
|
|
if result > 0:
|
|
total = len(parsed_args.snapshot)
|
|
msg = (_("%(result)s of %(total)s snapshots failed "
|
|
"to abandon.") % {'result': result, 'total': total})
|
|
raise exceptions.CommandError(msg)
|
|
|
|
|
|
class ShareSnapshotAccessAllow(command.ShowOne):
|
|
"""Allow read only access to a snapshot."""
|
|
|
|
_description = _("Allow access to a snapshot")
|
|
|
|
def get_parser(self, prog_name):
|
|
parser = super(ShareSnapshotAccessAllow, self).get_parser(prog_name)
|
|
parser.add_argument(
|
|
"snapshot",
|
|
metavar="<snapshot>",
|
|
help=_("Name or ID of the snapshot")
|
|
)
|
|
parser.add_argument(
|
|
'access_type',
|
|
metavar="<access_type>",
|
|
help=_('Access rule type (only "ip", "user" (user or group), '
|
|
'"cert" or "cephx" are supported).')
|
|
)
|
|
parser.add_argument(
|
|
'access_to',
|
|
metavar="<access_to>",
|
|
help=_('Value that defines access.')
|
|
)
|
|
return parser
|
|
|
|
def take_action(self, parsed_args):
|
|
share_client = self.app.client_manager.share
|
|
|
|
snapshot_obj = utils.find_resource(
|
|
share_client.share_snapshots,
|
|
parsed_args.snapshot)
|
|
|
|
try:
|
|
snapshot_access = share_client.share_snapshots.allow(
|
|
snapshot=snapshot_obj,
|
|
access_type=parsed_args.access_type,
|
|
access_to=parsed_args.access_to
|
|
)
|
|
return self.dict2columns(snapshot_access)
|
|
|
|
except Exception as e:
|
|
raise exceptions.CommandError(
|
|
"Failed to create access to share snapshot "
|
|
"'%s': %s" % (snapshot_obj, e))
|
|
|
|
|
|
class ShareSnapshotAccessDeny(command.Command):
|
|
"""Delete access to a snapshot"""
|
|
|
|
_description = _(
|
|
"Delete access to a snapshot")
|
|
|
|
def get_parser(self, prog_name):
|
|
parser = super(ShareSnapshotAccessDeny, self).get_parser(prog_name)
|
|
parser.add_argument(
|
|
"snapshot",
|
|
metavar="<snapshot>",
|
|
help=_("Name or ID of the share snapshot to deny access to.")
|
|
)
|
|
parser.add_argument(
|
|
"id",
|
|
metavar="<id>",
|
|
nargs="+",
|
|
help=_("ID(s) of the access rule(s) to be deleted.")
|
|
)
|
|
return parser
|
|
|
|
def take_action(self, parsed_args):
|
|
share_client = self.app.client_manager.share
|
|
result = 0
|
|
|
|
snapshot_obj = utils.find_resource(
|
|
share_client.share_snapshots,
|
|
parsed_args.snapshot)
|
|
|
|
for access_id in parsed_args.id:
|
|
try:
|
|
share_client.share_snapshots.deny(
|
|
snapshot=snapshot_obj,
|
|
id=access_id
|
|
)
|
|
except Exception as e:
|
|
result += 1
|
|
LOG.error(_(
|
|
"Failed to delete access to share snapshot "
|
|
"for an access rule with ID '%(access)s': %(e)s"),
|
|
{'access': access_id, 'e': e})
|
|
|
|
if result > 0:
|
|
total = len(parsed_args.id)
|
|
msg = (_("Failed to delete access to a share snapshot for "
|
|
"%(result)s out of %(total)s access rule ID's ")
|
|
% {'result': result, 'total': total})
|
|
raise exceptions.CommandError(msg)
|
|
|
|
|
|
class ShareSnapshotAccessList(command.Lister):
|
|
"""Show access list for a snapshot"""
|
|
|
|
_description = _(
|
|
"Show access list for a snapshot")
|
|
|
|
def get_parser(self, prog_name):
|
|
parser = super(ShareSnapshotAccessList, self).get_parser(prog_name)
|
|
parser.add_argument(
|
|
"snapshot",
|
|
metavar="<snapshot>",
|
|
help=_("Name or ID of the share snapshot to show access list for.")
|
|
)
|
|
return parser
|
|
|
|
def take_action(self, parsed_args):
|
|
share_client = self.app.client_manager.share
|
|
|
|
snapshot_obj = utils.find_resource(
|
|
share_client.share_snapshots,
|
|
parsed_args.snapshot)
|
|
|
|
access_rules = share_client.share_snapshots.access_list(
|
|
snapshot_obj)
|
|
|
|
columns = [
|
|
"ID",
|
|
"Access Type",
|
|
"Access To",
|
|
"State"
|
|
]
|
|
|
|
return (columns,
|
|
(utils.get_item_properties(s, columns) for s in access_rules))
|
|
|
|
|
|
class ShareSnapshotListExportLocation(command.Lister):
|
|
"""List export locations of a given snapshot"""
|
|
|
|
_description = _(
|
|
"List export locations of a given snapshot")
|
|
|
|
def get_parser(self, prog_name):
|
|
parser = super(ShareSnapshotListExportLocation, self).get_parser(
|
|
prog_name)
|
|
parser.add_argument(
|
|
"snapshot",
|
|
metavar="<snapshot>",
|
|
help=_("Name or ID of the share snapshot.")
|
|
)
|
|
return parser
|
|
|
|
def take_action(self, parsed_args):
|
|
share_client = self.app.client_manager.share
|
|
|
|
snapshot_obj = utils.find_resource(
|
|
share_client.share_snapshots,
|
|
parsed_args.snapshot)
|
|
|
|
export_locations = share_client.share_snapshot_export_locations.list(
|
|
snapshot=snapshot_obj)
|
|
|
|
columns = ["ID", "Path"]
|
|
|
|
return (
|
|
columns,
|
|
(utils.get_item_properties(s, columns) for s in export_locations))
|
|
|
|
|
|
class ShareSnapshotShowExportLocation(command.ShowOne):
|
|
"""Show export location of the share snapshot"""
|
|
|
|
_description = _(
|
|
"Show export location of the share snapshot")
|
|
|
|
def get_parser(self, prog_name):
|
|
parser = super(ShareSnapshotShowExportLocation, self).get_parser(
|
|
prog_name)
|
|
parser.add_argument(
|
|
"snapshot",
|
|
metavar="<snapshot>",
|
|
help=_("Name or ID of the share snapshot.")
|
|
)
|
|
parser.add_argument(
|
|
"export_location",
|
|
metavar="<export-location>",
|
|
help=_("ID of the share snapshot export location.")
|
|
)
|
|
return parser
|
|
|
|
def take_action(self, parsed_args):
|
|
share_client = self.app.client_manager.share
|
|
|
|
snapshot_obj = utils.find_resource(
|
|
share_client.share_snapshots,
|
|
parsed_args.snapshot)
|
|
|
|
export_location = share_client.share_snapshot_export_locations.get(
|
|
export_location=parsed_args.export_location,
|
|
snapshot=snapshot_obj)
|
|
|
|
return self.dict2columns(export_location._info)
|