Metadata for share export location
Adds set and unset commands for export location properties within unified CLI Depends-On: Icf096a5cbc650f02eca68d714c876eb854499b9b Partially-implements: bp metadata-for-share-resources Change-Id: I3878868c2359fba7aa8a49421a31a952a5776766
This commit is contained in:
parent
0e74a7bcf2
commit
5ba65e94e4
@ -27,7 +27,7 @@ from manilaclient import utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
MAX_VERSION = '2.84'
|
||||
MAX_VERSION = '2.87'
|
||||
MIN_VERSION = '2.0'
|
||||
DEPRECATED_VERSION = '1.0'
|
||||
_VERSIONED_METHOD_MAP = {}
|
||||
|
@ -1179,8 +1179,15 @@ class ShareExportLocationShow(command.ShowOne):
|
||||
share=share,
|
||||
export_location=parsed_args.export_location
|
||||
)
|
||||
data = export_location._info
|
||||
data.update(
|
||||
{
|
||||
'properties':
|
||||
format_columns.DictColumn(data.pop('metadata', {})),
|
||||
},
|
||||
)
|
||||
|
||||
return self.dict2columns(export_location._info)
|
||||
return self.dict2columns(data)
|
||||
|
||||
|
||||
class ShareExportLocationList(command.Lister):
|
||||
@ -1218,6 +1225,120 @@ class ShareExportLocationList(command.Lister):
|
||||
(s, list_of_keys) for s in export_locations))
|
||||
|
||||
|
||||
class ShareExportLocationSet(command.Command):
|
||||
"""Set an export location property."""
|
||||
|
||||
_description = _("Set an export location property.")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShareExportLocationSet, self).get_parser(
|
||||
prog_name)
|
||||
|
||||
parser.add_argument(
|
||||
'share',
|
||||
metavar="<share>",
|
||||
help=_('Name or ID of share')
|
||||
)
|
||||
parser.add_argument(
|
||||
'export_location',
|
||||
metavar="<export_location>",
|
||||
help=_('ID of the export location')
|
||||
)
|
||||
parser.add_argument(
|
||||
"--property",
|
||||
metavar="<key=value>",
|
||||
default={},
|
||||
action=parseractions.KeyValueAction,
|
||||
help=_("Set a property to this export location "
|
||||
"(repeat option to set multiple properties). "
|
||||
"Available only for microversion >= 2.87."),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
share_client = self.app.client_manager.share
|
||||
share_id = apiutils.find_resource(
|
||||
share_client.shares,
|
||||
parsed_args.share).id
|
||||
|
||||
if (parsed_args.property and
|
||||
share_client.api_version < api_versions.APIVersion("2.87")):
|
||||
raise exceptions.CommandError(
|
||||
"Property can be specified only with manila API "
|
||||
"version >= 2.87.")
|
||||
|
||||
if parsed_args.property:
|
||||
try:
|
||||
share_client.share_export_locations.set_metadata(
|
||||
share_id,
|
||||
parsed_args.property,
|
||||
subresource=parsed_args.export_location)
|
||||
except Exception as e:
|
||||
raise exceptions.CommandError(_(
|
||||
"Failed to set export location property "
|
||||
"'%(properties)s': %(e)s") %
|
||||
{'properties': parsed_args.property, 'e': e}
|
||||
)
|
||||
|
||||
|
||||
class ShareExportLocationUnset(command.Command):
|
||||
"""Unset a share export location property"""
|
||||
_description = _("Unset a share export location property")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShareExportLocationUnset, self).get_parser(
|
||||
prog_name)
|
||||
|
||||
parser.add_argument(
|
||||
'share',
|
||||
metavar="<share>",
|
||||
help=_('Name or ID of share')
|
||||
)
|
||||
parser.add_argument(
|
||||
'export_location',
|
||||
metavar="<export_location>",
|
||||
help=_('ID of the export location')
|
||||
)
|
||||
parser.add_argument(
|
||||
"--property",
|
||||
metavar="<key>",
|
||||
action='append',
|
||||
help=_("Remove a property from export location "
|
||||
"(repeat option to remove multiple properties). "
|
||||
"Available only for microversion >= 2.87."),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
share_client = self.app.client_manager.share
|
||||
share_id = apiutils.find_resource(
|
||||
share_client.shares,
|
||||
parsed_args.share).id
|
||||
|
||||
if (parsed_args.property and
|
||||
share_client.api_version < api_versions.APIVersion("2.87")):
|
||||
raise exceptions.CommandError(
|
||||
"Property can be specified only with manila API "
|
||||
"version >= 2.87.")
|
||||
|
||||
if parsed_args.property:
|
||||
result = 0
|
||||
for key in parsed_args.property:
|
||||
try:
|
||||
share_client.share_export_locations.delete_metadata(
|
||||
share_id, [key],
|
||||
subresource=parsed_args.export_location)
|
||||
except Exception as e:
|
||||
result += 1
|
||||
LOG.error("Failed to unset export location property "
|
||||
"'%(key)s': %(e)s", {'key': key, 'e': e})
|
||||
if result > 0:
|
||||
total = len(parsed_args.property)
|
||||
raise exceptions.CommandError(
|
||||
f"{result} of {total} export location properties failed "
|
||||
f"to be unset.")
|
||||
|
||||
|
||||
class ShowShareProperties(command.ShowOne):
|
||||
"""Show properties of a share"""
|
||||
_description = _("Show share properties")
|
||||
|
@ -330,6 +330,7 @@ class FakeShareExportLocation(object):
|
||||
"id": "id-" + uuid.uuid4().hex,
|
||||
"is_admin_only": False,
|
||||
"preferred": False,
|
||||
"properties": {},
|
||||
"updated_at": 'time-' + uuid.uuid4().hex,
|
||||
}
|
||||
|
||||
|
@ -1910,6 +1910,148 @@ class TestShareExportLocationList(TestShare):
|
||||
self.assertCountEqual(self.values, data)
|
||||
|
||||
|
||||
class TestExportLocationSet(TestShare):
|
||||
|
||||
def setUp(self):
|
||||
super(TestExportLocationSet, self).setUp()
|
||||
|
||||
self._share = manila_fakes.FakeShare.create_one_share(
|
||||
methods={"set_metadata": None}
|
||||
)
|
||||
self.shares_mock.get.return_value = self._share
|
||||
|
||||
self._export_location = (
|
||||
manila_fakes.FakeShareExportLocation.create_one_export_location(
|
||||
{'fake_share_instance_id': self._share.id}))
|
||||
|
||||
self.export_locations_mock.get.return_value = (
|
||||
self._export_location
|
||||
)
|
||||
|
||||
self.cmd = osc_shares.ShareExportLocationSet(self.app, None)
|
||||
|
||||
def test_share_set_export_location_property(self):
|
||||
self.app.client_manager.share.api_version = api_versions.APIVersion(
|
||||
'2.87'
|
||||
)
|
||||
arglist = [
|
||||
self._share.id,
|
||||
self._export_location.id,
|
||||
'--property', 'Bobcat=manila',
|
||||
|
||||
]
|
||||
verifylist = [
|
||||
('share', self._share.id),
|
||||
('export_location', self._export_location.id),
|
||||
('property', {'Bobcat': 'manila'}),
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.cmd.take_action(parsed_args)
|
||||
self.export_locations_mock.set_metadata.assert_called_once_with(
|
||||
self._share.id, {'Bobcat': 'manila'},
|
||||
subresource=self._export_location.id)
|
||||
|
||||
def test_share_set_export_location_property_exception(self):
|
||||
self.app.client_manager.share.api_version = api_versions.APIVersion(
|
||||
'2.87'
|
||||
)
|
||||
arglist = [
|
||||
self._share.id,
|
||||
self._export_location.id,
|
||||
'--property', 'key=',
|
||||
]
|
||||
verifylist = [
|
||||
('share', self._share.id),
|
||||
('export_location', self._export_location.id),
|
||||
('property', {'key': ''}),
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
self.export_locations_mock.set_metadata.assert_called_once_with(
|
||||
self._share.id, {'key': ''},
|
||||
subresource=self._export_location.id)
|
||||
|
||||
self.export_locations_mock.set_metadata.side_effect = (
|
||||
exceptions.BadRequest)
|
||||
self.assertRaises(
|
||||
osc_exceptions.CommandError, self.cmd.take_action,
|
||||
parsed_args)
|
||||
|
||||
|
||||
class TestExportLocationUnset(TestShare):
|
||||
|
||||
def setUp(self):
|
||||
super(TestExportLocationUnset, self).setUp()
|
||||
|
||||
self._share = manila_fakes.FakeShare.create_one_share(
|
||||
methods={"set_metadata": None}
|
||||
)
|
||||
self.shares_mock.get.return_value = self._share
|
||||
|
||||
self._export_location = (
|
||||
manila_fakes.FakeShareExportLocation.create_one_export_location(
|
||||
{'fake_share_instance_id': self._share.id}))
|
||||
|
||||
self.export_locations_mock.get.return_value = (
|
||||
self._export_location
|
||||
)
|
||||
|
||||
self.cmd = osc_shares.ShareExportLocationUnset(self.app, None)
|
||||
|
||||
def test_share_unset_export_location_property(self):
|
||||
self.app.client_manager.share.api_version = api_versions.APIVersion(
|
||||
'2.87'
|
||||
)
|
||||
arglist = [
|
||||
self._share.id,
|
||||
self._export_location.id,
|
||||
'--property', 'Bobcat',
|
||||
|
||||
]
|
||||
verifylist = [
|
||||
('share', self._share.id),
|
||||
('export_location', self._export_location.id),
|
||||
('property', ['Bobcat']),
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.cmd.take_action(parsed_args)
|
||||
self.export_locations_mock.delete_metadata.assert_called_once_with(
|
||||
self._share.id, ['Bobcat'],
|
||||
subresource=self._export_location.id)
|
||||
|
||||
def test_share_unset_export_location_property_exception(self):
|
||||
self.app.client_manager.share.api_version = api_versions.APIVersion(
|
||||
'2.87'
|
||||
)
|
||||
arglist = [
|
||||
self._share.id,
|
||||
self._export_location.id,
|
||||
'--property', 'key',
|
||||
]
|
||||
verifylist = [
|
||||
('share', self._share.id),
|
||||
('export_location', self._export_location.id),
|
||||
('property', ['key']),
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
self.export_locations_mock.delete_metadata.assert_has_calls([
|
||||
mock.call(self._share.id, ['key'],
|
||||
subresource=self._export_location.id)])
|
||||
|
||||
self.export_locations_mock.delete_metadata.side_effect = (
|
||||
exceptions.NotFound)
|
||||
self.assertRaises(
|
||||
osc_exceptions.CommandError, self.cmd.take_action,
|
||||
parsed_args)
|
||||
|
||||
|
||||
class TestShowShareProperties(TestShare):
|
||||
|
||||
properties = {
|
||||
|
@ -27,9 +27,11 @@ class ShareExportLocation(base.Resource):
|
||||
return self._info[key]
|
||||
|
||||
|
||||
class ShareExportLocationManager(base.ManagerWithFind):
|
||||
class ShareExportLocationManager(base.MetadataCapableManager):
|
||||
"""Manage :class:`ShareExportLocation` resources."""
|
||||
resource_class = ShareExportLocation
|
||||
resource_path = '/shares'
|
||||
subresource_path = '/export_locations'
|
||||
|
||||
@api_versions.wraps("2.9")
|
||||
def list(self, share, search_opts=None):
|
||||
@ -47,3 +49,23 @@ class ShareExportLocationManager(base.ManagerWithFind):
|
||||
"/shares/%(share_id)s/export_locations/%(export_location_id)s" % {
|
||||
"share_id": share_id,
|
||||
"export_location_id": export_location_id}, "export_location")
|
||||
|
||||
@api_versions.wraps('2.87')
|
||||
def get_metadata(self, share, share_export_location):
|
||||
return super(ShareExportLocationManager, self).get_metadata(
|
||||
share, subresource=share_export_location)
|
||||
|
||||
@api_versions.wraps('2.87')
|
||||
def set_metadata(self, resource, metadata, subresource=None):
|
||||
return super(ShareExportLocationManager, self).set_metadata(
|
||||
resource, metadata, subresource=subresource)
|
||||
|
||||
@api_versions.wraps('2.87')
|
||||
def delete_metadata(self, resource, keys, subresource=None):
|
||||
return super(ShareExportLocationManager, self).delete_metadata(
|
||||
resource, keys, subresource=subresource)
|
||||
|
||||
@api_versions.wraps('2.87')
|
||||
def update_all_metadata(self, resource, metadata, subresource=None):
|
||||
return super(ShareExportLocationManager, self).update_all_metadata(
|
||||
resource, metadata, subresource=subresource)
|
||||
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Adds support to set and unset share export location properties
|
||||
(only with the OpenStackClient).
|
@ -52,6 +52,8 @@ openstack.share.v2 =
|
||||
share_migration_show = manilaclient.osc.v2.share:ShareMigrationShow
|
||||
share_export_location_show = manilaclient.osc.v2.share:ShareExportLocationShow
|
||||
share_export_location_list = manilaclient.osc.v2.share:ShareExportLocationList
|
||||
share_export_location_set = manilaclient.osc.v2.share:ShareExportLocationSet
|
||||
share_export_location_unset = manilaclient.osc.v2.share:ShareExportLocationUnset
|
||||
share_properties_show = manilaclient.osc.v2.share:ShowShareProperties
|
||||
share_restore = manilaclient.osc.v2.share:RestoreShare
|
||||
share_revert = manilaclient.osc.v2.share:RevertShare
|
||||
|
Loading…
Reference in New Issue
Block a user