Merge "Add skip list option in order to provide a black list for validation"
This commit is contained in:
commit
58c757cdee
|
@ -45,6 +45,111 @@ class TestValidationActions(TestCase):
|
||||||
'My Validation Two Name',
|
'My Validation Two Name',
|
||||||
['prep', 'pre-introspection'])]))
|
['prep', 'pre-introspection'])]))
|
||||||
|
|
||||||
|
@mock.patch('validations_libs.utils.get_validations_playbook',
|
||||||
|
return_value=['/tmp/foo/fake.yaml'])
|
||||||
|
def test_validation_skip_validation(self, mock_validation_play):
|
||||||
|
|
||||||
|
playbook = ['fake.yaml']
|
||||||
|
inventory = 'tmp/inventory.yaml'
|
||||||
|
skip_list = {'fake': {'hosts': 'ALL',
|
||||||
|
'reason': None,
|
||||||
|
'lp': None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
run = ValidationActions()
|
||||||
|
run_return = run.run_validations(playbook, inventory,
|
||||||
|
validations_dir='/tmp/foo',
|
||||||
|
skip_list=skip_list,
|
||||||
|
limit_hosts=None)
|
||||||
|
self.assertEqual(run_return, [])
|
||||||
|
|
||||||
|
@mock.patch('validations_libs.utils.get_validations_playbook',
|
||||||
|
return_value=['/tmp/foo/fake.yaml'])
|
||||||
|
@mock.patch('validations_libs.ansible.Ansible.run')
|
||||||
|
@mock.patch('validations_libs.utils.create_artifacts_dir',
|
||||||
|
return_value=('1234', '/tmp/'))
|
||||||
|
def test_validation_skip_on_specific_host(self, mock_tmp, mock_ansible_run,
|
||||||
|
mock_validation_play):
|
||||||
|
mock_ansible_run.return_value = ('fake.yaml', 0, 'successful')
|
||||||
|
run_called_args = {
|
||||||
|
'workdir': '/tmp/',
|
||||||
|
'playbook': '/tmp/foo/fake.yaml',
|
||||||
|
'base_dir': '/usr/share/ansible/',
|
||||||
|
'playbook_dir': '/tmp/foo',
|
||||||
|
'parallel_run': True,
|
||||||
|
'inventory': 'tmp/inventory.yaml',
|
||||||
|
'output_callback': 'validation_stdout',
|
||||||
|
'quiet': True,
|
||||||
|
'extra_vars': None,
|
||||||
|
'limit_hosts': '!cloud1',
|
||||||
|
'ansible_artifact_path': '/tmp/',
|
||||||
|
'extra_env_variables': None,
|
||||||
|
'ansible_cfg': None,
|
||||||
|
'gathering_policy': 'explicit',
|
||||||
|
'log_path': None,
|
||||||
|
'run_async': False,
|
||||||
|
'python_interpreter': None
|
||||||
|
}
|
||||||
|
|
||||||
|
playbook = ['fake.yaml']
|
||||||
|
inventory = 'tmp/inventory.yaml'
|
||||||
|
skip_list = {'fake': {'hosts': 'cloud1',
|
||||||
|
'reason': None,
|
||||||
|
'lp': None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
run = ValidationActions()
|
||||||
|
run_return = run.run_validations(playbook, inventory,
|
||||||
|
validations_dir='/tmp/foo',
|
||||||
|
skip_list=skip_list,
|
||||||
|
limit_hosts=None)
|
||||||
|
mock_ansible_run.assert_called_with(**run_called_args)
|
||||||
|
|
||||||
|
@mock.patch('validations_libs.utils.get_validations_playbook',
|
||||||
|
return_value=['/tmp/foo/fake.yaml'])
|
||||||
|
@mock.patch('validations_libs.ansible.Ansible.run')
|
||||||
|
@mock.patch('validations_libs.utils.create_artifacts_dir',
|
||||||
|
return_value=('1234', '/tmp/'))
|
||||||
|
def test_validation_skip_with_limit_host(self, mock_tmp, mock_ansible_run,
|
||||||
|
mock_validation_play):
|
||||||
|
mock_ansible_run.return_value = ('fake.yaml', 0, 'successful')
|
||||||
|
run_called_args = {
|
||||||
|
'workdir': '/tmp/',
|
||||||
|
'playbook': '/tmp/foo/fake.yaml',
|
||||||
|
'base_dir': '/usr/share/ansible/',
|
||||||
|
'playbook_dir': '/tmp/foo',
|
||||||
|
'parallel_run': True,
|
||||||
|
'inventory': 'tmp/inventory.yaml',
|
||||||
|
'output_callback': 'validation_stdout',
|
||||||
|
'quiet': True,
|
||||||
|
'extra_vars': None,
|
||||||
|
'limit_hosts': '!cloud1,cloud,!cloud2',
|
||||||
|
'ansible_artifact_path': '/tmp/',
|
||||||
|
'extra_env_variables': None,
|
||||||
|
'ansible_cfg': None,
|
||||||
|
'gathering_policy': 'explicit',
|
||||||
|
'log_path': None,
|
||||||
|
'run_async': False,
|
||||||
|
'python_interpreter': None
|
||||||
|
}
|
||||||
|
|
||||||
|
playbook = ['fake.yaml']
|
||||||
|
inventory = 'tmp/inventory.yaml'
|
||||||
|
skip_list = {'fake': {'hosts': 'cloud1',
|
||||||
|
'reason': None,
|
||||||
|
'lp': None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
run = ValidationActions()
|
||||||
|
run_return = run.run_validations(playbook, inventory,
|
||||||
|
validations_dir='/tmp/foo',
|
||||||
|
skip_list=skip_list,
|
||||||
|
limit_hosts='cloud,cloud1,!cloud2')
|
||||||
|
mock_ansible_run.assert_called_with(**run_called_args)
|
||||||
|
|
||||||
@mock.patch('validations_libs.validation_logs.ValidationLogs.get_results')
|
@mock.patch('validations_libs.validation_logs.ValidationLogs.get_results')
|
||||||
@mock.patch('validations_libs.utils.parse_all_validations_on_disk')
|
@mock.patch('validations_libs.utils.parse_all_validations_on_disk')
|
||||||
@mock.patch('validations_libs.ansible.Ansible.run')
|
@mock.patch('validations_libs.ansible.Ansible.run')
|
||||||
|
|
|
@ -129,13 +129,89 @@ class ValidationActions(object):
|
||||||
data.update(data_format)
|
data.update(data_format)
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
def _skip_hosts(self, skip_list, playbook, limit_hosts=None):
|
||||||
|
"""Check Ansible Hosts and return an updated limit_hosts
|
||||||
|
:param skip_list: The list of the validation to skip
|
||||||
|
:type validation_name: ``dict``
|
||||||
|
:param playbook: The name of the playbook
|
||||||
|
:type base_dir: ``string``
|
||||||
|
:param limit_hosts: Limit the execution to the hosts.
|
||||||
|
:type limit_hosts: ``string``
|
||||||
|
|
||||||
|
:return the limit hosts according the skip_list or None if the
|
||||||
|
validation should be skipped on ALL hosts.
|
||||||
|
:example
|
||||||
|
limit_hosts = 'cloud1,cloud2'
|
||||||
|
skip_list = {'xyz': {'hosts': 'cloud1',
|
||||||
|
'reason': None,
|
||||||
|
'lp': None}
|
||||||
|
}
|
||||||
|
>>> _skip_hosts(skip_list, playbook, limit_hosts='cloud1,cloud2')
|
||||||
|
'cloud2,!cloud1'
|
||||||
|
|
||||||
|
"""
|
||||||
|
hosts = skip_list[playbook].get('hosts')
|
||||||
|
if hosts == 'ALL' or hosts is None:
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
_hosts = ['!{}'.format(hosts)]
|
||||||
|
if limit_hosts:
|
||||||
|
# check if skipped hosts is already in limit host
|
||||||
|
_hosts.extend([limit for limit in limit_hosts.split(',')
|
||||||
|
if hosts not in limit])
|
||||||
|
return ','.join(_hosts)
|
||||||
|
|
||||||
|
def _skip_playbook(self, skip_list, playbook, limit_hosts=None):
|
||||||
|
"""Check if playbook is in the ski plist
|
||||||
|
:param skip_list: The list of the validation to skip
|
||||||
|
:type validation_name: ``dict``
|
||||||
|
:param playbook: The name of the playbook
|
||||||
|
:type base_dir: ``string``
|
||||||
|
:param limit_hosts: Limit the execution to the hosts.
|
||||||
|
:type limit_hosts: ``string``
|
||||||
|
|
||||||
|
:return a tuple of playbook and hosts
|
||||||
|
:example
|
||||||
|
skip_list = {'xyz': {'hosts': 'cloud1',
|
||||||
|
'reason': None,
|
||||||
|
'lp': None}
|
||||||
|
}
|
||||||
|
If playbook not in skip list:
|
||||||
|
>>> _skip_playbook(skip_list, 'foo', None)
|
||||||
|
('foo', None)
|
||||||
|
|
||||||
|
If playbook in the skip list, but with restriction only on
|
||||||
|
host cloud1:
|
||||||
|
>>> _skip_playbook(skip_list, 'xyz', None)
|
||||||
|
('xyz', '!cloud1')
|
||||||
|
|
||||||
|
If playbook in the skip list, and should be skip on ALL hosts:
|
||||||
|
skip_list = {'xyz': {'hosts': 'ALL',
|
||||||
|
'reason': None,
|
||||||
|
'lp': None}
|
||||||
|
}
|
||||||
|
>>> _skip_playbook(skip_list, 'xyz', None)
|
||||||
|
(None, None)
|
||||||
|
|
||||||
|
"""
|
||||||
|
if skip_list:
|
||||||
|
if playbook in skip_list.keys():
|
||||||
|
_hosts = self._skip_hosts(skip_list, playbook,
|
||||||
|
limit_hosts)
|
||||||
|
if _hosts:
|
||||||
|
return playbook, _hosts
|
||||||
|
else:
|
||||||
|
return None, _hosts
|
||||||
|
return playbook, limit_hosts
|
||||||
|
|
||||||
def run_validations(self, validation_name=None, inventory='localhost',
|
def run_validations(self, validation_name=None, inventory='localhost',
|
||||||
group=None, extra_vars=None, validations_dir=None,
|
group=None, extra_vars=None, validations_dir=None,
|
||||||
extra_env_vars=None, ansible_cfg=None, quiet=True,
|
extra_env_vars=None, ansible_cfg=None, quiet=True,
|
||||||
workdir=None, limit_hosts=None, run_async=False,
|
workdir=None, limit_hosts=None, run_async=False,
|
||||||
base_dir=constants.DEFAULT_VALIDATIONS_BASEDIR,
|
base_dir=constants.DEFAULT_VALIDATIONS_BASEDIR,
|
||||||
log_path=None, python_interpreter=None,
|
log_path=None, python_interpreter=None,
|
||||||
output_callback='validation_stdout'):
|
output_callback='validation_stdout',
|
||||||
|
skip_list=None):
|
||||||
"""Run one or multiple validations by name(s) or by group(s)
|
"""Run one or multiple validations by name(s) or by group(s)
|
||||||
|
|
||||||
:param validation_name: A list of validation names
|
:param validation_name: A list of validation names
|
||||||
|
@ -181,6 +257,11 @@ class ValidationActions(object):
|
||||||
:param output_callback: The Callback plugin to use.
|
:param output_callback: The Callback plugin to use.
|
||||||
(Defaults to 'validation_stdout')
|
(Defaults to 'validation_stdout')
|
||||||
:type output_callback: ``string``
|
:type output_callback: ``string``
|
||||||
|
:param skip_list: List of validations to skip during the Run form as
|
||||||
|
{'xyz': {'hosts': 'ALL', 'reason': None, 'lp': None}
|
||||||
|
}
|
||||||
|
(Defaults to 'None')
|
||||||
|
:type skip_list: ``dict``
|
||||||
|
|
||||||
:return: A list of dictionary containing the informations of the
|
:return: A list of dictionary containing the informations of the
|
||||||
validations executions (Validations, Duration, Host_Group,
|
validations executions (Validations, Duration, Host_Group,
|
||||||
|
@ -248,33 +329,42 @@ class ValidationActions(object):
|
||||||
self.log.debug('Running the validations with Ansible')
|
self.log.debug('Running the validations with Ansible')
|
||||||
results = []
|
results = []
|
||||||
for playbook in playbooks:
|
for playbook in playbooks:
|
||||||
validation_uuid, artifacts_dir = v_utils.create_artifacts_dir(
|
# Check if playbook should be skipped and on which hosts
|
||||||
dir_path=log_path, prefix=os.path.basename(playbook))
|
play_name = os.path.basename(os.path.splitext(playbook)[0])
|
||||||
run_ansible = v_ansible(validation_uuid)
|
_play, _hosts = self._skip_playbook(skip_list,
|
||||||
_playbook, _rc, _status = run_ansible.run(
|
play_name,
|
||||||
workdir=artifacts_dir,
|
limit_hosts)
|
||||||
playbook=playbook,
|
if _play:
|
||||||
base_dir=base_dir,
|
validation_uuid, artifacts_dir = v_utils.create_artifacts_dir(
|
||||||
playbook_dir=validations_dir,
|
dir_path=log_path, prefix=os.path.basename(playbook))
|
||||||
parallel_run=True,
|
run_ansible = v_ansible(validation_uuid)
|
||||||
inventory=inventory,
|
_playbook, _rc, _status = run_ansible.run(
|
||||||
output_callback=output_callback,
|
workdir=artifacts_dir,
|
||||||
quiet=quiet,
|
playbook=playbook,
|
||||||
extra_vars=extra_vars,
|
base_dir=base_dir,
|
||||||
limit_hosts=limit_hosts,
|
playbook_dir=validations_dir,
|
||||||
extra_env_variables=extra_env_vars,
|
parallel_run=True,
|
||||||
ansible_cfg=ansible_cfg,
|
inventory=inventory,
|
||||||
gathering_policy='explicit',
|
output_callback=output_callback,
|
||||||
ansible_artifact_path=artifacts_dir,
|
quiet=quiet,
|
||||||
log_path=log_path,
|
extra_vars=extra_vars,
|
||||||
run_async=run_async,
|
limit_hosts=_hosts,
|
||||||
python_interpreter=python_interpreter)
|
extra_env_variables=extra_env_vars,
|
||||||
results.append({'playbook': _playbook,
|
ansible_cfg=ansible_cfg,
|
||||||
'rc_code': _rc,
|
gathering_policy='explicit',
|
||||||
'status': _status,
|
ansible_artifact_path=artifacts_dir,
|
||||||
'validations': _playbook.split('.')[0],
|
log_path=log_path,
|
||||||
'UUID': validation_uuid,
|
run_async=run_async,
|
||||||
})
|
python_interpreter=python_interpreter)
|
||||||
|
results.append({'playbook': _playbook,
|
||||||
|
'rc_code': _rc,
|
||||||
|
'status': _status,
|
||||||
|
'validations': _playbook.split('.')[0],
|
||||||
|
'UUID': validation_uuid,
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
self.log.debug('Skipping Validations: {}'.format(playbook))
|
||||||
|
|
||||||
if run_async:
|
if run_async:
|
||||||
return results
|
return results
|
||||||
# Return log results
|
# Return log results
|
||||||
|
|
Loading…
Reference in New Issue