Merge "Expose --limit, --skip-tags, and --tags on the CLI." into stable/train

This commit is contained in:
Zuul 2020-05-15 17:09:29 +00:00 committed by Gerrit Code Review
commit fbfd3098d3
14 changed files with 191 additions and 74 deletions

View File

@ -1517,7 +1517,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
'heat-admin', None, 'ctlplane', None, None,
deployment_options={},
deployment_timeout=26880, # 451 - 3 = 448m time left
in_flight_validations=False, timeout=42, verbosity=1)],
in_flight_validations=False, limit_hosts=None,
skip_tags=None, tags=None, timeout=42, verbosity=1)],
fixture.mock_config_download.mock_calls)
fixture.mock_config_download.assert_called()
mock_copy.assert_called_once()
@ -1571,7 +1572,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
'heat-admin', None, 'ctlplane', None, None,
deployment_options={},
deployment_timeout=14400, # 240 * 60
in_flight_validations=False, timeout=42, verbosity=1)],
in_flight_validations=False, limit_hosts=None,
skip_tags=None, tags=None, timeout=42, verbosity=1)],
fixture.mock_config_download.mock_calls)
mock_copy.assert_called_once()

View File

@ -56,7 +56,7 @@ class TestOvercloudExternalUpdateRun(fakes.TestOvercloudExternalUpdateRun):
update_ansible.assert_called_once_with(
self.app.client_manager,
container='overcloud',
nodes='all',
nodes=None,
inventory_file=mock_open().__enter__().read(),
playbook='external_update_steps_playbook.yaml',
node_user='tripleo-admin',
@ -89,7 +89,7 @@ class TestOvercloudExternalUpdateRun(fakes.TestOvercloudExternalUpdateRun):
update_ansible.assert_called_once_with(
self.app.client_manager,
container='overcloud',
nodes='all',
nodes=None,
inventory_file=mock_open().__enter__().read(),
playbook='external_update_steps_playbook.yaml',
node_user='tripleo-admin',

View File

@ -56,7 +56,7 @@ class TestOvercloudExternalUpgradeRun(fakes.TestOvercloudExternalUpgradeRun):
update_ansible.assert_called_once_with(
self.app.client_manager,
container='overcloud',
nodes='all',
nodes=None,
inventory_file=mock_open().__enter__().read(),
playbook='external_upgrade_steps_playbook.yaml',
node_user='tripleo-admin',
@ -89,7 +89,7 @@ class TestOvercloudExternalUpgradeRun(fakes.TestOvercloudExternalUpgradeRun):
update_ansible.assert_called_once_with(
self.app.client_manager,
container='overcloud',
nodes='all',
nodes=None,
inventory_file=mock_open().__enter__().read(),
playbook='external_upgrade_steps_playbook.yaml',
node_user='tripleo-admin',

View File

@ -166,11 +166,11 @@ class TestFFWDUpgradeRun(fakes.TestFFWDUpgradeRun):
self.app.client_manager,
container='overcloud',
inventory_file=mock_open().__enter__().read(),
nodes='',
nodes=None,
playbook=constants.FFWD_UPGRADE_PLAYBOOK,
node_user='heat-admin',
tags='',
skip_tags='',
tags=None,
skip_tags=None,
verbosity=1,
extra_vars=None
)
@ -194,11 +194,11 @@ class TestFFWDUpgradeRun(fakes.TestFFWDUpgradeRun):
self.app.client_manager,
container='overcloud',
inventory_file=mock_open().__enter__().read(),
nodes='',
nodes=None,
playbook=constants.FFWD_UPGRADE_PLAYBOOK,
node_user='my-user',
tags='',
skip_tags='',
tags=None,
skip_tags=None,
verbosity=1,
extra_vars=None
)
@ -211,11 +211,24 @@ class TestFFWDUpgradeRun(fakes.TestFFWDUpgradeRun):
def test_upgrade_no_nodes_or_roles(self, mock_open, mock_execute,
mock_expanduser, upgrade_ansible):
mock_expanduser.return_value = '/home/fake/'
argslist = ["--nodes", "controller-1", "--roles", "foo", "--yes"]
argslist = ["--limit", "controller-1", "--roles", "foo", "--yes"]
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')
def test_upgrade_limit(self, mock_open, mock_execute,
mock_expanduser, upgrade_ansible):
mock_expanduser.return_value = '/home/fake/'
argslist = ['--limit', 'controller1,controller2,controll3']
verifylist = [('limit', 'controller1,controller2,controll3')]
self.assertRaises(ParserException, lambda: self.check_parser(
self.cmd, argslist, verifylist))
class TestFFWDUpgradeConverge(fakes.TestFFWDUpgradeConverge):

View File

@ -153,8 +153,8 @@ class TestOvercloudUpdateRun(fakes.TestOvercloudUpdateRun):
inventory_file=mock_open().__enter__().read(),
playbook='fake-playbook.yaml',
node_user='tripleo-admin',
tags='',
skip_tags='',
tags=None,
skip_tags=None,
verbosity=1,
extra_vars=None
)
@ -186,8 +186,8 @@ class TestOvercloudUpdateRun(fakes.TestOvercloudUpdateRun):
inventory_file=mock_open().__enter__().read(),
playbook=book,
node_user='tripleo-admin',
tags='',
skip_tags='',
tags=None,
skip_tags=None,
verbosity=1,
extra_vars=None
)

View File

@ -189,7 +189,7 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun):
upgrade_ansible.assert_called_once_with(
self.app.client_manager,
container='overcloud',
nodes='Compute, Controller',
nodes='Compute:Controller',
inventory_file=mock_open().__enter__().read(),
playbook='fake-playbook.yaml',
node_user='tripleo-admin',
@ -277,10 +277,10 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun):
def test_upgrade_nodes_with_playbook_no_skip_tags(
self, mock_open, mock_execute, mock_expanduser, upgrade_ansible):
mock_expanduser.return_value = '/home/fake/'
argslist = ['--limit', 'compute-0, compute-1',
argslist = ['--limit', 'compute-0,compute-1',
'--playbook', 'fake-playbook.yaml', ]
verifylist = [
('limit', 'compute-0, compute-1'),
('limit', 'compute-0,compute-1'),
('static_inventory', None),
('playbook', 'fake-playbook.yaml'),
]
@ -292,7 +292,7 @@ class TestOvercloudUpgradeRun(fakes.TestOvercloudUpgradeRun):
upgrade_ansible.assert_called_once_with(
self.app.client_manager,
container='overcloud',
nodes='compute-0, compute-1',
nodes='compute-0:compute-1',
inventory_file=mock_open().__enter__().read(),
playbook='fake-playbook.yaml',
node_user='tripleo-admin',

View File

@ -35,6 +35,7 @@ import json
import netaddr
import os
import os.path
import re
import simplejson
import six
import socket
@ -77,8 +78,8 @@ def run_ansible_playbook(logger,
key=None,
module_path=None,
limit_hosts=None,
tags=None,
skip_tags=None,
tags=None,
verbosity=1,
extra_vars=None,
plan='overcloud',
@ -1212,7 +1213,7 @@ def process_multiple_environments(created_env_files, tht_root,
def run_update_ansible_action(log, clients, stack, nodes, inventory,
playbook, all_playbooks, ssh_user,
action=None, tags='', skip_tags='',
action=None, skip_tags=None, tags=None,
verbosity='1', extra_vars=None,
workdir='', priv_key=''):
@ -1225,7 +1226,7 @@ def run_update_ansible_action(log, clients, stack, nodes, inventory,
action.update_ansible(clients, container=stack, nodes=nodes,
inventory_file=inventory,
playbook=book, node_user=ssh_user,
tags=tags, skip_tags=skip_tags,
skip_tags=skip_tags, tags=tags,
verbosity=verbosity, extra_vars=extra_vars)
else:
run_ansible_playbook(logger=LOG,
@ -1235,8 +1236,9 @@ def run_update_ansible_action(log, clients, stack, nodes, inventory,
ssh_user=ssh_user,
key=ssh_private_key(workdir, priv_key),
module_path='/usr/share/ansible-modules',
limit_hosts=nodes, tags=tags,
skip_tags=skip_tags)
limit_hosts=nodes,
skip_tags=skip_tags,
tags=tags)
def ssh_private_key(workdir, key):
@ -2102,3 +2104,20 @@ def copy_clouds_yaml(user):
' with sudo') % {'user': user, 'dir': clouds_config_dir}
LOG.error(msg)
raise exceptions.DeploymentError(msg)
def playbook_limit_parse(limit_nodes):
"""Return a parsed string for limits.
This will sanitize user inputs so that we guarantee what is provided is
expected to be functional. If limit_nodes is None, this function will
return None.
:returns: String
"""
if not limit_nodes:
return limit_nodes
return ':'.join([i.strip() for i in re.split(',| |:', limit_nodes) if i])

View File

@ -903,6 +903,29 @@ class DeployOvercloud(command.Command):
metavar='<baremetal_deployment.yaml>',
help=_('Configuration file describing the '
'baremetal deployment'))
parser.add_argument(
'--limit',
action='store',
default=None,
help=_("A string that identifies a single node or comma-separated"
"list of nodes the config-download Ansible playbook "
"execution will be limited to. For example: --limit"
" \"compute-0,compute-1,compute-5\".")
)
parser.add_argument(
'--tags',
action='store',
default=None,
help=_('A list of tags to use when running the config-download'
' ansible-playbook command.')
)
parser.add_argument(
'--skip-tags',
action='store',
default=None,
help=_('A list of tags to skip when running the'
' config-download ansible-playbook command.')
)
return parser
def take_action(self, parsed_args):
@ -997,7 +1020,12 @@ class DeployOvercloud(command.Command):
verbosity=self.app_args.verbose_level,
deployment_options=deployment_options,
in_flight_validations=parsed_args.inflight,
deployment_timeout=timeout
deployment_timeout=timeout,
tags=parsed_args.tags,
skip_tags=parsed_args.skip_tags,
limit_hosts=utils.playbook_limit_parse(
limit_nodes=parsed_args.limit
)
)
except Exception:
deployment.set_deployment_status(

View File

@ -91,6 +91,15 @@ class ExternalUpdateRun(command.Command):
'system command instead of running Ansible'
'via the TripleO mistral workflows.')
)
parser.add_argument(
'--limit',
action='store',
default=None,
help=_("A string that identifies a single node or comma-separated"
"list of nodes the config-download Ansible playbook "
"execution will be limited to. For example: --limit"
" \"compute-0,compute-1,compute-5\".")
)
return parser
@ -112,7 +121,8 @@ class ExternalUpdateRun(command.Command):
# Run ansible:
inventory = oooutils.get_tripleo_ansible_inventory(
parsed_args.static_inventory, parsed_args.ssh_user, stack)
limit_hosts = 'all'
limit_hosts = oooutils.playbook_limit_parse(
limit_nodes=parsed_args.limit)
playbook = 'all'
extra_vars = oooutils.parse_extra_vars(parsed_args.extra_vars)

View File

@ -91,6 +91,15 @@ class ExternalUpgradeRun(command.Command):
'system command instead of running Ansible'
'via the TripleO mistral workflows.')
)
parser.add_argument(
'--limit',
action='store',
default=None,
help=_("A string that identifies a single node or comma-separated"
"list of nodes the config-download Ansible playbook "
"execution will be limited to. For example: --limit"
" \"compute-0,compute-1,compute-5\".")
)
return parser
@ -112,7 +121,8 @@ class ExternalUpgradeRun(command.Command):
# Run ansible:
inventory = oooutils.get_tripleo_ansible_inventory(
parsed_args.static_inventory, parsed_args.ssh_user, stack)
limit_hosts = 'all'
limit_hosts = oooutils.playbook_limit_parse(
limit_nodes=parsed_args.limit)
playbook = 'all'
extra_vars = oooutils.parse_extra_vars(parsed_args.extra_vars)

View File

@ -171,7 +171,7 @@ class FFWDUpgradeRun(command.Command):
inventory_file=parsed_args.static_inventory,
ssh_user=parsed_args.ssh_user, stack=parsed_args.stack)
# Don't expost limit_hosts. We need this on the whole overcloud.
limit_hosts = ''
limit_hosts = None
oooutils.run_update_ansible_action(
self.log, clients, parsed_args.stack, limit_hosts, inventory,
constants.FFWD_UPGRADE_PLAYBOOK, [], parsed_args.ssh_user,

View File

@ -85,11 +85,13 @@ class UpdateRun(command.Command):
def get_parser(self, prog_name):
parser = super(UpdateRun, self).get_parser(prog_name)
parser.add_argument(
'--limit', action='store', required=True, help=_(
"A string that identifies a single node or comma-separated"
" list of nodes to be upgraded in parallel in this upgrade"
" run invocation. For example: --limit \"compute-0,"
" compute-1, compute-5\".")
'--limit',
action='store',
required=True,
help=_("A string that identifies a single node or comma-separated"
"list of nodes the config-download Ansible playbook "
"execution will be limited to. For example: --limit"
" \"compute-0,compute-1,compute-5\".")
)
parser.add_argument('--playbook',
action="store",
@ -136,7 +138,20 @@ class UpdateRun(command.Command):
'system command instead of running Ansible'
'via the TripleO mistral workflows.')
)
parser.add_argument(
'--tags',
action='store',
default=None,
help=_('A list of tags to use when running the config-download'
' ansible-playbook command.')
)
parser.add_argument(
'--skip-tags',
action='store',
default=None,
help=_('A list of tags to skip when running the'
' config-download ansible-playbook command.')
)
return parser
def take_action(self, parsed_args):
@ -155,20 +170,26 @@ class UpdateRun(command.Command):
key = package_update.get_key(clients)
# 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)
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)
limit_hosts = oooutils.playbook_limit_parse(
limit_nodes=parsed_args.limit)
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),
skip_tags=parsed_args.skip_tags,
tags=parsed_args.tags,
verbosity=verbosity,
workdir=ansible_dir,
priv_key=key)
class UpdateConverge(DeployOvercloud):

View File

@ -108,11 +108,13 @@ class UpgradeRun(command.Command):
def get_parser(self, prog_name):
parser = super(UpgradeRun, self).get_parser(prog_name)
parser.add_argument(
'--limit', action='store', required=True, help=_(
"A string that identifies a single node or comma-separated"
"list of nodes to be upgraded in parallel in this upgrade"
" run invocation. For example: --limit \"compute-0,"
" compute-1, compute-5\".")
'--limit',
action='store',
required=True,
help=_("A string that identifies a single node or comma-separated"
"list of nodes the config-download Ansible playbook "
"execution will be limited to. For example: --limit"
" \"compute-0,compute-1,compute-5\".")
)
parser.add_argument('--playbook',
action="store",
@ -211,23 +213,27 @@ class UpgradeRun(command.Command):
key = package_update.get_key(clients)
# 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)
skip_tags = self._validate_skip_tags(parsed_args.skip_tags)
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)
limit_hosts = oooutils.playbook_limit_parse(
limit_nodes=parsed_args.limit)
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),
skip_tags,
parsed_args.tags,
verbosity,
workdir=ansible_dir,
priv_key=key)
playbooks = (constants.MAJOR_UPGRADE_PLAYBOOKS
if playbook == 'all' else playbook)

View File

@ -326,17 +326,23 @@ def enable_ssh_admin(log, clients, plan_name, hosts, ssh_user, ssh_key,
print("Enabling ssh admin - COMPLETE.")
def config_download(log, clients, stack, templates, ssh_user, ssh_key,
ssh_network, output_dir, override_ansible_cfg, timeout=600,
verbosity=1, deployment_options={},
in_flight_validations=False, deployment_timeout=None):
def config_download(log, clients, stack, templates,
ssh_user, ssh_key, ssh_network,
output_dir, override_ansible_cfg, timeout, verbosity=1,
deployment_options={},
in_flight_validations=False,
deployment_timeout=None,
skip_tags=None,
tags=None,
limit_hosts=None):
workflow_client = clients.workflow_engine
tripleoclients = clients.tripleoclient
if in_flight_validations:
skip_tags = ''
else:
skip_tags = 'opendev-validation'
if not in_flight_validations:
if skip_tags:
skip_tags = 'opendev-validation,{}'.format(skip_tags)
else:
skip_tags = 'opendev-validation'
workflow_input = {
'verbosity': verbosity,
@ -345,7 +351,9 @@ def config_download(log, clients, stack, templates, ssh_user, ssh_key,
'connection_timeout': timeout,
'config_download_timeout': deployment_timeout,
'deployment_options': deployment_options,
'skip_tags': skip_tags
'skip_tags': skip_tags,
'tags': tags,
'limit_hosts': utils.playbook_limit_parse(limit_hosts)
}
if output_dir:
workflow_input.update(dict(work_dir=output_dir))