Introduce command to abort introspection

The Inspector API now supports introspection aborting for a node.
This change purpose is to expose that API through the client.

Usage:
  openstack baremetal introspection abort <node-UUID>

Change-Id: Ibfb515087fcc4740bbd2c2bd88459958f74647bf
Related-Bug: #1525235
This commit is contained in:
dparalen 2016-02-11 16:01:37 +01:00
parent f7283cdf2d
commit 94a7730b27
8 changed files with 97 additions and 0 deletions

View File

@ -121,6 +121,17 @@ If file name is not provided, the data is dumped to stdout.
This feature requires Swift support to be enabled in **Ironic Inspector**
by setting ``[processing]store_data`` configuration option to ``swift``.
Aborting introspection
~~~~~~~~~~~~~~~~~~~~~~
``client.abort(uuid)``
* ``uuid`` - Ironic node UUID.
CLI::
$ openstack baremetal introspection abort UUID
Introspection Rules API
~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -116,6 +116,19 @@ class StatusCommand(show.ShowOne):
return zip(*sorted(status.items()))
class AbortCommand(command.Command):
"""Abort running introspection for node."""
def get_parser(self, prog_name):
parser = super(AbortCommand, self).get_parser(prog_name)
parser.add_argument('uuid', help='baremetal node UUID')
return parser
def take_action(self, parsed_args):
client = self.app.client_manager.baremetal_introspection
client.abort(parsed_args.uuid)
class RuleImportCommand(command.Command):
"""Import one or several introspection rules from a json file."""

View File

@ -14,6 +14,7 @@
import eventlet
eventlet.monkey_patch()
import requests
import unittest
from ironic_inspector.test import functional
@ -46,6 +47,32 @@ class TestV1PythonAPI(functional.Base):
status = self.client.get_status(self.uuid)
self.assertEqual({'finished': True, 'error': None}, status)
def test_abort_introspection(self):
# assert abort doesn't work before introspect request
self.assertRaises(client.ClientError, self.client.abort,
self.uuid)
self.client.introspect(self.uuid)
eventlet.greenthread.sleep(functional.DEFAULT_SLEEP)
self.cli.node.set_power_state.assert_called_once_with(self.uuid,
'reboot')
status = self.client.get_status(self.uuid)
self.assertEqual({'finished': False, 'error': None}, status)
res = self.client.abort(self.uuid)
eventlet.greenthread.sleep(functional.DEFAULT_SLEEP)
self.assertEqual(202, res.status_code)
self.assertEqual('', res.text)
status = self.client.get_status(self.uuid)
self.assertEqual({'finished': True, 'error': 'Canceled by '
'operator'}, status)
# assert continue doesn't work after abort
self.assertRaises(requests.HTTPError, self.call_continue, self.data)
def test_setup_ipmi(self):
self.node.provision_state = 'enroll'
self.client.introspect(self.uuid, new_ipmi_username='admin',

View File

@ -125,6 +125,21 @@ class TestIntrospect(BaseTest):
self.assertEqual([('uuid1', None), ('uuid2', 'boom'), ('uuid3', None)],
sorted(values))
def test_abort(self):
node = 'uuid1'
arglist = [node]
verifylist = [('uuid', node)]
response_mock = mock.Mock(status_code=202, content=b'')
self.client.abort.return_value = response_mock
cmd = shell.AbortCommand(self.app, None)
parsed_args = self.check_parser(cmd, arglist, verifylist)
result = cmd.take_action(parsed_args)
self.client.abort.assert_called_once_with(node)
self.assertIs(None, result)
class TestRules(BaseTest):
def test_import_single(self):

View File

@ -264,3 +264,14 @@ class TestRules(BaseTest):
self.get_rules().delete_all()
mock_req.assert_called_once_with('delete', '/rules')
@mock.patch.object(http.BaseClient, 'request')
class TestAbort(BaseTest):
def test(self, mock_req):
self.get_client().abort(self.uuid)
mock_req.assert_called_once_with('post',
'/introspection/%s/abort' % self.uuid)
def test_invalid_input(self, _):
self.assertRaises(TypeError, self.get_client().abort, 42)

View File

@ -154,6 +154,21 @@ class ClientV1(http.BaseClient):
else:
return resp.json()
def abort(self, uuid):
"""Abort running introspection for a node.
:param uuid: node UUID.
:raises: ClientError on error reported from a server.
:raises: VersionNotSupported if requested api_version is not supported.
:raises: *requests* library exception on connection problems.
:raises: TypeError if uuid is not a string.
"""
if not isinstance(uuid, six.string_types):
raise TypeError(_("Expected string for uuid argument, got"
" %r") % uuid)
return self.request('post', '/introspection/%s/abort' % uuid)
class _RulesAPI(object):
"""Introspection rules API."""

View File

@ -0,0 +1,4 @@
---
features:
- Introduced command "openstack baremetal introspection abort <UUID>"
to abort running introspection for a node.

View File

@ -23,6 +23,7 @@ openstack.cli.extension =
openstack.baremetal_introspection.v1 =
baremetal_introspection_start = ironic_inspector_client.shell:StartCommand
baremetal_introspection_status = ironic_inspector_client.shell:StatusCommand
baremetal_introspection_abort = ironic_inspector_client.shell:AbortCommand
baremetal_introspection_data_save = ironic_inspector_client.shell:DataSaveCommand
baremetal_introspection_rule_import = ironic_inspector_client.shell:RuleImportCommand
baremetal_introspection_rule_list = ironic_inspector_client.shell:RuleListCommand