Merge "Add 'openstack overcloud node introspect' command"

This commit is contained in:
Jenkins 2016-08-01 09:31:27 +00:00 committed by Gerrit Code Review
commit 66cd751c46
6 changed files with 232 additions and 1 deletions

View File

@ -67,6 +67,7 @@ openstack.tripleoclient.v1 =
overcloud_image_build = tripleoclient.v1.overcloud_image:BuildOvercloudImage
overcloud_image_upload = tripleoclient.v1.overcloud_image:UploadOvercloudImage
overcloud_node_delete = tripleoclient.v1.overcloud_node:DeleteNode
overcloud_node_introspect = tripleoclient.v1.overcloud_node:IntrospectNode
overcloud_node_provide = tripleoclient.v1.overcloud_node:ProvideNode
overcloud_profiles_match = tripleoclient.v1.overcloud_profiles:MatchProfiles
overcloud_profiles_list = tripleoclient.v1.overcloud_profiles:ListProfiles

View File

@ -128,3 +128,109 @@ class TestProvideNode(fakes.TestOvercloudNode):
self.assertRaises(test_utils.ParserException,
self.check_parser,
self.cmd, argslist, verifylist)
class TestIntrospectNode(fakes.TestOvercloudNode):
def setUp(self):
super(TestIntrospectNode, self).setUp()
self.workflow = self.app.client_manager.workflow_engine
client = self.app.client_manager.tripleoclient
self.websocket = client.messaging_websocket()
# Get the command object to test
self.cmd = overcloud_node.IntrospectNode(self.app, None)
def _check_introspect_all_manageable(self, parsed_args, provide=False):
self.websocket.wait_for_message.return_value = {
"status": "SUCCESS",
"message": "Success",
"introspected_nodes": {}
}
self.cmd.take_action(parsed_args)
call_list = [mock.call(
'tripleo.baremetal.v1.introspect_manageable_nodes',
workflow_input={'queue_name': 'UUID4'}
)]
if provide:
call_list.append(mock.call(
'tripleo.baremetal.v1.provide_manageable_nodes',
workflow_input={'queue_name': 'UUID4'}
))
self.workflow.executions.create.assert_has_calls(call_list)
self.assertEqual(self.workflow.executions.create.call_count,
2 if provide else 1)
def _check_introspect_nodes(self, parsed_args, nodes, provide=False):
self.websocket.wait_for_message.return_value = {
"status": "SUCCESS",
"message": "Success",
"introspected_nodes": {}
}
self.cmd.take_action(parsed_args)
call_list = [mock.call(
'tripleo.baremetal.v1.introspect', workflow_input={
'node_uuids': nodes,
'queue_name': 'UUID4'}
)]
if provide:
call_list.append(mock.call(
'tripleo.baremetal.v1.provide', workflow_input={
'node_uuids': nodes,
'queue_name': 'UUID4'}
))
self.workflow.executions.create.assert_has_calls(call_list)
self.assertEqual(self.workflow.executions.create.call_count,
2 if provide else 1)
def test_introspect_all_manageable_nodes_without_provide(self):
parsed_args = self.check_parser(self.cmd,
['--all-manageable'],
[('all_manageable', True)])
self._check_introspect_all_manageable(parsed_args, provide=False)
def test_introspect_all_manageable_nodes_with_provide(self):
parsed_args = self.check_parser(self.cmd,
['--all-manageable', '--provide'],
[('all_manageable', True),
('provide', True)])
self._check_introspect_all_manageable(parsed_args, provide=True)
def test_introspect_nodes_without_provide(self):
nodes = ['node_uuid1', 'node_uuid2']
parsed_args = self.check_parser(self.cmd,
nodes,
[('node_uuids', nodes)])
self._check_introspect_nodes(parsed_args, nodes, provide=False)
def test_introspect_nodes_with_provide(self):
nodes = ['node_uuid1', 'node_uuid2']
argslist = nodes + ['--provide']
parsed_args = self.check_parser(self.cmd,
argslist,
[('node_uuids', nodes),
('provide', True)])
self._check_introspect_nodes(parsed_args, nodes, provide=True)
def test_introspect_no_node_or_flag_specified(self):
self.assertRaises(test_utils.ParserException,
self.check_parser,
self.cmd, [], [])
def test_introspect_uuids_and_all_both_specified(self):
argslist = ['node_id1', 'node_id2', '--all-manageable']
verifylist = [('node_uuids', ['node_id1', 'node_id2']),
('all_manageable', True)]
self.assertRaises(test_utils.ParserException,
self.check_parser,
self.cmd, argslist, verifylist)

View File

@ -120,6 +120,45 @@ class TestBaremetalWorkflows(utils.TestCommand):
'queue_name': "QUEUE_NAME"
})
def test_introspect_success(self):
self.websocket.wait_for_message.return_value = {
"status": "SUCCESS",
"introspected_nodes": {}
}
baremetal.introspect(self.app.client_manager, node_uuids=[],
queue_name="QUEUE_NAME")
self.workflow.executions.create.assert_called_once_with(
'tripleo.baremetal.v1.introspect',
workflow_input={
'node_uuids': [],
'queue_name': "QUEUE_NAME"
})
def test_introspect_error(self):
self.websocket.wait_for_message.return_value = {
"status": "FAIL",
"message": "Failed",
"introspected_nodes": {}
}
self.assertRaises(
exceptions.IntrospectionError,
baremetal.introspect,
self.app.client_manager,
node_uuids=[],
queue_name="QUEUE_NAME")
self.workflow.executions.create.assert_called_once_with(
'tripleo.baremetal.v1.introspect',
workflow_input={
'node_uuids': [],
'queue_name': "QUEUE_NAME"
})
def test_introspect_manageable_nodes_success(self):
self.websocket.wait_for_message.return_value = {

View File

@ -241,13 +241,19 @@ class ImportBaremetal(command.Command):
class StartBaremetalIntrospectionBulk(command.Command):
"""Start bulk introspection on all baremetal nodes"""
"""Start bulk introspection on all baremetal nodes (Deprecated).
Please use 'openstack overcloud node introspect' instead.
"""
log = logging.getLogger(__name__ + ".StartBaremetalIntrospectionBulk")
def take_action(self, parsed_args):
self.log.debug("take_action(%s)" % parsed_args)
self.log.warning('This command is deprecated. Please use "openstack '
'overcloud node introspect" to introspect manageable '
'nodes instead.\n')
queue_name = str(uuid.uuid4())
clients = self.app.client_manager

View File

@ -98,3 +98,51 @@ class ProvideNode(command.Command):
else:
baremetal.provide_manageable_nodes(self.app.client_manager,
queue_name=queue_name)
class IntrospectNode(command.Command):
"""Introspect specified nodes or all nodes in 'manageable' state."""
log = logging.getLogger(__name__ + ".IntrospectNode")
def get_parser(self, prog_name):
parser = super(IntrospectNode, self).get_parser(prog_name)
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('node_uuids',
nargs="*",
metavar="<node_uuid>",
default=[],
help=_('Ironic UUIDs for the node(s) to be '
'introspected'))
group.add_argument("--all-manageable",
action='store_true',
help=_("Introspect all nodes currently in "
"'manageable' state"))
parser.add_argument('--provide',
action='store_true',
help=_('Provide (make available) the nodes once '
'introspected'))
return parser
def take_action(self, parsed_args):
self.log.debug("take_action(%s)" % parsed_args)
queue_name = str(uuid.uuid4())
nodes = parsed_args.node_uuids
if nodes:
baremetal.introspect(self.app.client_manager,
node_uuids=nodes,
queue_name=queue_name)
else:
baremetal.introspect_manageable_nodes(self.app.client_manager,
queue_name=queue_name)
if parsed_args.provide:
if nodes:
baremetal.provide(self.app.client_manager,
node_uuids=nodes,
queue_name=queue_name)
else:
baremetal.provide_manageable_nodes(self.app.client_manager,
queue_name=queue_name)

View File

@ -70,6 +70,37 @@ def provide(clients, **workflow_input):
payload['message']))
def introspect(clients, **workflow_input):
"""Introspect Baremetal Nodes
Run the tripleo.baremetal.v1.introspect Mistral workflow.
"""
workflow_client = clients.workflow_engine
tripleoclients = clients.tripleoclient
queue_name = workflow_input['queue_name']
execution = workflow_client.executions.create(
'tripleo.baremetal.v1.introspect',
workflow_input={'node_uuids': workflow_input['node_uuids'],
'queue_name': queue_name}
)
print("Waiting for introspection to finish...")
with tripleoclients.messaging_websocket(queue_name) as ws:
payload = ws.wait_for_message(execution.id)
if payload['status'] == 'SUCCESS':
print('Successfully introspected all nodes.')
else:
raise exceptions.IntrospectionError(
"Introspection completed with errors:\n%s" % '\n'
.join(msg for msg in payload['message'] if msg))
print("Introspection completed.")
def introspect_manageable_nodes(clients, **workflow_input):
"""Introspect all manageable nodes