Adding image stores info command

This is an equivalent for ``glance stores-info``.

Depends-on: https://review.opendev.org/c/openstack/openstacksdk/+/883493
Change-Id: I15d2c2c523ace1cfb32045328ecee8ce8beea63f
This commit is contained in:
Mridula Joshi 2023-05-18 11:14:54 +00:00
parent 7dc1276f40
commit 18a6199ed0
5 changed files with 124 additions and 0 deletions

View File

@ -1836,3 +1836,48 @@ class ImportImage(command.ShowOne):
info = _format_image(image)
return zip(*sorted(info.items()))
class StoresInfo(command.Lister):
_description = _(
"Get available backends (only valid with Multi-Backend support)"
)
def get_parser(self, prog_name):
parser = super().get_parser(prog_name)
parser.add_argument(
"--detail",
action='store_true',
default=None,
help=_(
'Shows details of stores (admin only) '
'(requires --os-image-api-version 2.15 or later)'
),
)
return parser
def take_action(self, parsed_args):
image_client = self.app.client_manager.image
try:
columns = ("id", "description", "is_default")
column_headers = ("ID", "Description", "Default")
if parsed_args.detail:
columns += ("properties",)
column_headers += ("Properties",)
data = list(image_client.stores(details=parsed_args.detail))
except sdk_exceptions.ResourceNotFound:
msg = _('Multi Backend support not enabled')
raise exceptions.CommandError(msg)
else:
return (
column_headers,
(
utils.get_item_properties(
store,
columns,
formatters=_formatters,
)
for store in data
),
)

View File

@ -57,6 +57,7 @@ class FakeImagev2Client:
self.get_task = mock.Mock()
self.get_import_info = mock.Mock()
self.stores = mock.Mock()
self.auth_token = kwargs['token']
self.management_url = kwargs['endpoint']
@ -171,6 +172,38 @@ def create_one_import_info(attrs=None):
return _service_info.Import(**import_info)
def create_one_stores_info(attrs=None):
"""Create a fake stores info.
:param attrs: A dictionary with all attributes of stores
:type attrs: dict
:return: A fake Store object list.
:rtype: `openstack.image.v2.service_info.Store`
"""
attrs = attrs or {}
stores_info = {
"stores": [
{
"id": "reliable",
"description": "More expensive store with data redundancy",
},
{
"id": "fast",
"description": "Provides quick access to your image data",
"default": True,
},
{
"id": "cheap",
"description": "Less expensive store for seldom-used images",
},
]
}
stores_info.update(attrs)
return _service_info.Store(**stores_info)
def create_one_task(attrs=None):
"""Create a fake task.

View File

@ -2101,3 +2101,43 @@ class TestImageGetData(TestImage):
test_fd = _image.get_data_from_stdin()
self.assertIsNone(test_fd)
class TestStoresInfo(TestImage):
stores_info = image_fakes.create_one_stores_info()
def setUp(self):
super().setUp()
self.client.stores.return_value = self.stores_info
self.cmd = _image.StoresInfo(self.app, None)
def test_stores_info(self):
arglist = []
parsed_args = self.check_parser(self.cmd, arglist, [])
self.cmd.take_action(parsed_args)
self.client.stores.assert_called()
def test_stores_info_with_detail(self):
arglist = ['--detail']
parsed_args = self.check_parser(self.cmd, arglist, [])
self.cmd.take_action(parsed_args)
self.client.stores.assert_called_with(details=True)
def test_stores_info_neg(self):
arglist = []
parsed_args = self.check_parser(self.cmd, arglist, [])
self.client.stores.side_effect = sdk_exceptions.ResourceNotFound()
exc = self.assertRaises(
exceptions.CommandError,
self.cmd.take_action,
parsed_args,
)
self.assertIn(
"Multi Backend support not enabled",
str(exc),
)

View File

@ -0,0 +1,3 @@
features:
- |
Add ``image stores info`` command, allowing users to know available backends.

View File

@ -388,6 +388,9 @@ openstack.image.v2 =
image_task_show = openstackclient.image.v2.task:ShowTask
image_task_list = openstackclient.image.v2.task:ListTask
image_import_info = openstackclient.image.v2.info:ImportInfo
image_import = openstackclient.image.v2.image:ImportImage
image_stores_list = openstackclient.image.v2.image:StoresInfo
image_metadef_namespace_create = openstackclient.image.v2.metadef_namespaces:CreateMetadefNameSpace
image_metadef_namespace_delete = openstackclient.image.v2.metadef_namespaces:DeleteMetadefNameSpace