Merge "volume: Add 'block storage resource filter list' command"
This commit is contained in:
commit
644106a89c
|
@ -0,0 +1,8 @@
|
|||
=============================
|
||||
block storage resource filter
|
||||
=============================
|
||||
|
||||
Block Storage v3
|
||||
|
||||
.. autoprogram-cliff:: openstack.volume.v3
|
||||
:command: block storage resource filter *
|
|
@ -77,6 +77,7 @@ referring to both Compute and Volume quotas.
|
|||
* ``aggregate``: (**Compute**) a grouping of compute hosts
|
||||
* ``availability zone``: (**Compute**, **Network**, **Volume**) a logical partition of hosts or block storage or network services
|
||||
* ``block storage cluster``: (**Volume**) clusters of volume services
|
||||
* ``block storage resource filter``: (**Volume**) filters for volume service resources
|
||||
* ``catalog``: (**Identity**) service catalog
|
||||
* ``command``: (**Internal**) installed commands in the OSC process
|
||||
* ``compute agent``: (**Compute**) a cloud Compute agent available to a hypervisor
|
||||
|
|
|
@ -69,7 +69,7 @@ group-update,volume group set,Updates a group. (Supported by API versions 3.13 -
|
|||
image-metadata,volume set --image-property,Sets or deletes volume image metadata.
|
||||
image-metadata-show,volume show,Shows volume image metadata.
|
||||
list,volume list,Lists all volumes.
|
||||
list-filters,,List enabled filters. (Supported by API versions 3.33 - 3.latest)
|
||||
list-filters,block storage resource filter list,List enabled filters. (Supported by API versions 3.33 - 3.latest)
|
||||
manage,volume create --remote-source k=v,Manage an existing volume.
|
||||
manageable-list,,Lists all manageable volumes. (Supported by API versions 3.8 - 3.latest)
|
||||
message-delete,volume message delete,Removes one or more messages. (Supported by API versions 3.3 - 3.latest)
|
||||
|
|
|
|
@ -42,6 +42,8 @@ class FakeVolumeClient(object):
|
|||
self.group_types.resource_class = fakes.FakeResource(None, {})
|
||||
self.messages = mock.Mock()
|
||||
self.messages.resource_class = fakes.FakeResource(None, {})
|
||||
self.resource_filters = mock.Mock()
|
||||
self.resource_filters.resource_class = fakes.FakeResource(None, {})
|
||||
self.volumes = mock.Mock()
|
||||
self.volumes.resource_class = fakes.FakeResource(None, {})
|
||||
self.volume_types = mock.Mock()
|
||||
|
@ -124,6 +126,53 @@ class FakeCluster:
|
|||
return clusters
|
||||
|
||||
|
||||
class FakeResourceFilter:
|
||||
"""Fake one or more resource filters."""
|
||||
|
||||
@staticmethod
|
||||
def create_one_resource_filter(attrs=None):
|
||||
"""Create a fake resource filter.
|
||||
|
||||
:param attrs: A dictionary with all attributes of resource filter
|
||||
:return: A FakeResource object with id, name, status, etc.
|
||||
"""
|
||||
attrs = attrs or {}
|
||||
|
||||
# Set default attribute
|
||||
|
||||
resource_filter_info = {
|
||||
'filters': [
|
||||
'name',
|
||||
'status',
|
||||
'image_metadata',
|
||||
'bootable',
|
||||
'migration_status',
|
||||
],
|
||||
'resource': 'volume',
|
||||
}
|
||||
|
||||
# Overwrite default attributes if there are some attributes set
|
||||
resource_filter_info.update(attrs)
|
||||
|
||||
return fakes.FakeResource(None, resource_filter_info, loaded=True)
|
||||
|
||||
@staticmethod
|
||||
def create_resource_filters(attrs=None, count=2):
|
||||
"""Create multiple fake resource filters.
|
||||
|
||||
:param attrs: A dictionary with all attributes of resource filter
|
||||
:param count: The number of resource filters to be faked
|
||||
:return: A list of FakeResource objects
|
||||
"""
|
||||
resource_filters = []
|
||||
for n in range(0, count):
|
||||
resource_filters.append(
|
||||
FakeResourceFilter.create_one_resource_filter(attrs)
|
||||
)
|
||||
|
||||
return resource_filters
|
||||
|
||||
|
||||
class FakeVolumeGroup:
|
||||
"""Fake one or more volume groups."""
|
||||
|
||||
|
@ -309,11 +358,10 @@ class FakeVolumeMessage:
|
|||
# Overwrite default attributes if there are some attributes set
|
||||
message_info.update(attrs)
|
||||
|
||||
message = fakes.FakeResource(
|
||||
return fakes.FakeResource(
|
||||
None,
|
||||
message_info,
|
||||
loaded=True)
|
||||
return message
|
||||
|
||||
@staticmethod
|
||||
def create_volume_messages(attrs=None, count=2):
|
||||
|
@ -402,11 +450,10 @@ class FakeVolumeAttachment:
|
|||
# Overwrite default attributes if there are some attributes set
|
||||
attachment_info.update(attrs)
|
||||
|
||||
attachment = fakes.FakeResource(
|
||||
return fakes.FakeResource(
|
||||
None,
|
||||
attachment_info,
|
||||
loaded=True)
|
||||
return attachment
|
||||
|
||||
@staticmethod
|
||||
def create_volume_attachments(attrs=None, count=2):
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
# 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.
|
||||
|
||||
from cinderclient import api_versions
|
||||
from osc_lib import exceptions
|
||||
|
||||
from openstackclient.tests.unit.volume.v3 import fakes as volume_fakes
|
||||
from openstackclient.volume.v3 import block_storage_resource_filter
|
||||
|
||||
|
||||
class TestBlockStorageResourceFilter(volume_fakes.TestVolume):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
# Get a shortcut to the ResourceFilterManager Mock
|
||||
self.resource_filter_mock = \
|
||||
self.app.client_manager.volume.resource_filters
|
||||
self.resource_filter_mock.reset_mock()
|
||||
|
||||
|
||||
class TestBlockStorageResourceFilterList(TestBlockStorageResourceFilter):
|
||||
|
||||
# The resource filters to be listed
|
||||
fake_resource_filters = \
|
||||
volume_fakes.FakeResourceFilter.create_resource_filters()
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
self.resource_filter_mock.list.return_value = \
|
||||
self.fake_resource_filters
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = block_storage_resource_filter\
|
||||
.ListBlockStorageResourceFilter(self.app, None)
|
||||
|
||||
def test_resource_filter_list(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.33')
|
||||
|
||||
arglist = []
|
||||
verifylist = []
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
expected_columns = ('Resource', 'Filters')
|
||||
expected_data = tuple(
|
||||
(
|
||||
resource_filter.resource,
|
||||
resource_filter.filters,
|
||||
) for resource_filter in self.fake_resource_filters
|
||||
)
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.assertEqual(expected_columns, columns)
|
||||
self.assertEqual(expected_data, tuple(data))
|
||||
|
||||
# checking if proper call was made to list clusters
|
||||
self.resource_filter_mock.list.assert_called_with()
|
||||
|
||||
def test_resource_filter_list_pre_v333(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.32')
|
||||
|
||||
arglist = []
|
||||
verifylist = []
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.33 or greater is required', str(exc))
|
||||
|
||||
|
||||
class TestBlockStorageResourceFilterShow(TestBlockStorageResourceFilter):
|
||||
|
||||
# The resource filters to be listed
|
||||
fake_resource_filter = \
|
||||
volume_fakes.FakeResourceFilter.create_one_resource_filter()
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
self.resource_filter_mock.list.return_value = \
|
||||
iter([self.fake_resource_filter])
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = block_storage_resource_filter\
|
||||
.ShowBlockStorageResourceFilter(self.app, None)
|
||||
|
||||
def test_resource_filter_show(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.33')
|
||||
|
||||
arglist = [
|
||||
self.fake_resource_filter.resource,
|
||||
]
|
||||
verifylist = [
|
||||
('resource', self.fake_resource_filter.resource),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
expected_columns = ('filters', 'resource')
|
||||
expected_data = (
|
||||
self.fake_resource_filter.filters,
|
||||
self.fake_resource_filter.resource,
|
||||
)
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.assertEqual(expected_columns, columns)
|
||||
self.assertEqual(expected_data, data)
|
||||
|
||||
# checking if proper call was made to list clusters
|
||||
self.resource_filter_mock.list.assert_called_with(resource='volume')
|
||||
|
||||
def test_resource_filter_show_pre_v333(self):
|
||||
self.app.client_manager.volume.api_version = \
|
||||
api_versions.APIVersion('3.32')
|
||||
|
||||
arglist = [
|
||||
self.fake_resource_filter.resource,
|
||||
]
|
||||
verifylist = [
|
||||
('resource', self.fake_resource_filter.resource),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
self.assertIn(
|
||||
'--os-volume-api-version 3.33 or greater is required', str(exc))
|
|
@ -0,0 +1,83 @@
|
|||
# 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 V3 Resource Filters implementations"""
|
||||
|
||||
from cinderclient import api_versions
|
||||
from osc_lib.command import command
|
||||
from osc_lib import exceptions
|
||||
from osc_lib import utils
|
||||
|
||||
from openstackclient.i18n import _
|
||||
|
||||
|
||||
class ListBlockStorageResourceFilter(command.Lister):
|
||||
_description = _('List block storage resource filters')
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
|
||||
if volume_client.api_version < api_versions.APIVersion('3.33'):
|
||||
msg = _(
|
||||
"--os-volume-api-version 3.33 or greater is required to "
|
||||
"support the 'block storage resource filter list' command"
|
||||
)
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
column_headers = (
|
||||
'Resource',
|
||||
'Filters',
|
||||
)
|
||||
|
||||
data = volume_client.resource_filters.list()
|
||||
|
||||
return (
|
||||
column_headers,
|
||||
(utils.get_item_properties(s, column_headers) for s in data)
|
||||
)
|
||||
|
||||
|
||||
class ShowBlockStorageResourceFilter(command.ShowOne):
|
||||
_description = _('Show filters for a block storage resource type')
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super().get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'resource',
|
||||
metavar='<resource>',
|
||||
help=_('Resource to show filters for (name).')
|
||||
)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
|
||||
if volume_client.api_version < api_versions.APIVersion('3.33'):
|
||||
msg = _(
|
||||
"--os-volume-api-version 3.33 or greater is required to "
|
||||
"support the 'block storage resource filter show' command"
|
||||
)
|
||||
raise exceptions.CommandError(msg)
|
||||
|
||||
data = volume_client.resource_filters.list(
|
||||
resource=parsed_args.resource
|
||||
)
|
||||
if not data:
|
||||
msg = _(
|
||||
"No resource filter with a name of {parsed_args.resource}' "
|
||||
"exists."
|
||||
)
|
||||
raise exceptions.CommandError(msg)
|
||||
resource_filter = next(data)
|
||||
|
||||
return zip(*sorted(resource_filter._info.items()))
|
|
@ -759,6 +759,8 @@ openstack.volume.v3 =
|
|||
block_storage_cluster_list = openstackclient.volume.v3.block_storage_cluster:ListBlockStorageCluster
|
||||
block_storage_cluster_set = openstackclient.volume.v3.block_storage_cluster:SetBlockStorageCluster
|
||||
block_storage_cluster_show = openstackclient.volume.v3.block_storage_cluster:ShowBlockStorageCluster
|
||||
block_storage_resource_filter_list = openstackclient.volume.v3.block_storage_resource_filter:ListBlockStorageResourceFilter
|
||||
block_storage_resource_filter_show = openstackclient.volume.v3.block_storage_resource_filter:ShowBlockStorageResourceFilter
|
||||
|
||||
volume_snapshot_create = openstackclient.volume.v2.volume_snapshot:CreateVolumeSnapshot
|
||||
volume_snapshot_delete = openstackclient.volume.v2.volume_snapshot:DeleteVolumeSnapshot
|
||||
|
|
Loading…
Reference in New Issue