コード例 #1
0
 def test_get_logfile_content_by_uuid(self, mock_open, mock_json,
                                      mock_glob):
     mock_glob.return_value = \
         ['/tmp/123_foo_2020-03-30T13:17:22.447857Z.json']
     vlogs = ValidationLogs('/tmp/foo')
     content = vlogs.get_logfile_content_by_uuid('123')
     self.assertEqual(content, fakes.VALIDATIONS_LOGS_CONTENTS_LIST)
コード例 #2
0
    def take_action(self, parsed_args):

        self.app.LOG.debug(
            ("Obtaining information about the validation run {}\n"
             "From directory {}").format(parsed_args.uuid,
                                         parsed_args.validation_log_dir))

        vlogs = ValidationLogs(logs_path=parsed_args.validation_log_dir)

        try:
            log_files = vlogs.get_logfile_content_by_uuid(parsed_args.uuid)
        except IOError as io_error:
            raise RuntimeError((
                "Encountered a following IO error while attempting read a log "
                "file linked to UUID: {} .\n"
                "{}").format(parsed_args.uuid, io_error))

        if log_files:
            if parsed_args.full:
                for log_file in log_files:
                    print(json.dumps(log_file, indent=4, sort_keys=True))
            else:
                for log_file in log_files:
                    for validation_result in log_file.get(
                            'validation_output', []):
                        print(
                            json.dumps(validation_result['task'],
                                       indent=4,
                                       sort_keys=True))
        else:
            raise RuntimeError(
                "Could not find the log file linked to this UUID: {}".format(
                    parsed_args.uuid))
コード例 #3
0
 def test_get_logfile_by_uuid(self, mock_open, mock_json, mock_glob):
     mock_glob.return_value = \
         ['/tmp/123_foo_2020-03-30T13:17:22.447857Z.json']
     vlogs = ValidationLogs('/tmp/foo')
     log = vlogs.get_logfile_by_uuid('123')
     self.assertEqual(log,
                      ['/tmp/123_foo_2020-03-30T13:17:22.447857Z.json'])
コード例 #4
0
 def test_get_all_logfiles_content(self, mock_open, mock_json, mock_listdir,
                                   mock_isfile):
     mock_listdir.return_value = \
         ['/tmp/123_foo_2020-03-30T13:17:22.447857Z.json']
     mock_isfile.return_value = True
     vlogs = ValidationLogs('/tmp/foo')
     content = vlogs.get_all_logfiles_content()
     self.assertEqual(content, fakes.VALIDATIONS_LOGS_CONTENTS_LIST)
コード例 #5
0
 def test_get_all_logfiles(self, mock_open, mock_json, mock_listdir,
                           mock_isfile):
     mock_listdir.return_value = \
         ['/tmp/123_foo_2020-03-30T13:17:22.447857Z.json']
     mock_isfile.return_value = True
     vlogs = ValidationLogs('/tmp/foo')
     log = vlogs.get_all_logfiles()
     self.assertEqual(log,
                      ['/tmp/123_foo_2020-03-30T13:17:22.447857Z.json'])
コード例 #6
0
ファイル: test_validation_logs.py プロジェクト: matbu/ova
 def test_get_results(self, mock_open, mock_json, mock_get_validation):
     mock_get_validation.return_value = \
         ['/tmp/123_foo_2020-03-30T13:17:22.447857Z.json']
     vlogs = ValidationLogs('/tmp/foo')
     content = vlogs.get_results(uuid='123', validation_id='foo')
     self.assertEquals(content, [{'UUID': '123',
                                  'Validations': 'foo',
                                  'Status': 'PASSED',
                                  'Status_by_Host': 'undercloud,PASSED',
                                  'Host_Group': 'undercloud',
                                  'Unreachable_Hosts': '',
                                  'Duration': '0:00:03.753',
                                  'Validations': 'foo'}])
コード例 #7
0
ファイル: test_validation_logs.py プロジェクト: matbu/ova
 def test_log_not_found(self, mock_open):
     mock_open.side_effect = IOError()
     vlogs = ValidationLogs()
     self.assertRaises(
         IOError,
         vlogs._get_content,
         '/var/log/non-existing.json'
     )
コード例 #8
0
    def show_validations(self, validation,
                         log_path=constants.VALIDATIONS_LOG_BASEDIR):
        """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
        :type log_path: `string`

        :return: The detailed information for a validation
        :rtype: `dict`

        :Example:

        >>> path = "/foo/bar"
        >>> validation = 'foo'
        >>> action = ValidationActions(validation_path=path)
        >>> results = action.show_validations(validation=validation)
        >>> print(results)
        {
         'Description': 'Description of the foo validation',
         'Groups': ['group1', 'group2'],
         'ID': 'foo',
         'Last execution date': None,
         'Name': 'Name of the validation foo',
         'Number of execution': 'Total: 0, Passed: 0, Failed: 0',
         'Parameters': {'foo1': bar1}
        }
        """
        self.log = logging.getLogger(__name__ + ".show_validations")
        # Get validation data:
        vlog = ValidationLogs(log_path)
        data = v_utils.get_validations_data(validation, self.validation_path)
        if not data:
            msg = "Validation {} not found in the path: {}".format(
                validation,
                self.validation_path)
            raise RuntimeError(msg)
        logfiles = vlog.get_logfile_content_by_validation(validation)
        data_format = vlog.get_validations_stats(logfiles)
        data.update(data_format)
        return data
コード例 #9
0
 def test_validation_log_file(self, mock_open, mock_json):
     vlogs = ValidationLogs('/tmp/foo')
     content = vlogs._get_content('/tmp/foo/bar.json')
     self.assertEqual(content, fakes.VALIDATIONS_LOGS_CONTENTS_LIST)
コード例 #10
0
 def test_get_results_none(self):
     vlogs = ValidationLogs('/tmp/foo')
     self.assertRaises(RuntimeError, vlogs.get_results, uuid=None)
コード例 #11
0
 def test_get_validations_stats(self, mock_open, mock_json):
     vlogs = ValidationLogs('/tmp/foo')
     content = vlogs.get_validations_stats(
         fakes.VALIDATIONS_LOGS_CONTENTS_LIST)
     self.assertEqual(content, fakes.VALIDATIONS_STATS)
コード例 #12
0
    def get_status(self, validation_id=None, uuid=None, status='FAILED',
                   log_path=constants.VALIDATIONS_LOG_BASEDIR):
        """Return validations execution details by status

        :param validation_id: The validation id
        :type validation_id: ``string``
        :param uuid: The UUID of the execution
        :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
        :type log_path: ``string``

        :return: A list of validations execution with details and by status
        :rtype: ``tuple``

        :Example:

        >>> actions = ValidationActions(validation_path='/foo/bar')
        >>> status = actions.get_status(validation_id='foo'))
        >>> print(status)
        (['name', 'host', 'status', 'task_data'],
         [('Check if debug mode is disabled.',
         'localhost',
         'FAILED',
         {'_ansible_no_log': False,
             'action': 'fail',
             'changed': False,
             'failed': True,
             'msg': 'Debug mode is not disabled.'}),
         ('Check if debug mode is disabled.',
         'localhost',
         'FAILED',
         {'_ansible_no_log': False,
             'action': 'fail',
             'changed': False,
             'failed': True,
             'msg': 'Debug mode is not disabled.'}),
         ('Check if debug mode is disabled.',
         'localhost',
         'FAILED',
         {'_ansible_no_log': False,
             'action': 'fail',
             'changed': False,
             'failed': True,
             'msg': 'Debug mode is not disabled.'})])
        """
        vlogs = ValidationLogs(log_path)
        if validation_id:
            logs = vlogs.get_logfile_by_validation(validation_id)
        elif uuid:
            logs = vlogs.get_logfile_by_uuid(uuid)
        else:
            raise RuntimeError("You need to provide a validation_id or a uuid")

        values = []
        column_name = ['name', 'host', 'status', 'task_data']
        for log in logs:
            vlog = ValidationLog(logfile=log)
            if vlog.is_valid_format():
                for task in vlog.get_tasks_data:
                    if task['status'] == status:
                        for host in task['hosts']:
                            values.append((task['name'], host, task['status'],
                                           task['hosts'][host]))
        return (column_name, values)
コード例 #13
0
    def show_history(self, validation_ids=None, extension='json',
                     log_path=constants.VALIDATIONS_LOG_BASEDIR):
        """Return validation executions history

        :param validation_ids: The validation ids
        :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
        :type log_path: ``string``

        :return: Returns the information about the validation executions
                 history
        :rtype: ``tuple``

        :Example:

        >>> actions = ValidationActions(constants.ANSIBLE_VALIDATION_DIR)
        >>> print(actions.show_history())
        (('UUID', 'Validations', 'Status', 'Execution at', 'Duration'),
         [('5afb1597-e2a1-4635-b2df-7afe21d00de6',
         'foo',
         'PASSED',
         '2020-11-13T11:47:04.740442Z',
         '0:00:02.388'),
         ('32a5e217-d7a9-49a5-9838-19e5f9b82a77',
         'foo2',
         'PASSED',
         '2020-11-13T11:47:07.931184Z',
         '0:00:02.455'),
         ('62d4d54c-7cce-4f38-9091-292cf49268d7',
         'foo',
         'PASSED',
         '2020-11-13T11:47:47.188876Z',
         '0:00:02.285'),
         ('04e6165c-7c33-4881-bac7-73ff3f909c24',
         'foo3',
         'PASSED',
         '2020-11-13T11:47:50.279662Z',
         '0:00:02.237')])
        >>> actions = ValidationActions(constants.ANSIBLE_VALIDATION_DIR)
        >>> print(actions.show_history(validation_ids=['foo']))
        (('UUID', 'Validations', 'Status', 'Execution at', 'Duration'),
         [('5afb1597-e2a1-4635-b2df-7afe21d00de6',
         'foo',
         'PASSED',
         '2020-11-13T11:47:04.740442Z',
         '0:00:02.388'),
         ('04e6165c-7c33-4881-bac7-73ff3f909c24',
         'foo',
         'PASSED',
         '2020-11-13T11:47:50.279662Z',
         '0:00:02.237')])
        """
        vlogs = ValidationLogs(log_path)
        if validation_ids:
            if not isinstance(validation_ids, list):
                validation_ids = [validation_ids]
            logs = []
            for validation_id in validation_ids:
                logs.extend(vlogs.get_logfile_by_validation(validation_id))
        else:
            logs = vlogs.get_all_logfiles(extension)

        values = []
        column_name = ('UUID', 'Validations',
                       'Status', 'Execution at',
                       'Duration')
        for log in logs:
            vlog = ValidationLog(logfile=log)
            if vlog.is_valid_format():
                for play in vlog.get_plays:
                    values.append((play['id'], play['validation_id'],
                                   vlog.get_status,
                                   play['duration'].get('start'),
                                   play['duration'].get('time_elapsed')))
        return (column_name, values)
コード例 #14
0
    def run_validations(self, validation_name=None, inventory='localhost',
                        group=None, extra_vars=None, validations_dir=None,
                        extra_env_vars=None, ansible_cfg=None, quiet=True,
                        workdir=None, limit_hosts=None, run_async=False,
                        base_dir=constants.DEFAULT_VALIDATIONS_BASEDIR,
                        log_path=None, python_interpreter=None,
                        output_callback='validation_stdout',
                        skip_list=None):
        """Run one or multiple validations by name(s) or by group(s)

        :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``)
        :type inventory: ``string``
        :param group: A list of group names
        :type group: ``list``
        :param extra_vars: Set additional variables as a Dict or the absolute
                           path of a JSON or YAML file type.
        :type extra_vars: Either a Dict or the absolute path of JSON or YAML
        :param validations_dir: The absolute path of the validations playbooks
        :type validations_dir: ``string``
        :param extra_env_vars: Set additional ansible variables using an
                                extravar dictionary.
        :type extra_env_vars: ``dict``
        :param ansible_cfg: Path to an ansible configuration file. One will be
                            generated in the artifact path if this option is
                            None.
        :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
                          (Defaults to ``False``)
        :type run_async: ``boolean``
        :param base_dir: The absolute path of the validations base directory
                         (Defaults to
                         ``constants.DEFAULT_VALIDATIONS_BASEDIR``)
        :type base_dir: ``string``
        :param log_path: The absolute path of the validations logs directory
        :type log_path: ``string``
        :param python_interpreter: Path to the Python interpreter to be
                                   used for module execution on remote targets,
                                   or an automatic discovery mode (``auto``,
                                   ``auto_silent`` or the default one
                                   ``auto_legacy``)
        :type python_interpreter: ``string``
        :param output_callback: The Callback plugin to use.
                                (Defaults to 'validation_stdout')
        :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
                 validations executions (Validations, Duration, Host_Group,
                 Status, Status_by_Host, UUID and Unreachable_Hosts)
        :rtype: ``list``

        :Example:

        >>> path = "/u/s/a"
        >>> validation_name = ['foo', 'bar']
        >>> actions = ValidationActions(validation_path=path)
        >>> results = actions.run_validations(inventory='localhost',
                                              validation_name=validation_name,
                                              quiet=True)
        >>> print(results)
        [{'Duration': '0:00:02.285',
          'Host_Group': 'all',
          'Status': 'PASSED',
          'Status_by_Host': 'localhost,PASSED',
          'UUID': '62d4d54c-7cce-4f38-9091-292cf49268d7',
          'Unreachable_Hosts': '',
          'Validations': 'foo'},
         {'Duration': '0:00:02.237',
          'Host_Group': 'all',
          'Status': 'PASSED',
          'Status_by_Host': 'localhost,PASSED',
          'UUID': '04e6165c-7c33-4881-bac7-73ff3f909c24',
          'Unreachable_Hosts': '',
          'Validations': 'bar'}]
        """
        self.log = logging.getLogger(__name__ + ".run_validations")
        playbooks = []
        validations_dir = (validations_dir if validations_dir
                           else self.validation_path)
        if group:
            self.log.debug('Getting the validations list by group')
            try:
                validations = v_utils.parse_all_validations_on_disk(
                    validations_dir, group)
                for val in validations:
                    playbooks.append(val.get('id') + '.yaml')
            except Exception as e:
                raise(e)
        elif validation_name:
            validation_name = v_utils.convert_data(validation_name)

            playbooks = v_utils.get_validations_playbook(validations_dir,
                                                         validation_name,
                                                         group)

            if not playbooks or len(validation_name) != len(playbooks):
                p = []
                for play in playbooks:
                    p.append(os.path.basename(os.path.splitext(play)[0]))

                unknown_validation = list(set(validation_name) - set(p))

                msg = "Validation {} not found in {}.".format(
                    unknown_validation, validations_dir)

                raise RuntimeError(msg)
        else:
            raise RuntimeError("No validations found")

        self.log.debug('Running the validations with Ansible')
        results = []
        for playbook in playbooks:
            # Check if playbook should be skipped and on which hosts
            play_name = os.path.basename(os.path.splitext(playbook)[0])
            _play, _hosts = self._skip_playbook(skip_list,
                                                play_name,
                                                limit_hosts)
            if _play:
                validation_uuid, artifacts_dir = v_utils.create_artifacts_dir(
                    dir_path=log_path, prefix=os.path.basename(playbook))
                run_ansible = v_ansible(validation_uuid)
                _playbook, _rc, _status = run_ansible.run(
                    workdir=artifacts_dir,
                    playbook=playbook,
                    base_dir=base_dir,
                    playbook_dir=validations_dir,
                    parallel_run=True,
                    inventory=inventory,
                    output_callback=output_callback,
                    quiet=quiet,
                    extra_vars=extra_vars,
                    limit_hosts=_hosts,
                    extra_env_variables=extra_env_vars,
                    ansible_cfg=ansible_cfg,
                    gathering_policy='explicit',
                    ansible_artifact_path=artifacts_dir,
                    log_path=log_path,
                    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:
            return results
        # Return log results
        uuid = [id['UUID'] for id in results]
        vlog = ValidationLogs()
        return vlog.get_results(uuid)