Merge "Add "yes" prompt for update/upgrades commands" into stable/train

This commit is contained in:
Zuul 2020-07-20 15:33:53 +00:00 committed by Gerrit Code Review
commit 11d7950d71
11 changed files with 205 additions and 26 deletions

View File

@ -0,0 +1,7 @@
---
features:
- |
The upgrade/update commands have a prompt by default now that ask for
confirmation before proceeding. It'll prevent an operator to run the
command and cause the problems to infrastructure.
This prompt can be skipped with --yes/-y argument.

View File

@ -193,10 +193,17 @@ UNDERCLOUD_EXTRA_PACKAGES = [
"tripleo-ansible" "tripleo-ansible"
] ]
# UPGRADE_PROMPT UPGRADE_PROMPT = _('You are about to run a UPGRADE command. '
UPGRADE_PROMPT = _('It is strongly recommended to perform a backup ' 'It is strongly recommended to perform a backup '
'before the upgrade. Are you sure you want to ' 'before the upgrade. Are you sure you want to '
'upgrade [y/N]?') 'upgrade [y/N]?')
UPGRADE_NO = _('User did not confirm upgrade, so exiting. ' UPGRADE_NO = _('User did not confirm upgrade, so exiting. '
'Consider using the --yes parameter if you ' 'Consider using the --yes/-y parameter if you '
'prefer to skip this warning in the future') 'prefer to skip this warning in the future')
UPDATE_PROMPT = _('You are about to run a UPDATE command. '
'It is strongly recommended to perform a backup '
'before the update. Are you sure you want to '
'update [y/N]?')
UPDATE_NO = _('User did not confirm update, so exiting. '
'Consider using the --yes/-y parameter if you '
'prefer to skip this warning in the future')

View File

@ -133,6 +133,14 @@ class UndercloudUpgradeNotConfirmed(Base):
"""Undercloud upgrade security question not confirmed.""" """Undercloud upgrade security question not confirmed."""
class OvercloudUpdateNotConfirmed(Base):
"""Overcloud Update security question not confirmed."""
class OvercloudUpgradeNotConfirmed(Base):
"""Overcloud Update security question not confirmed."""
class CellExportError(Base): class CellExportError(Base):
"""Cell export failed""" """Cell export failed"""

View File

@ -34,13 +34,16 @@ class TestOvercloudExternalUpdateRun(fakes.TestOvercloudExternalUpdateRun):
self.mock_uuid4 = uuid4_patcher.start() self.mock_uuid4 = uuid4_patcher.start()
self.addCleanup(self.mock_uuid4.stop) self.addCleanup(self.mock_uuid4.stop)
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
return_value=True)
@mock.patch('tripleoclient.workflows.package_update.update_ansible', @mock.patch('tripleoclient.workflows.package_update.update_ansible',
autospec=True) autospec=True)
@mock.patch('os.path.expanduser') @mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute') @mock.patch('oslo_concurrency.processutils.execute')
@mock.patch('six.moves.builtins.open') @mock.patch('six.moves.builtins.open')
def test_update_with_user_and_tags(self, mock_open, mock_execute, def test_update_with_user_and_tags(self, mock_open, mock_execute,
mock_expanduser, update_ansible): mock_expanduser, update_ansible,
mock_confirm):
mock_expanduser.return_value = '/home/fake/' mock_expanduser.return_value = '/home/fake/'
argslist = ['--ssh-user', 'tripleo-admin', argslist = ['--ssh-user', 'tripleo-admin',
'--tags', 'ceph'] '--tags', 'ceph']
@ -66,13 +69,16 @@ class TestOvercloudExternalUpdateRun(fakes.TestOvercloudExternalUpdateRun):
extra_vars={} extra_vars={}
) )
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
return_value=True)
@mock.patch('tripleoclient.workflows.package_update.update_ansible', @mock.patch('tripleoclient.workflows.package_update.update_ansible',
autospec=True) autospec=True)
@mock.patch('os.path.expanduser') @mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute') @mock.patch('oslo_concurrency.processutils.execute')
@mock.patch('six.moves.builtins.open') @mock.patch('six.moves.builtins.open')
def test_update_with_user_and_extra_vars(self, mock_open, mock_execute, def test_update_with_user_and_extra_vars(self, mock_open, mock_execute,
mock_expanduser, update_ansible): mock_expanduser, update_ansible,
mock_confirm):
mock_expanduser.return_value = '/home/fake/' mock_expanduser.return_value = '/home/fake/'
argslist = ['--ssh-user', 'tripleo-admin', argslist = ['--ssh-user', 'tripleo-admin',
'--extra-vars', 'key1=val1', '--extra-vars', 'key1=val1',

View File

@ -34,13 +34,16 @@ class TestOvercloudExternalUpgradeRun(fakes.TestOvercloudExternalUpgradeRun):
self.mock_uuid4 = uuid4_patcher.start() self.mock_uuid4 = uuid4_patcher.start()
self.addCleanup(self.mock_uuid4.stop) self.addCleanup(self.mock_uuid4.stop)
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
return_value=True)
@mock.patch('tripleoclient.workflows.package_update.update_ansible', @mock.patch('tripleoclient.workflows.package_update.update_ansible',
autospec=True) autospec=True)
@mock.patch('os.path.expanduser') @mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute') @mock.patch('oslo_concurrency.processutils.execute')
@mock.patch('six.moves.builtins.open') @mock.patch('six.moves.builtins.open')
def test_upgrade_with_user_and_tags(self, mock_open, mock_execute, def test_upgrade_with_user_and_tags(self, mock_open, mock_execute,
mock_expanduser, update_ansible): mock_expanduser, update_ansible,
mock_confirm):
mock_expanduser.return_value = '/home/fake/' mock_expanduser.return_value = '/home/fake/'
argslist = ['--ssh-user', 'tripleo-admin', argslist = ['--ssh-user', 'tripleo-admin',
'--tags', 'ceph'] '--tags', 'ceph']
@ -66,13 +69,16 @@ class TestOvercloudExternalUpgradeRun(fakes.TestOvercloudExternalUpgradeRun):
extra_vars={} extra_vars={}
) )
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
return_value=True)
@mock.patch('tripleoclient.workflows.package_update.update_ansible', @mock.patch('tripleoclient.workflows.package_update.update_ansible',
autospec=True) autospec=True)
@mock.patch('os.path.expanduser') @mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute') @mock.patch('oslo_concurrency.processutils.execute')
@mock.patch('six.moves.builtins.open') @mock.patch('six.moves.builtins.open')
def test_upgrade_with_user_and_extra_vars(self, mock_open, mock_execute, def test_upgrade_with_user_and_extra_vars(self, mock_open, mock_execute,
mock_expanduser, update_ansible): mock_expanduser, update_ansible,
mock_confirm):
mock_expanduser.return_value = '/home/fake/' mock_expanduser.return_value = '/home/fake/'
argslist = ['--ssh-user', 'tripleo-admin', argslist = ['--ssh-user', 'tripleo-admin',
'--extra-vars', 'key1=val1', '--extra-vars', 'key1=val1',

View File

@ -36,6 +36,8 @@ class TestOvercloudUpdatePrepare(fakes.TestOvercloudUpdatePrepare):
self.mock_uuid4 = uuid4_patcher.start() self.mock_uuid4 = uuid4_patcher.start()
self.addCleanup(self.mock_uuid4.stop) self.addCleanup(self.mock_uuid4.stop)
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
return_value=True)
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
'_get_undercloud_host_entry', autospec=True, '_get_undercloud_host_entry', autospec=True,
return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane') return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane')
@ -53,7 +55,8 @@ class TestOvercloudUpdatePrepare(fakes.TestOvercloudUpdatePrepare):
'_deploy_tripleo_heat_templates_tmpdir', autospec=True) '_deploy_tripleo_heat_templates_tmpdir', autospec=True)
def test_update_out(self, mock_deploy, mock_open, mock_copy, mock_yaml, def test_update_out(self, mock_deploy, mock_open, mock_copy, mock_yaml,
mock_abspath, mock_update, mock_logger, mock_abspath, mock_update, mock_logger,
mock_get_stack, mock_get_undercloud_host_entry): mock_get_stack, mock_get_undercloud_host_entry,
mock_confirm):
mock_stack = mock.Mock(parameters={'DeployIdentifier': ''}) mock_stack = mock.Mock(parameters={'DeployIdentifier': ''})
mock_stack.stack_name = 'overcloud' mock_stack.stack_name = 'overcloud'
mock_get_stack.return_value = mock_stack mock_get_stack.return_value = mock_stack
@ -77,6 +80,8 @@ class TestOvercloudUpdatePrepare(fakes.TestOvercloudUpdatePrepare):
container='overcloud', container='overcloud',
) )
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
return_value=True)
@mock.patch('tripleoclient.utils.get_stack', @mock.patch('tripleoclient.utils.get_stack',
autospec=True) autospec=True)
@mock.patch('tripleoclient.workflows.package_update.update', @mock.patch('tripleoclient.workflows.package_update.update',
@ -89,7 +94,7 @@ class TestOvercloudUpdatePrepare(fakes.TestOvercloudUpdatePrepare):
'_deploy_tripleo_heat_templates', autospec=True) '_deploy_tripleo_heat_templates', autospec=True)
def test_update_failed(self, mock_deploy, mock_copy, mock_yaml, def test_update_failed(self, mock_deploy, mock_copy, mock_yaml,
mock_abspath, mock_open, mock_update, mock_abspath, mock_open, mock_update,
mock_get_stack): mock_get_stack, mock_confirm):
mock_stack = mock.Mock(parameters={'DeployIdentifier': ''}) mock_stack = mock.Mock(parameters={'DeployIdentifier': ''})
mock_stack.stack_name = 'overcloud' mock_stack.stack_name = 'overcloud'
mock_get_stack.return_value = mock_stack mock_get_stack.return_value = mock_stack
@ -124,13 +129,16 @@ class TestOvercloudUpdateRun(fakes.TestOvercloudUpdateRun):
self.mock_uuid4 = uuid4_patcher.start() self.mock_uuid4 = uuid4_patcher.start()
self.addCleanup(self.mock_uuid4.stop) self.addCleanup(self.mock_uuid4.stop)
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
return_value=True)
@mock.patch('tripleoclient.workflows.package_update.update_ansible', @mock.patch('tripleoclient.workflows.package_update.update_ansible',
autospec=True) autospec=True)
@mock.patch('os.path.expanduser') @mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute') @mock.patch('oslo_concurrency.processutils.execute')
@mock.patch('six.moves.builtins.open') @mock.patch('six.moves.builtins.open')
def test_update_with_playbook_and_user(self, mock_open, mock_execute, def test_update_with_playbook_and_user(self, mock_open, mock_execute,
mock_expanduser, update_ansible): mock_expanduser, update_ansible,
mock_confirm):
mock_expanduser.return_value = '/home/fake/' mock_expanduser.return_value = '/home/fake/'
argslist = ['--limit', 'Compute', argslist = ['--limit', 'Compute',
'--playbook', 'fake-playbook.yaml', '--playbook', 'fake-playbook.yaml',
@ -159,13 +167,16 @@ class TestOvercloudUpdateRun(fakes.TestOvercloudUpdateRun):
extra_vars=None extra_vars=None
) )
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
return_value=True)
@mock.patch('tripleoclient.workflows.package_update.update_ansible', @mock.patch('tripleoclient.workflows.package_update.update_ansible',
autospec=True) autospec=True)
@mock.patch('os.path.expanduser') @mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute') @mock.patch('oslo_concurrency.processutils.execute')
@mock.patch('six.moves.builtins.open') @mock.patch('six.moves.builtins.open')
def test_update_limit_with_all_playbooks(self, mock_open, mock_execute, def test_update_limit_with_all_playbooks(self, mock_open, mock_execute,
mock_expanduser, update_ansible): mock_expanduser, update_ansible,
mock_confirm):
mock_expanduser.return_value = '/home/fake/' mock_expanduser.return_value = '/home/fake/'
argslist = ['--limit', 'Compute', '--playbook', 'all'] argslist = ['--limit', 'Compute', '--playbook', 'all']
verifylist = [ verifylist = [
@ -192,13 +203,16 @@ class TestOvercloudUpdateRun(fakes.TestOvercloudUpdateRun):
extra_vars=None extra_vars=None
) )
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
return_value=True)
@mock.patch('tripleoclient.workflows.package_update.update_ansible', @mock.patch('tripleoclient.workflows.package_update.update_ansible',
autospec=True) autospec=True)
@mock.patch('os.path.expanduser') @mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute') @mock.patch('oslo_concurrency.processutils.execute')
@mock.patch('six.moves.builtins.open') @mock.patch('six.moves.builtins.open')
def test_update_with_no_limit( def test_update_with_no_limit(
self, mock_open, mock_execute, mock_expanduser, update_ansible): self, mock_open, mock_execute, mock_expanduser, update_ansible,
mock_confirm):
mock_expanduser.return_value = '/home/fake/' mock_expanduser.return_value = '/home/fake/'
argslist = [] argslist = []
verifylist = [ verifylist = [
@ -219,9 +233,11 @@ class TestOvercloudUpdateConverge(fakes.TestOvercloudUpdateConverge):
app_args.verbose_level = 1 app_args.verbose_level = 1
self.cmd = overcloud_update.UpdateConverge(self.app, app_args) self.cmd = overcloud_update.UpdateConverge(self.app, app_args)
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
return_value=True)
@mock.patch( @mock.patch(
'tripleoclient.v1.overcloud_deploy.DeployOvercloud.take_action') 'tripleoclient.v1.overcloud_deploy.DeployOvercloud.take_action')
def test_update_converge(self, deploy_action): def test_update_converge(self, deploy_action, mock_confirm):
argslist = ['--templates', '--stack', 'cloud'] argslist = ['--templates', '--stack', 'cloud']
verifylist = [ verifylist = [
('stack', 'cloud') ('stack', 'cloud')

View File

@ -37,6 +37,8 @@ class TestOvercloudUpgradePrepare(fakes.TestOvercloudUpgradePrepare):
self.mock_uuid4 = uuid4_patcher.start() self.mock_uuid4 = uuid4_patcher.start()
self.addCleanup(self.mock_uuid4.stop) self.addCleanup(self.mock_uuid4.stop)
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
return_value=True)
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
'take_action') 'take_action')
@mock.patch('tripleoclient.workflows.deployment.' @mock.patch('tripleoclient.workflows.deployment.'
@ -58,7 +60,8 @@ class TestOvercloudUpgradePrepare(fakes.TestOvercloudUpgradePrepare):
add_env, add_env,
mock_get_config, mock_get_config,
mock_enable_ssh_admin, mock_enable_ssh_admin,
mock_overcloud_deploy): mock_overcloud_deploy,
mock_confirm):
mock_stack = mock.Mock(parameters={'DeployIdentifier': ''}) mock_stack = mock.Mock(parameters={'DeployIdentifier': ''})
mock_stack.stack_name = 'overcloud' mock_stack.stack_name = 'overcloud'
@ -92,6 +95,8 @@ class TestOvercloudUpgradePrepare(fakes.TestOvercloudUpgradePrepare):
parsed_args.overcloud_ssh_user, mock.ANY, parsed_args.overcloud_ssh_user, mock.ANY,
10, 10) 10, 10)
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
return_value=True)
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
'take_action') 'take_action')
@mock.patch('tripleoclient.utils.get_stack', @mock.patch('tripleoclient.utils.get_stack',
@ -100,7 +105,8 @@ class TestOvercloudUpgradePrepare(fakes.TestOvercloudUpgradePrepare):
@mock.patch('six.moves.builtins.open') @mock.patch('six.moves.builtins.open')
@mock.patch('yaml.load') @mock.patch('yaml.load')
def test_upgrade_failed(self, mock_yaml, mock_open, def test_upgrade_failed(self, mock_yaml, mock_open,
add_env, mock_get_stack, mock_overcloud_deploy): add_env, mock_get_stack, mock_overcloud_deploy,
mock_confirm):
mock_overcloud_deploy.side_effect = exceptions.DeploymentError() mock_overcloud_deploy.side_effect = exceptions.DeploymentError()
mock_yaml.return_value = {'fake_container': 'fake_value'} mock_yaml.return_value = {'fake_container': 'fake_value'}
mock_stack = mock.Mock(parameters={'DeployIdentifier': ''}) mock_stack = mock.Mock(parameters={'DeployIdentifier': ''})
@ -144,13 +150,16 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun):
self.mock_uuid4 = uuid4_patcher.start() self.mock_uuid4 = uuid4_patcher.start()
self.addCleanup(self.mock_uuid4.stop) self.addCleanup(self.mock_uuid4.stop)
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
return_value=True)
@mock.patch('tripleoclient.workflows.package_update.update_ansible', @mock.patch('tripleoclient.workflows.package_update.update_ansible',
autospec=True) autospec=True)
@mock.patch('os.path.expanduser') @mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute') @mock.patch('oslo_concurrency.processutils.execute')
@mock.patch('six.moves.builtins.open') @mock.patch('six.moves.builtins.open')
def test_upgrade_limit_with_playbook_and_user( def test_upgrade_limit_with_playbook_and_user(
self, mock_open, mock_execute, mock_expanduser, upgrade_ansible): self, mock_open, mock_execute, mock_expanduser, upgrade_ansible,
mock_confirm):
mock_expanduser.return_value = '/home/fake/' mock_expanduser.return_value = '/home/fake/'
argslist = ['--limit', 'Compute, Controller', argslist = ['--limit', 'Compute, Controller',
'--playbook', 'fake-playbook.yaml', '--playbook', 'fake-playbook.yaml',
@ -178,13 +187,16 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun):
extra_vars=None extra_vars=None
) )
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
return_value=True)
@mock.patch('tripleoclient.workflows.package_update.update_ansible', @mock.patch('tripleoclient.workflows.package_update.update_ansible',
autospec=True) autospec=True)
@mock.patch('os.path.expanduser') @mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute') @mock.patch('oslo_concurrency.processutils.execute')
@mock.patch('six.moves.builtins.open') @mock.patch('six.moves.builtins.open')
def test_upgrade_limit_all_playbooks_skip_validation( def test_upgrade_limit_all_playbooks_skip_validation(
self, mock_open, mock_execute, mock_expanduser, upgrade_ansible): self, mock_open, mock_execute, mock_expanduser, upgrade_ansible,
mock_confirm):
mock_expanduser.return_value = '/home/fake/' mock_expanduser.return_value = '/home/fake/'
argslist = ['--limit', 'Compute', '--playbook', 'all', argslist = ['--limit', 'Compute', '--playbook', 'all',
'--skip-tags', 'validation'] '--skip-tags', 'validation']
@ -213,13 +225,16 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun):
extra_vars=None extra_vars=None
) )
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
return_value=True)
@mock.patch('tripleoclient.workflows.package_update.update_ansible', @mock.patch('tripleoclient.workflows.package_update.update_ansible',
autospec=True) autospec=True)
@mock.patch('os.path.expanduser') @mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute') @mock.patch('oslo_concurrency.processutils.execute')
@mock.patch('six.moves.builtins.open') @mock.patch('six.moves.builtins.open')
def test_upgrade_limit_all_playbooks_only_validation( def test_upgrade_limit_all_playbooks_only_validation(
self, mock_open, mock_execute, mock_expanduser, upgrade_ansible): self, mock_open, mock_execute, mock_expanduser, upgrade_ansible,
mock_confirm):
mock_expanduser.return_value = '/home/fake/' mock_expanduser.return_value = '/home/fake/'
argslist = ['--limit', 'Compute', '--playbook', 'all', argslist = ['--limit', 'Compute', '--playbook', 'all',
'--tags', 'validation'] '--tags', 'validation']
@ -248,13 +263,16 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun):
extra_vars=None extra_vars=None
) )
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
return_value=True)
@mock.patch('tripleoclient.workflows.package_update.update_ansible', @mock.patch('tripleoclient.workflows.package_update.update_ansible',
autospec=True) autospec=True)
@mock.patch('os.path.expanduser') @mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute') @mock.patch('oslo_concurrency.processutils.execute')
@mock.patch('six.moves.builtins.open') @mock.patch('six.moves.builtins.open')
def test_upgrade_nodes_with_playbook_no_skip_tags( def test_upgrade_nodes_with_playbook_no_skip_tags(
self, mock_open, mock_execute, mock_expanduser, upgrade_ansible): self, mock_open, mock_execute, mock_expanduser, upgrade_ansible,
mock_confirm):
mock_expanduser.return_value = '/home/fake/' mock_expanduser.return_value = '/home/fake/'
argslist = ['--limit', 'compute-0,compute-1', argslist = ['--limit', 'compute-0,compute-1',
'--playbook', 'fake-playbook.yaml', ] '--playbook', 'fake-playbook.yaml', ]
@ -281,13 +299,16 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun):
extra_vars=None extra_vars=None
) )
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
return_value=True)
@mock.patch('tripleoclient.workflows.package_update.update_ansible', @mock.patch('tripleoclient.workflows.package_update.update_ansible',
autospec=True) autospec=True)
@mock.patch('os.path.expanduser') @mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute') @mock.patch('oslo_concurrency.processutils.execute')
@mock.patch('six.moves.builtins.open') @mock.patch('six.moves.builtins.open')
def test_upgrade_node_all_playbooks_skip_tags_default( def test_upgrade_node_all_playbooks_skip_tags_default(
self, mock_open, mock_execute, mock_expanduser, upgrade_ansible): self, mock_open, mock_execute, mock_expanduser, upgrade_ansible,
mock_confirm):
mock_expanduser.return_value = '/home/fake/' mock_expanduser.return_value = '/home/fake/'
argslist = ['--limit', 'swift-1', '--playbook', 'all'] argslist = ['--limit', 'swift-1', '--playbook', 'all']
verifylist = [ verifylist = [
@ -314,13 +335,16 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun):
extra_vars=None extra_vars=None
) )
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
return_value=True)
@mock.patch('tripleoclient.workflows.package_update.update_ansible', @mock.patch('tripleoclient.workflows.package_update.update_ansible',
autospec=True) autospec=True)
@mock.patch('os.path.expanduser') @mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute') @mock.patch('oslo_concurrency.processutils.execute')
@mock.patch('six.moves.builtins.open') @mock.patch('six.moves.builtins.open')
def test_upgrade_node_all_playbooks_skip_tags_all_supported( def test_upgrade_node_all_playbooks_skip_tags_all_supported(
self, mock_open, mock_execute, mock_expanduser, upgrade_ansible): self, mock_open, mock_execute, mock_expanduser, upgrade_ansible,
mock_confirm):
mock_expanduser.return_value = '/home/fake/' mock_expanduser.return_value = '/home/fake/'
argslist = ['--limit', 'swift-1', '--playbook', 'all', argslist = ['--limit', 'swift-1', '--playbook', 'all',
'--skip-tags', 'pre-upgrade,validation'] '--skip-tags', 'pre-upgrade,validation']
@ -362,6 +386,8 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun):
self.assertRaises(ParserException, lambda: self.check_parser( self.assertRaises(ParserException, lambda: self.check_parser(
self.cmd, argslist, verifylist)) self.cmd, argslist, verifylist))
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
return_value=True)
@mock.patch('tripleoclient.workflows.package_update.update_ansible', @mock.patch('tripleoclient.workflows.package_update.update_ansible',
autospec=True) autospec=True)
@mock.patch('os.path.expanduser') @mock.patch('os.path.expanduser')
@ -369,7 +395,8 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun):
@mock.patch('six.moves.builtins.open') @mock.patch('six.moves.builtins.open')
# it is 'validation' not 'validations' # it is 'validation' not 'validations'
def test_upgrade_skip_tags_validations(self, mock_open, mock_execute, def test_upgrade_skip_tags_validations(self, mock_open, mock_execute,
mock_expanduser, upgrade_ansible): mock_expanduser, upgrade_ansible,
mock_confirm):
mock_expanduser.return_value = '/home/fake/' mock_expanduser.return_value = '/home/fake/'
argslist = ['--limit', 'overcloud-compute-1', argslist = ['--limit', 'overcloud-compute-1',
'--skip-tags', 'validations'] '--skip-tags', 'validations']
@ -385,6 +412,8 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun):
self.assertRaises(exceptions.InvalidConfiguration, self.assertRaises(exceptions.InvalidConfiguration,
lambda: self.cmd.take_action(parsed_args)) lambda: self.cmd.take_action(parsed_args))
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
return_value=True)
@mock.patch('tripleoclient.workflows.package_update.update_ansible', @mock.patch('tripleoclient.workflows.package_update.update_ansible',
autospec=True) autospec=True)
@mock.patch('os.path.expanduser') @mock.patch('os.path.expanduser')
@ -392,7 +421,8 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun):
@mock.patch('six.moves.builtins.open') @mock.patch('six.moves.builtins.open')
# should only support the constants.MAJOR_UPGRADE_SKIP_TAGS # should only support the constants.MAJOR_UPGRADE_SKIP_TAGS
def test_upgrade_skip_tags_unsupported_validation_anything_else( def test_upgrade_skip_tags_unsupported_validation_anything_else(
self, mock_open, mock_execute, mock_expanduser, upgrade_ansible): self, mock_open, mock_execute, mock_expanduser, upgrade_ansible,
mock_confirm):
mock_expanduser.return_value = '/home/fake/' mock_expanduser.return_value = '/home/fake/'
argslist = ['--limit', 'overcloud-compute-1', argslist = ['--limit', 'overcloud-compute-1',
'--skip-tags', 'validation,anything-else'] '--skip-tags', 'validation,anything-else']
@ -408,6 +438,8 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun):
self.assertRaises(exceptions.InvalidConfiguration, self.assertRaises(exceptions.InvalidConfiguration,
lambda: self.cmd.take_action(parsed_args)) lambda: self.cmd.take_action(parsed_args))
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
return_value=True)
@mock.patch('tripleoclient.workflows.package_update.update_ansible', @mock.patch('tripleoclient.workflows.package_update.update_ansible',
autospec=True) autospec=True)
@mock.patch('os.path.expanduser') @mock.patch('os.path.expanduser')
@ -415,7 +447,8 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun):
@mock.patch('six.moves.builtins.open') @mock.patch('six.moves.builtins.open')
# should only support the constants.MAJOR_UPGRADE_SKIP_TAGS # should only support the constants.MAJOR_UPGRADE_SKIP_TAGS
def test_upgrade_skip_tags_unsupported_pre_upgrade_anything_else( def test_upgrade_skip_tags_unsupported_pre_upgrade_anything_else(
self, mock_open, mock_execute, mock_expanduser, upgrade_ansible): self, mock_open, mock_execute, mock_expanduser, upgrade_ansible,
mock_confirm):
mock_expanduser.return_value = '/home/fake/' mock_expanduser.return_value = '/home/fake/'
argslist = ['--limit', 'overcloud-compute-1', argslist = ['--limit', 'overcloud-compute-1',
'--skip-tags', 'pre-upgrade,anything-else'] '--skip-tags', 'pre-upgrade,anything-else']

View File

@ -18,6 +18,8 @@ from oslo_log import log as logging
from osc_lib.i18n import _ from osc_lib.i18n import _
from osc_lib import utils from osc_lib import utils
from tripleoclient.exceptions import OvercloudUpdateNotConfirmed
from tripleoclient import command from tripleoclient import command
from tripleoclient import constants from tripleoclient import constants
from tripleoclient import utils as oooutils from tripleoclient import utils as oooutils
@ -91,6 +93,12 @@ class ExternalUpdateRun(command.Command):
'system command instead of running Ansible' 'system command instead of running Ansible'
'via the TripleO mistral workflows.') 'via the TripleO mistral workflows.')
) )
parser.add_argument('-y', '--yes', default=False,
action='store_true',
help=_("Use -y or --yes to skip the confirmation "
"required before any upgrade "
"operation. Use this with caution! "),
)
parser.add_argument( parser.add_argument(
'--limit', '--limit',
action='store', action='store',
@ -105,6 +113,12 @@ class ExternalUpdateRun(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)
if (not parsed_args.yes
and not oooutils.prompt_user_for_confirmation(
constants.UPDATE_PROMPT, self.log)):
raise OvercloudUpdateNotConfirmed(constants.UPDATE_NO)
clients = self.app.client_manager clients = self.app.client_manager
orchestration = clients.orchestration orchestration = clients.orchestration
verbosity = self.app_args.verbose_level verbosity = self.app_args.verbose_level

View File

@ -18,6 +18,8 @@ from oslo_log import log as logging
from osc_lib.i18n import _ from osc_lib.i18n import _
from osc_lib import utils from osc_lib import utils
from tripleoclient.exceptions import OvercloudUpgradeNotConfirmed
from tripleoclient import command from tripleoclient import command
from tripleoclient import constants from tripleoclient import constants
from tripleoclient import utils as oooutils from tripleoclient import utils as oooutils
@ -91,6 +93,13 @@ class ExternalUpgradeRun(command.Command):
'system command instead of running Ansible' 'system command instead of running Ansible'
'via the TripleO mistral workflows.') 'via the TripleO mistral workflows.')
) )
parser.add_argument('-y', '--yes', default=False,
action='store_true',
help=_("Use -y or --yes to skip the confirmation "
"required before any upgrade "
"operation. Use this with caution! "),
)
parser.add_argument( parser.add_argument(
'--limit', '--limit',
action='store', action='store',
@ -105,6 +114,12 @@ class ExternalUpgradeRun(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)
if (not parsed_args.yes
and not oooutils.prompt_user_for_confirmation(
constants.UPGRADE_PROMPT, self.log)):
raise OvercloudUpgradeNotConfirmed(constants.UPGRADE_NO)
clients = self.app.client_manager clients = self.app.client_manager
orchestration = clients.orchestration orchestration = clients.orchestration
verbosity = self.app_args.verbose_level verbosity = self.app_args.verbose_level

View File

@ -18,6 +18,8 @@ from oslo_log import log as logging
from osc_lib.i18n import _ from osc_lib.i18n import _
from osc_lib import utils from osc_lib import utils
from tripleoclient.exceptions import OvercloudUpdateNotConfirmed
from tripleoclient import command from tripleoclient import command
from tripleoclient import constants from tripleoclient import constants
from tripleoclient import utils as oooutils from tripleoclient import utils as oooutils
@ -41,10 +43,22 @@ class UpdatePrepare(DeployOvercloud):
def get_parser(self, prog_name): def get_parser(self, prog_name):
parser = super(UpdatePrepare, self).get_parser(prog_name) parser = super(UpdatePrepare, self).get_parser(prog_name)
parser.add_argument('-y', '--yes', default=False,
action='store_true',
help=_("Use -y or --yes to skip the confirmation "
"required before any update operation. "
"Use this with caution! "),
)
return parser return parser
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)
if (not parsed_args.yes
and not oooutils.prompt_user_for_confirmation(
constants.UPDATE_PROMPT, self.log)):
raise OvercloudUpdateNotConfirmed(constants.UPDATE_NO)
clients = self.app.client_manager clients = self.app.client_manager
stack = oooutils.get_stack(clients.orchestration, stack = oooutils.get_stack(clients.orchestration,
@ -152,10 +166,23 @@ class UpdateRun(command.Command):
help=_('A list of tags to skip when running the' help=_('A list of tags to skip when running the'
' config-download ansible-playbook command.') ' config-download ansible-playbook command.')
) )
parser.add_argument(
'-y', '--yes',
default=False,
action='store_true',
help=_("Use -y or --yes to skip the confirmation required before "
"any update operation. Use this with caution! "),
)
return parser return parser
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)
if (not parsed_args.yes
and not oooutils.prompt_user_for_confirmation(
constants.UPDATE_PROMPT, self.log)):
raise OvercloudUpdateNotConfirmed(constants.UPDATE_NO)
clients = self.app.client_manager clients = self.app.client_manager
orchestration = clients.orchestration orchestration = clients.orchestration
verbosity = self.app_args.verbose_level verbosity = self.app_args.verbose_level
@ -201,9 +228,24 @@ class UpdateConverge(DeployOvercloud):
log = logging.getLogger(__name__ + ".UpdateConverge") log = logging.getLogger(__name__ + ".UpdateConverge")
def get_parser(self, prog_name):
parser = super(UpdateConverge, self).get_parser(prog_name)
parser.add_argument('-y', '--yes', default=False,
action='store_true',
help=_("Use -y or --yes to skip the confirmation "
"required before any update operation. "
"Use this with caution! "),
)
return parser
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)
if (not parsed_args.yes
and not oooutils.prompt_user_for_confirmation(
constants.UPDATE_PROMPT, self.log)):
raise OvercloudUpdateNotConfirmed(constants.UPDATE_NO)
# Add the update-converge.yaml environment to unset noops # Add the update-converge.yaml environment to unset noops
templates_dir = (parsed_args.templates or templates_dir = (parsed_args.templates or
constants.TRIPLEO_HEAT_TEMPLATES) constants.TRIPLEO_HEAT_TEMPLATES)

View File

@ -18,6 +18,8 @@ from oslo_log import log as logging
from osc_lib.i18n import _ from osc_lib.i18n import _
from osc_lib import utils from osc_lib import utils
from tripleoclient.exceptions import OvercloudUpgradeNotConfirmed
from tripleoclient import command from tripleoclient import command
from tripleoclient import constants from tripleoclient import constants
from tripleoclient import exceptions from tripleoclient import exceptions
@ -50,11 +52,22 @@ class UpgradePrepare(DeployOvercloud):
def get_parser(self, prog_name): def get_parser(self, prog_name):
parser = super(UpgradePrepare, self).get_parser(prog_name) parser = super(UpgradePrepare, self).get_parser(prog_name)
parser.add_argument('-y', '--yes', default=False,
action='store_true',
help=_("Use -y or --yes to skip the confirmation "
"required before any upgrade "
"operation. Use this with caution! "),
)
return parser return parser
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)
if (not parsed_args.yes
and not oooutils.prompt_user_for_confirmation(
constants.UPGRADE_PROMPT, self.log)):
raise OvercloudUpgradeNotConfirmed(constants.UPGRADE_NO)
# Throw deprecation warning if service is enabled and # Throw deprecation warning if service is enabled and
# ask user if upgrade should still be continued. # ask user if upgrade should still be continued.
if parsed_args.environment_files: if parsed_args.environment_files:
@ -186,7 +199,8 @@ class UpgradeRun(command.Command):
help=_('Name or ID of heat stack ' help=_('Name or ID of heat stack '
'(default=Env: OVERCLOUD_STACK_NAME)'), '(default=Env: OVERCLOUD_STACK_NAME)'),
default=utils.env('OVERCLOUD_STACK_NAME', default=utils.env('OVERCLOUD_STACK_NAME',
default='overcloud')) default='overcloud')
)
parser.add_argument('--no-workflow', dest='no_workflow', parser.add_argument('--no-workflow', dest='no_workflow',
action='store_true', action='store_true',
default=False, default=False,
@ -194,7 +208,12 @@ class UpgradeRun(command.Command):
'system command instead of running Ansible' 'system command instead of running Ansible'
'via the TripleO mistral workflows.') 'via the TripleO mistral workflows.')
) )
parser.add_argument('-y', '--yes', default=False,
action='store_true',
help=_("Use -y or --yes to skip the confirmation "
"required before any upgrade "
"operation. Use this with caution! ")
)
return parser return parser
def _validate_skip_tags(self, skip_tags): def _validate_skip_tags(self, skip_tags):
@ -209,6 +228,12 @@ class UpgradeRun(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)
if (not parsed_args.yes
and not oooutils.prompt_user_for_confirmation(
constants.UPGRADE_PROMPT, self.log)):
raise OvercloudUpgradeNotConfirmed(constants.UPGRADE_NO)
clients = self.app.client_manager clients = self.app.client_manager
verbosity = self.app_args.verbose_level verbosity = self.app_args.verbose_level
orchestration = clients.orchestration orchestration = clients.orchestration