Merge "Validation actions refactor" into stable/1.6
This commit is contained in:
@@ -62,11 +62,10 @@ class ListHistory(BaseLister):
|
||||
("Limiting output to the maximum of "
|
||||
"{} last validations.").format(history_limit))
|
||||
|
||||
actions = ValidationActions()
|
||||
actions = ValidationActions(log_path=parsed_args.validation_log_dir)
|
||||
|
||||
return actions.show_history(
|
||||
validation_ids=parsed_args.validation,
|
||||
log_path=parsed_args.validation_log_dir,
|
||||
history_limit=history_limit)
|
||||
|
||||
|
||||
|
||||
@@ -171,7 +171,8 @@ class Run(BaseCommand):
|
||||
# Get config:
|
||||
config = self.base.config
|
||||
|
||||
v_actions = ValidationActions(parsed_args.validation_dir)
|
||||
v_actions = ValidationActions(
|
||||
parsed_args.validation_dir, log_path=parsed_args.validation_log_dir)
|
||||
# Ansible execution should be quiet while using the validations_json
|
||||
# default callback and be verbose while passing ANSIBLE_SDTOUT_CALLBACK
|
||||
# environment variable to Ansible through the --extra-env-vars argument
|
||||
@@ -213,7 +214,6 @@ class Run(BaseCommand):
|
||||
python_interpreter=parsed_args.python_interpreter,
|
||||
quiet=quiet_mode,
|
||||
ssh_user=parsed_args.ssh_user,
|
||||
log_path=parsed_args.validation_log_dir,
|
||||
validation_config=config,
|
||||
skip_list=skip_list)
|
||||
except RuntimeError as e:
|
||||
|
||||
@@ -71,8 +71,8 @@ class ShowGroup(BaseLister):
|
||||
self.base.set_argument_parser(self, parsed_args)
|
||||
|
||||
v_actions = ValidationActions(parsed_args.validation_dir)
|
||||
|
||||
return v_actions.group_information(
|
||||
constants.VALIDATION_GROUPS_INFO,
|
||||
validation_config=self.base.config)
|
||||
|
||||
|
||||
|
||||
@@ -68,10 +68,10 @@ class Group(object):
|
||||
return self.data
|
||||
|
||||
@property
|
||||
def get_formated_group(self):
|
||||
"""Get a formated content for output display
|
||||
def get_formated_groups(self):
|
||||
"""Get a formated list of groups for output display
|
||||
|
||||
:return:
|
||||
:return: information about parsed groups
|
||||
:rtype: `list` of `tuples`
|
||||
|
||||
:Example:
|
||||
|
||||
@@ -29,7 +29,8 @@ class TestListHistory(BaseCommand):
|
||||
self.cmd = history.ListHistory(self.app, None)
|
||||
|
||||
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||
'show_history')
|
||||
'show_history',
|
||||
autospec=True)
|
||||
def test_list_history(self, mock_history):
|
||||
arglist = ['--validation-log-dir', '/foo/log/dir']
|
||||
verifylist = [('validation_log_dir', '/foo/log/dir')]
|
||||
@@ -80,7 +81,8 @@ class TestGetHistory(BaseCommand):
|
||||
|
||||
@mock.patch('validations_libs.validation_logs.ValidationLogs.'
|
||||
'get_logfile_content_by_uuid',
|
||||
return_value=fakes.VALIDATIONS_LOGS_CONTENTS_LIST)
|
||||
return_value=fakes.VALIDATIONS_LOGS_CONTENTS_LIST,
|
||||
autospec=True)
|
||||
def test_get_history(self, mock_logs):
|
||||
arglist = ['123']
|
||||
verifylist = [('uuid', '123')]
|
||||
@@ -91,7 +93,8 @@ class TestGetHistory(BaseCommand):
|
||||
|
||||
@mock.patch('validations_libs.validation_logs.ValidationLogs.'
|
||||
'get_logfile_content_by_uuid',
|
||||
return_value=fakes.VALIDATIONS_LOGS_CONTENTS_LIST)
|
||||
return_value=fakes.VALIDATIONS_LOGS_CONTENTS_LIST,
|
||||
autospec=True)
|
||||
def test_get_history_from_log_dir(self, mock_logs):
|
||||
arglist = ['123', '--validation-log-dir', '/foo/log/dir']
|
||||
verifylist = [('uuid', '123'), ('validation_log_dir', '/foo/log/dir')]
|
||||
@@ -102,7 +105,8 @@ class TestGetHistory(BaseCommand):
|
||||
|
||||
@mock.patch('validations_libs.validation_logs.ValidationLogs.'
|
||||
'get_logfile_content_by_uuid',
|
||||
return_value=fakes.VALIDATIONS_LOGS_CONTENTS_LIST)
|
||||
return_value=fakes.VALIDATIONS_LOGS_CONTENTS_LIST,
|
||||
autospec=True)
|
||||
def test_get_history_full_arg(self, mock_logs):
|
||||
arglist = ['123', '--full']
|
||||
verifylist = [('uuid', '123'), ('full', True)]
|
||||
|
||||
@@ -30,7 +30,8 @@ class TestList(BaseCommand):
|
||||
|
||||
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||
'list_validations',
|
||||
return_value=fakes.VALIDATIONS_LIST)
|
||||
return_value=fakes.VALIDATIONS_LIST,
|
||||
autospec=True)
|
||||
def test_list_validations(self, mock_list):
|
||||
arglist = ['--validation-dir', 'foo']
|
||||
verifylist = [('validation_dir', 'foo')]
|
||||
@@ -59,7 +60,8 @@ class TestList(BaseCommand):
|
||||
|
||||
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||
'list_validations',
|
||||
return_value=[])
|
||||
return_value=[],
|
||||
autospec=True)
|
||||
def test_list_validations_empty(self, mock_list):
|
||||
arglist = ['--validation-dir', 'foo']
|
||||
verifylist = [('validation_dir', 'foo')]
|
||||
@@ -69,7 +71,8 @@ class TestList(BaseCommand):
|
||||
self.assertEqual(result, [])
|
||||
|
||||
@mock.patch('validations_libs.utils.parse_all_validations_on_disk',
|
||||
return_value=fakes.VALIDATIONS_LIST_GROUP)
|
||||
return_value=fakes.VALIDATIONS_LIST_GROUP,
|
||||
autospec=True)
|
||||
def test_list_validations_group(self, mock_list):
|
||||
arglist = ['--validation-dir', 'foo', '--group', 'prep']
|
||||
verifylist = [('validation_dir', 'foo'),
|
||||
@@ -82,7 +85,8 @@ class TestList(BaseCommand):
|
||||
self.assertEqual(result, val_list)
|
||||
|
||||
@mock.patch('validations_libs.utils.parse_all_validations_on_disk',
|
||||
return_value=fakes.VALIDATIONS_LIST_GROUP)
|
||||
return_value=fakes.VALIDATIONS_LIST_GROUP,
|
||||
autospec=True)
|
||||
def test_list_validations_by_category(self, mock_list):
|
||||
arglist = ['--validation-dir', 'foo', '--category', 'networking']
|
||||
verifylist = [('validation_dir', 'foo'),
|
||||
@@ -95,7 +99,8 @@ class TestList(BaseCommand):
|
||||
self.assertEqual(result, val_list)
|
||||
|
||||
@mock.patch('validations_libs.utils.parse_all_validations_on_disk',
|
||||
return_value=fakes.VALIDATIONS_LIST_GROUP)
|
||||
return_value=fakes.VALIDATIONS_LIST_GROUP,
|
||||
autospec=True)
|
||||
def test_list_validations_by_product(self, mock_list):
|
||||
arglist = ['--validation-dir', 'foo', '--product', 'product1']
|
||||
verifylist = [('validation_dir', 'foo'),
|
||||
|
||||
@@ -32,7 +32,8 @@ class TestRun(BaseCommand):
|
||||
|
||||
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||
'run_validations',
|
||||
return_value=None)
|
||||
return_value=None,
|
||||
autospec=True)
|
||||
def test_run_command_return_none(self, mock_run):
|
||||
args = self._set_args(['--validation', 'foo'])
|
||||
verifylist = [('validation_name', ['foo'])]
|
||||
@@ -43,7 +44,8 @@ class TestRun(BaseCommand):
|
||||
@mock.patch('validations_libs.cli.common.open')
|
||||
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||
'run_validations',
|
||||
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN))
|
||||
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN),
|
||||
autospec=True)
|
||||
def test_run_command_success(self, mock_run, mock_open):
|
||||
args = self._set_args(['--validation', 'foo'])
|
||||
verifylist = [('validation_name', ['foo'])]
|
||||
@@ -65,10 +67,12 @@ class TestRun(BaseCommand):
|
||||
return_value='doe')
|
||||
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||
'run_validations',
|
||||
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN))
|
||||
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN),
|
||||
autospec=True)
|
||||
@mock.patch('validations_libs.utils.load_config', return_value={})
|
||||
def test_run_command_extra_vars(self, mock_config, mock_run,
|
||||
mock_user, mock_print, mock_log_dir):
|
||||
def test_run_command_extra_vars(self, mock_config,
|
||||
mock_run, mock_user,
|
||||
mock_print, mock_log_dir):
|
||||
run_called_args = {
|
||||
'inventory': 'localhost',
|
||||
'limit_hosts': None,
|
||||
@@ -83,7 +87,6 @@ class TestRun(BaseCommand):
|
||||
'python_interpreter': sys.executable,
|
||||
'quiet': True,
|
||||
'ssh_user': 'doe',
|
||||
'log_path': mock_log_dir,
|
||||
'validation_config': {},
|
||||
'skip_list': None
|
||||
}
|
||||
@@ -95,7 +98,9 @@ class TestRun(BaseCommand):
|
||||
self._set_args(arglist)
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.cmd.take_action(parsed_args)
|
||||
mock_run.assert_called_with(**run_called_args)
|
||||
call_args = mock_run.mock_calls[0][2]
|
||||
|
||||
self.assertDictEqual(call_args, run_called_args)
|
||||
|
||||
@mock.patch('validations_libs.constants.VALIDATIONS_LOG_BASEDIR')
|
||||
@mock.patch('validations_libs.cli.common.print_dict')
|
||||
@@ -103,10 +108,11 @@ class TestRun(BaseCommand):
|
||||
return_value='doe')
|
||||
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||
'run_validations',
|
||||
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN))
|
||||
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN),
|
||||
autospec=True)
|
||||
@mock.patch('validations_libs.utils.load_config', return_value={})
|
||||
def test_run_command_extra_vars_twice(self, mock_config,
|
||||
mock_run, mock_user, mock_print,
|
||||
def test_run_command_extra_vars_twice(self, mock_config, mock_run,
|
||||
mock_user, mock_print,
|
||||
mock_log_dir):
|
||||
run_called_args = {
|
||||
'inventory': 'localhost',
|
||||
@@ -122,7 +128,6 @@ class TestRun(BaseCommand):
|
||||
'python_interpreter': sys.executable,
|
||||
'quiet': True,
|
||||
'ssh_user': 'doe',
|
||||
'log_path': mock_log_dir,
|
||||
'validation_config': {},
|
||||
'skip_list': None
|
||||
}
|
||||
@@ -135,7 +140,9 @@ class TestRun(BaseCommand):
|
||||
self._set_args(arglist)
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.cmd.take_action(parsed_args)
|
||||
mock_run.assert_called_with(**run_called_args)
|
||||
call_args = mock_run.mock_calls[0][2]
|
||||
|
||||
self.assertDictEqual(call_args, run_called_args)
|
||||
|
||||
def test_run_command_exclusive_vars(self):
|
||||
arglist = ['--validation', 'foo',
|
||||
@@ -154,7 +161,8 @@ class TestRun(BaseCommand):
|
||||
return_value='doe')
|
||||
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||
'run_validations',
|
||||
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN))
|
||||
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN),
|
||||
autospec=True)
|
||||
@mock.patch('validations_libs.utils.load_config', return_value={})
|
||||
def test_run_command_extra_vars_file(self, mock_config, mock_run,
|
||||
mock_user, mock_open,
|
||||
@@ -174,7 +182,6 @@ class TestRun(BaseCommand):
|
||||
'python_interpreter': sys.executable,
|
||||
'quiet': True,
|
||||
'ssh_user': 'doe',
|
||||
'log_path': mock_log_dir,
|
||||
'validation_config': {},
|
||||
'skip_list': None
|
||||
}
|
||||
@@ -186,14 +193,17 @@ class TestRun(BaseCommand):
|
||||
self._set_args(arglist)
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.cmd.take_action(parsed_args)
|
||||
mock_run.assert_called_with(**run_called_args)
|
||||
call_args = mock_run.mock_calls[0][2]
|
||||
|
||||
self.assertDictEqual(call_args, run_called_args)
|
||||
|
||||
@mock.patch('validations_libs.constants.VALIDATIONS_LOG_BASEDIR')
|
||||
@mock.patch('getpass.getuser',
|
||||
return_value='doe')
|
||||
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||
'run_validations',
|
||||
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN))
|
||||
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN),
|
||||
autospec=True)
|
||||
@mock.patch('validations_libs.utils.load_config', return_value={})
|
||||
def test_run_command_extra_env_vars(self, mock_config, mock_run,
|
||||
mock_user, mock_log_dir):
|
||||
@@ -211,7 +221,6 @@ class TestRun(BaseCommand):
|
||||
'python_interpreter': sys.executable,
|
||||
'quiet': True,
|
||||
'ssh_user': 'doe',
|
||||
'log_path': mock_log_dir,
|
||||
'validation_config': {},
|
||||
'skip_list': None
|
||||
}
|
||||
@@ -223,14 +232,17 @@ class TestRun(BaseCommand):
|
||||
self._set_args(arglist)
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.cmd.take_action(parsed_args)
|
||||
mock_run.assert_called_with(**run_called_args)
|
||||
call_args = mock_run.mock_calls[0][2]
|
||||
|
||||
self.assertDictEqual(call_args, run_called_args)
|
||||
|
||||
@mock.patch('validations_libs.constants.VALIDATIONS_LOG_BASEDIR')
|
||||
@mock.patch('getpass.getuser',
|
||||
return_value='doe')
|
||||
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||
'run_validations',
|
||||
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN))
|
||||
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN),
|
||||
autospec=True)
|
||||
@mock.patch('validations_libs.utils.load_config', return_value={})
|
||||
def test_run_command_extra_env_vars_with_custom_callback(self,
|
||||
mock_config,
|
||||
@@ -240,7 +252,6 @@ class TestRun(BaseCommand):
|
||||
run_called_args = {
|
||||
'inventory': 'localhost',
|
||||
'limit_hosts': None,
|
||||
'log_path': mock_log_dir,
|
||||
'quiet': False,
|
||||
'group': [],
|
||||
'category': [],
|
||||
@@ -264,14 +275,17 @@ class TestRun(BaseCommand):
|
||||
self._set_args(arglist)
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.cmd.take_action(parsed_args)
|
||||
mock_run.assert_called_with(**run_called_args)
|
||||
call_args = mock_run.mock_calls[0][2]
|
||||
|
||||
self.assertDictEqual(call_args, run_called_args)
|
||||
|
||||
@mock.patch('validations_libs.constants.VALIDATIONS_LOG_BASEDIR')
|
||||
@mock.patch('getpass.getuser',
|
||||
return_value='doe')
|
||||
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||
'run_validations',
|
||||
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN))
|
||||
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN),
|
||||
autospec=True)
|
||||
@mock.patch('validations_libs.utils.load_config', return_value={})
|
||||
def test_run_command_extra_env_vars_twice(self, mock_config,
|
||||
mock_run, mock_user,
|
||||
@@ -290,7 +304,6 @@ class TestRun(BaseCommand):
|
||||
'python_interpreter': sys.executable,
|
||||
'quiet': True,
|
||||
'ssh_user': 'doe',
|
||||
'log_path': mock_log_dir,
|
||||
'validation_config': {},
|
||||
'skip_list': None
|
||||
}
|
||||
@@ -303,14 +316,17 @@ class TestRun(BaseCommand):
|
||||
self._set_args(arglist)
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.cmd.take_action(parsed_args)
|
||||
mock_run.assert_called_with(**run_called_args)
|
||||
call_args = mock_run.mock_calls[0][2]
|
||||
|
||||
self.assertDictEqual(call_args, run_called_args)
|
||||
|
||||
@mock.patch('validations_libs.constants.VALIDATIONS_LOG_BASEDIR')
|
||||
@mock.patch('getpass.getuser',
|
||||
return_value='doe')
|
||||
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||
'run_validations',
|
||||
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN))
|
||||
return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN),
|
||||
autospec=True)
|
||||
@mock.patch('validations_libs.utils.load_config', return_value={})
|
||||
def test_run_command_extra_env_vars_and_extra_vars(self,
|
||||
mock_config,
|
||||
@@ -331,7 +347,6 @@ class TestRun(BaseCommand):
|
||||
'python_interpreter': sys.executable,
|
||||
'quiet': True,
|
||||
'ssh_user': 'doe',
|
||||
'log_path': mock_log_dir,
|
||||
'validation_config': {},
|
||||
'skip_list': None
|
||||
}
|
||||
@@ -345,7 +360,9 @@ class TestRun(BaseCommand):
|
||||
self._set_args(arglist)
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.cmd.take_action(parsed_args)
|
||||
mock_run.assert_called_with(**run_called_args)
|
||||
call_args = mock_run.mock_calls[0][2]
|
||||
|
||||
self.assertDictEqual(call_args, run_called_args)
|
||||
|
||||
def test_run_command_exclusive_wrong_extra_vars(self):
|
||||
arglist = ['--validation', 'foo',
|
||||
@@ -356,50 +373,18 @@ class TestRun(BaseCommand):
|
||||
self.assertRaises(Exception, self.check_parser, self.cmd,
|
||||
arglist, verifylist)
|
||||
|
||||
@mock.patch('validations_libs.utils.find_config_file',
|
||||
return_value="/etc/validations_foo.cfg")
|
||||
@mock.patch('validations_libs.constants.VALIDATIONS_LOG_BASEDIR')
|
||||
@mock.patch('getpass.getuser',
|
||||
return_value='doe')
|
||||
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||
'run_validations',
|
||||
return_value=copy.deepcopy(fakes.FAKE_FAILED_RUN))
|
||||
return_value=copy.deepcopy(fakes.FAKE_FAILED_RUN),
|
||||
autospec=True)
|
||||
@mock.patch('validations_libs.utils.load_config', return_value={})
|
||||
def test_run_command_failed_validation(self, mock_config,
|
||||
mock_run, mock_user, mock_log_dir):
|
||||
run_called_args = {
|
||||
'inventory': 'localhost',
|
||||
'limit_hosts': None,
|
||||
'group': [],
|
||||
'category': [],
|
||||
'product': [],
|
||||
'extra_vars': None,
|
||||
'validations_dir': '/usr/share/ansible/validation-playbooks',
|
||||
'base_dir': '/usr/share/ansible',
|
||||
'validation_name': ['foo'],
|
||||
'extra_env_vars': None,
|
||||
'python_interpreter': sys.executable,
|
||||
'quiet': True,
|
||||
'ssh_user': 'doe',
|
||||
'log_path': mock_log_dir,
|
||||
'validation_config': {},
|
||||
'skip_list': None
|
||||
}
|
||||
|
||||
arglist = ['--validation', 'foo']
|
||||
verifylist = [('validation_name', ['foo'])]
|
||||
|
||||
self._set_args(arglist)
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.assertRaises(RuntimeError, self.cmd.take_action, parsed_args)
|
||||
mock_run.assert_called_with(**run_called_args)
|
||||
|
||||
@mock.patch('getpass.getuser',
|
||||
return_value='doe')
|
||||
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||
'run_validations',
|
||||
return_value=[])
|
||||
@mock.patch('validations_libs.utils.load_config', return_value={})
|
||||
def test_run_command_no_validation(self, mock_config, mock_run,
|
||||
mock_user):
|
||||
def test_run_command_failed_validation(self, mock_config, mock_run, mock_user,
|
||||
mock_log_dir, mock_config_file):
|
||||
run_called_args = {
|
||||
'inventory': 'localhost',
|
||||
'limit_hosts': None,
|
||||
@@ -418,8 +403,56 @@ class TestRun(BaseCommand):
|
||||
'skip_list': None
|
||||
}
|
||||
|
||||
arglist = ['--validation', 'foo']
|
||||
verifylist = [('validation_name', ['foo'])]
|
||||
arglist = [
|
||||
'--validation', 'foo',
|
||||
'--extra-vars', 'key=value',
|
||||
'--extra-env-vars', 'key2=value2']
|
||||
verifylist = [
|
||||
('validation_name', ['foo']),
|
||||
('extra_vars', {'key': 'value'}),
|
||||
('extra_env_vars', {'key2': 'value2'})]
|
||||
|
||||
self._set_args(arglist)
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.assertRaises(RuntimeError, self.cmd.take_action, parsed_args)
|
||||
call_args = mock_run.mock_calls[0][2]
|
||||
|
||||
self.assertDictEqual(call_args, run_called_args)
|
||||
|
||||
@mock.patch('validations_libs.constants.VALIDATIONS_LOG_BASEDIR')
|
||||
@mock.patch('getpass.getuser',
|
||||
return_value='doe')
|
||||
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||
'run_validations',
|
||||
return_value=[],
|
||||
autospec=True)
|
||||
def test_run_command_no_validation(self, mock_run, mock_user, mock_log_dir):
|
||||
run_called_args = {
|
||||
'inventory': 'localhost',
|
||||
'limit_hosts': None,
|
||||
'group': [],
|
||||
'category': [],
|
||||
'product': [],
|
||||
'extra_vars': {'key': 'value'},
|
||||
'validations_dir': '/usr/share/ansible/validation-playbooks',
|
||||
'base_dir': '/usr/share/ansible',
|
||||
'validation_name': ['foo'],
|
||||
'extra_env_vars': {'key2': 'value2'},
|
||||
'python_interpreter': sys.executable,
|
||||
'quiet': True,
|
||||
'ssh_user': 'doe',
|
||||
'validation_config': {},
|
||||
'skip_list': None,
|
||||
'log_path': mock_log_dir}
|
||||
|
||||
arglist = [
|
||||
'--validation', 'foo',
|
||||
'--extra-vars', 'key=value',
|
||||
'--extra-env-vars', 'key2=value2']
|
||||
verifylist = [
|
||||
('validation_name', ['foo']),
|
||||
('extra_vars', {'key': 'value'}),
|
||||
('extra_env_vars', {'key2': 'value2'})]
|
||||
|
||||
self._set_args(arglist)
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
@@ -451,7 +484,6 @@ class TestRun(BaseCommand):
|
||||
'python_interpreter': sys.executable,
|
||||
'quiet': True,
|
||||
'ssh_user': 'doe',
|
||||
'log_path': mock_log_dir,
|
||||
'validation_config': {},
|
||||
'skip_list': None
|
||||
}
|
||||
@@ -489,7 +521,6 @@ class TestRun(BaseCommand):
|
||||
'python_interpreter': sys.executable,
|
||||
'quiet': True,
|
||||
'ssh_user': 'doe',
|
||||
'log_path': mock_log_dir,
|
||||
'validation_config': {},
|
||||
'skip_list': None
|
||||
}
|
||||
@@ -526,7 +557,6 @@ class TestRun(BaseCommand):
|
||||
'python_interpreter': sys.executable,
|
||||
'quiet': True,
|
||||
'ssh_user': 'doe',
|
||||
'log_path': mock_log_dir,
|
||||
'validation_config': {},
|
||||
'skip_list': {'key': 'value'}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ try:
|
||||
except ImportError:
|
||||
import mock
|
||||
|
||||
from validations_libs import group
|
||||
from validations_libs.validation_actions import ValidationActions
|
||||
from validations_libs.cli import show
|
||||
from validations_libs.tests import fakes
|
||||
from validations_libs.tests.cli.fakes import BaseCommand
|
||||
@@ -48,22 +50,17 @@ class TestShowGroup(BaseCommand):
|
||||
@mock.patch('yaml.safe_load', return_value=fakes.GROUP)
|
||||
@mock.patch('six.moves.builtins.open')
|
||||
def test_show_validations_group_info(self, mock_open, mock_yaml, mock_actions):
|
||||
arglist = []
|
||||
|
||||
mock_info = mock.MagicMock()
|
||||
mock_info.group_information = mock.MagicMock(return_value='foo')
|
||||
mock_actions.return_value = mock_info
|
||||
method_calls = [
|
||||
mock.call(fakes.FAKE_VALIDATIONS_PATH),
|
||||
mock.call().group_information(validation_config={})]
|
||||
|
||||
arglist = []
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, [])
|
||||
|
||||
group_info = self.cmd.take_action(parsed_args)
|
||||
|
||||
mock_actions.assert_called_once_with(
|
||||
validation_path=fakes.FAKE_VALIDATIONS_PATH)
|
||||
|
||||
mock_info.group_information.assert_called_once()
|
||||
|
||||
self.assertEqual('foo', group_info)
|
||||
self.cmd.take_action(parsed_args)
|
||||
mock_actions.assert_called_with(fakes.FAKE_VALIDATIONS_PATH)
|
||||
|
||||
|
||||
class TestShowParameter(BaseCommand):
|
||||
@@ -73,10 +70,15 @@ class TestShowParameter(BaseCommand):
|
||||
self.cmd = show.ShowParameter(self.app, None)
|
||||
|
||||
@mock.patch('six.moves.builtins.open')
|
||||
def test_show_validations_parameters_by_group(self, mock_open):
|
||||
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||
'show_validations_parameters', autospec=True)
|
||||
def test_show_validations_parameters_by_group(self, mock_show, mock_open):
|
||||
arglist = ['--group', 'prep']
|
||||
verifylist = [('group', ['prep'])]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
mock_show.assert_called_once()
|
||||
|
||||
def test_show_parameter_exclusive_group(self):
|
||||
arglist = ['--validation', 'foo', '--group', 'bar']
|
||||
@@ -86,23 +88,32 @@ class TestShowParameter(BaseCommand):
|
||||
arglist, verifylist)
|
||||
|
||||
@mock.patch('six.moves.builtins.open')
|
||||
def test_show_validations_parameters_by_validations(self, mock_open):
|
||||
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||
'show_validations_parameters', autospec=True)
|
||||
def test_show_validations_parameters_by_validations(self, mock_show, mock_open):
|
||||
arglist = ['--group', 'prep']
|
||||
verifylist = [('group', ['prep'])]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
mock_show.assert_called_once()
|
||||
|
||||
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||
'show_validations_parameters')
|
||||
'show_validations_parameters', autospec=True)
|
||||
def test_show_validations_parameters_by_categories(self, mock_show):
|
||||
arglist = ['--category', 'os']
|
||||
verifylist = [('category', ['os'])]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
mock_show.assert_called_once()
|
||||
|
||||
@mock.patch('validations_libs.validation_actions.ValidationActions.'
|
||||
'show_validations_parameters')
|
||||
'show_validations_parameters', autospec=True)
|
||||
def test_show_validations_parameters_by_products(self, mock_show):
|
||||
arglist = ['--product', 'product1']
|
||||
verifylist = [('product', ['product1'])]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
mock_show.assert_called_once()
|
||||
|
||||
@@ -57,9 +57,9 @@ VALIDATION_LIST_RESULT = (('ID', 'Name', 'Groups', 'Categories', 'Products'),
|
||||
['product1'])])
|
||||
|
||||
GROUPS_LIST = [
|
||||
('group1', 'Group1 description'),
|
||||
('group2', 'Group2 description'),
|
||||
('group3', 'Group3 description'),
|
||||
'group1',
|
||||
'group2',
|
||||
'group3'
|
||||
]
|
||||
|
||||
BAD_VALIDATIONS_LOGS_CONTENTS_LIST = [{
|
||||
|
||||
@@ -40,7 +40,7 @@ class TestGroup(TestCase):
|
||||
def test_get_formated_group(self, mock_open, mock_yaml):
|
||||
grp = Group('/tmp/foo')
|
||||
ret = [('no-op', 'noop-foo'), ('post', 'post-foo'), ('pre', 'pre-foo')]
|
||||
data = grp.get_formated_group
|
||||
data = grp.get_formated_groups
|
||||
self.assertEqual(data, ret)
|
||||
|
||||
@mock.patch('yaml.safe_load', return_value=fakes.GROUP)
|
||||
|
||||
@@ -354,22 +354,6 @@ class TestUtils(TestCase):
|
||||
result = utils.get_validation_group_name_list('/foo/groups.yaml')
|
||||
self.assertEqual(result, ['no-op', 'post', 'pre'])
|
||||
|
||||
@mock.patch('validations_libs.utils.parse_all_validations_on_disk',
|
||||
return_value=[fakes.FAKE_METADATA])
|
||||
@mock.patch('yaml.safe_load', return_value=fakes.GROUP)
|
||||
@mock.patch('six.moves.builtins.open')
|
||||
def test_get_validations_details(self, mock_open, mock_load, mock_parse):
|
||||
|
||||
result = utils.get_validations_details('foo')
|
||||
self.assertEqual(result, fakes.FAKE_METADATA)
|
||||
|
||||
@mock.patch('six.moves.builtins.open')
|
||||
def test_get_validations_details_wrong_type(self, mock_open):
|
||||
validation = ['foo']
|
||||
self.assertRaises(TypeError,
|
||||
utils.get_validations_details,
|
||||
validation=validation)
|
||||
|
||||
def test_get_validations_parameters_wrong_validations_data_type(self):
|
||||
self.assertRaises(TypeError,
|
||||
utils.get_validations_parameters,
|
||||
|
||||
@@ -20,8 +20,6 @@ except ImportError:
|
||||
import mock
|
||||
from mock import ANY
|
||||
|
||||
import json
|
||||
|
||||
from unittest import TestCase
|
||||
|
||||
from validations_libs.tests import fakes
|
||||
@@ -62,8 +60,7 @@ class TestValidationActions(TestCase):
|
||||
skip_list = {'fake': {'hosts': 'ALL',
|
||||
'reason': None,
|
||||
'lp': None
|
||||
}
|
||||
}
|
||||
}}
|
||||
|
||||
run = ValidationActions()
|
||||
run_return = run.run_validations(playbook, inventory,
|
||||
@@ -124,9 +121,8 @@ class TestValidationActions(TestCase):
|
||||
}
|
||||
}
|
||||
|
||||
run = ValidationActions()
|
||||
run = ValidationActions(log_path='/var/log/validations')
|
||||
run_return = run.run_validations(playbook, inventory,
|
||||
log_path='/var/log/validations',
|
||||
validations_dir='/tmp/foo',
|
||||
skip_list=skip_list,
|
||||
limit_hosts='!cloud1')
|
||||
@@ -185,9 +181,8 @@ class TestValidationActions(TestCase):
|
||||
}
|
||||
}
|
||||
|
||||
run = ValidationActions()
|
||||
run = ValidationActions(log_path='/var/log/validations')
|
||||
run_return = run.run_validations(playbook, inventory,
|
||||
log_path='/var/log/validations',
|
||||
validations_dir='/tmp/foo',
|
||||
skip_list=skip_list,
|
||||
limit_hosts='cloud,cloud1,!cloud2')
|
||||
@@ -256,9 +251,8 @@ class TestValidationActions(TestCase):
|
||||
|
||||
run = ValidationActions()
|
||||
self.assertRaises(RuntimeError, run.run_validations,
|
||||
validation_name='fake.yaml',
|
||||
validations_dir='/tmp/foo'
|
||||
)
|
||||
validation_name=['fake'],
|
||||
validations_dir='/tmp/foo')
|
||||
|
||||
@mock.patch('validations_libs.utils.get_validations_playbook')
|
||||
def test_validation_run_not_all_found(self, mock_validation_play):
|
||||
@@ -271,7 +265,7 @@ class TestValidationActions(TestCase):
|
||||
validations_dir='/tmp/foo')
|
||||
except RuntimeError as runtime_error:
|
||||
self.assertEqual(
|
||||
"Validation ['foo'] not found in /tmp/foo.",
|
||||
"Following validations were not found in '/tmp/foo': foo",
|
||||
str(runtime_error))
|
||||
else:
|
||||
self.fail("Runtime error exception should have been raised")
|
||||
@@ -435,7 +429,7 @@ class TestValidationActions(TestCase):
|
||||
@mock.patch('six.moves.builtins.open')
|
||||
def test_group_information(self, mock_open, mock_yaml, mock_data):
|
||||
v_actions = ValidationActions()
|
||||
col, values = v_actions.group_information('512e')
|
||||
col, values = v_actions.group_information()
|
||||
self.assertEqual(col, ('Groups', 'Description',
|
||||
'Number of Validations'))
|
||||
self.assertEqual(values, [('no-op', 'noop-foo', 1),
|
||||
|
||||
@@ -382,36 +382,6 @@ def get_validation_group_name_list(groups_path=None):
|
||||
return gp.get_groups_keys_list
|
||||
|
||||
|
||||
def get_validations_details(validation):
|
||||
"""Return information details for a validation
|
||||
|
||||
:param validation: Name of the validation
|
||||
:type validation: `string`
|
||||
:return: The information of the validation
|
||||
:rtype: `dict`
|
||||
:raises: a `TypeError` exception if `validation` is not a string
|
||||
|
||||
:Example:
|
||||
|
||||
>>> validation = "check-something"
|
||||
>>> get_validations_details(validation)
|
||||
{'description': 'Verify that the server has enough something.',
|
||||
'groups': ['group1', 'group2'],
|
||||
'categories': ['category1', 'category2'],
|
||||
'products': ['product1', 'product2'],
|
||||
'id': 'check-something',
|
||||
'name': 'Verify the server fits the something requirements'}
|
||||
"""
|
||||
if not isinstance(validation, six.string_types):
|
||||
raise TypeError("The 'validation' argument must be a String")
|
||||
|
||||
results = parse_all_validations_on_disk(constants.ANSIBLE_VALIDATION_DIR)
|
||||
for r in results:
|
||||
if r['id'] == validation:
|
||||
return r
|
||||
return {}
|
||||
|
||||
|
||||
def get_validations_data(
|
||||
validation,
|
||||
path=constants.ANSIBLE_VALIDATION_DIR,
|
||||
|
||||
@@ -42,10 +42,23 @@ class ValidationActions(object):
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, validation_path=constants.ANSIBLE_VALIDATION_DIR):
|
||||
|
||||
def __init__(self, validation_path=constants.ANSIBLE_VALIDATION_DIR,
|
||||
groups_path=constants.VALIDATION_GROUPS_INFO,
|
||||
log_path=constants.VALIDATIONS_LOG_BASEDIR):
|
||||
"""
|
||||
:param groups_path: The absolute path to the validation groups
|
||||
definition file.
|
||||
(Defaults to ``constants.VALIDATION_GROUPS_INFO``)
|
||||
:type groups_path: ``string``
|
||||
:param log_path: The absolute path of the validations logs directory
|
||||
(Defaults to ``constants.VALIDATIONS_LOG_BASEDIR``)
|
||||
:type log_path: ``string``
|
||||
"""
|
||||
self.log = logging.getLogger(__name__ + ".ValidationActions")
|
||||
self.validation_path = validation_path
|
||||
self.log_path = log_path
|
||||
|
||||
self.groups_path = groups_path
|
||||
|
||||
def list_validations(self,
|
||||
groups=None,
|
||||
@@ -84,7 +97,7 @@ class ValidationActions(object):
|
||||
| val3 | val_name3 | ['group4'] | ['category3'] | ['product3'] |
|
||||
+------+-----------+----------------------+---------------+--------------+
|
||||
|
||||
:Example:
|
||||
:example:
|
||||
|
||||
>>> path = "/foo/bar"
|
||||
>>> groups = ['group1']
|
||||
@@ -130,13 +143,16 @@ class ValidationActions(object):
|
||||
return (column_names, return_values)
|
||||
|
||||
def show_validations(self, validation,
|
||||
log_path=constants.VALIDATIONS_LOG_BASEDIR,
|
||||
log_path=None,
|
||||
validation_config=None):
|
||||
"""Display detailed information about a Validation
|
||||
|
||||
:param validation: The name of the validation
|
||||
:type validation: `string`
|
||||
:param log_path: The absolute path of the validations logs
|
||||
:param log_path: The absolute path of the validations logs.
|
||||
The 'log_path' argument is deprecated and
|
||||
will be removed in the next release.
|
||||
Use the 'log_path' argument of the init method.
|
||||
:type log_path: `string`
|
||||
:param validation_config: A dictionary of configuration for Validation
|
||||
loaded from an validation.cfg file.
|
||||
@@ -146,7 +162,7 @@ class ValidationActions(object):
|
||||
:return: The detailed information for a validation
|
||||
:rtype: `dict`
|
||||
|
||||
:Example:
|
||||
:example:
|
||||
|
||||
>>> path = "/foo/bar"
|
||||
>>> validation = 'foo'
|
||||
@@ -166,7 +182,14 @@ class ValidationActions(object):
|
||||
"""
|
||||
self.log = logging.getLogger(__name__ + ".show_validations")
|
||||
# Get validation data:
|
||||
vlog = ValidationLogs(log_path)
|
||||
if log_path:
|
||||
self.log.warning((
|
||||
"The 'log_path' argument is deprecated and"
|
||||
" will be removed in the next release. "
|
||||
"Use the 'log_path' argument of the init method."))
|
||||
vlog = ValidationLogs(log_path)
|
||||
else:
|
||||
vlog = ValidationLogs(self.log_path)
|
||||
data = v_utils.get_validations_data(
|
||||
validation,
|
||||
self.validation_path,
|
||||
@@ -185,75 +208,91 @@ class ValidationActions(object):
|
||||
data.update(data_format)
|
||||
return data
|
||||
|
||||
def _skip_hosts(self, skip_list, playbook, limit_hosts=None):
|
||||
def _skip_hosts(self, skip_list, 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 skip_list: list of hosts to skip with reasons why
|
||||
:type skip_list: `dict`
|
||||
: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'
|
||||
:example:
|
||||
|
||||
>>> v_actions = ValidationActions()
|
||||
>>> limit_hosts = 'cloud1,cloud2'
|
||||
>>> skip_list = {
|
||||
... 'xyz': {
|
||||
... 'hosts': 'cloud1',
|
||||
... 'reason': None,
|
||||
... 'lp': None}}
|
||||
>>> v_actions._skip_hosts(skip_list, validation, limit_hosts='cloud1,cloud2')
|
||||
'!cloud1,cloud2'
|
||||
"""
|
||||
hosts = skip_list[playbook].get('hosts', 'all')
|
||||
hosts = skip_list.get('hosts', 'all')
|
||||
if hosts.lower() == 'all':
|
||||
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)
|
||||
_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``
|
||||
"""Check if playbook is in the skiplist
|
||||
:param skip_list: Dictionary of validations to skip.
|
||||
:type skip_list: `dictionary`
|
||||
:param playbook: The name of the playbook
|
||||
:type base_dir: ``string``
|
||||
:type playbook: `string`
|
||||
:param limit_hosts: Limit the execution to the hosts.
|
||||
:type limit_hosts: ``string``
|
||||
: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)
|
||||
:rtype: `tuple`
|
||||
|
||||
If playbook in the skip list, but with restriction only on
|
||||
host cloud1:
|
||||
>>> _skip_playbook(skip_list, 'xyz', None)
|
||||
('xyz', '!cloud1')
|
||||
:example:
|
||||
|
||||
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)
|
||||
>>> skip_list = {
|
||||
... 'xyz': {
|
||||
... 'hosts': 'cloud1',
|
||||
... 'reason': None,
|
||||
... 'lp': None}}
|
||||
|
||||
If playbook is not in skip list:
|
||||
>>> v_actions = ValidationActions()
|
||||
>>> v_actions._skip_playbook(skip_list, 'foo', None)
|
||||
('foo', None)
|
||||
|
||||
If playbook is in the skip list, but with restriction only on
|
||||
host cloud1:
|
||||
>>> v_actions = ValidationActions()
|
||||
>>> v_actions._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}}
|
||||
>>> v_actions = ValidationActions()
|
||||
>>> v_actions._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 playbook in skip_list:
|
||||
|
||||
self.log.info((
|
||||
"Validation '{}' skipped on following hosts '{}' "
|
||||
"with reason: '{}'.").format(
|
||||
playbook,
|
||||
skip_list[playbook].get('hosts', 'All'),
|
||||
skip_list[playbook].get('reason', None)))
|
||||
|
||||
_hosts = self._skip_hosts(
|
||||
skip_list[playbook],
|
||||
limit_hosts)
|
||||
if _hosts:
|
||||
return playbook, _hosts
|
||||
else:
|
||||
@@ -266,6 +305,14 @@ class ValidationActions(object):
|
||||
with the last time the file was modified serving as a key.
|
||||
Finally we take the last `n` logs, where `n` == `history_limit`
|
||||
and return them while discarding the time information.
|
||||
|
||||
:param logs: List of validation log file paths
|
||||
:type logs: `list`
|
||||
:param history_limit: number of entries to display
|
||||
:type history_limit: `int`
|
||||
|
||||
:return: List of time-modified, path tuples of length =< history_limit
|
||||
:rtype: `list`
|
||||
"""
|
||||
|
||||
history_limit = min(history_limit, len(logs))
|
||||
@@ -280,17 +327,16 @@ class ValidationActions(object):
|
||||
group=None, category=None, product=None,
|
||||
extra_vars=None, validations_dir=None,
|
||||
extra_env_vars=None, ansible_cfg=None, quiet=True,
|
||||
workdir=None, limit_hosts=None, run_async=False,
|
||||
limit_hosts=None, run_async=False,
|
||||
base_dir=constants.DEFAULT_VALIDATIONS_BASEDIR,
|
||||
log_path=constants.VALIDATIONS_LOG_BASEDIR,
|
||||
python_interpreter=None, skip_list=None,
|
||||
log_path=None, python_interpreter=None, skip_list=None,
|
||||
callback_whitelist=None,
|
||||
output_callback='validation_stdout', ssh_user=None,
|
||||
validation_config=None):
|
||||
"""Run one or multiple validations by name(s), by group(s) or by
|
||||
product(s)
|
||||
|
||||
:param validation_name: A list of validation names
|
||||
:param validation_name: A list of validation names.
|
||||
:type validation_name: ``list``
|
||||
:param inventory: Either proper inventory file, or a comma-separated
|
||||
list. (Defaults to ``localhost``)
|
||||
@@ -315,8 +361,6 @@ class ValidationActions(object):
|
||||
:type ansible_cfg: ``string``
|
||||
:param quiet: Disable all output (Defaults to ``True``)
|
||||
:type quiet: ``Boolean``
|
||||
:param workdir: Location of the working directory
|
||||
:type workdir: ``string``
|
||||
:param limit_hosts: Limit the execution to the hosts.
|
||||
:type limit_hosts: ``string``
|
||||
:param run_async: Enable the Ansible asynchronous mode
|
||||
@@ -329,6 +373,9 @@ class ValidationActions(object):
|
||||
:param log_path: The absolute path of the validations logs directory
|
||||
(Defaults to
|
||||
``constants.VALIDATIONS_LOG_BASEDIR``)
|
||||
The absolute path of the validations logs directory.
|
||||
The 'log_path' argument is deprecated and will be removed in the next release.
|
||||
Use the 'log_path' argument of the init method.
|
||||
:type log_path: ``string``
|
||||
:param python_interpreter: Path to the Python interpreter to be
|
||||
used for module execution on remote targets,
|
||||
@@ -359,7 +406,7 @@ class ValidationActions(object):
|
||||
Status, Status_by_Host, UUID and Unreachable_Hosts)
|
||||
:rtype: ``list``
|
||||
|
||||
:Example:
|
||||
:example:
|
||||
|
||||
>>> path = "/u/s/a"
|
||||
>>> validation_name = ['foo', 'bar']
|
||||
@@ -402,27 +449,45 @@ class ValidationActions(object):
|
||||
for val in validations:
|
||||
playbooks.append("{path}/{id}.yaml".format(**val))
|
||||
elif validation_name:
|
||||
self.log.debug(
|
||||
"Getting the {} validation.".format(
|
||||
validation_name))
|
||||
|
||||
playbooks = v_utils.get_validations_playbook(
|
||||
validations_dir,
|
||||
validation_name,
|
||||
validation_config=validation_config)
|
||||
|
||||
if not playbooks or len(validation_name) != len(playbooks):
|
||||
p = []
|
||||
found_playbooks = []
|
||||
for play in playbooks:
|
||||
p.append(os.path.basename(os.path.splitext(play)[0]))
|
||||
found_playbooks.append(
|
||||
os.path.basename(os.path.splitext(play)[0]))
|
||||
|
||||
unknown_validation = list(set(validation_name) - set(p))
|
||||
unknown_validations = list(
|
||||
set(validation_name) - set(found_playbooks))
|
||||
|
||||
msg = "Validation {} not found in {}.".format(
|
||||
unknown_validation, validations_dir)
|
||||
msg = (
|
||||
"Following validations were not found in '{}': {}"
|
||||
).format(validations_dir, ', '.join(unknown_validations))
|
||||
|
||||
raise RuntimeError(msg)
|
||||
else:
|
||||
raise RuntimeError("No validations found")
|
||||
if log_path:
|
||||
self.log.warning((
|
||||
"The 'log_path' argument is deprecated and"
|
||||
" will be removed in the next release. "
|
||||
"Use the 'log_path' argument of the init method."))
|
||||
log_path = v_utils.create_log_dir(log_path)
|
||||
else:
|
||||
log_path = v_utils.create_log_dir(self.log_path)
|
||||
|
||||
self.log.debug((
|
||||
'Running the validations with Ansible.\n'
|
||||
'Gathered playbooks:\n -{}').format(
|
||||
'\n -'.join(playbooks)))
|
||||
|
||||
log_path = v_utils.create_log_dir(log_path)
|
||||
self.log.debug('Running the validations with Ansible')
|
||||
results = []
|
||||
for playbook in playbooks:
|
||||
# Check if playbook should be skipped and on which hosts
|
||||
@@ -485,17 +550,6 @@ class ValidationActions(object):
|
||||
'validations': _playbook.split('.')[0],
|
||||
'UUID': validation_uuid,
|
||||
})
|
||||
# Print hosts which has been skipped:
|
||||
if _hosts:
|
||||
skipped_hosts = [h.replace('!', '')
|
||||
for h in _hosts.split(',') if '!' in h]
|
||||
if skipped_hosts:
|
||||
msg = ("Validation {} has been skipped "
|
||||
"on hosts: {}").format(_play,
|
||||
','.join(skipped_hosts))
|
||||
self.log.info(msg)
|
||||
else:
|
||||
self.log.info('Skipping Validations: {}'.format(playbook))
|
||||
|
||||
if run_async:
|
||||
return results
|
||||
@@ -504,7 +558,7 @@ class ValidationActions(object):
|
||||
vlog = ValidationLogs(log_path)
|
||||
return vlog.get_results(uuid)
|
||||
|
||||
def group_information(self, groups, validation_config=None):
|
||||
def group_information(self, groups=None, validation_config=None):
|
||||
"""Get Information about Validation Groups
|
||||
|
||||
This is used to print table from python ``Tuple`` with ``PrettyTable``.
|
||||
@@ -519,7 +573,10 @@ class ValidationActions(object):
|
||||
| group3 | Description of group3 | 1 |
|
||||
+----------+--------------------------+-----------------------+
|
||||
|
||||
:param groups: The absolute path of the groups.yaml file
|
||||
:param groups: The absolute path of the groups.yaml file.
|
||||
The argument is deprecated and will be removed
|
||||
in the next release.
|
||||
Use the 'groups_path' argument of the init method.
|
||||
:type groups: ``string``
|
||||
:param validation_config: A dictionary of configuration for Validation
|
||||
loaded from an validation.cfg file.
|
||||
@@ -529,19 +586,27 @@ class ValidationActions(object):
|
||||
the numbers of validation belonging to them.
|
||||
:rtype: ``tuple``
|
||||
|
||||
:Example:
|
||||
:example:
|
||||
|
||||
>>> groups = "/foo/bar/groups.yaml"
|
||||
>>> actions = ValidationActions(constants.ANSIBLE_VALIDATION_DIR)
|
||||
>>> group_info = actions.group_information(groups)
|
||||
>>> actions = ValidationActions(constants.ANSIBLE_VALIDATION_DIR, groups)
|
||||
>>> group_info = actions.group_information()
|
||||
>>> print(group_info)
|
||||
(('Groups', 'Desciption', 'Number of Validations'),
|
||||
[('group1', 'Description of group1', 3),
|
||||
('group2', 'Description of group2', 12),
|
||||
('group3', 'Description of group3', 1)])
|
||||
"""
|
||||
val_gp = Group(groups)
|
||||
group_definitions = val_gp.get_formated_group
|
||||
if groups:
|
||||
self.log.warning((
|
||||
"The 'groups' argument is deprecated and"
|
||||
" will be removed in the next release. "
|
||||
"Use the 'groups_path' argument of the init method."))
|
||||
val_group = Group(groups)
|
||||
else:
|
||||
val_group = Group(self.groups_path)
|
||||
|
||||
group_definitions = val_group.get_formated_groups
|
||||
|
||||
group_info = []
|
||||
|
||||
@@ -599,7 +664,7 @@ class ValidationActions(object):
|
||||
:return: A JSON or a YAML dump (By default, JSON).
|
||||
if `download_file` is used, a file containing only the
|
||||
parameters will be created in the file system.
|
||||
:exemple:
|
||||
:example:
|
||||
|
||||
>>> validations = ['check-cpu', 'check-ram']
|
||||
>>> groups = None
|
||||
@@ -620,26 +685,8 @@ class ValidationActions(object):
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"""
|
||||
if not validations:
|
||||
validations = []
|
||||
elif not isinstance(validations, list):
|
||||
raise TypeError("The 'validations' argument must be a List")
|
||||
|
||||
if not groups:
|
||||
groups = []
|
||||
elif not isinstance(groups, list):
|
||||
raise TypeError("The 'groups' argument must be a List")
|
||||
|
||||
if not categories:
|
||||
categories = []
|
||||
elif not isinstance(categories, list):
|
||||
raise TypeError("The 'categories' argument must be a List")
|
||||
|
||||
if not products:
|
||||
products = []
|
||||
elif not isinstance(products, list):
|
||||
raise TypeError("The 'products' argument must be a List")
|
||||
|
||||
supported_format = ['json', 'yaml']
|
||||
|
||||
@@ -667,7 +714,7 @@ class ValidationActions(object):
|
||||
params_only = {}
|
||||
try:
|
||||
with open(download_file, 'w') as parameters_file:
|
||||
for val_name in params.keys():
|
||||
for val_name in params:
|
||||
params_only.update(params[val_name].get('parameters'))
|
||||
|
||||
if output_format == 'json':
|
||||
@@ -698,7 +745,7 @@ class ValidationActions(object):
|
||||
return params
|
||||
|
||||
def show_history(self, validation_ids=None, extension='json',
|
||||
log_path=constants.VALIDATIONS_LOG_BASEDIR,
|
||||
log_path=None,
|
||||
history_limit=None):
|
||||
"""Return validation executions history
|
||||
|
||||
@@ -706,7 +753,10 @@ class ValidationActions(object):
|
||||
:type validation_ids: a list of strings
|
||||
:param extension: The log file extension (Defaults to ``json``)
|
||||
:type extension: ``string``
|
||||
:param log_path: The absolute path of the validations logs directory
|
||||
:param log_path: The absolute path of the validations logs directory.
|
||||
The 'log_path' argument is deprecated and will
|
||||
be removed in the next release.
|
||||
Use the 'log_path' argument of the init method.
|
||||
:type log_path: ``string``
|
||||
:param history_limit: The number of most recent history logs
|
||||
to be displayed.
|
||||
@@ -716,7 +766,7 @@ class ValidationActions(object):
|
||||
history
|
||||
:rtype: ``tuple``
|
||||
|
||||
:Example:
|
||||
:example:
|
||||
|
||||
>>> actions = ValidationActions(constants.ANSIBLE_VALIDATION_DIR)
|
||||
>>> print(actions.show_history())
|
||||
@@ -754,8 +804,17 @@ class ValidationActions(object):
|
||||
'PASSED',
|
||||
'2020-11-13T11:47:50.279662Z',
|
||||
'0:00:02.237')])
|
||||
|
||||
"""
|
||||
vlogs = ValidationLogs(log_path)
|
||||
if log_path:
|
||||
self.log.warning((
|
||||
"The 'log_path' argument is deprecated and"
|
||||
" will be removed in the next release. "
|
||||
"Use the 'log_path' argument of the init method."))
|
||||
vlogs = ValidationLogs(log_path)
|
||||
else:
|
||||
vlogs = ValidationLogs(self.log_path)
|
||||
|
||||
if validation_ids:
|
||||
if not isinstance(validation_ids, list):
|
||||
validation_ids = [validation_ids]
|
||||
@@ -794,13 +853,16 @@ class ValidationActions(object):
|
||||
:type uuid: ``string``
|
||||
:param status: The status of the execution (Defaults to FAILED)
|
||||
:type status: ``string``
|
||||
:param log_path: The absolute path of the validations logs directory
|
||||
:param log_path: The absolute path of the validations logs directory.
|
||||
The 'log_path' argument is deprecated and will
|
||||
be removed in the next release.
|
||||
Use the 'log_path' argument of the init method.
|
||||
:type log_path: ``string``
|
||||
|
||||
:return: A list of validations execution with details and by status
|
||||
:rtype: ``tuple``
|
||||
|
||||
:Example:
|
||||
:example:
|
||||
|
||||
>>> actions = ValidationActions(validation_path='/foo/bar')
|
||||
>>> status = actions.get_status(validation_id='foo'))
|
||||
@@ -831,7 +893,15 @@ class ValidationActions(object):
|
||||
'failed': True,
|
||||
'msg': 'Debug mode is not disabled.'})])
|
||||
"""
|
||||
vlogs = ValidationLogs(log_path)
|
||||
if log_path:
|
||||
self.log.warning((
|
||||
"The 'log_path' argument is deprecated and"
|
||||
" will be removed in the next release. "
|
||||
"Use the 'log_path' argument of the init method."))
|
||||
vlogs = ValidationLogs(log_path)
|
||||
else:
|
||||
vlogs = ValidationLogs(self.log_path)
|
||||
|
||||
if validation_id:
|
||||
logs = vlogs.get_logfile_by_validation(validation_id)
|
||||
elif uuid:
|
||||
|
||||
Reference in New Issue
Block a user