Пример #1
0
def resource_agent_error_to_report_item(
    e: ResourceAgentError,
    severity: SeverityLevel = reports.ReportItemSeverity.ERROR,
    forceable: bool = False,
) -> reports.ReportItem:
    """
    Transform ResourceAgentError to ReportItem
    """
    force = None
    if e.__class__ == UnableToGetAgentMetadata:
        if severity == reports.ReportItemSeverity.ERROR and forceable:
            force = reports.codes.FORCE
        return reports.ReportItem(
            severity=reports.ReportItemSeverity(severity, force),
            message=reports.messages.UnableToGetAgentMetadata(
                e.agent, e.message
            ),
        )
    if e.__class__ == InvalidResourceAgentName:
        return reports.ReportItem.error(
            reports.messages.InvalidResourceAgentName(e.agent)
        )
    if e.__class__ == InvalidStonithAgentName:
        return reports.ReportItem.error(
            reports.messages.InvalidStonithAgentName(e.agent)
        )
    raise e
Пример #2
0
 def _get_report_item(self, value: validate.ValuePair) -> reports.ReportItem:
     return reports.ReportItem(
         severity=self._severity,
         message=reports.messages.StonithWatchdogTimeoutTooSmall(
             self._threshold, value.original
         ),
     )
Пример #3
0
def resource_agent_error_to_report_item(
    e: ResourceAgentError,
    severity: reports.ReportItemSeverity = reports.ReportItemSeverity.error(),
    is_stonith: bool = False,
) -> reports.ReportItem:
    """
    Transform a ResourceAgentError to a ReportItem
    """
    message: reports.item.ReportItemMessage = (
        reports.messages.AgentGenericError(e.agent_name))
    if isinstance(e, AgentNameGuessFoundMoreThanOne):
        message = reports.messages.AgentNameGuessFoundMoreThanOne(
            e.searched_name, sorted(e.names_found))
    elif isinstance(e, AgentNameGuessFoundNone):
        message = reports.messages.AgentNameGuessFoundNone(e.searched_name)
    elif isinstance(e, InvalidResourceAgentName):
        if is_stonith:
            message = reports.messages.InvalidStonithAgentName(e.agent_name)
        else:
            message = reports.messages.InvalidResourceAgentName(e.agent_name)
    elif isinstance(e, UnableToGetAgentMetadata):
        message = reports.messages.UnableToGetAgentMetadata(
            e.agent_name, e.message)
    elif isinstance(e, UnsupportedOcfVersion):
        message = reports.messages.AgentImplementsUnsupportedOcfVersion(
            e.agent_name,
            e.ocf_version,
            sorted(const.SUPPORTED_OCF_VERSIONS),
        )
    return reports.ReportItem(severity, message)
Пример #4
0
def _validate_unique_instance_attributes(
    resource_agent: ResourceAgentMetadata,
    instance_attributes: Mapping[str, str],
    resources_section: _Element,
    resource_id: Optional[str] = None,
    force: bool = False,
) -> reports.ReportItemList:
    if not resource_agent.unique_parameter_groups:
        return []

    report_list = []
    same_agent_resources = _find_primitives_by_agent(resources_section,
                                                     resource_agent.name)

    for (
            group_name,
            group_attrs,
    ) in resource_agent.unique_parameter_groups.items():
        new_group_values_map = {
            name: instance_attributes.get(name, "")
            for name in group_attrs
        }
        if not any(new_group_values_map.values()):
            continue

        conflicting_resources: Set[str] = set()
        for primitive in same_agent_resources:
            if primitive.attrib["id"] == resource_id:
                continue
            existing_group_values_map = {
                name: get_value(INSTANCE_ATTRIBUTES_TAG, primitive, name, "")
                for name in group_attrs
            }
            if new_group_values_map == existing_group_values_map:
                conflicting_resources.add(str(primitive.attrib["id"]))

        if conflicting_resources:
            if len(new_group_values_map) == 1:
                message: reports.item.ReportItemMessage = (
                    reports.messages.ResourceInstanceAttrValueNotUnique(
                        *new_group_values_map.popitem(),
                        resource_agent.name.full_name,
                        sorted(conflicting_resources),
                    ))
            else:
                message = (
                    reports.messages.ResourceInstanceAttrGroupValueNotUnique(
                        group_name,
                        new_group_values_map,
                        resource_agent.name.full_name,
                        sorted(conflicting_resources),
                    ))
            report_list.append(
                reports.ReportItem(
                    reports.item.get_severity(reports.codes.FORCE, force),
                    message,
                ))
    return report_list
Пример #5
0
def validate_stonith_watchdog_timeout(
    stonith_watchdog_timeout: str, force: bool = False
) -> reports.ReportItemList:
    """
    Check sbd status and config when user is setting stonith-watchdog-timeout
    Returns error message if the value is unacceptable, otherwise return nothing
    to set the property

    stonith_watchdog_timeout -- value to be validated
    """
    severity = reports.get_severity(reports.codes.FORCE, force)
    if _is_device_set_local():
        return (
            [
                reports.ReportItem(
                    severity,
                    reports.messages.StonithWatchdogTimeoutCannotBeSet(
                        reports.const.SBD_SET_UP_WITH_DEVICES
                    ),
                )
            ]
            if stonith_watchdog_timeout not in ["", "0"]
            else []
        )

    if stonith_watchdog_timeout in ["", "0"]:
        return [
            reports.ReportItem(
                severity,
                reports.messages.StonithWatchdogTimeoutCannotBeUnset(
                    reports.const.SBD_SET_UP_WITHOUT_DEVICES
                ),
            )
        ]
    return validate.ValidatorAll(
        [
            _StonithWatchdogTimeoutValidator(
                "stonith-watchdog-timeout",
                _get_local_sbd_watchdog_timeout(),
                severity=severity,
            )
        ]
    ).validate({"stonith-watchdog-timeout": stonith_watchdog_timeout})
Пример #6
0
def _validate_stonith_action(instance_attributes: Mapping[str, str],
                             force: bool = False) -> reports.ReportItemList:
    if instance_attributes.get("action"):
        return [
            reports.ReportItem(
                reports.item.get_severity(reports.codes.FORCE, force),
                reports.messages.DeprecatedOption(
                    "action", sorted(STONITH_ACTION_REPLACED_BY), "stonith"),
            )
        ]
    return []
Пример #7
0
 def _validate_action_is_deprecated(
     self, parameters: Mapping[str, str], force: bool = False
 ) -> reports.ReportItemList:
     if parameters.get("action", ""):
         return [
             reports.ReportItem(
                 self._validate_report_severity(force),
                 reports.messages.DeprecatedOption(
                     "action",
                     sorted(STONITH_ACTION_REPLACED_BY),
                     self._agent_type_label,
                 ),
             )
         ]
     return []
Пример #8
0
def raw_file_error_report(
    error: RawFileError,
    force_code: Optional[reports.types.ForceCode] = None,
    is_forced_or_warning: bool = False,
) -> reports.ReportItem:
    """
    Translate a RawFileError instance to a report

    error -- an exception to be translated
    force_code -- is it a forcible error? by which code?
    is_forced_or_warning -- translate to a warning if True, error otherwise
    """
    return reports.ReportItem(
        severity=reports.get_severity(force_code, is_forced_or_warning),
        message=reports.messages.FileIoError(
            error.metadata.file_type_code,
            error.action,
            error.reason,
            # do not report real file path if we were working with a ghost file
            file_path=("" if isinstance(error, GhostFileError) else
                       error.metadata.path),
        ),
    )
Пример #9
0
    def validate_parameters_update(
        self,
        current_parameters: Mapping[str, str],
        new_parameters: Mapping[str, str],
        force: bool = False,
    ) -> reports.ReportItemList:
        # 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.get_severity(reports.codes.FORCE, 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(
                reports.ReportItem(
                    severity=self._validate_report_severity(force),
                    message=reports.messages.RequiredOptionsAreMissing(
                        sorted(missing_parameters),
                        self._agent_type_label,
                    ),
                )
            )

        return report_items
Пример #10
0
    def validate_parameters_create(
        self,
        parameters: Mapping[str, str],
        force: bool = False,
        # TODO remove this argument, see pcs.lib.cib.commands.remote_node.create
        # for details
        do_not_report_instance_attribute_server_exists: bool = False,
    ) -> reports.ReportItemList:
        # 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,
                severity=reports.get_severity(reports.codes.FORCE, 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, reports.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(
                reports.ReportItem(
                    severity=self._validate_report_severity(force),
                    message=reports.messages.RequiredOptionsAreMissing(
                        sorted(missing_parameters),
                        self._agent_type_label,
                    ),
                )
            )

        return report_items