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
def _get_report_item(self, value: validate.ValuePair) -> reports.ReportItem: return reports.ReportItem( severity=self._severity, message=reports.messages.StonithWatchdogTimeoutTooSmall( self._threshold, value.original ), )
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)
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
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})
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 []
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 []
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), ), )
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
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