def validate_resource_instance_attributes_create( resource_agent: ResourceAgentFacade, instance_attributes: Mapping[str, str], resources_section: _Element, force: bool = False, ) -> reports.ReportItemList: report_items: reports.ReportItemList = [] report_items += validate.ValidatorAll([ validate.ValueNotEmpty(name, None) for name in instance_attributes ]).validate(instance_attributes) if resource_agent.metadata.agent_exists: report_items += validate.ValidatorAll( resource_agent.get_validators_allowed_parameters(force) + resource_agent.get_validators_required_parameters(force)).validate( instance_attributes) report_items += validate.ValidatorAll( resource_agent.get_validators_deprecated_parameters()).validate({ name: value for name, value in instance_attributes.items() # we create a custom report for stonith parameter "action" if not (resource_agent.metadata.name.is_stonith and name == "action") }) if resource_agent.metadata.name.is_stonith: report_items += _validate_stonith_action(instance_attributes, force) if resource_agent.metadata.agent_exists: report_items += _validate_unique_instance_attributes( resource_agent.metadata, instance_attributes, resources_section, force=force, ) return report_items
def _fixture_stonith(): return ResourceAgentFacade( _fixture_metadata( ResourceAgentName("stonith", None, "type"), [ _fixture_parameter("required", True, []), _fixture_parameter("optional", False, []), _fixture_parameter("action", True, []), ], ))
def _fixture_void(stonith=False): return ResourceAgentFacade( ResourceAgentMetadata( ResourceAgentName("stonith", None, "type") if stonith else ResourceAgentName("standard", "provider", "type"), agent_exists=False, ocf_version=const.OCF_1_0, shortdesc=None, longdesc=None, parameters=[], actions=[], ))
def _fixture_agent_deprecated_loop(): return ResourceAgentFacade( _fixture_metadata( ResourceAgentName("standard", "provider", "type"), [ _fixture_parameter("loop1", True, ["loop1"]), _fixture_parameter("loop2a", True, ["loop2b"]), _fixture_parameter("loop2b", True, ["loop2a"]), _fixture_parameter("loop3a", True, ["loop3b"]), _fixture_parameter("loop3b", True, ["loop3c"]), _fixture_parameter("loop3c", True, ["loop3a"]), ], ))
def _fixture_agent(): return ResourceAgentFacade( _fixture_metadata( ResourceAgentName("standard", "provider", "type"), [ _fixture_parameter("optional1_new", False, []), _fixture_parameter("optional1_old", False, ["optional1_new"]), _fixture_parameter("optional2_new", False, []), _fixture_parameter("optional2_old", False, ["optional2_new"]), _fixture_parameter("required1_new", True, []), _fixture_parameter("required1_old", True, ["required1_new"]), _fixture_parameter("required2_new", True, []), _fixture_parameter("required2_old", True, ["required2_new"]), _fixture_parameter("action", False, []), ], ))
def validate_resource_instance_attributes_update( resource_agent: ResourceAgentFacade, instance_attributes: Mapping[str, str], resource_id: str, resources_section: _Element, force: bool = False, ) -> reports.ReportItemList: # TODO This function currently accepts the updated resource as a string and # finds the corresponding xml element by itself. This is needed as the # function is called from old pcs code which uses dom while pcs.lib uses # lxml. Once resource update command is moved to pcs.lib, this function # will be fixed to accept the updated resource as an element instead of a # string. report_items: reports.ReportItemList = [] current_instance_attrs = get_nvset_as_dict( INSTANCE_ATTRIBUTES_TAG, find_element_by_tag_and_id(TAG, resources_section, resource_id), ) if resource_agent.metadata.agent_exists: report_items += validate.ValidatorAll( resource_agent.get_validators_allowed_parameters(force) ).validate( # Do not report unknown parameters already set in the CIB. It would # be confusing to report an error in an option not actually created # now. { name: value for name, value in instance_attributes.items() if name not in current_instance_attrs } ) report_items += validate.ValidatorAll( resource_agent.get_validators_deprecated_parameters() ).validate( { name: value for name, value in instance_attributes.items() # Allow removing deprecated parameters if value != "" # we create a custom report for stonith parameter "action" and not ( resource_agent.metadata.name.is_stonith and name == "action" ) } ) # Check that required parameters have not been removed. This is # complicated by two facts: # * parameters may by deprecated by other parameters, setting one # required parameter from such group is enough # * we only want to report errors related to attributes to be updated final_attrs = dict(current_instance_attrs) for name, value in instance_attributes.items(): if value == "": final_attrs.pop(name, None) else: final_attrs[name] = value report_items += validate.ValidatorAll( # Limit validation only to parameters entered now in an update # command. We don't want to report missing parameters not mentioned # in a command now, that would be confusing to users. resource_agent.get_validators_required_parameters( force, only_parameters=instance_attributes.keys() ) ).validate(final_attrs) if resource_agent.metadata.name.is_stonith: report_items += _validate_stonith_action(instance_attributes, force) if resource_agent.metadata.agent_exists: report_items += _validate_unique_instance_attributes( resource_agent.metadata, instance_attributes, resources_section, resource_id=resource_id, force=force, ) return report_items