diff --git a/tripleoclient/tests/v1/overcloud_node/test_overcloud_node.py b/tripleoclient/tests/v1/overcloud_node/test_overcloud_node.py index 62a13cf40..55b0f5502 100644 --- a/tripleoclient/tests/v1/overcloud_node/test_overcloud_node.py +++ b/tripleoclient/tests/v1/overcloud_node/test_overcloud_node.py @@ -466,10 +466,7 @@ class TestCleanNode(fakes.TestOvercloudNode): self.cmd.take_action(parsed_args) - call_list = [mock.call( - 'tripleo.baremetal.v1.clean_manageable_nodes', - workflow_input={} - )] + call_list = [] if provide: call_list.append(mock.call( @@ -478,8 +475,6 @@ class TestCleanNode(fakes.TestOvercloudNode): )) 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): self.websocket.wait_for_messages.return_value = [{ @@ -490,10 +485,7 @@ class TestCleanNode(fakes.TestOvercloudNode): self.cmd.take_action(parsed_args) - call_list = [mock.call( - 'tripleo.baremetal.v1.clean_nodes', workflow_input={ - 'node_uuids': nodes} - )] + call_list = [] if provide: call_list.append(mock.call( @@ -502,8 +494,6 @@ class TestCleanNode(fakes.TestOvercloudNode): )) 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): parsed_args = self.check_parser(self.cmd, @@ -595,6 +585,11 @@ class TestImportNodeMultiArch(fakes.TestOvercloudNode): 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 = {os.path.join(self.http_boot, name + ext) for name in existing for ext in ('.kernel', '.ramdisk')} @@ -614,21 +609,19 @@ class TestImportNodeMultiArch(fakes.TestOvercloudNode): "execution_id": "IDID" }] - with mock.patch('tripleoclient.utils.run_ansible_playbook', - autospec=True): - file_return_nodes = [ - { - 'uuid': 'MOCK_NODE_UUID' - } - ] - mock_open = mock.mock_open(read_data=json.dumps(file_return_nodes)) - # TODO(cloudnull): Remove this when py27 is dropped - if sys.version_info >= (3, 0): - mock_open_path = 'builtins.open' - else: - mock_open_path = 'tripleoclient.v1.overcloud_node.open' - with mock.patch(mock_open_path, mock_open): - self.cmd.take_action(parsed_args) + file_return_nodes = [ + { + 'uuid': 'MOCK_NODE_UUID' + } + ] + mock_open = mock.mock_open(read_data=json.dumps(file_return_nodes)) + # TODO(cloudnull): Remove this when py27 is dropped + if sys.version_info >= (3, 0): + mock_open_path = 'builtins.open' + else: + mock_open_path = 'tripleoclient.v1.overcloud_node.open' + with mock.patch(mock_open_path, mock_open): + self.cmd.take_action(parsed_args) nodes_list = copy.deepcopy(self.nodes_list) if not no_deploy_image: @@ -649,13 +642,15 @@ class TestImportNodeMultiArch(fakes.TestOvercloudNode): call_list = [] if introspect: - call_count += 1 - call_list.append(mock.call( - 'tripleo.baremetal.v1.introspect', workflow_input={ + self.mock_run_ansible_playbook.assert_called_with( + extra_vars={ 'node_uuids': ['MOCK_NODE_UUID'], - 'run_validations': False, - 'concurrency': 20} - )) + 'run_validations': False, 'concurrency': 20}, + inventory='localhost,', + playbook='cli-baremetal-introspect.yaml', + playbook_dir='/usr/share/ansible/tripleo-playbooks', + workdir=mock.ANY, + ) if provide: call_count += 1 @@ -677,16 +672,14 @@ class TestImportNodeMultiArch(fakes.TestOvercloudNode): parsed_args = self.check_parser(self.cmd, argslist, verifylist) self._check_workflow_call(parsed_args) - @mock.patch('tripleoclient.utils.run_ansible_playbook', - autospec=True) - def test_import_and_introspect(self, mock_playbook): + def test_import_and_introspect(self): parsed_args = self.check_parser(self.cmd, [self.json_file.name, '--introspect'], [('introspect', True), ('provide', False)]) self.cmd.take_action(parsed_args) - mock_playbook.assert_called_once_with( + self.mock_run_ansible_playbook.assert_called_once_with( workdir=mock.ANY, playbook=mock.ANY, inventory=mock.ANY, @@ -706,9 +699,7 @@ class TestImportNodeMultiArch(fakes.TestOvercloudNode): parsed_args = self.check_parser(self.cmd, argslist, verifylist) self._check_workflow_call(parsed_args, provide=True) - @mock.patch('tripleoclient.utils.run_ansible_playbook', - autospec=True) - def test_import_and_introspect_and_provide(self, mock_playbook): + def test_import_and_introspect_and_provide(self): parsed_args = self.check_parser(self.cmd, [self.json_file.name, '--introspect', @@ -716,7 +707,7 @@ class TestImportNodeMultiArch(fakes.TestOvercloudNode): [('introspect', True), ('provide', True)]) self.cmd.take_action(parsed_args) - mock_playbook.assert_called_once_with( + self.mock_run_ansible_playbook.assert_called_once_with( workdir=mock.ANY, playbook=mock.ANY, inventory=mock.ANY, @@ -883,6 +874,13 @@ class TestDiscoverNode(fakes.TestOvercloudNode): 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): argslist = ['--range', '10.0.0.0/24', '--credentials', 'admin:password'] @@ -922,17 +920,6 @@ class TestDiscoverNode(fakes.TestOvercloudNode): parsed_args = self.check_parser(self.cmd, argslist, verifylist) 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): diff --git a/tripleoclient/tests/v2/overcloud_node/test_overcloud_node.py b/tripleoclient/tests/v2/overcloud_node/test_overcloud_node.py index 8524e7372..cc352259e 100644 --- a/tripleoclient/tests/v2/overcloud_node/test_overcloud_node.py +++ b/tripleoclient/tests/v2/overcloud_node/test_overcloud_node.py @@ -210,8 +210,7 @@ class TestIntrospectNode(fakes.TestOvercloudNode): extra_vars={ 'node_uuids': [], 'run_validations': False, - 'concurrency': 20, - 'all_manageable': True + 'concurrency': 20 } ) @@ -232,8 +231,7 @@ class TestIntrospectNode(fakes.TestOvercloudNode): extra_vars={ 'node_uuids': [], 'run_validations': False, - 'concurrency': 20, - 'all_manageable': True + 'concurrency': 20 } ) @@ -253,8 +251,7 @@ class TestIntrospectNode(fakes.TestOvercloudNode): extra_vars={ 'node_uuids': nodes, 'run_validations': False, - 'concurrency': 20, - 'all_manageable': False + 'concurrency': 20 } ) @@ -276,8 +273,7 @@ class TestIntrospectNode(fakes.TestOvercloudNode): extra_vars={ 'node_uuids': nodes, 'run_validations': False, - 'concurrency': 20, - 'all_manageable': False + 'concurrency': 20 } ) diff --git a/tripleoclient/tests/workflows/test_baremetal.py b/tripleoclient/tests/workflows/test_baremetal.py index b1fd05619..d78a1ef01 100644 --- a/tripleoclient/tests/workflows/test_baremetal.py +++ b/tripleoclient/tests/workflows/test_baremetal.py @@ -47,6 +47,13 @@ class TestBaremetalWorkflows(fakes.FakePlaybookExecution): "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): self.assertEqual(baremetal.register_or_update( self.app.client_manager, @@ -106,101 +113,13 @@ class TestBaremetalWorkflows(fakes.FakePlaybookExecution): ) def test_introspect_success(self): - - self.websocket.wait_for_messages.return_value = self.message_success - baremetal.introspect(self.app.client_manager, node_uuids=[], 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): - - self.websocket.wait_for_messages.return_value = iter([{ - "execution_id": "IDID", - "status": "SUCCESS", - "introspected_nodes": {}, - }]) - 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_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): @@ -215,20 +134,6 @@ class TestBaremetalWorkflows(fakes.FakePlaybookExecution): 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): baremetal.configure(self.app.client_manager, node_uuids=[]) diff --git a/tripleoclient/v1/overcloud_node.py b/tripleoclient/v1/overcloud_node.py index aef6c3482..197026090 100644 --- a/tripleoclient/v1/overcloud_node.py +++ b/tripleoclient/v1/overcloud_node.py @@ -437,11 +437,13 @@ class DiscoverNode(command.Command): nodes_uuids = [node.uuid for node in nodes] if parsed_args.introspect: - baremetal.introspect(self.app.client_manager, - node_uuids=nodes_uuids, - run_validations=parsed_args.run_validations, - concurrency=parsed_args.concurrency - ) + baremetal.introspect( + self.app.client_manager, + node_uuids=nodes_uuids, + run_validations=parsed_args.run_validations, + concurrency=parsed_args.concurrency + ) + if parsed_args.provide: baremetal.provide(self.app.client_manager, node_uuids=nodes_uuids diff --git a/tripleoclient/v2/overcloud_node.py b/tripleoclient/v2/overcloud_node.py index 8afbf6a87..36cdfe385 100644 --- a/tripleoclient/v2/overcloud_node.py +++ b/tripleoclient/v2/overcloud_node.py @@ -163,20 +163,18 @@ class IntrospectNode(command.Command): def take_action(self, parsed_args): self.log.debug("take_action(%s)" % parsed_args) - extra_vars = { - "node_uuids": parsed_args.node_uuids, - "run_validations": parsed_args.run_validations, - "concurrency": parsed_args.concurrency, - "all_manageable": parsed_args.all_manageable, - } - - with oooutils.TempDirs() as tmp: - oooutils.run_ansible_playbook( - playbook='cli-baremetal-introspect.yaml', - inventory='localhost,', - workdir=tmp, - playbook_dir=constants.ANSIBLE_TRIPLEO_PLAYBOOKS, - extra_vars=extra_vars + if parsed_args.all_manageable: + baremetal.introspect_manageable_nodes( + self.app.client_manager, + run_validations=parsed_args.run_validations, + concurrency=parsed_args.concurrency + ) + else: + baremetal.introspect( + self.app.client_manager, + node_uuids=parsed_args.node_uuids, + run_validations=parsed_args.run_validations, + concurrency=parsed_args.concurrency ) # NOTE(cloudnull): This is using the old provide function, in a future diff --git a/tripleoclient/workflows/baremetal.py b/tripleoclient/workflows/baremetal.py index 1f07287de..accf734d7 100644 --- a/tripleoclient/workflows/baremetal.py +++ b/tripleoclient/workflows/baremetal.py @@ -144,80 +144,43 @@ def provide(clients, **workflow_input): '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 Run the tripleo.baremetal.v1.introspect Mistral workflow. """ - workflow_client = clients.workflow_engine - tripleoclients = clients.tripleoclient - - print("Waiting for introspection to finish...") - - with tripleoclients.messaging_websocket() as ws: - execution = base.start_workflow( - workflow_client, - 'tripleo.baremetal.v1.introspect', - workflow_input={ - 'node_uuids': workflow_input['node_uuids'], - 'run_validations': workflow_input['run_validations'], - 'concurrency': workflow_input.get('concurrency', 20) + with utils.TempDirs() as tmp: + utils.run_ansible_playbook( + playbook='cli-baremetal-introspect.yaml', + inventory='localhost,', + workdir=tmp, + playbook_dir=constants.ANSIBLE_TRIPLEO_PLAYBOOKS, + extra_vars={ + "node_uuids": node_uuids, + "run_validations": run_validations, + "concurrency": concurrency, } ) - for payload in base.wait_for_messages(workflow_client, ws, execution): - if 'message' in payload: - print(payload['message']) - - if payload['status'] != 'SUCCESS': - raise exceptions.IntrospectionError( - "Introspection completed with errors: {}" - .format(payload['message'])) + print('Successfully introspected nodes: {}'.format(node_uuids)) -def introspect_manageable_nodes(clients, **workflow_input): +def introspect_manageable_nodes(clients, run_validations, concurrency): """Introspect all manageable nodes Run the tripleo.baremetal.v1.introspect_manageable_nodes Mistral workflow. """ - workflow_client = clients.workflow_engine - tripleoclients = clients.tripleoclient - - print("Waiting for introspection to finish...") - - errors = [] - - with tripleoclients.messaging_websocket() as ws: - 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.") + introspect( + clients=clients, + node_uuids=[ + i.uuid for i in clients.baremetal.node.list() + if i.provision_state == "manageable" and not i.maintenance + ], + run_validations=run_validations, + concurrency=concurrency + ) def provide_manageable_nodes(clients, **workflow_input):