Пример #1
0
 def show_progress(self, stdout_data):
     """Function shows a progress of assessment"""
     try:
         self.width_size = int(ScanProgress.get_terminal_width()[1])
     except IndexError:
         self.width_size = 80
     logger_report.debug(stdout_data.strip())
     xccdf_rule = ""
     dummy_result = ""
     try:
         xccdf_rule, dummy_result = stdout_data.strip().split(':')
     except ValueError:
         print (stdout_data)
         return
     self.output_data.append(u'{0}:{1}'.format(self.names[xccdf_rule], stdout_data.strip()))
     self.current_count += 1
     old_width = self.width_size
     self.width_size -= 21
     prev_msg = self._return_correct_msg(self.get_full_name(self.current_count - 1))
     self.width_size = old_width
     cur_msg = self._return_correct_msg(self.get_full_name(self.current_count))
     cnt_back = 7 + len(prev_msg) + 3
     msg = u'%sdone    (%s)' % ('\b' * cnt_back, prev_msg)
     log_message(msg, new_line=True)
     if self.total_count > self.current_count:
         msg = self._return_correct_msg(u'%.3d/%.3d ...running (%s)' % (self.current_count + 1,
                                                                        self.total_count,
                                                                        cur_msg))
         log_message(msg, new_line=False)
Пример #2
0
    def get_and_print_inplace_risk(verbose, inplace_risk):
        """
        The function browse throw the list and find first
        inplace_risk and return corresponding status.
        If verbose mode is used then it prints out
        all inplace risks higher then SLIGHT.
        """
        risks = {
            'SLIGHT:': 0,
            'MEDIUM:': 0,
            'HIGH:': 1,
            'EXTREME:': 2,
        }

        return_value = -1
        for key, val in sorted(iter(risks.items()), key=itemgetter(1),
                               reverse=False):
            matched = [x for x in inplace_risk if key in x]
            logger_report.debug(matched)
            if matched:
                # if matched and return_value the remember her
                if return_value < val:
                    return_value = val
                # If verbose mode is used and value is bigger then 0 then
                # prints out
                if int(verbose) > 1:
                    log_message('\n'.join(matched))
                elif int(verbose) == 1 and val > 0:
                    log_message('\n'.join(matched))

        return return_value
Пример #3
0
 def update_check_description(self):
     logger_report.debug("Update check description")
     for rule in self._get_all_rules():
         for description in self.filter_children(rule, 'description'):
             lines = description.text.split('\n')
             details = 'Details:'
             expected_results = 'Expected results:'
             attr = ' xml:lang="en"'
             tag_exp_results = expected_results[:-1].lower().replace(
                 ' ', '-')
             tag_details = details[:-1].lower()
             found = 0
             for index, line in enumerate(lines):
                 if line.strip().startswith(details):
                     found = 1
                     lines[index] = line.replace(
                         details, '<ns0:' + tag_details + attr + '>')
                     continue
                 if line.strip().startswith(expected_results):
                     found = 1
                     lines[index] = line.replace(
                         expected_results, '</ns0:' + tag_details +
                         '>\n<ns0:' + tag_exp_results + attr + '>')
                     continue
             if found == 1:
                 lines.append('</ns0:' + tag_exp_results + '>')
                 description.text = '\n'.join(lines)
     self.write_xml()
Пример #4
0
 def show_progress(self, stdout_data):
     """Function shows a progress of assessment"""
     try:
         self.width_size = int(ScanProgress.get_terminal_width()[1])
     except IndexError:
         self.width_size = 80
     logger_report.debug(stdout_data.strip())
     xccdf_rule = ""
     dummy_result = ""
     try:
         xccdf_rule, dummy_result = stdout_data.strip().split(':')
     except ValueError:
         print(stdout_data)
         return
     self.output_data.append(u'{0}:{1}'.format(self.names[xccdf_rule],
                                               stdout_data.strip()))
     self.current_count += 1
     old_width = self.width_size
     self.width_size -= 21
     prev_msg = self._return_correct_msg(
         self.get_full_name(self.current_count - 1))
     self.width_size = old_width
     cur_msg = self._return_correct_msg(
         self.get_full_name(self.current_count))
     cnt_back = 7 + len(prev_msg) + 3
     msg = u'%sdone    (%s)' % ('\b' * cnt_back, prev_msg)
     log_message(msg, new_line=True)
     if self.total_count > self.current_count:
         msg = self._return_correct_msg(
             u'%.3d/%.3d ...running (%s)' %
             (self.current_count + 1, self.total_count, cur_msg))
         log_message(msg, new_line=False)
 def update_check_description(self):
     logger_report.debug("Update check description")
     for rule in self._get_all_rules():
         for description in self.filter_children(rule, 'description'):
             lines = description.text.split('\n')
             details = 'Details:'
             expected_results = 'Expected results:'
             attr = ' xml:lang="en"'
             tag_exp_results = expected_results[:-1].lower().replace(' ', '-')
             tag_details = details[:-1].lower()
             found = 0
             for index, line in enumerate(lines):
                 if line.strip().startswith(details):
                     found = 1
                     lines[index] = line.replace(details, '<ns0:' + tag_details + attr + '>')
                     continue
                 if line.strip().startswith(expected_results):
                     found = 1
                     lines[index] = line.replace(expected_results,
                                                 '</ns0:' + tag_details + '>\n<ns0:' + tag_exp_results + attr + '>')
                     continue
             if found == 1:
                 lines.append('</ns0:' + tag_exp_results + '>')
                 description.text = '\n'.join(lines)
     self.write_xml()
    def add_global_tags(self, result_dir, scenario, mode, devel_mode, dist_native):

        for child in self.get_nodes(self.target_tree, self.profile):
            last_child = child
            for key, val in iter(xml_tags.GLOBAL_DIC_VALUES.items()):
                if key == "tmp_preupgrade":
                    val = result_dir
                elif key == "migrate" or key == "upgrade":
                    if not mode or 'migrate' in mode or 'upgrade' in mode:
                        val = "1"
                    else:
                        val = "0"
                elif key == "report_dir":
                    val = os.path.join(result_dir, scenario)
                elif key == "devel_mode":
                    val = str(devel_mode)
                elif key == "dist_native":
                    if dist_native is None:
                        val = "sign"
                    else:
                        val = dist_native
                logger_report.debug("'%s:%s'", key, val)
                new_child = ElementTree.Element(self.element_prefix + 'Value',
                                                {'id': xml_tags.TAG_VALUE + key,
                                                 'type': 'string'
                                                 })
                sub_child = ElementTree.SubElement(new_child, self.element_prefix + 'value')
                sub_child.text = val
                self.target_tree.insert(self.target_tree._children.index(last_child) + 1,
                                        new_child)
        self.write_xml()
    def modify_platform_tag(self, platform_tag):
        """The function updates platform tag to the assessment system tag"""
        for platform in self.filter_children(self.target_tree, "platform"):
            if "cpe:/o:redhat:enterprise_linux:" in platform.get("idref"):
                logger_report.debug("Update platform tag to '%s'", platform_tag)
                platform.set("idref", "cpe:/o:redhat:enterprise_linux:"+platform_tag)

        self.write_xml()
    def modify_result_path(self, result_dir, scenario, mode):
        """Function modifies result path in XML file"""
        for values in self.get_nodes(self.target_tree, "Value", prefix='.//'):
            if '_current_dir' not in values.get('id'):
                continue
            for value in self.get_nodes(values, "value"):
                logger_report.debug("Replace '%s' with '%s'", value.text, os.path.join(result_dir, scenario))
                value.text = value.text.replace("SCENARIO", os.path.join(result_dir, scenario))

        self.write_xml()
Пример #9
0
    def modify_platform_tag(self, platform_tag):
        """The function updates platform tag to the assessment system tag"""
        for platform in self.filter_children(self.target_tree, "platform"):
            if "cpe:/o:redhat:enterprise_linux:" in platform.get("idref"):
                logger_report.debug("Update platform tag to '%s'",
                                    platform_tag)
                platform.set("idref",
                             "cpe:/o:redhat:enterprise_linux:" + platform_tag)

        self.write_xml()
Пример #10
0
 def update_data(self, changed_fields):
     """Function updates a data"""
     for index, row in enumerate(self.output_data):
         try:
             title, rule_id, dummy_result = row.split(':')
             logger_report.debug(row)
         except ValueError:
             continue
         else:
             result_list = [x for x in changed_fields if rule_id in x]
             if result_list:
                 self.output_data[index] = u"%s:%s:%s" % (title, rule_id, result_list[0].split(':')[1])
Пример #11
0
 def update_data(self, changed_fields):
     """Function updates a data"""
     for index, row in enumerate(self.output_data):
         try:
             title, rule_id, dummy_result = row.split(':')
             logger_report.debug(row)
         except ValueError:
             continue
         else:
             result_list = [x for x in changed_fields if rule_id in x]
             if result_list:
                 self.output_data[index] = u"%s:%s:%s" % (
                     title, rule_id, result_list[0].split(':')[1])
Пример #12
0
    def select_rules(self, list_rules):
        """
        Function marks choice a specific rules based on the content generation

        :return:
        """
        for select in self.get_select_rules():
            idref = select.get('idref', None)
            logger_report.debug(select)
            logger_report.debug(idref)
            if idref in list_rules:
                select.set('selected', 'true')
            else:
                select.set('selected', 'false')
        self.write_xml()
Пример #13
0
 def find_solution_files(self, result_name, xml_solution_files):
     """
     Function finds all text files in conten
     and updates XML and HTML results
     """
     solution_files = {}
     self.xml_solution_files = xml_solution_files
     for dir_name, sub_dir, file_name in os.walk(self.dirname):
         files = [x for x in file_name if x.endswith(".txt")]
         if files:
             logger_report.debug(files)
             solution_files[dir_name] = files
     self.update_html(result_name, solution_files)
     self.update_html(result_name, solution_files, extension="xml")
     clean_html(os.path.join(self.dirname, result_name + ".html"))
    def select_rules(self, list_rules):
        """
        Function marks choice a specific rules based on the content generation

        :return:
        """
        for select in self.get_select_rules():
            idref = select.get('idref', None)
            logger_report.debug(select)
            logger_report.debug(idref)
            if idref in list_rules:
                select.set('selected', 'true')
            else:
                select.set('selected', 'false')
        self.write_xml()
 def find_solution_files(self, result_name, xml_solution_files):
     """
     Function finds all text files in conten
     and updates XML and HTML results
     """
     solution_files = {}
     self.xml_solution_files = xml_solution_files
     for dir_name, sub_dir, file_name in os.walk(self.dirname):
         files = [x for x in file_name if x.endswith(".txt")]
         if files:
             logger_report.debug(files)
             solution_files[dir_name] = files
     self.update_html(result_name, solution_files)
     self.update_html(result_name, solution_files, extension="xml")
     clean_html(os.path.join(self.dirname, result_name + ".html"))
 def update_inplace_risk(self, scanning_progress, rule, res):
     """Function updates inplace risk"""
     inplace_risk = XccdfHelper.get_check_import_inplace_risk(rule)
     if inplace_risk:
         logger_report.debug("Update_inplace_risk '%s'", inplace_risk)
         return_value = XccdfHelper.get_and_print_inplace_risk(0, inplace_risk)
         logger_report.debug("Get and print inplace risk return code '%s'", return_value)
         if int(return_value)/2 == 1:
             res.text = ReportHelper.get_needs_inspection()
         elif int(return_value)/2 == 2:
             res.text = ReportHelper.get_needs_action()
         for index, row in enumerate(scanning_progress.output_data):
             if self.get_nodes_text(rule, "title") in row:
                 scanning_progress.output_data[index] = "{0}:{1}".format(
                     self.get_nodes_text(rule, "title"),
                     res.text)
Пример #17
0
 def get_check_import_inplace_risk(tree):
     """
     Function returns implace risks
     """
     inplace_risk = []
     risk_regex = "preupg\.risk\.(?P<level>\w+): (?P<message>.+)"
     for check in tree.findall(".//" + XMLNS + "check-import"):
         if not check.text:
             continue
         lines = check.text.strip().split('\n')
         for line in lines:
             match = re.match(risk_regex, line)
             if match:
                 logger_report.debug(line)
                 if line not in inplace_risk:
                     inplace_risk.append(line)
     return inplace_risk
Пример #18
0
    def update_html(self, result_name, solution_files, extension="html"):
        """
         Function updates a XML or HTML file with relevant solution
         texts
        """
        orig_file = os.path.join(self.dirname, result_name + "." + extension)
        lines = FileHelper.get_file_content(orig_file, "rb", method=True)
        for dir_name, files in six.iteritems(solution_files):
            section = dir_name.replace(
                os.path.join(self.dirname, self.scenario),
                "").replace("/", "_")
            solution_text = section + "_SOLUTION_MSG"

            file_name = self._return_correct_text_file(section, files)
            if not file_name or file_name is None:
                continue
            else:
                logger_report.debug("Solution text '%s' name '%s'",
                                    solution_text, file_name)
                text = FileHelper.get_file_content(os.path.join(
                    dir_name, file_name),
                                                   "rb",
                                                   method=True)
            for cnt, line in enumerate(lines):
                # If in preupg.risk is a [link] then update them
                # to /root/pre{migrate,upgrade}/...
                if 'preupg.risk.' in line.strip():
                    logger_report.debug(line.strip())
                    lines[cnt] = tag_formating([line], extension)[0]
                    continue
                # Find correct block
                if solution_text not in line.strip():
                    continue

                # Get updated text if it is HTML or TEXT
                lines[cnt] = self.get_updated_text(solution_text, text, line,
                                                   extension)

        if extension == 'xml':
            for cnt, line in enumerate(lines):
                if 'SOLUTION_MSG' in line.strip():
                    lines[cnt] = re.sub(r'>.*SOLUTION_MSG.*<', '><',
                                        line.strip())

        FileHelper.write_to_file(orig_file, "wb", lines)
    def get_solution_files(self):
        """
        Function returns a dictionary with solution_files

        Format is:
        xccdf_preupg_backup_solution_file=solution.txt
        """
        dict_solution = {}
        for values in self.get_nodes(self.target_tree, "Value", prefix='.//'):
            value_id = values.get('id')
            if not value_id.endswith("_state_solution_file"):
                continue
            for value in self.get_nodes(values, "value"):
                logger_report.debug(value_id)
                value_id = value_id.replace('xccdf_preupg_value_', '').replace("_state_solution_file", '')
                dict_solution[value_id] = value.text
        logger_report.debug(dict_solution)
        return dict_solution
    def load_solution_texts(self):
        """Load solution texts into a dictionary."""
        for dir_name in self.paths_to_all_modules:
            section = dir_name.replace(self.copied_module_set_path,
                                       "").replace("/", "_")
            solution_placeholder = section + "_SOLUTION_MSG"

            logger_report.debug("Processing solution placeholder '%s'",
                                solution_placeholder)
            try:
                solution_text = FileHelper.get_file_content(
                    os.path.join(dir_name, settings.solution_txt), "rb")
            except IOError:
                # solution file is not mandatory
                solution_text = ""

            updated_solution_text = self.get_updated_solution(solution_text)
            self.solution_texts[solution_placeholder] = updated_solution_text
    def load_solution_texts(self):
        """Load solution texts into a dictionary."""
        for dir_name in self.paths_to_all_modules:
            section = dir_name.replace(
                self.copied_module_set_path, "").replace("/", "_")
            solution_placeholder = section + "_SOLUTION_MSG"

            logger_report.debug("Processing solution placeholder '%s'",
                                solution_placeholder)
            try:
                solution_text = FileHelper.get_file_content(
                    os.path.join(dir_name, settings.solution_txt), "rb")
            except IOError:
                # solution file is not mandatory
                solution_text = ""

            updated_solution_text = self.get_updated_solution(solution_text)
            self.solution_texts[solution_placeholder] = updated_solution_text
Пример #22
0
    def get_solution_files(self):
        """
        Function returns a dictionary with solution_files

        Format is:
        xccdf_preupg_backup_solution_file=solution.txt
        """
        dict_solution = {}
        for values in self.get_nodes(self.target_tree, "Value", prefix='.//'):
            value_id = values.get('id')
            if not value_id.endswith("_state_solution_file"):
                continue
            for value in self.get_nodes(values, "value"):
                logger_report.debug(value_id)
                value_id = value_id.replace('xccdf_preupg_value_', '').replace(
                    "_state_solution_file", '')
                dict_solution[value_id] = value.text
        logger_report.debug(dict_solution)
        return dict_solution
    def update_html(self, result_name, solution_files, extension="html"):
        """
         Function updates a XML or HTML file with relevant solution
         texts
        """
        orig_file = os.path.join(self.dirname,
                                 result_name + "." + extension)
        lines = FileHelper.get_file_content(orig_file, "rb", method=True)
        for dir_name, files in six.iteritems(solution_files):
            section = dir_name.replace(os.path.join(self.dirname, self.scenario),
                                       "").replace("/", "_")
            solution_text = section + "_SOLUTION_MSG"

            file_name = self._return_correct_text_file(section, files)
            if not file_name or file_name is None:
                continue
            else:
                logger_report.debug("Solution text '%s' name '%s'", solution_text, file_name)
                text = FileHelper.get_file_content(os.path.join(dir_name, file_name), "rb", method=True)
            for cnt, line in enumerate(lines):
                # If in preupg.risk is a [link] then update them
                # to /root/pre{migrate,upgrade}/...
                if 'preupg.risk.' in line.strip():
                    logger_report.debug(line.strip())
                    lines[cnt] = tag_formating([line], extension)[0]
                    continue
                # Find correct block
                if solution_text not in line.strip():
                    continue

                # Get updated text if it is HTML or TEXT
                lines[cnt] = self.get_updated_text(solution_text,
                                                   text,
                                                   line,
                                                   extension)

        if extension == 'xml':
            for cnt, line in enumerate(lines):
                if 'SOLUTION_MSG' in line.strip():
                    lines[cnt] = re.sub(r'>.*SOLUTION_MSG.*<', '><', line.strip())

        FileHelper.write_to_file(orig_file, "wb", lines)
 def _return_correct_text_file(self, section, files):
     """
     Function returns only one text file
     based on section and list of txt files from content
     directory
     """
     file_name = None
     for key, value in self.xml_solution_files.items():
         # section is in format _<path_content>
         section_name = section[1:] + "_"
         if section_name not in key:
             continue
         # This will return only
         try:
             logger_report.debug(value)
             file_name = [txt for txt in files if txt == value][0]
             logger_report.debug(file_name)
             break
         except IndexError:
             logger_report.debug("Value '%s'", value)
     logger_report.debug("Found text file '%s'.", file_name)
     return file_name
Пример #25
0
 def _return_correct_text_file(self, section, files):
     """
     Function returns only one text file
     based on section and list of txt files from content
     directory
     """
     file_name = None
     for key, value in self.xml_solution_files.items():
         # section is in format _<path_content>
         section_name = section[1:] + "_"
         if section_name not in key:
             continue
         # This will return only
         try:
             logger_report.debug(value)
             file_name = [txt for txt in files if txt == value][0]
             logger_report.debug(file_name)
             break
         except IndexError:
             logger_report.debug("Value '%s'", value)
     logger_report.debug("Found text file '%s'.", file_name)
     return file_name
Пример #26
0
    def replace_inplace_risk(self, scanning_results=None):
        """
        This function has aim to replace FAILED to
        NEEDS_INSPECTION in case that risks are SLIGHT or MEDIUM
        """
        #Filter all rule-result in TestResult
        changed_fields = []
        self.remove_empty_check_import()
        inplace_dict = {
            0: ReportHelper.upd_inspection,
            1: ReportHelper.upd_action,
            2: ReportHelper.upd_extreme,
        }
        for rule in self.get_all_result_rules():
            result = [
                x for x in self.get_nodes(rule, "result") if x.text == "fail"
            ]
            # Get all affected rules and taken their names
            for res in result:
                inplace_risk = XccdfHelper.get_check_import_inplace_risk(rule)
                logger_report.debug(inplace_risk)
                # In case that report has state fail and
                # no log_risk than it should be needs_inspection
                if not inplace_risk:
                    changed = rule.get("idref")
                    res.text = "fail"
                    log_message(
                        'The %s module exits as fail but without a risk.' %
                        rule.get("idref"))
                else:
                    inplace_num = XccdfHelper.get_and_print_inplace_risk(
                        0, inplace_risk)
                    logger_report.debug("Call function '%s'",
                                        inplace_dict[inplace_num])
                    changed, res.text = inplace_dict[inplace_num](rule)
                    logger_report.debug("Replace text '%s:%s'", changed,
                                        res.text)
                if changed is not None:
                    changed_fields.append(changed + ":" + res.text)

        if scanning_results:
            scanning_results.update_data(changed_fields)

        self.write_xml()
    def replace_inplace_risk(self, scanning_results=None):
        """
        This function has aim to replace FAILED to
        NEEDS_INSPECTION in case that risks are SLIGHT or MEDIUM
        """
        #Filter all rule-result in TestResult
        changed_fields = []
        self.remove_empty_check_import()
        inplace_dict = {
            0: ReportHelper.upd_inspection,
            1: ReportHelper.upd_action,
            2: ReportHelper.upd_extreme,
        }
        for rule in self.get_all_result_rules():
            result = [x for x in self.get_nodes(rule, "result") if x.text == "fail"]
            # Get all affected rules and taken their names
            for res in result:
                inplace_risk = XccdfHelper.get_check_import_inplace_risk(rule)
                logger_report.debug(inplace_risk)
                # In case that report has state fail and
                # no log_risk than it should be needs_inspection
                if not inplace_risk:
                    changed = rule.get("idref")
                    res.text = "fail"
                    log_message('The %s module exits as fail but without a risk.' % rule.get("idref"))
                else:
                    inplace_num = XccdfHelper.get_and_print_inplace_risk(0, inplace_risk)
                    logger_report.debug("Call function '%s'", inplace_dict[inplace_num])
                    changed, res.text = inplace_dict[inplace_num](rule)
                    logger_report.debug("Replace text '%s:%s'", changed, res.text)
                if changed is not None:
                    changed_fields.append(changed+":"+res.text)

        if scanning_results:
            scanning_results.update_data(changed_fields)

        self.write_xml()
Пример #28
0
    def check_inplace_risk(xccdf_file, verbose):
        """
        The function read the content of the file
        and finds out all "preupg.risk" rows in TestResult tree.
        return code is get from function get_and_print_inplace_risk
        """
        message = "'preupg' command was not run yet. Run 'preupg' before getting list of risks."
        try:
            content = FileHelper.get_file_content(xccdf_file, 'rb', False, False)
            if not content:
                # WE NEED TO RETURN -1 FOR RED-HAT-UPGRADE-TOOL
                log_message(message)
                return -1
        except IOError:
            # WE NEED TO RETURN -1 FOR RED-HAT-UPGRADE-TOOL
            log_message(message)
            return -1

        target_tree = ElementTree.fromstring(content)
        results = {}
        for profile in target_tree.findall(XMLNS + "TestResult"):
            # Collect all inplace risk for each return code
            for rule_result in profile.findall(XMLNS + "rule-result"):
                result_value = None
                for check in rule_result.findall(XMLNS + "result"):
                    result_value = check.text
                if check.text not in results:
                    results[check.text] = []
                inplace_risk = XccdfHelper.get_check_import_inplace_risk(rule_result)
                if not inplace_risk:
                    continue
                for risk in inplace_risk:
                    if risk not in results[result_value]:
                        results[result_value].append(risk)
        logger_report.debug(results)
        return_val = 0
        for result in settings.ORDERED_LIST:
            if result in results:
                current_val = 0
                logger_report.debug('%s found in assessment' % result)
                current_val = settings.PREUPG_RETURN_VALUES[result]
                ret_val = XccdfHelper.get_and_print_inplace_risk(verbose, results[result])
                """
                if not results[result]:
                    ret_val = XccdfHelper.get_and_print_inplace_risk(verbose, results[result])
                    if result == 'fail' and int(ret_val) == -1:
                        current_val = settings.PREUPG_RETURN_VALUES['error']
                    else:
                        current_val = settings.PREUPG_RETURN_VALUES[result]
                else:
                    ret_val = XccdfHelper.get_and_print_inplace_risk(verbose, results[result])
                    logger_report.debug('Return value from "get_and_print_inplace_risk" is %s' % ret_val)
                    if result == 'fail' and int(ret_val) == -1:
                        current_val = settings.PREUPG_RETURN_VALUES['error']
                    elif result in settings.ERROR_RETURN_VALUES and int(ret_val) != -1:
                        current_val = settings.PREUPG_RETURN_VALUES['error']
                    elif int(ret_val) == -1:
                        current_val = settings.PREUPG_RETURN_VALUES[result]
                    else:
                        # EXTREME has to return 2 as FAIL
                        if ret_val == 2:
                            current_val = ModuleValues.FAIL
                        else:
                            # Needs_action has to return 1 as needs_inspection
                            current_val = ModuleValues.NEEDS_INSPECTION
                """
                if return_val < current_val:
                    return_val = current_val
        return return_val