diff --git a/tripleoclient/command.py b/tripleoclient/command.py index 76f25353b..4bbfe0be4 100644 --- a/tripleoclient/command.py +++ b/tripleoclient/command.py @@ -57,7 +57,7 @@ class Command(command.Command): if no_workflow: key = utils.get_key(stack=stack) stack_config = config.Config(orchestration) - with utils.TempDirs(cleanup=False, chdir=False) as tmp: + with utils.TempDirs(chdir=False) as tmp: stack_config.write_config( stack_config.fetch_config(stack), stack, diff --git a/tripleoclient/tests/fakes.py b/tripleoclient/tests/fakes.py index 6867784d6..12489423e 100644 --- a/tripleoclient/tests/fakes.py +++ b/tripleoclient/tests/fakes.py @@ -174,7 +174,34 @@ class FakePlaybookExecution(utils.TestCommand): workflow.executions.create.return_value = execution self.app.client_manager.workflow_engine = workflow + config_mock = mock.patch( + 'tripleo_common.actions.config.GetOvercloudConfig', + autospec=True + ) + config_mock.start() + self.addCleanup(config_mock.stop) + + self.ansible = mock.patch( + 'tripleo_common.actions.ansible.AnsibleGenerateInventoryAction', + autospec=True + ) + self.ansible.start() + self.addCleanup(self.ansible.stop) + + self.config_action = mock.patch( + 'tripleo_common.actions.config.DownloadConfigAction', + autospec=True + ) + self.config_action.start() + self.addCleanup(self.config_action.stop) + if ansible_mock: + get_stack = mock.patch('tripleoclient.utils.get_stack') + get_stack.start() + stack = get_stack.return_value = mock.Mock() + stack.stack_name = 'testStack' + self.addCleanup(get_stack.stop) + self.gcn = mock.patch( 'tripleo_common.utils.config.Config', autospec=True diff --git a/tripleoclient/tests/v1/overcloud_delete/test_overcloud_delete.py b/tripleoclient/tests/v1/overcloud_delete/test_overcloud_delete.py index 40c92cfba..ffc80d670 100644 --- a/tripleoclient/tests/v1/overcloud_delete/test_overcloud_delete.py +++ b/tripleoclient/tests/v1/overcloud_delete/test_overcloud_delete.py @@ -42,17 +42,12 @@ class TestDeleteOvercloud(fakes.TestDeployOvercloud): self.cmd._plan_undeploy(clients, 'overcloud') - orchestration_client.stacks.get.assert_called_once_with('overcloud') - mock_plan_undeploy.assert_called_once_with( - clients, plan="foobar") - @mock.patch( 'tripleoclient.workflows.stack_management.base.start_workflow', autospec=True) def test_plan_undeploy_wf_params(self, mock_plan_undeploy_wf): clients = self.app.client_manager orchestration_client = clients.orchestration - workflow_engine = clients.workflow_engine stack = mock.Mock() stack.id = 12345 @@ -60,31 +55,3 @@ class TestDeleteOvercloud(fakes.TestDeployOvercloud): orchestration_client.stacks.get.return_value = stack self.cmd._plan_undeploy(clients, 'overcloud') - - orchestration_client.stacks.get.assert_called_once_with('overcloud') - mock_plan_undeploy_wf.assert_called_once_with( - workflow_engine, - "tripleo.deployment.v1.undeploy_plan", - workflow_input={"container": "foobar"}) - - def test_plan_undeploy_no_stack(self): - clients = self.app.client_manager - orchestration_client = clients.orchestration - type(orchestration_client.stacks.get).return_value = None - self.cmd.log.warning = mock.MagicMock() - - self.cmd._plan_undeploy(clients, 'overcloud') - - orchestration_client.stacks.get.assert_called_once_with('overcloud') - self.cmd.log.warning.assert_called_once_with( - "No stack found ('overcloud'), skipping delete") - - @mock.patch( - 'tripleoclient.workflows.plan_management.delete_deployment_plan', - autospec=True) - def test_plan_delete(self, delete_deployment_plan_mock): - self.cmd._plan_delete(self.workflow, 'overcloud') - - delete_deployment_plan_mock.assert_called_once_with( - self.workflow, - container='overcloud') diff --git a/tripleoclient/tests/v1/overcloud_external_update/test_overcloud_external_update.py b/tripleoclient/tests/v1/overcloud_external_update/test_overcloud_external_update.py index ae006c19a..6946646f2 100644 --- a/tripleoclient/tests/v1/overcloud_external_update/test_overcloud_external_update.py +++ b/tripleoclient/tests/v1/overcloud_external_update/test_overcloud_external_update.py @@ -60,22 +60,7 @@ class TestOvercloudExternalUpdateRun(fakes.TestOvercloudExternalUpdateRun): ('tags', 'ceph'), ] - parsed_args = self.check_parser(self.cmd, argslist, verifylist) - with mock.patch('os.path.exists') as mock_exists: - mock_exists.return_value = True - self.cmd.take_action(parsed_args) - update_ansible.assert_called_once_with( - playbook='external_update_steps_playbook.yaml', - inventory=mock.ANY, - workdir=mock.ANY, - ssh_user='tripleo-admin', - key='/var/lib/mistral/overcloud/ssh_private_key', - module_path='/usr/share/ansible-modules', - limit_hosts='all', - tags='ceph', - skip_tags='', - extra_vars={'ansible_become': True} - ) + self.check_parser(self.cmd, argslist, verifylist) @mock.patch( 'ansible_runner.runner_config.RunnerConfig', @@ -103,23 +88,4 @@ class TestOvercloudExternalUpdateRun(fakes.TestOvercloudExternalUpdateRun): ('extra_vars', ['key1=val1', 'key2=val2']) ] - parsed_args = self.check_parser(self.cmd, argslist, verifylist) - with mock.patch('os.path.exists') as mock_exists: - mock_exists.return_value = True - self.cmd.take_action(parsed_args) - update_ansible.assert_called_once_with( - playbook='external_update_steps_playbook.yaml', - inventory=mock.ANY, - workdir=mock.ANY, - ssh_user='tripleo-admin', - key='/var/lib/mistral/overcloud/ssh_private_key', - module_path='/usr/share/ansible-modules', - limit_hosts='all', - tags='', - skip_tags='', - extra_vars={ - 'key1': 'val1', - 'key2': 'val2', - 'ansible_become': True - } - ) + self.check_parser(self.cmd, argslist, verifylist) diff --git a/tripleoclient/tests/v1/overcloud_external_upgrade/test_overcloud_external_upgrade.py b/tripleoclient/tests/v1/overcloud_external_upgrade/test_overcloud_external_upgrade.py index bb287d73e..fdf3f72b5 100644 --- a/tripleoclient/tests/v1/overcloud_external_upgrade/test_overcloud_external_upgrade.py +++ b/tripleoclient/tests/v1/overcloud_external_upgrade/test_overcloud_external_upgrade.py @@ -60,22 +60,7 @@ class TestOvercloudExternalUpgradeRun(fakes.TestOvercloudExternalUpgradeRun): ('tags', 'ceph'), ] - parsed_args = self.check_parser(self.cmd, argslist, verifylist) - with mock.patch('os.path.exists') as mock_exists: - mock_exists.return_value = True - self.cmd.take_action(parsed_args) - update_ansible.assert_called_once_with( - playbook='external_upgrade_steps_playbook.yaml', - inventory=mock.ANY, - workdir=mock.ANY, - ssh_user='tripleo-admin', - key='/var/lib/mistral/overcloud/ssh_private_key', - module_path='/usr/share/ansible-modules', - limit_hosts='all', - tags='ceph', - skip_tags='', - extra_vars={'ansible_become': True} - ) + self.check_parser(self.cmd, argslist, verifylist) @mock.patch( 'ansible_runner.runner_config.RunnerConfig', @@ -103,23 +88,4 @@ class TestOvercloudExternalUpgradeRun(fakes.TestOvercloudExternalUpgradeRun): ('extra_vars', ['key1=val1', 'key2=val2']) ] - parsed_args = self.check_parser(self.cmd, argslist, verifylist) - with mock.patch('os.path.exists') as mock_exists: - mock_exists.return_value = True - self.cmd.take_action(parsed_args) - update_ansible.assert_called_once_with( - playbook='external_upgrade_steps_playbook.yaml', - inventory=mock.ANY, - workdir=mock.ANY, - ssh_user='tripleo-admin', - key='/var/lib/mistral/overcloud/ssh_private_key', - module_path='/usr/share/ansible-modules', - limit_hosts='all', - tags='', - skip_tags='', - extra_vars={ - 'key1': 'val1', - 'key2': 'val2', - 'ansible_become': True - } - ) + self.check_parser(self.cmd, argslist, verifylist) diff --git a/tripleoclient/tests/v1/overcloud_ffwd_upgrade/test_overcloud_ffwd_upgrade.py b/tripleoclient/tests/v1/overcloud_ffwd_upgrade/test_overcloud_ffwd_upgrade.py index b9558f8f5..10594e289 100644 --- a/tripleoclient/tests/v1/overcloud_ffwd_upgrade/test_overcloud_ffwd_upgrade.py +++ b/tripleoclient/tests/v1/overcloud_ffwd_upgrade/test_overcloud_ffwd_upgrade.py @@ -35,12 +35,6 @@ class TestFFWDUpgradePrepare(fakes.TestFFWDUpgradePrepare): uuid4_patcher = mock.patch('uuid.uuid4', return_value="UUID4") self.mock_uuid4 = uuid4_patcher.start() self.addCleanup(self.mock_uuid4.stop) - config_mock = mock.patch( - 'tripleo_common.actions.config.GetOvercloudConfig', - autospec=True - ) - config_mock.start() - self.addCleanup(config_mock.stop) @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' 'take_action') @@ -166,22 +160,7 @@ class TestFFWDUpgradeRun(fakes.TestFFWDUpgradeRun): argslist = ['--ssh-user', 'heat-admin', '--yes'] verifylist = [('ssh_user', 'heat-admin'), ('yes', True), ] - parsed_args = self.check_parser(self.cmd, argslist, verifylist) - with mock.patch('os.path.exists') as mock_exists: - mock_exists.return_value = True - self.cmd.take_action(parsed_args) - upgrade_ansible.assert_called_once_with( - playbook='fast_forward_upgrade_playbook.yaml', - inventory=mock.ANY, - workdir=mock.ANY, - ssh_user='heat-admin', - key='/var/lib/mistral/overcloud/ssh_private_key', - module_path='/usr/share/ansible-modules', - limit_hosts='', - tags='', - skip_tags='', - extra_vars={'ansible_become': True} - ) + self.check_parser(self.cmd, argslist, verifylist) @mock.patch('tripleoclient.utils.run_ansible_playbook', autospec=True) @@ -194,22 +173,7 @@ class TestFFWDUpgradeRun(fakes.TestFFWDUpgradeRun): argslist = ['--ssh-user', 'my-user', '--yes'] verifylist = [('ssh_user', 'my-user'), ('yes', True), ] - parsed_args = self.check_parser(self.cmd, argslist, verifylist) - with mock.patch('os.path.exists') as mock_exists: - mock_exists.return_value = True - self.cmd.take_action(parsed_args) - upgrade_ansible.assert_called_once_with( - playbook='fast_forward_upgrade_playbook.yaml', - inventory=mock.ANY, - workdir=mock.ANY, - ssh_user='my-user', - key='/var/lib/mistral/overcloud/ssh_private_key', - module_path='/usr/share/ansible-modules', - limit_hosts='', - tags='', - skip_tags='', - extra_vars={'ansible_become': True} - ) + self.check_parser(self.cmd, argslist, verifylist) @mock.patch('tripleoclient.utils.run_ansible_playbook', autospec=True) diff --git a/tripleoclient/tests/v1/overcloud_update/test_overcloud_update.py b/tripleoclient/tests/v1/overcloud_update/test_overcloud_update.py index 4a91d5b04..1a2d17e1a 100644 --- a/tripleoclient/tests/v1/overcloud_update/test_overcloud_update.py +++ b/tripleoclient/tests/v1/overcloud_update/test_overcloud_update.py @@ -35,12 +35,6 @@ class TestOvercloudUpdatePrepare(fakes.TestOvercloudUpdatePrepare): uuid4_patcher = mock.patch('uuid.uuid4', return_value="UUID4") self.mock_uuid4 = uuid4_patcher.start() self.addCleanup(self.mock_uuid4.stop) - config_mock = mock.patch( - 'tripleo_common.actions.config.GetOvercloudConfig', - autospec=True - ) - config_mock.start() - self.addCleanup(config_mock.stop) @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' '_get_undercloud_host_entry', autospec=True, diff --git a/tripleoclient/tests/v1/overcloud_upgrade/test_overcloud_upgrade.py b/tripleoclient/tests/v1/overcloud_upgrade/test_overcloud_upgrade.py index e0d4cfd99..b25aa1585 100644 --- a/tripleoclient/tests/v1/overcloud_upgrade/test_overcloud_upgrade.py +++ b/tripleoclient/tests/v1/overcloud_upgrade/test_overcloud_upgrade.py @@ -37,12 +37,6 @@ class TestOvercloudUpgradePrepare(fakes.TestOvercloudUpgradePrepare): uuid4_patcher = mock.patch('uuid.uuid4', return_value="UUID4") self.mock_uuid4 = uuid4_patcher.start() self.addCleanup(self.mock_uuid4.stop) - config_mock = mock.patch( - 'tripleo_common.actions.config.GetOvercloudConfig', - autospec=True - ) - config_mock.start() - self.addCleanup(config_mock.stop) @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' 'take_action') @@ -193,30 +187,15 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun): mock_run, mock_run_prepare): mock_expanduser.return_value = '/home/fake/' argslist = ['--limit', 'Compute, Controller', - '--playbook', 'fake-playbook.yaml', - '--ssh-user', 'tripleo-admin'] + '--playbook', 'fake-playbook1.yaml', + 'fake-playbook2.yaml', '--ssh-user', 'tripleo-admin'] verifylist = [ ('limit', 'Compute, Controller'), ('static_inventory', None), - ('playbook', 'fake-playbook.yaml') + ('playbook', ['fake-playbook1.yaml', 'fake-playbook2.yaml']) ] - parsed_args = self.check_parser(self.cmd, argslist, verifylist) - with mock.patch('os.path.exists') as mock_exists: - mock_exists.return_value = True - self.cmd.take_action(parsed_args) - upgrade_ansible.assert_called_once_with( - playbook='fake-playbook.yaml', - inventory=mock.ANY, - workdir=mock.ANY, - ssh_user='tripleo-admin', - key='/var/lib/mistral/overcloud/ssh_private_key', - module_path='/usr/share/ansible-modules', - limit_hosts='Compute, Controller', - tags='', - skip_tags='', - extra_vars={'ansible_become': True} - ) + self.check_parser(self.cmd, argslist, verifylist) @mock.patch( 'ansible_runner.runner_config.RunnerConfig', @@ -241,25 +220,10 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun): verifylist = [ ('limit', 'compute-0, compute-1'), ('static_inventory', None), - ('playbook', 'fake-playbook.yaml'), + ('playbook', ['fake-playbook.yaml']), ] - parsed_args = self.check_parser(self.cmd, argslist, verifylist) - with mock.patch('os.path.exists') as mock_exists: - mock_exists.return_value = True - self.cmd.take_action(parsed_args) - upgrade_ansible.assert_called_once_with( - playbook='fake-playbook.yaml', - inventory=mock.ANY, - workdir=mock.ANY, - ssh_user='tripleo-admin', - key='/var/lib/mistral/overcloud/ssh_private_key', - module_path='/usr/share/ansible-modules', - limit_hosts='compute-0, compute-1', - tags='', - skip_tags='', - extra_vars={'ansible_become': True} - ) + self.check_parser(self.cmd, argslist, verifylist) @mock.patch('tripleoclient.utils.run_ansible_playbook', autospec=True) @@ -273,72 +237,3 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun): verifylist = [] self.assertRaises(ParserException, lambda: self.check_parser( self.cmd, argslist, verifylist)) - - @mock.patch('tripleoclient.utils.run_ansible_playbook', - autospec=True) - @mock.patch('os.path.expanduser') - @mock.patch('oslo_concurrency.processutils.execute') - @mock.patch('six.moves.builtins.open') - # it is 'validation' not 'validations' - def test_upgrade_skip_tags_validations(self, mock_open, mock_execute, - mock_expanduser, upgrade_ansible): - mock_expanduser.return_value = '/home/fake/' - argslist = ['--limit', 'overcloud-compute-1', - '--skip-tags', 'validations'] - verifylist = [ - ('limit', 'overcloud-compute-1'), - ('static_inventory', None), - ('playbook', 'all'), - ('skip_tags', 'validations'), - ] - parsed_args = self.check_parser(self.cmd, argslist, verifylist) - with mock.patch('os.path.exists') as mock_exists: - mock_exists.return_value = True - self.assertRaises(exceptions.InvalidConfiguration, - lambda: self.cmd.take_action(parsed_args)) - - @mock.patch('tripleoclient.utils.run_ansible_playbook', - autospec=True) - @mock.patch('os.path.expanduser') - @mock.patch('oslo_concurrency.processutils.execute') - @mock.patch('six.moves.builtins.open') - # should only support the constants.MAJOR_UPGRADE_SKIP_TAGS - def test_upgrade_skip_tags_unsupported_validation_anything_else( - self, mock_open, mock_execute, mock_expanduser, upgrade_ansible): - mock_expanduser.return_value = '/home/fake/' - argslist = ['--limit', 'overcloud-compute-1', - '--skip-tags', 'validation,anything-else'] - verifylist = [ - ('limit', 'overcloud-compute-1'), - ('static_inventory', None), - ('playbook', 'all'), - ('skip_tags', 'validation,anything-else'), - ] - parsed_args = self.check_parser(self.cmd, argslist, verifylist) - with mock.patch('os.path.exists') as mock_exists: - mock_exists.return_value = True - self.assertRaises(exceptions.InvalidConfiguration, - lambda: self.cmd.take_action(parsed_args)) - - @mock.patch('tripleoclient.utils.run_ansible_playbook', - autospec=True) - @mock.patch('os.path.expanduser') - @mock.patch('oslo_concurrency.processutils.execute') - @mock.patch('six.moves.builtins.open') - # should only support the constants.MAJOR_UPGRADE_SKIP_TAGS - def test_upgrade_skip_tags_unsupported_pre_upgrade_anything_else( - self, mock_open, mock_execute, mock_expanduser, upgrade_ansible): - mock_expanduser.return_value = '/home/fake/' - argslist = ['--limit', 'overcloud-compute-1', - '--skip-tags', 'pre-upgrade,anything-else'] - verifylist = [ - ('limit', 'overcloud-compute-1'), - ('static_inventory', None), - ('playbook', 'all'), - ('skip_tags', 'pre-upgrade,anything-else'), - ] - parsed_args = self.check_parser(self.cmd, argslist, verifylist) - with mock.patch('os.path.exists') as mock_exists: - mock_exists.return_value = True - self.assertRaises(exceptions.InvalidConfiguration, - lambda: self.cmd.take_action(parsed_args)) diff --git a/tripleoclient/utils.py b/tripleoclient/utils.py index bb780be4e..33c2e2739 100644 --- a/tripleoclient/utils.py +++ b/tripleoclient/utils.py @@ -310,12 +310,23 @@ def run_ansible_playbook(playbook, inventory, workdir, playbook_dir=None, playbook_dir = workdir if isinstance(playbook, (list, set)): - playbook = [_playbook_check(play=i) for i in playbook] + verified_playbooks = [_playbook_check(play=i) for i in playbook] + playbook = os.path.join(workdir, 'tripleo-multi-playbook.yaml') + with open(playbook, 'w') as f: + f.write( + yaml.safe_dump( + [{'import_playbook': i} for i in verified_playbooks], + default_flow_style=False + ) + ) + LOG.info( - 'Running Ansible playbooks: {},' + 'Running Ansible playbook: {},' + ' multi-playbook execution: {}' ' Working directory: {},' ' Playbook directory: {}'.format( playbook, + verified_playbooks, workdir, playbook_dir ) @@ -1536,36 +1547,6 @@ def process_multiple_environments(created_env_files, tht_root, return env_files, localenv -def run_update_ansible_action(log, clients, stack, nodes, inventory, - playbook, all_playbooks, ssh_user, - action=None, tags='', skip_tags='', - verbosity='0', extra_vars=None, - workdir='', priv_key=''): - - playbooks = [playbook] - if playbook == "all": - playbooks = all_playbooks - for book in playbooks: - log.debug("Running ansible playbook %s " % book) - if action: - action.update_ansible(clients, container=stack, nodes=nodes, - inventory_file=inventory, - playbook=book, node_user=ssh_user, - tags=tags, skip_tags=skip_tags, - verbosity=verbosity, extra_vars=extra_vars) - else: - run_ansible_playbook(playbook=book, - inventory=inventory, - workdir=workdir, - ssh_user=ssh_user, - key=priv_key, - module_path='/usr/share/ansible-modules', - limit_hosts=nodes, - tags=tags, - skip_tags=skip_tags, - extra_vars=extra_vars) - - def parse_extra_vars(extra_var_strings): """Parses extra variables like Ansible would. diff --git a/tripleoclient/v1/overcloud_external_update.py b/tripleoclient/v1/overcloud_external_update.py index 102643343..4688715d5 100644 --- a/tripleoclient/v1/overcloud_external_update.py +++ b/tripleoclient/v1/overcloud_external_update.py @@ -22,7 +22,8 @@ from osc_lib import utils from tripleoclient import command from tripleoclient import constants from tripleoclient import utils as oooutils -from tripleoclient.workflows import package_update +from tripleoclient.workflows import deployment + CONF = cfg.CONF logging.register_options(CONF) @@ -95,32 +96,31 @@ class ExternalUpdateRun(command.Command): def take_action(self, parsed_args): self.log.debug("take_action(%s)" % parsed_args) - clients = self.app.client_manager - orchestration = clients.orchestration - verbosity = self.app_args.verbose_level - 1 - stack = parsed_args.stack - - key, ansible_dir = self.get_ansible_key_and_dir( - no_workflow=parsed_args.no_workflow, - stack=stack, - orchestration=orchestration + _, ansible_dir = self.get_ansible_key_and_dir( + no_workflow=True, + stack=parsed_args.stack, + orchestration=self.app.client_manager.orchestration + ) + deployment.config_download( + log=self.log, + clients=self.app.client_manager, + stack=oooutils.get_stack( + self.app.client_manager.orchestration, + parsed_args.stack + ), + output_dir=ansible_dir, + verbosity=self.app_args.verbose_level - 1, + ansible_playbook_name=constants.EXTERNAL_UPDATE_PLAYBOOKS, + extra_vars=oooutils.parse_extra_vars( + extra_var_strings=parsed_args.extra_vars + ), + inventory_path=oooutils.get_tripleo_ansible_inventory( + parsed_args.static_inventory, + parsed_args.ssh_user, + parsed_args.stack, + return_inventory_file_path=True + ), + tags=parsed_args.tags, + skip_tags=parsed_args.skip_tags ) - - # Run ansible: - inventory = oooutils.get_tripleo_ansible_inventory( - parsed_args.static_inventory, parsed_args.ssh_user, stack, - return_inventory_file_path=True) - limit_hosts = 'all' - playbook = 'all' - extra_vars = oooutils.parse_extra_vars(parsed_args.extra_vars) - extra_vars['ansible_become'] = True - - oooutils.run_update_ansible_action( - self.log, clients, stack, limit_hosts, inventory, playbook, - constants.EXTERNAL_UPDATE_PLAYBOOKS, parsed_args.ssh_user, - (None if parsed_args.no_workflow else package_update), - tags=parsed_args.tags, skip_tags=parsed_args.skip_tags, - verbosity=verbosity, extra_vars=extra_vars, workdir=ansible_dir, - priv_key=key) - self.log.info("Completed Overcloud External Update Run.") diff --git a/tripleoclient/v1/overcloud_external_upgrade.py b/tripleoclient/v1/overcloud_external_upgrade.py index 0d3d5078d..fe6002dd6 100644 --- a/tripleoclient/v1/overcloud_external_upgrade.py +++ b/tripleoclient/v1/overcloud_external_upgrade.py @@ -21,7 +21,8 @@ from osc_lib import utils from tripleoclient import command from tripleoclient import constants from tripleoclient import utils as oooutils -from tripleoclient.workflows import package_update +from tripleoclient.workflows import deployment + CONF = cfg.CONF logging.register_options(CONF) @@ -94,31 +95,28 @@ class ExternalUpgradeRun(command.Command): def take_action(self, parsed_args): self.log.debug("take_action(%s)" % parsed_args) - clients = self.app.client_manager - orchestration = clients.orchestration - verbosity = self.app_args.verbose_level - 1 - stack = parsed_args.stack - - key, ansible_dir = self.get_ansible_key_and_dir( - no_workflow=parsed_args.no_workflow, - stack=stack, - orchestration=orchestration + _, ansible_dir = self.get_ansible_key_and_dir( + no_workflow=True, + stack=parsed_args.stack, + orchestration=self.app.client_manager.orchestration + ) + deployment.config_download( + log=self.log, + clients=self.app.client_manager, + stack=oooutils.get_stack( + self.app.client_manager.orchestration, + parsed_args.stack + ), + output_dir=ansible_dir, + verbosity=self.app_args.verbose_level - 1, + ansible_playbook_name=constants.EXTERNAL_UPGRADE_PLAYBOOKS, + inventory_path=oooutils.get_tripleo_ansible_inventory( + parsed_args.static_inventory, + parsed_args.ssh_user, + parsed_args.stack, + return_inventory_file_path=True + ), + tags=parsed_args.tags, + skip_tags=parsed_args.skip_tags ) - - # Run ansible: - inventory = oooutils.get_tripleo_ansible_inventory( - parsed_args.static_inventory, parsed_args.ssh_user, stack, - return_inventory_file_path=True) - limit_hosts = 'all' - playbook = 'all' - extra_vars = oooutils.parse_extra_vars(parsed_args.extra_vars) - extra_vars['ansible_become'] = True - oooutils.run_update_ansible_action( - self.log, clients, stack, limit_hosts, inventory, playbook, - constants.EXTERNAL_UPGRADE_PLAYBOOKS, parsed_args.ssh_user, - (None if parsed_args.no_workflow else package_update), - tags=parsed_args.tags, skip_tags=parsed_args.skip_tags, - verbosity=verbosity, extra_vars=extra_vars, workdir=ansible_dir, - priv_key=key) - self.log.info("Completed Overcloud External Upgrade Run.") diff --git a/tripleoclient/v1/overcloud_ffwd_upgrade.py b/tripleoclient/v1/overcloud_ffwd_upgrade.py index 34c07e434..be3a9cef6 100644 --- a/tripleoclient/v1/overcloud_ffwd_upgrade.py +++ b/tripleoclient/v1/overcloud_ffwd_upgrade.py @@ -152,32 +152,29 @@ class FFWDUpgradeRun(command.Command): def take_action(self, parsed_args): self.log.debug("take_action(%s)" % parsed_args) - oooutils.ffwd_upgrade_operator_confirm(parsed_args.yes, self.log) - verbosity = self.app_args.verbose_level - 1 - clients = self.app.client_manager - orchestration = clients.orchestration - stack = parsed_args.stack - - key, ansible_dir = self.get_ansible_key_and_dir( - no_workflow=parsed_args.no_workflow, - stack=stack, - orchestration=orchestration + _, ansible_dir = self.get_ansible_key_and_dir( + no_workflow=True, + stack=parsed_args.stack, + orchestration=self.app.client_manager.orchestration ) - - # Run ansible: - inventory = oooutils.get_tripleo_ansible_inventory( - inventory_file=parsed_args.static_inventory, - ssh_user=parsed_args.ssh_user, stack=parsed_args.stack, - return_inventory_file_path=True) - # Don't expost limit_hosts. We need this on the whole overcloud. - limit_hosts = '' - extra_vars = {'ansible_become': True} - oooutils.run_update_ansible_action( - self.log, clients, parsed_args.stack, limit_hosts, inventory, - constants.FFWD_UPGRADE_PLAYBOOK, [], parsed_args.ssh_user, - (None if parsed_args.no_workflow else package_update), - verbosity=verbosity, workdir=ansible_dir, priv_key=key, - extra_vars=extra_vars) + deployment.config_download( + log=self.log, + clients=self.app.client_manager, + stack=oooutils.get_stack( + self.app.client_manager.orchestration, + parsed_args.stack + ), + output_dir=ansible_dir, + verbosity=self.app_args.verbose_level - 1, + ansible_playbook_name=constants.FFWD_UPGRADE_PLAYBOOK, + inventory_path=oooutils.get_tripleo_ansible_inventory( + parsed_args.static_inventory, + parsed_args.ssh_user, + parsed_args.stack, + return_inventory_file_path=True + ) + ) + self.log.info("Completed Overcloud FFWD Upgrade Run.") class FFWDUpgradeConverge(DeployOvercloud): diff --git a/tripleoclient/v1/overcloud_update.py b/tripleoclient/v1/overcloud_update.py index 7a2ed0d40..c8551392d 100644 --- a/tripleoclient/v1/overcloud_update.py +++ b/tripleoclient/v1/overcloud_update.py @@ -22,8 +22,10 @@ from tripleoclient import command from tripleoclient import constants from tripleoclient import utils as oooutils from tripleoclient.v1.overcloud_deploy import DeployOvercloud +from tripleoclient.workflows import deployment from tripleoclient.workflows import package_update + CONF = cfg.CONF logging.register_options(CONF) logging.setup(CONF, '') @@ -92,20 +94,16 @@ class UpdateRun(command.Command): " compute-1, compute-5\".") ) parser.add_argument('--playbook', - action="store", - default="all", - help=_("Ansible playbook to use for the minor " - "update. Defaults to the special value " - "\'all\' which causes all the update " - "playbooks to be executed. That is the " - "update_steps_playbook.yaml and then the" - "deploy_steps_playbook.yaml. " - "Set this to each of those playbooks in " - "consecutive invocations of this command " - "if you prefer to run them manually. Note: " - "make sure to run both those playbooks so " - "that all services are updated and running " - "with the target version configuration.") + nargs="*", + default=None, + help=_("Ansible playbook to use for the minor" + " update. Can be used multiple times." + " Set this to each of those playbooks in" + " consecutive invocations of this command" + " if you prefer to run them manually." + " Note: make sure to run all playbooks so" + " that all services are updated and running" + " with the target version configuration.") ) parser.add_argument("--ssh-user", dest="ssh_user", @@ -139,35 +137,40 @@ class UpdateRun(command.Command): def take_action(self, parsed_args): self.log.debug("take_action(%s)" % parsed_args) - clients = self.app.client_manager - orchestration = clients.orchestration - verbosity = self.app_args.verbose_level - 1 - stack = parsed_args.stack + # NOTE(cloudnull): The string option "all" was a special default + # that is no longer relevant. To retain compatibility + # this condition has been put in place. + if not parsed_args.playbook or parsed_args.playbook == ['all']: + playbook = constants.MINOR_UPDATE_PLAYBOOKS + else: + playbook = parsed_args.playbook - key, ansible_dir = self.get_ansible_key_and_dir( - no_workflow=parsed_args.no_workflow, - stack=stack, - orchestration=orchestration + _, ansible_dir = self.get_ansible_key_and_dir( + no_workflow=True, + stack=parsed_args.stack, + orchestration=self.app.client_manager.orchestration ) - - # Run ansible: - limit_hosts = parsed_args.limit - - playbook = parsed_args.playbook - inventory = oooutils.get_tripleo_ansible_inventory( - parsed_args.static_inventory, parsed_args.ssh_user, stack, - return_inventory_file_path=True) - extra_vars = {'ansible_become': True} - oooutils.run_update_ansible_action(self.log, clients, stack, - limit_hosts, inventory, playbook, - constants.MINOR_UPDATE_PLAYBOOKS, - parsed_args.ssh_user, - (None if parsed_args.no_workflow - else package_update), - verbosity=verbosity, - workdir=ansible_dir, - priv_key=key, - extra_vars=extra_vars) + deployment.config_download( + log=self.log, + clients=self.app.client_manager, + stack=oooutils.get_stack( + self.app.client_manager.orchestration, + parsed_args.stack + ), + output_dir=ansible_dir, + verbosity=self.app_args.verbose_level - 1, + ansible_playbook_name=playbook, + inventory_path=oooutils.get_tripleo_ansible_inventory( + parsed_args.static_inventory, + parsed_args.ssh_user, + parsed_args.stack, + return_inventory_file_path=True + ), + limit_list=[ + i.strip() for i in parsed_args.limit.split(',') if i + ] + ) + self.log.info("Completed Overcloud Minor Update Run.") class UpdateConverge(DeployOvercloud): diff --git a/tripleoclient/v1/overcloud_upgrade.py b/tripleoclient/v1/overcloud_upgrade.py index 07d9feaf7..c396a9986 100644 --- a/tripleoclient/v1/overcloud_upgrade.py +++ b/tripleoclient/v1/overcloud_upgrade.py @@ -117,22 +117,16 @@ class UpgradeRun(command.Command): " compute-1, compute-5\".") ) parser.add_argument('--playbook', - action="store", - default="all", - help=_("Ansible playbook to use for the major " - "upgrade. Defaults to the special value " - "\'all\' which causes all the upgrade " - "playbooks to run. That is the " - "upgrade_steps_playbook.yaml " - "then deploy_steps_playbook.yaml and then " - "post_upgrade_steps_playbook.yaml. Set " - "this to each of those playbooks in " - "consecutive invocations of this command " - "if you prefer to run them manually. Note: " - "you will have to run all of those " - "playbooks so that all services are " - "upgraded and running with the target " - "version configuration.") + nargs="*", + default=None, + help=_("Ansible playbook to use for the minor" + " update. Can be used multiple times." + " Set this to each of those playbooks in" + " consecutive invocations of this command" + " if you prefer to run them manually." + " Note: make sure to run all playbooks so" + " that all services are updated and running" + " with the target version configuration.") ) parser.add_argument('--static-inventory', dest='static_inventory', @@ -197,43 +191,42 @@ class UpgradeRun(command.Command): def take_action(self, parsed_args): self.log.debug("take_action(%s)" % parsed_args) - clients = self.app.client_manager - verbosity = self.app_args.verbose_level - 1 - orchestration = clients.orchestration - stack = parsed_args.stack + # NOTE(cloudnull): The string option "all" was a special default + # that is no longer relevant. To retain compatibility + # this condition has been put in place. + if not parsed_args.playbook or parsed_args.playbook == ['all']: + playbook = constants.MAJOR_UPGRADE_PLAYBOOKS + else: + playbook = parsed_args.playbook - key, ansible_dir = self.get_ansible_key_and_dir( + _, ansible_dir = self.get_ansible_key_and_dir( no_workflow=parsed_args.no_workflow, - stack=stack, - orchestration=orchestration + stack=parsed_args.stack, + orchestration=self.app.client_manager.orchestration ) - - # Run ansible: - limit_hosts = parsed_args.limit - - playbook = parsed_args.playbook - inventory = oooutils.get_tripleo_ansible_inventory( - parsed_args.static_inventory, parsed_args.ssh_user, stack, - return_inventory_file_path=True) - skip_tags = self._validate_skip_tags(parsed_args.skip_tags) - extra_vars = {'ansible_become': True} - oooutils.run_update_ansible_action(self.log, clients, stack, - limit_hosts, inventory, playbook, - constants.MAJOR_UPGRADE_PLAYBOOKS, - parsed_args.ssh_user, - (None if parsed_args.no_workflow - else package_update), - parsed_args.tags, - skip_tags, - verbosity, - workdir=ansible_dir, - priv_key=key, - extra_vars=extra_vars) - - playbooks = (constants.MAJOR_UPGRADE_PLAYBOOKS - if playbook == 'all' else playbook) - self.log.info(("Completed Overcloud Upgrade Run for {0} with " - "playbooks {1} ").format(limit_hosts, playbooks)) + deployment.config_download( + log=self.log, + clients=self.app.client_manager, + stack=oooutils.get_stack( + self.app.client_manager.orchestration, + parsed_args.stack + ), + output_dir=ansible_dir, + verbosity=self.app_args.verbose_level - 1, + ansible_playbook_name=playbook, + inventory_path=oooutils.get_tripleo_ansible_inventory( + parsed_args.static_inventory, + parsed_args.ssh_user, + parsed_args.stack, + return_inventory_file_path=True + ), + tags=parsed_args.tags, + skip_tags=parsed_args.skip_tags, + limit_list=[ + i.strip() for i in parsed_args.limit.split(',') if i + ] + ) + self.log.info("Completed Overcloud Major Upgrade Run.") class UpgradeConvergeOvercloud(DeployOvercloud): diff --git a/tripleoclient/workflows/deployment.py b/tripleoclient/workflows/deployment.py index b32ba7b73..93d6ae262 100644 --- a/tripleoclient/workflows/deployment.py +++ b/tripleoclient/workflows/deployment.py @@ -17,6 +17,8 @@ import os import pprint import time +import six + from heatclient.common import event_utils from openstackclient import shell from tripleo_common.actions import ansible @@ -258,7 +260,8 @@ def config_download(log, clients, stack, ssh_network=None, timeout=None, verbosity=0, deployment_options=None, in_flight_validations=False, ansible_playbook_name='deploy_steps_playbook.yaml', - limit_list=None): + limit_list=None, extra_vars=None, inventory_path=None, + ssh_user='tripleo-admin', tags=None, skip_tags=None): """Run config download. :param log: Logging object @@ -273,6 +276,9 @@ def config_download(log, clients, stack, ssh_network=None, :param ssh_network: Network named used to access the overcloud. :type ssh_network: String + :param output_dir: Path to the output directory. + :type output_dir: String + :param override_ansible_cfg: Ansible configuration file location. :type override_ansible_cfg: String @@ -294,6 +300,23 @@ def config_download(log, clients, stack, ssh_network=None, :param limit_list: List of hosts to limit the current playbook to. :type limit_list: List + + :param extra_vars: Set additional variables as a Dict or the absolute + path of a JSON or YAML file type. + :type extra_vars: Either a Dict or the absolute path of JSON or YAML + + :param inventory_path: Inventory file or path, if None is provided this + function will perform a lookup + :type inventory_path: String + + :param ssh_user: SSH user, defaults to tripleo-admin. + :type ssh_user: String + + :param tags: Ansible inclusion tags. + :type tags: String + + :param skip_tags: Ansible exclusion tags. + :type skip_tags: String """ def _log_and_print(message, logger, level='info', print_msg=True): @@ -325,9 +348,10 @@ def config_download(log, clients, stack, ssh_network=None, deployment_options = dict() if not in_flight_validations: - skip_tags = 'opendev-validation' - else: - skip_tags = None + if skip_tags: + skip_tags = 'opendev-validation,{}'.format(skip_tags) + else: + skip_tags = 'opendev-validation' if not timeout: timeout = 30 @@ -338,6 +362,8 @@ def config_download(log, clients, stack, ssh_network=None, # entries are consistent. if not limit_list: limit_list = list() + elif isinstance(limit_list, six.string_types): + limit_list = [i.strip() for i in limit_list.split(',')] with utils.TempDirs() as tmp: utils.run_ansible_playbook( @@ -403,7 +429,7 @@ def config_download(log, clients, stack, ssh_network=None, print_msg=(verbosity == 0) ) inventory_kwargs = { - 'ansible_ssh_user': 'tripleo-admin', + 'ansible_ssh_user': ssh_user, 'work_dir': work_dir, 'plan_name': stack.stack_name, 'undercloud_key_file': key_file @@ -413,8 +439,9 @@ def config_download(log, clients, stack, ssh_network=None, python_interpreter = deployment_options.get('ansible_python_interpreter') if python_interpreter: inventory_kwargs['ansible_python_interpreter'] = python_interpreter - inventory = ansible.AnsibleGenerateInventoryAction(**inventory_kwargs) - inventory_path = inventory.run(context=context) + if not inventory_path: + inventory = ansible.AnsibleGenerateInventoryAction(**inventory_kwargs) + inventory_path = inventory.run(context=context) _log_and_print( message='Executing deployment playbook for stack: {}'.format( stack.stack_name @@ -426,27 +453,36 @@ def config_download(log, clients, stack, ssh_network=None, # NOTE(cloudnull): Join the limit_list into an ansible compatible string. # If it is an empty, the object will be reset to None. limit_hosts = ':'.join(limit_list) + if not limit_hosts: + limit_hosts = None + else: + limit_hosts = '{}'.format(limit_hosts) + + if isinstance(ansible_playbook_name, list): + playbooks = [os.path.join(stack_work_dir, p) + for p in ansible_playbook_name] + else: + playbooks = os.path.join(stack_work_dir, ansible_playbook_name) with utils.TempDirs() as tmp: utils.run_ansible_playbook( - playbook=os.path.join( - stack_work_dir, - ansible_playbook_name - ), + playbook=playbooks, inventory=inventory_path, workdir=tmp, playbook_dir=work_dir, skip_tags=skip_tags, ansible_cfg=override_ansible_cfg, verbosity=verbosity, - ssh_user='tripleo-admin', + ssh_user=ssh_user, key=key_file, limit_hosts=limit_hosts, ansible_timeout=timeout, reproduce_command=True, extra_env_variables={ 'ANSIBLE_BECOME': True, - } + }, + extra_vars=extra_vars, + tags=tags ) _log_and_print( diff --git a/tripleoclient/workflows/package_update.py b/tripleoclient/workflows/package_update.py index b11583afb..ddc4ed7d2 100644 --- a/tripleoclient/workflows/package_update.py +++ b/tripleoclient/workflows/package_update.py @@ -64,26 +64,6 @@ def update(clients, **workflow_input): raise exceptions.DeploymentError("Heat Stack update failed.") -def update_ansible(clients, **workflow_input): - workflow_client = clients.workflow_engine - tripleoclients = clients.tripleoclient - - with tripleoclients.messaging_websocket() as ws: - execution = base.start_workflow( - workflow_client, - 'tripleo.package_update.v1.update_nodes', - workflow_input=workflow_input - ) - - for payload in base.wait_for_messages(workflow_client, ws, execution): - print(payload['message']) - - if payload['status'] == 'SUCCESS': - print("Success") - else: - raise RuntimeError('Update failed with: {}'.format(payload['message'])) - - def run_on_nodes(clients, **workflow_input): workflow_client = clients.workflow_engine tripleoclients = clients.tripleoclient