Merge "image: Add 'image task show' commands"

This commit is contained in:
Zuul 2022-09-30 11:59:18 +00:00 committed by Gerrit Code Review
commit 97af1b661e
6 changed files with 218 additions and 1 deletions
doc/source/cli/data
openstackclient
image/v2
tests/unit/image/v2
releasenotes/notes
setup.cfg

@ -55,6 +55,6 @@ stores-delete,,Delete image from specific store.
stores-info,,Print available backends from Glance.
task-create,,Create a new task.
task-list,,List tasks you can access.
task-show,,Describe a specific task.
task-show,image task show,Describe a specific task.
bash-completion,complete,Prints arguments for bash_completion.
help,help,Display help about this program or one of its subcommands.

1 explain WONTFIX Describe a specific model.
55 stores-info Print available backends from Glance.
56 task-create Create a new task.
57 task-list List tasks you can access.
58 task-show image task show Describe a specific task.
59 bash-completion complete Prints arguments for bash_completion.
60 help help Display help about this program or one of its subcommands.

@ -0,0 +1,78 @@
# 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 osc_lib.cli import format_columns
from osc_lib.command import command
from openstackclient.i18n import _
def _format_task(task):
"""Format an task to make it more consistent with OSC operations."""
info = {}
properties = {}
# the only fields we're not including is "links", "tags" and the properties
fields_to_show = [
'created_at',
'expires_at',
'id',
'input',
'message',
'owner_id',
'result',
'status',
'type',
'updated_at',
]
# split out the usual key and the properties which are top-level
for field in fields_to_show:
info[field] = task.get(field)
for key in task:
if key in fields_to_show:
continue
if key in {'location', 'name', 'schema'}:
continue
properties[key] = task.get(key)
# add properties back into the dictionary as a top-level key
info['properties'] = format_columns.DictColumn(properties)
return info
class ShowTask(command.ShowOne):
_description = _('Display task details')
def get_parser(self, prog_name):
parser = super(ShowTask, self).get_parser(prog_name)
parser.add_argument(
'task',
metavar='<Task ID>',
help=_('Task to display (ID)'),
)
return parser
def take_action(self, parsed_args):
image_client = self.app.client_manager.image
task = image_client.get_task(parsed_args.task)
info = _format_task(task)
return zip(*sorted(info.items()))

@ -18,6 +18,7 @@ import uuid
from openstack.image.v2 import image
from openstack.image.v2 import member
from openstack.image.v2 import task
from openstackclient.tests.unit import fakes
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
@ -44,6 +45,9 @@ class FakeImagev2Client:
self.remove_tag = mock.Mock()
self.tasks = mock.Mock()
self.get_task = mock.Mock()
self.auth_token = kwargs['token']
self.management_url = kwargs['endpoint']
self.version = 2.0
@ -129,3 +133,53 @@ def create_one_image_member(attrs=None):
image_member_info.update(attrs)
return member.Member(**image_member_info)
def create_one_task(attrs=None):
"""Create a fake task.
:param attrs: A dictionary with all attributes of task
:type attrs: dict
:return: A fake Task object.
:rtype: `openstack.image.v2.task.Task`
"""
attrs = attrs or {}
# Set default attribute
task_info = {
'created_at': '2016-06-29T16:13:07Z',
'expires_at': '2016-07-01T16:13:07Z',
'id': str(uuid.uuid4()),
'input': {
'image_properties': {
'container_format': 'ovf',
'disk_format': 'vhd'
},
'import_from': 'https://apps.openstack.org/excellent-image',
'import_from_format': 'qcow2'
},
'message': '',
'owner': str(uuid.uuid4()),
'result': {
'image_id': str(uuid.uuid4()),
},
'schema': '/v2/schemas/task',
'status': random.choice(
[
'pending',
'processing',
'success',
'failure',
]
),
# though not documented, the API only allows 'import'
# https://github.com/openstack/glance/blob/24.0.0/glance/api/v2/tasks.py#L186-L190
'type': 'import',
'updated_at': '2016-06-29T16:13:07Z',
}
# Overwrite default attributes if there are some attributes set
task_info.update(attrs)
return task.Task(**task_info)

@ -0,0 +1,80 @@
# 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 osc_lib.cli import format_columns
from openstackclient.image.v2 import task
from openstackclient.tests.unit.image.v2 import fakes as image_fakes
class TestTask(image_fakes.TestImagev2):
def setUp(self):
super().setUp()
# Get shortcuts to mocked image client
self.client = self.app.client_manager.image
class TestTaskShow(TestTask):
task = image_fakes.create_one_task()
columns = (
'created_at',
'expires_at',
'id',
'input',
'message',
'owner_id',
'properties',
'result',
'status',
'type',
'updated_at',
)
data = (
task.created_at,
task.expires_at,
task.id,
task.input,
task.message,
task.owner_id,
format_columns.DictColumn({}),
task.result,
task.status,
task.type,
task.updated_at,
)
def setUp(self):
super().setUp()
self.client.get_task.return_value = self.task
# Get the command object to test
self.cmd = task.ShowTask(self.app, None)
def test_task_show(self):
arglist = [self.task.id]
verifylist = [
('task', self.task.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# In base command class ShowOne in cliff, abstract method take_action()
# returns a two-part tuple with a tuple of column names and a tuple of
# data to be shown.
columns, data = self.cmd.take_action(parsed_args)
self.client.get_task.assert_called_with(self.task.id)
self.assertEqual(self.columns, columns)
self.assertCountEqual(self.data, data)

@ -0,0 +1,4 @@
---
features:
- |
Add ``image task show`` command to show a task for the image service.

@ -382,6 +382,7 @@ openstack.image.v2 =
image_show = openstackclient.image.v2.image:ShowImage
image_set = openstackclient.image.v2.image:SetImage
image_unset = openstackclient.image.v2.image:UnsetImage
image_task_show = openstackclient.image.v2.task:ShowTask
openstack.network.v2 =
address_group_create = openstackclient.network.v2.address_group:CreateAddressGroup