Example #1
0
    def validate(self, option_dict: TypeOptionMap) -> ReportItemList:
        name_set = set(option_dict.keys())
        banned_names = set()
        if not (self._severity.force_code is None
                and self._severity.level == ReportItemSeverity.ERROR):
            banned_names = name_set & self._banned_name_set
        invalid_names = name_set - set(self._option_name_list) - banned_names

        report_list = []
        if invalid_names:
            report_list.append(
                ReportItem(
                    severity=self._severity,
                    message=reports.messages.InvalidOptions(
                        sorted(invalid_names),
                        sorted(self._option_name_list),
                        self._option_type,
                        allowed_patterns=sorted(self._allowed_option_patterns),
                    ),
                ))
        if banned_names:
            report_list.append(
                ReportItem.error(
                    reports.messages.InvalidOptions(
                        sorted(banned_names),
                        sorted(self._option_name_list),
                        self._option_type,
                    )))
        return report_list
Example #2
0
    def validate(self, option_dict):
        name_set = set(option_dict.keys())
        banned_names = set()
        if not (self._code_for_warning is None and not self._produce_warning):
            banned_names = name_set & self._banned_name_set
        invalid_names = name_set - set(self._option_name_list) - banned_names

        report_list = []
        if invalid_names:
            report_list.append(
                ReportItem(
                    severity=reports.item.get_severity(
                        self._code_for_warning, self._produce_warning,
                    ),
                    message=reports.messages.InvalidOptions(
                        sorted(invalid_names),
                        sorted(self._option_name_list),
                        self._option_type,
                        allowed_patterns=sorted(self._allowed_option_patterns),
                    ),
                )
            )
        if banned_names:
            report_list.append(
                ReportItem.error(
                    reports.messages.InvalidOptions(
                        sorted(banned_names),
                        sorted(self._option_name_list),
                        self._option_type,
                    )
                )
            )
        return report_list
Example #3
0
    def validate_parameters_create(
        self,
        parameters,
        force=False,
        # TODO remove this argument, see pcs.lib.cib.commands.remote_node.create
        # for details
        do_not_report_instance_attribute_server_exists=False,
    ):
        # This is just a basic validation checking that required parameters are
        # set and all set parameters are known to an agent. Missing checks are:
        # 1. values checks - if a param is an integer, then "abc" is not valid
        # 2. warnings should be emitted when a deprecated param is set
        # 3. errors should be emitted when a deprecated parameter and a
        #    parameter obsoleting it are set at the same time
        # 4. possibly some other checks
        # All of these have been missing in pcs since ever (ad 1. agents have
        # never provided enough info for us to do such validations, ad 2. and
        # 3. there were no deprecated parameters before). The checks should be
        # implemented in agents themselves, so I'm not adding them now either.
        report_items = []

        # report unknown parameters
        report_items.extend(
            validate.NamesIn(
                {param["name"]
                 for param in self.get_parameters()},
                option_type=self._agent_type_label,
                **validate.set_warning(reports.codes.FORCE_OPTIONS, force),
            ).validate(parameters))
        # TODO remove this "if", see pcs.lib.cib.commands.remote_node.create
        # for details
        if do_not_report_instance_attribute_server_exists:
            for report_item in report_items:
                if isinstance(report_item, ReportItem) and isinstance(
                        report_item.message, reports.messages.InvalidOptions):
                    report_msg = cast(reports.messages.InvalidOptions,
                                      report_item.message)
                    report_item.message = reports.messages.InvalidOptions(
                        report_msg.option_names,
                        sorted([
                            value for value in report_msg.allowed
                            if value != "server"
                        ]),
                        report_msg.option_type,
                        report_msg.allowed_patterns,
                    )

        # report missing required parameters
        missing_parameters = self._find_missing_required_parameters(parameters)
        if missing_parameters:
            report_items.append(
                ReportItem(
                    severity=self._validate_report_severity(force),
                    message=reports.messages.RequiredOptionsAreMissing(
                        sorted(missing_parameters),
                        self._agent_type_label,
                    ),
                ))

        return report_items
Example #4
0
def _find_resources_to_remove(
    cib,
    report_processor: ReportProcessor,
    node_type,
    node_identifier,
    allow_remove_multiple_nodes,
    find_resources,
):
    resource_element_list = find_resources(get_resources(cib), node_identifier)

    if not resource_element_list:
        raise LibraryError(
            ReportItem.error(
                reports.messages.NodeNotFound(node_identifier, [node_type])))

    if len(resource_element_list) > 1:
        if report_processor.report(
                ReportItem(
                    severity=reports.item.get_severity(
                        reports.codes.FORCE,
                        allow_remove_multiple_nodes,
                    ),
                    message=reports.messages.MultipleResultsFound(
                        "resource",
                        [
                            resource.attrib["id"]
                            for resource in resource_element_list
                        ],
                        node_identifier,
                    ),
                )).has_errors:
            raise LibraryError()

    return resource_element_list
Example #5
0
    def validate_parameters_update(self,
                                   current_parameters,
                                   new_parameters,
                                   force=False):
        # This is just a basic validation checking that required parameters are
        # set and all set parameters are known to an agent. Missing checks are:
        # 1. values checks - if a param is an integer, then "abc" is not valid
        # 2. warnings should be emitted when a deprecated param is set
        # 3. errors should be emitted when a deprecated parameter and a
        #    parameter obsoleting it are set at the same time
        # 4. possibly some other checks
        # All of these have been missing in pcs since ever (ad 1. agents have
        # never provided enough info for us to do such validations, ad 2. and
        # 3. there were no deprecated parameters before). The checks should be
        # implemented in agents themselves, so I'm not adding them now either.
        report_items = []

        # get resulting set of agent's parameters
        final_parameters = dict(current_parameters)
        for name, value in new_parameters.items():
            if value:
                final_parameters[name] = value
            else:
                if name in final_parameters:
                    del final_parameters[name]

        # report unknown parameters
        report_items.extend(
            validate.NamesIn(
                {param["name"]
                 for param in self.get_parameters()},
                option_type=self._agent_type_label,
                severity=reports.item.get_severity(reports.codes.FORCE_OPTIONS,
                                                   force),
            ).validate(
                # Do not report unknown parameters already set in the CIB. They
                # have been reported already when the were added to the CIB.
                {
                    name: value
                    for name, value in new_parameters.items()
                    if name not in current_parameters
                }))

        # report missing or removed required parameters
        missing_parameters = self._find_missing_required_parameters(
            final_parameters)
        if missing_parameters:
            report_items.append(
                ReportItem(
                    severity=self._validate_report_severity(force),
                    message=reports.messages.RequiredOptionsAreMissing(
                        sorted(missing_parameters),
                        self._agent_type_label,
                    ),
                ))

        return report_items
Example #6
0
 def _get_report_item(self, value: ValuePair) -> ReportItem:
     return ReportItem(
         severity=self._severity,
         message=reports.messages.InvalidOptionValue(
             self._get_option_name_for_report(),
             value.original,
             self._get_allowed_values(),
             cannot_be_empty=self._value_cannot_be_empty,
             forbidden_characters=self._forbidden_characters,
         ),
     )
Example #7
0
 def validate(self, option_dict: TypeOptionMap) -> ReportItemList:
     return [
         ReportItem(
             severity=self._severity,
             message=reports.messages.DeprecatedOption(
                 option_name,
                 self._deprecated_by,
                 self._option_type,
             ),
         ) for option_name in self._option_name_list
         if (option_name in option_dict)
     ]
Example #8
0
 def validate(self, option_dict: TypeOptionMap) -> ReportItemList:
     missing = set(self._option_name_list) - set(option_dict.keys())
     if missing:
         return [
             ReportItem(
                 severity=self._severity,
                 message=reports.messages.RequiredOptionsAreMissing(
                     sorted(missing),
                     self._option_type,
                 ),
             )
         ]
     return []
Example #9
0
 def validate(self, option_dict: TypeOptionMap) -> ReportItemList:
     found = set(self._option_name_list) & set(option_dict.keys())
     if len(found) > 1:
         return [
             ReportItem(
                 self._severity,
                 reports.messages.MutuallyExclusiveOptions(
                     sorted(found),
                     self._option_type,
                 ),
             )
         ]
     return []
Example #10
0
 def _validate_action_is_deprecated(self, parameters, force=False):
     if parameters.get("action", ""):
         return [
             ReportItem(
                 self._validate_report_severity(force),
                 reports.messages.DeprecatedOption(
                     "action",
                     sorted(STONITH_ACTION_REPLACED_BY),
                     self._agent_type_label,
                 ),
             )
         ]
     return []
Example #11
0
 def exception_to_report_list(exception, file_type_code, file_path,
                              force_code, is_forced_or_warning):
     del file_type_code  # this is defined by the report code
     if isinstance(exception, InvalidLines):
         return [
             ReportItem(
                 severity=get_severity(force_code, is_forced_or_warning),
                 message=reports.messages.BoothConfigUnexpectedLines(
                     exception.args[0],
                     file_path,
                 ),
             )
         ]
     raise exception
Example #12
0
 def validate(self, option_dict: TypeOptionMap) -> ReportItemList:
     return [
         ReportItem(
             self._severity,
             reports.messages.PrerequisiteOptionIsMissing(
                 option_name,
                 self._prerequisite_name,
                 self._option_type,
                 self._prerequisite_type,
             ),
         ) for option_name in self._option_name_list
         if (option_name in option_dict
             and self._prerequisite_name not in option_dict)
     ]
Example #13
0
    def _validate_value(self, value: ValuePair) -> ReportItemList:
        if value.normalized in self._deprecation_map:
            return [
                ReportItem(
                    severity=self._severity,
                    message=reports.messages.DeprecatedOptionValue(
                        option_name=self._get_option_name_for_report(),
                        deprecated_value=value.original,
                        replaced_by=self._deprecation_map[value.normalized],
                    ),
                )
            ]

        return []
Example #14
0
 def validate(self, option_dict: TypeOptionMap) -> ReportItemList:
     found = set(self._option_name_list) & set(option_dict.keys())
     if not found:
         return [
             ReportItem(
                 self._severity,
                 reports.messages.RequiredOptionOfAlternativesIsMissing(
                     sorted(self._option_name_list),
                     sorted(self._deprecated_option_name_list),
                     self._option_type,
                 ),
             )
         ]
     return []
Example #15
0
    def _validate_value(self, value: ValuePair) -> ReportItemList:
        if not self._is_valid(value.normalized):
            return [
                ReportItem(
                    severity=self._severity,
                    message=reports.messages.InvalidOptionValue(
                        self._get_option_name_for_report(),
                        value.original,
                        self._get_allowed_values(),
                        cannot_be_empty=self._value_cannot_be_empty,
                        forbidden_characters=self._forbidden_characters,
                    ),
                )
            ]

        return []
Example #16
0
def booth_multiple_times_in_cib(name, severity=ReportItemSeverity.ERROR):
    """
    Each booth instance should be in a cib once maximally. But multiple
        occurences detected. For example during remove booth instance from cib.
        Notify user about this fact is required. When operation is forced
        user should be notified about multiple occurences.
    string name is booth instance name
    ReportItemSeverity severit should be ERROR or WARNING (depends on context)
        is flag for next report processing
        Because of severity coupling with ReportItem is it specified here.
    """
    return ReportItem(report_codes.BOOTH_MULTIPLE_TIMES_IN_CIB,
                      severity,
                      info={
                          "name": name,
                      },
                      forceable=report_codes.FORCE_BOOTH_REMOVE_FROM_CIB
                      if severity == ReportItemSeverity.ERROR else None)
Example #17
0
    def _validate_value(self, value):
        if not self._is_valid(value.normalized):
            return [
                ReportItem(
                    severity=reports.item.get_severity(
                        self._code_for_warning, self._produce_warning,
                    ),
                    message=reports.messages.InvalidOptionValue(
                        self._get_option_name_for_report(),
                        value.original,
                        self._get_allowed_values(),
                        cannot_be_empty=self._value_cannot_be_empty,
                        forbidden_characters=self._forbidden_characters,
                    ),
                )
            ]

        return []
Example #18
0
def booth_config_unexpected_lines(
    line_list,
    file_path=None,
    severity=ReportItemSeverity.ERROR,
    forceable=None,
):
    """
    Lines not conforming to expected config structure found in a booth config

    list line_list -- not valid lines
    string file_path -- path to the conf file if available
    """
    return ReportItem(report_codes.BOOTH_CONFIG_UNEXPECTED_LINES,
                      severity,
                      info={
                          "line_list": line_list,
                          "file_path": file_path,
                      },
                      forceable=forceable)
Example #19
0
 def validate(self, option_dict: TypeOptionMap) -> ReportItemList:
     not_valid_options = [
         name for name in option_dict
         if corosync_constants.OPTION_NAME_RE.fullmatch(name) is None
     ]
     if not_valid_options:
         # We must be strict and do not allow to override this validation,
         # otherwise setting a cratfed option name could be misused for
         # setting arbitrary corosync.conf settings.
         return [
             ReportItem(
                 self._severity,
                 reports.messages.InvalidUserdefinedOptions(
                     sorted(not_valid_options),
                     "a-z A-Z 0-9 /_-",
                     self._option_type,
                 ),
             )
         ]
     return []
Example #20
0
def resource_agent_error_to_report_item(e,
                                        severity=ReportItemSeverity.ERROR,
                                        forceable=False):
    """
    Transform ResourceAgentError to ReportItem
    """
    force = None
    if e.__class__ == UnableToGetAgentMetadata:
        if severity == ReportItemSeverity.ERROR and forceable:
            force = reports.codes.FORCE_METADATA_ISSUE
        return ReportItem(
            severity=reports.item.ReportItemSeverity(severity, force),
            message=reports.messages.UnableToGetAgentMetadata(
                e.agent, e.message),
        )
    if e.__class__ == InvalidResourceAgentName:
        return ReportItem.error(
            reports.messages.InvalidResourceAgentName(e.agent))
    if e.__class__ == InvalidStonithAgentName:
        return ReportItem.error(
            reports.messages.InvalidStonithAgentName(e.agent))
    raise e