diff --git a/releasenotes/notes/deploy-overcloud-pre-provisioned-9d55ca9bda6c8a84.yaml b/releasenotes/notes/deploy-overcloud-pre-provisioned-9d55ca9bda6c8a84.yaml new file mode 100644 index 000000000..9ce3c4720 --- /dev/null +++ b/releasenotes/notes/deploy-overcloud-pre-provisioned-9d55ca9bda6c8a84.yaml @@ -0,0 +1,7 @@ +--- +features: + - | + Add the `--deployed-server` flag that can only be used with the + `--disable-validations`. When specified, allows to deploy an + overcloud on the pre-provisioned nodes and ignores missing nova + and ironic UC services. diff --git a/tripleoclient/tests/v1/overcloud_deploy/test_overcloud_deploy.py b/tripleoclient/tests/v1/overcloud_deploy/test_overcloud_deploy.py index 359a9dd45..7df3cdcf5 100644 --- a/tripleoclient/tests/v1/overcloud_deploy/test_overcloud_deploy.py +++ b/tripleoclient/tests/v1/overcloud_deploy/test_overcloud_deploy.py @@ -1431,3 +1431,55 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): self.assertRaises(exceptions.InvalidConfiguration, self.cmd.take_action, parsed_args) + + @mock.patch('tripleoclient.utils.wait_for_provision_state') + @mock.patch('tripleoclient.workflows.baremetal', autospec=True) + @mock.patch('tripleoclient.v1.baremetal', autospec=True) + @mock.patch('tripleoclient.utils.get_overcloud_endpoint', autospec=True) + @mock.patch('tripleoclient.utils.write_overcloudrc', autospec=True) + @mock.patch('tripleoclient.workflows.deployment.overcloudrc', + autospec=True) + @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' + '_deploy_tripleo_heat_templates_tmpdir', autospec=True) + def test_deployed_server(self, mock_deploy_tmpdir, mock_overcloudrc, + mock_write_overcloudrc, + mock_get_overcloud_endpoint, + mock_baremetal, mock_workflows_bm, + mock_provision): + arglist = ['--templates', '--deployed-server', '--disable-validations'] + verifylist = [ + ('templates', '/usr/share/openstack-tripleo-heat-templates/'), + ('deployed_server', True), + ('disable_validations', True), + ] + + clients = self.app.client_manager + clients.baremetal = mock.Mock() + clients.compute = mock.Mock() + orchestration_client = clients.orchestration + orchestration_client.stacks.get.return_value = mock.Mock() + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.cmd.take_action(parsed_args) + self.assertTrue(mock_deploy_tmpdir.called) + # FIXME(bogdando) this checks nothing and passes w/o --deployed-server + # Verify these mocks and clients aren't invoked with --deployed-server + self.assertNotCalled(self.cmd._predeploy_verify_capabilities) + self.assertNotCalled(mock_provision) + self.assertNotCalled(clients.baremetal) + self.assertNotCalled(clients.compute) + + @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' + '_deploy_tripleo_heat_templates', autospec=True) + def test_fail_overcloud_deploy_with_deployed_server_and_validations( + self, mock_deploy_tmpdir): + arglist = ['--templates', '--deployed-server'] + verifylist = [ + ('templates', '/usr/share/openstack-tripleo-heat-templates/'), + ('deployed_server', True), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.assertRaises(oscexc.CommandError, + self.cmd.take_action, + parsed_args) + self.assertFalse(mock_deploy_tmpdir.called) diff --git a/tripleoclient/v1/overcloud_deploy.py b/tripleoclient/v1/overcloud_deploy.py index 3d1bb7afc..851f8fa5b 100644 --- a/tripleoclient/v1/overcloud_deploy.py +++ b/tripleoclient/v1/overcloud_deploy.py @@ -51,13 +51,14 @@ class DeployOvercloud(command.Command): predeploy_warnings = 0 _password_cache = None - def _setup_clients(self): + def _setup_clients(self, parsed_args): self.clients = self.app.client_manager self.object_client = self.clients.tripleoclient.object_store self.workflow_client = self.clients.workflow_engine self.orchestration_client = self.clients.orchestration - self.compute_client = self.clients.compute - self.baremetal_client = self.clients.baremetal + if not parsed_args.deployed_server: + self.compute_client = self.clients.compute + self.baremetal_client = self.clients.baremetal def _update_parameters(self, args, stack): parameters = {} @@ -567,6 +568,12 @@ class DeployOvercloud(command.Command): "Error: The following files were not found: {0}".format( ", ".join(nonexisting_envs))) + if parsed_args.deployed_server and (parsed_args.run_validations + or not parsed_args.disable_validations): + raise oscexc.CommandError( + "Error: The --deployed-server cannot be used without " + "the --disable-validations") + # Check if disable_upgrade_deployment is set once self.log.debug("Checking that the disable_upgrade_deployment flag " "is set at least once in the roles file") @@ -810,12 +817,21 @@ class DeployOvercloud(command.Command): default=False, help=_('Disable password generation.') ) + parser.add_argument( + '--deployed-server', + action='store_true', + default=False, + help=_('Use pre-provisioned overcloud nodes. Removes baremetal,' + 'compute and image services requirements from the' + 'undercloud node. Must only be used with the' + '--disable-validations.') + ) return parser def take_action(self, parsed_args): self.log.debug("take_action(%s)" % parsed_args) - self._setup_clients() + self._setup_clients(parsed_args) # Swiftclient logs things like 404s at error level, which is a problem # because we use EAFP to check for the existence of files. Turn off