Remove mistral from the introspection workflows

This change removes all of mistral from the introspection workflows
by calling the new introspection playbook.

Story: 2007212
Task: 38444
Task: 38445

Depends-On: I7ba8a31b71ed5bc9bdd944769ea472b537c83a98
Change-Id: I48bedfe9a705f5ff8e0eed1f852b77938d53c763
Signed-off-by: Kevin Carter <kecarter@redhat.com>
This commit is contained in:
Dougal Matthews 2020-02-11 16:01:06 +00:00
parent af719b795b
commit bb639bc65c
6 changed files with 91 additions and 240 deletions

View File

@ -466,10 +466,7 @@ class TestCleanNode(fakes.TestOvercloudNode):
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
call_list = [mock.call( call_list = []
'tripleo.baremetal.v1.clean_manageable_nodes',
workflow_input={}
)]
if provide: if provide:
call_list.append(mock.call( call_list.append(mock.call(
@ -478,8 +475,6 @@ class TestCleanNode(fakes.TestOvercloudNode):
)) ))
self.workflow.executions.create.assert_has_calls(call_list) self.workflow.executions.create.assert_has_calls(call_list)
self.assertEqual(self.workflow.executions.create.call_count,
2 if provide else 1)
def _check_clean_nodes(self, parsed_args, nodes, provide=False): def _check_clean_nodes(self, parsed_args, nodes, provide=False):
self.websocket.wait_for_messages.return_value = [{ self.websocket.wait_for_messages.return_value = [{
@ -490,10 +485,7 @@ class TestCleanNode(fakes.TestOvercloudNode):
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
call_list = [mock.call( call_list = []
'tripleo.baremetal.v1.clean_nodes', workflow_input={
'node_uuids': nodes}
)]
if provide: if provide:
call_list.append(mock.call( call_list.append(mock.call(
@ -502,8 +494,6 @@ class TestCleanNode(fakes.TestOvercloudNode):
)) ))
self.workflow.executions.create.assert_has_calls(call_list) self.workflow.executions.create.assert_has_calls(call_list)
self.assertEqual(self.workflow.executions.create.call_count,
2 if provide else 1)
def test_clean_all_manageable_nodes_without_provide(self): def test_clean_all_manageable_nodes_without_provide(self):
parsed_args = self.check_parser(self.cmd, parsed_args = self.check_parser(self.cmd,
@ -595,6 +585,11 @@ class TestImportNodeMultiArch(fakes.TestOvercloudNode):
self.http_boot = '/var/lib/ironic/httpboot' self.http_boot = '/var/lib/ironic/httpboot'
self.mock_playbook = mock.patch(
"tripleoclient.utils.run_ansible_playbook", spec=True)
self.mock_run_ansible_playbook = self.mock_playbook.start()
self.addCleanup(self.mock_playbook.stop)
existing = ['agent', 'x86_64/agent', 'SNB-x86_64/agent'] existing = ['agent', 'x86_64/agent', 'SNB-x86_64/agent']
existing = {os.path.join(self.http_boot, name + ext) existing = {os.path.join(self.http_boot, name + ext)
for name in existing for ext in ('.kernel', '.ramdisk')} for name in existing for ext in ('.kernel', '.ramdisk')}
@ -614,21 +609,19 @@ class TestImportNodeMultiArch(fakes.TestOvercloudNode):
"execution_id": "IDID" "execution_id": "IDID"
}] }]
with mock.patch('tripleoclient.utils.run_ansible_playbook', file_return_nodes = [
autospec=True): {
file_return_nodes = [ 'uuid': 'MOCK_NODE_UUID'
{ }
'uuid': 'MOCK_NODE_UUID' ]
} mock_open = mock.mock_open(read_data=json.dumps(file_return_nodes))
] # TODO(cloudnull): Remove this when py27 is dropped
mock_open = mock.mock_open(read_data=json.dumps(file_return_nodes)) if sys.version_info >= (3, 0):
# TODO(cloudnull): Remove this when py27 is dropped mock_open_path = 'builtins.open'
if sys.version_info >= (3, 0): else:
mock_open_path = 'builtins.open' mock_open_path = 'tripleoclient.v1.overcloud_node.open'
else: with mock.patch(mock_open_path, mock_open):
mock_open_path = 'tripleoclient.v1.overcloud_node.open' self.cmd.take_action(parsed_args)
with mock.patch(mock_open_path, mock_open):
self.cmd.take_action(parsed_args)
nodes_list = copy.deepcopy(self.nodes_list) nodes_list = copy.deepcopy(self.nodes_list)
if not no_deploy_image: if not no_deploy_image:
@ -649,13 +642,15 @@ class TestImportNodeMultiArch(fakes.TestOvercloudNode):
call_list = [] call_list = []
if introspect: if introspect:
call_count += 1 self.mock_run_ansible_playbook.assert_called_with(
call_list.append(mock.call( extra_vars={
'tripleo.baremetal.v1.introspect', workflow_input={
'node_uuids': ['MOCK_NODE_UUID'], 'node_uuids': ['MOCK_NODE_UUID'],
'run_validations': False, 'run_validations': False, 'concurrency': 20},
'concurrency': 20} inventory='localhost,',
)) playbook='cli-baremetal-introspect.yaml',
playbook_dir='/usr/share/ansible/tripleo-playbooks',
workdir=mock.ANY,
)
if provide: if provide:
call_count += 1 call_count += 1
@ -677,16 +672,14 @@ class TestImportNodeMultiArch(fakes.TestOvercloudNode):
parsed_args = self.check_parser(self.cmd, argslist, verifylist) parsed_args = self.check_parser(self.cmd, argslist, verifylist)
self._check_workflow_call(parsed_args) self._check_workflow_call(parsed_args)
@mock.patch('tripleoclient.utils.run_ansible_playbook', def test_import_and_introspect(self):
autospec=True)
def test_import_and_introspect(self, mock_playbook):
parsed_args = self.check_parser(self.cmd, parsed_args = self.check_parser(self.cmd,
[self.json_file.name, [self.json_file.name,
'--introspect'], '--introspect'],
[('introspect', True), [('introspect', True),
('provide', False)]) ('provide', False)])
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
mock_playbook.assert_called_once_with( self.mock_run_ansible_playbook.assert_called_once_with(
workdir=mock.ANY, workdir=mock.ANY,
playbook=mock.ANY, playbook=mock.ANY,
inventory=mock.ANY, inventory=mock.ANY,
@ -706,9 +699,7 @@ class TestImportNodeMultiArch(fakes.TestOvercloudNode):
parsed_args = self.check_parser(self.cmd, argslist, verifylist) parsed_args = self.check_parser(self.cmd, argslist, verifylist)
self._check_workflow_call(parsed_args, provide=True) self._check_workflow_call(parsed_args, provide=True)
@mock.patch('tripleoclient.utils.run_ansible_playbook', def test_import_and_introspect_and_provide(self):
autospec=True)
def test_import_and_introspect_and_provide(self, mock_playbook):
parsed_args = self.check_parser(self.cmd, parsed_args = self.check_parser(self.cmd,
[self.json_file.name, [self.json_file.name,
'--introspect', '--introspect',
@ -716,7 +707,7 @@ class TestImportNodeMultiArch(fakes.TestOvercloudNode):
[('introspect', True), [('introspect', True),
('provide', True)]) ('provide', True)])
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
mock_playbook.assert_called_once_with( self.mock_run_ansible_playbook.assert_called_once_with(
workdir=mock.ANY, workdir=mock.ANY,
playbook=mock.ANY, playbook=mock.ANY,
inventory=mock.ANY, inventory=mock.ANY,
@ -883,6 +874,13 @@ class TestDiscoverNode(fakes.TestOvercloudNode):
self.http_boot = '/var/lib/ironic/httpboot' self.http_boot = '/var/lib/ironic/httpboot'
self.mock_playbook = mock.patch(
'tripleoclient.utils.run_ansible_playbook',
autospec=True
)
self.mock_playbook.start()
self.addCleanup(self.mock_playbook.stop)
def test_with_ip_range(self): def test_with_ip_range(self):
argslist = ['--range', '10.0.0.0/24', argslist = ['--range', '10.0.0.0/24',
'--credentials', 'admin:password'] '--credentials', 'admin:password']
@ -922,17 +920,6 @@ class TestDiscoverNode(fakes.TestOvercloudNode):
parsed_args = self.check_parser(self.cmd, argslist, verifylist) parsed_args = self.check_parser(self.cmd, argslist, verifylist)
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
workflows_calls = [
mock.call('tripleo.baremetal.v1.introspect',
workflow_input={'node_uuids': ['MOCK_NODE_UUID'],
'run_validations': True,
'concurrency': 10}),
mock.call('tripleo.baremetal.v1.provide',
workflow_input={'node_uuids': ['MOCK_NODE_UUID']}
)
]
self.workflow.executions.create.assert_has_calls(workflows_calls)
class TestProvisionNode(fakes.TestOvercloudNode): class TestProvisionNode(fakes.TestOvercloudNode):

View File

@ -210,8 +210,7 @@ class TestIntrospectNode(fakes.TestOvercloudNode):
extra_vars={ extra_vars={
'node_uuids': [], 'node_uuids': [],
'run_validations': False, 'run_validations': False,
'concurrency': 20, 'concurrency': 20
'all_manageable': True
} }
) )
@ -232,8 +231,7 @@ class TestIntrospectNode(fakes.TestOvercloudNode):
extra_vars={ extra_vars={
'node_uuids': [], 'node_uuids': [],
'run_validations': False, 'run_validations': False,
'concurrency': 20, 'concurrency': 20
'all_manageable': True
} }
) )
@ -253,8 +251,7 @@ class TestIntrospectNode(fakes.TestOvercloudNode):
extra_vars={ extra_vars={
'node_uuids': nodes, 'node_uuids': nodes,
'run_validations': False, 'run_validations': False,
'concurrency': 20, 'concurrency': 20
'all_manageable': False
} }
) )
@ -276,8 +273,7 @@ class TestIntrospectNode(fakes.TestOvercloudNode):
extra_vars={ extra_vars={
'node_uuids': nodes, 'node_uuids': nodes,
'run_validations': False, 'run_validations': False,
'concurrency': 20, 'concurrency': 20
'all_manageable': False
} }
) )

View File

@ -47,6 +47,13 @@ class TestBaremetalWorkflows(fakes.FakePlaybookExecution):
"message": "Fail.", "message": "Fail.",
}]) }])
self.mock_playbook = mock.patch(
'tripleoclient.utils.run_ansible_playbook',
autospec=True
)
self.mock_playbook.start()
self.addCleanup(self.mock_playbook.stop)
def test_register_or_update_success(self): def test_register_or_update_success(self):
self.assertEqual(baremetal.register_or_update( self.assertEqual(baremetal.register_or_update(
self.app.client_manager, self.app.client_manager,
@ -106,101 +113,13 @@ class TestBaremetalWorkflows(fakes.FakePlaybookExecution):
) )
def test_introspect_success(self): def test_introspect_success(self):
self.websocket.wait_for_messages.return_value = self.message_success
baremetal.introspect(self.app.client_manager, node_uuids=[], baremetal.introspect(self.app.client_manager, node_uuids=[],
run_validations=True, concurrency=20) run_validations=True, concurrency=20)
self.workflow.executions.create.assert_called_once_with(
'tripleo.baremetal.v1.introspect',
workflow_input={
'node_uuids': [],
'run_validations': True,
'concurrency': 20
})
def test_introspect_error(self):
self.websocket.wait_for_messages.return_value = self.message_failed
self.assertRaises(
exceptions.IntrospectionError,
baremetal.introspect,
self.app.client_manager,
node_uuids=[],
run_validations=False,
concurrency=20
)
self.workflow.executions.create.assert_called_once_with(
'tripleo.baremetal.v1.introspect',
workflow_input={
'node_uuids': [],
'run_validations': False,
'concurrency': 20
})
def test_introspect_manageable_nodes_success(self): def test_introspect_manageable_nodes_success(self):
self.websocket.wait_for_messages.return_value = iter([{
"execution_id": "IDID",
"status": "SUCCESS",
"introspected_nodes": {},
}])
baremetal.introspect_manageable_nodes( baremetal.introspect_manageable_nodes(
self.app.client_manager, run_validations=False, concurrency=20 self.app.client_manager, run_validations=False, concurrency=20
) )
self.workflow.executions.create.assert_called_once_with(
'tripleo.baremetal.v1.introspect_manageable_nodes',
workflow_input={
'run_validations': False,
'concurrency': 20
})
def test_introspect_manageable_nodes_error(self):
self.websocket.wait_for_messages.return_value = self.message_failed
self.assertRaises(
exceptions.IntrospectionError,
baremetal.introspect_manageable_nodes,
self.app.client_manager,
run_validations=False,
concurrency=20
)
self.workflow.executions.create.assert_called_once_with(
'tripleo.baremetal.v1.introspect_manageable_nodes',
workflow_input={
'run_validations': False,
'concurrency': 20
})
def test_introspect_manageable_nodes_mixed_status(self):
self.websocket.wait_for_messages.return_value = iter([{
"execution_id": "IDID",
"status": "SUCCESS",
"introspected_nodes": {'node1': {'error': None},
'node2': {'error': 'Error'}}
}])
self.assertRaises(
exceptions.IntrospectionError,
baremetal.introspect_manageable_nodes,
self.app.client_manager,
run_validations=False,
concurrency=20
)
self.workflow.executions.create.assert_called_once_with(
'tripleo.baremetal.v1.introspect_manageable_nodes',
workflow_input={
'run_validations': False,
'concurrency': 20
})
def test_provide_manageable_nodes_success(self): def test_provide_manageable_nodes_success(self):
@ -215,20 +134,6 @@ class TestBaremetalWorkflows(fakes.FakePlaybookExecution):
workflow_input={} workflow_input={}
) )
def test_provide_manageable_nodes_error(self):
self.websocket.wait_for_messages.return_value = self.message_failed
self.assertRaises(
exceptions.NodeProvideError,
baremetal.provide_manageable_nodes,
self.app.client_manager)
self.workflow.executions.create.assert_called_once_with(
'tripleo.baremetal.v1.provide_manageable_nodes',
workflow_input={}
)
def test_configure_success(self): def test_configure_success(self):
baremetal.configure(self.app.client_manager, node_uuids=[]) baremetal.configure(self.app.client_manager, node_uuids=[])

View File

@ -437,11 +437,13 @@ class DiscoverNode(command.Command):
nodes_uuids = [node.uuid for node in nodes] nodes_uuids = [node.uuid for node in nodes]
if parsed_args.introspect: if parsed_args.introspect:
baremetal.introspect(self.app.client_manager, baremetal.introspect(
node_uuids=nodes_uuids, self.app.client_manager,
run_validations=parsed_args.run_validations, node_uuids=nodes_uuids,
concurrency=parsed_args.concurrency run_validations=parsed_args.run_validations,
) concurrency=parsed_args.concurrency
)
if parsed_args.provide: if parsed_args.provide:
baremetal.provide(self.app.client_manager, baremetal.provide(self.app.client_manager,
node_uuids=nodes_uuids node_uuids=nodes_uuids

View File

@ -163,20 +163,18 @@ class IntrospectNode(command.Command):
def take_action(self, parsed_args): def take_action(self, parsed_args):
self.log.debug("take_action(%s)" % parsed_args) self.log.debug("take_action(%s)" % parsed_args)
extra_vars = { if parsed_args.all_manageable:
"node_uuids": parsed_args.node_uuids, baremetal.introspect_manageable_nodes(
"run_validations": parsed_args.run_validations, self.app.client_manager,
"concurrency": parsed_args.concurrency, run_validations=parsed_args.run_validations,
"all_manageable": parsed_args.all_manageable, concurrency=parsed_args.concurrency
} )
else:
with oooutils.TempDirs() as tmp: baremetal.introspect(
oooutils.run_ansible_playbook( self.app.client_manager,
playbook='cli-baremetal-introspect.yaml', node_uuids=parsed_args.node_uuids,
inventory='localhost,', run_validations=parsed_args.run_validations,
workdir=tmp, concurrency=parsed_args.concurrency
playbook_dir=constants.ANSIBLE_TRIPLEO_PLAYBOOKS,
extra_vars=extra_vars
) )
# NOTE(cloudnull): This is using the old provide function, in a future # NOTE(cloudnull): This is using the old provide function, in a future

View File

@ -144,80 +144,43 @@ def provide(clients, **workflow_input):
'Failed to set nodes to available state: {}'.format(message)) 'Failed to set nodes to available state: {}'.format(message))
def introspect(clients, **workflow_input): def introspect(clients, node_uuids, run_validations, concurrency):
"""Introspect Baremetal Nodes """Introspect Baremetal Nodes
Run the tripleo.baremetal.v1.introspect Mistral workflow. Run the tripleo.baremetal.v1.introspect Mistral workflow.
""" """
workflow_client = clients.workflow_engine with utils.TempDirs() as tmp:
tripleoclients = clients.tripleoclient utils.run_ansible_playbook(
playbook='cli-baremetal-introspect.yaml',
print("Waiting for introspection to finish...") inventory='localhost,',
workdir=tmp,
with tripleoclients.messaging_websocket() as ws: playbook_dir=constants.ANSIBLE_TRIPLEO_PLAYBOOKS,
execution = base.start_workflow( extra_vars={
workflow_client, "node_uuids": node_uuids,
'tripleo.baremetal.v1.introspect', "run_validations": run_validations,
workflow_input={ "concurrency": concurrency,
'node_uuids': workflow_input['node_uuids'],
'run_validations': workflow_input['run_validations'],
'concurrency': workflow_input.get('concurrency', 20)
} }
) )
for payload in base.wait_for_messages(workflow_client, ws, execution): print('Successfully introspected nodes: {}'.format(node_uuids))
if 'message' in payload:
print(payload['message'])
if payload['status'] != 'SUCCESS':
raise exceptions.IntrospectionError(
"Introspection completed with errors: {}"
.format(payload['message']))
def introspect_manageable_nodes(clients, **workflow_input): def introspect_manageable_nodes(clients, run_validations, concurrency):
"""Introspect all manageable nodes """Introspect all manageable nodes
Run the tripleo.baremetal.v1.introspect_manageable_nodes Mistral workflow. Run the tripleo.baremetal.v1.introspect_manageable_nodes Mistral workflow.
""" """
workflow_client = clients.workflow_engine introspect(
tripleoclients = clients.tripleoclient clients=clients,
node_uuids=[
print("Waiting for introspection to finish...") i.uuid for i in clients.baremetal.node.list()
if i.provision_state == "manageable" and not i.maintenance
errors = [] ],
run_validations=run_validations,
with tripleoclients.messaging_websocket() as ws: concurrency=concurrency
execution = base.start_workflow( )
workflow_client,
'tripleo.baremetal.v1.introspect_manageable_nodes',
workflow_input={
'run_validations': workflow_input['run_validations'],
'concurrency': workflow_input.get('concurrency', 20)
}
)
for payload in base.wait_for_messages(workflow_client, ws, execution):
if 'message' in payload:
print(payload['message'])
if payload['status'] == 'SUCCESS':
introspected_nodes = payload['introspected_nodes'] or {}
for node_uuid, status in introspected_nodes.items():
if status['error'] is not None:
errors.append("%s: %s" % (node_uuid, status['error']))
else:
raise exceptions.IntrospectionError(
'Exception introspecting nodes: {}'.format(payload['message']))
if errors:
raise exceptions.IntrospectionError(
"Introspection completed with errors:\n%s" % '\n'
.join(errors))
print("Introspection completed.")
def provide_manageable_nodes(clients, **workflow_input): def provide_manageable_nodes(clients, **workflow_input):