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 test_search(self): self.assertEqual( lib.list_agents(self.env_assist.get_env(), False, "te"), [ self._fixture_agent_struct( ResourceAgentName("ocf", "test", "Delay")), self._fixture_agent_struct( ResourceAgentName("ocf", "test", "Stateful")), self._fixture_agent_struct( ResourceAgentName("service", None, "pacemaker_remote")), ], )
def test_with_provider(self): results = primitive._find_primitives_by_agent( self.resources_section, ResourceAgentName( "standard", "provider", "agent_type", ), ) expected_results = [ """<primitive class="standard" provider="provider" type="agent_type" id="r0" />""", """<primitive class="standard" provider="provider" type="agent_type" id="r4" />""", """<primitive class="standard" provider="provider" type="agent_type" id="r5" />""", """<primitive class="standard" provider="provider" type="agent_type" id="r6" />""", ] self.assertEqual(len(expected_results), len(results)) for i, res in enumerate(results): assert_xml_equal(expected_results[i], etree.tostring(res).decode())
def _fixture_metadata(): def _parameter(name, unique_group): return ResourceAgentParameter( name, shortdesc=None, longdesc=None, type="string", default=None, enum_values=None, required=False, advanced=False, deprecated=False, deprecated_by=None, deprecated_desc=None, unique_group=unique_group, reloadable=False, ) return ResourceAgentMetadata( name=ResourceAgentName("ocf", "pacemaker", "pcstest"), agent_exists=True, ocf_version=const.OCF_1_0, shortdesc=None, longdesc=None, parameters=[ _parameter("addr", "connection"), _parameter("port", "connection"), _parameter("something", None), _parameter("unique", "one-attr"), ], actions=[], )
def test_resource_only_necessary(self): agent_name = ResourceAgentName("ocf", "pacemaker", "Stateful") self.config.runner.pcmk.load_agent( agent_name=agent_name.full_name, env={"PATH": "/usr/sbin:/bin:/usr/bin"}, ) self.assertEqual( lib.get_agent_default_operations( self.env_assist.get_env(), agent_name.to_dto(), necessary_only=True, ), ListCibResourceOperationDto( operations=[ _operation_fixture( "monitor", "10s", timeout="20s", role=const.PCMK_ROLE_PROMOTED, ), _operation_fixture( "monitor", "11s", timeout="20s", role=const.PCMK_ROLE_UNPROMOTED, ), ] ), )
def test_resource(self): agent_name = ResourceAgentName("ocf", "pacemaker", "Stateful") self.config.runner.pcmk.load_agent( agent_name=agent_name.full_name, env={"PATH": "/usr/sbin:/bin:/usr/bin"}, ) self.assertEqual( lib.get_agent_default_operations( self.env_assist.get_env(), agent_name.to_dto() ), ListCibResourceOperationDto( operations=[ _operation_fixture("start", "0s", timeout="20s"), _operation_fixture("stop", "0s", timeout="20s"), _operation_fixture( "monitor", "10s", timeout="20s", role=const.PCMK_ROLE_PROMOTED, ), _operation_fixture( "monitor", "11s", timeout="20s", role=const.PCMK_ROLE_UNPROMOTED, ), _operation_fixture("promote", "0s", timeout="10s"), _operation_fixture("demote", "0s", timeout="10s"), _operation_fixture("notify", "0s", timeout="5s"), _operation_fixture("reload-agent", "0s", timeout="10s"), ] ), )
def _get_agent_facade( report_processor: reports.ReportProcessor, factory: ResourceAgentFacadeFactory, name: str, allow_absent_agent: bool, ) -> ResourceAgentFacade: try: if ":" in name: raise InvalidResourceAgentName(name) full_name = ResourceAgentName("stonith", None, name) return factory.facade_from_parsed_name(full_name) except (UnableToGetAgentMetadata, UnsupportedOcfVersion) as e: if allow_absent_agent: report_processor.report( resource_agent_error_to_report_item( e, reports.ReportItemSeverity.warning(), is_stonith=True)) return factory.void_facade_from_parsed_name(full_name) report_processor.report( resource_agent_error_to_report_item( e, reports.ReportItemSeverity.error(reports.codes.FORCE), is_stonith=True, )) raise LibraryError() from e except ResourceAgentError as e: report_processor.report( resource_agent_error_to_report_item( e, reports.ReportItemSeverity.error(), is_stonith=True)) raise LibraryError() from e
def _get_agent_names( runner: CommandRunner, standard_provider: StandardProviderTuple) -> List[ResourceAgentName]: return [ ResourceAgentName(standard_provider.standard, standard_provider.provider, agent) for agent in list_resource_agents(runner, standard_provider) ]
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_agent(actions): return ResourceAgentMetadata( ResourceAgentName("ocf", "pacemaker", "Dummy"), agent_exists=True, ocf_version=OCF_1_0, shortdesc="", longdesc="", parameters=[], actions=actions, )
def fixture_stonith_agent(actions): return ResourceAgentMetadata( ResourceAgentName("stonith", None, "fence_test"), agent_exists=True, ocf_version=OCF_1_0, shortdesc="", longdesc="", parameters=[], actions=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 test_success(self): name = ResourceAgentName("ocf", "pacemaker", "Dummy") self.assertEqual( name_to_void_metadata(name), ResourceAgentMetadata( name, False, const.OCF_1_0, shortdesc=None, longdesc=None, parameters=[], actions=[], ), )
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 test_stonith(self): results = primitive._find_primitives_by_agent( self.resources_section, ResourceAgentName( "stonith", None, "agent_type", ), ) expected_results = [ '<primitive class="stonith" type="agent_type" id="r1"/>', '<primitive class="stonith" type="agent_type" id="r2"/>', ] self.assertEqual(len(expected_results), len(results)) for i, res in enumerate(results): assert_xml_equal(expected_results[i], etree.tostring(res).decode())
def _test_stonith(self, necessary_only): agent_name = ResourceAgentName("stonith", None, "fence_unfencing") self.config.runner.pcmk.load_agent( agent_name=agent_name.full_name, env={"PATH": "/usr/sbin:/bin:/usr/bin"}, ) self.config.runner.pcmk.load_fenced_metadata() self.assertEqual( lib.get_agent_default_operations( self.env_assist.get_env(), agent_name.to_dto(), necessary_only=necessary_only, ), ListCibResourceOperationDto(operations=[ _operation_fixture("monitor", interval="60s"), ]), )
def describe_agent(lib_env: LibraryEnvironment, agent_name: str) -> Dict[str, Any]: """ Get agent's description (metadata) in a structure agent_name -- name of the agent (not containing "stonith:" prefix) """ runner = lib_env.cmd_runner() agent_factory = ResourceAgentFacadeFactory(runner, lib_env.report_processor) try: if ":" in agent_name: raise InvalidResourceAgentName(agent_name) return _agent_metadata_to_dict( agent_factory.facade_from_parsed_name( ResourceAgentName("stonith", None, agent_name)).metadata, describe=True, ) except ResourceAgentError as e: lib_env.report_processor.report( resource_agent_error_to_report_item(e, is_stonith=True)) raise LibraryError() from e
def create_in_cluster( env: LibraryEnvironment, ip: str, instance_name: Optional[str] = None, allow_absent_resource_agent: bool = False, ): """ Create group with ip resource and booth resource env -- provides all for communication with externals ip -- float ip address for the operation of the booth instance_name -- booth instance name allow_absent_resource_agent -- allowing creating booth resource even if its agent is not installed """ report_processor = env.report_processor booth_env = env.get_booth_env(instance_name) # Booth config path goes to CIB. Working with a mocked booth configs would # not work coorectly as the path would point to a mock file (the path to a # mock file is unknown to us in the lib anyway) # It makes sense to work with a mocked CIB, though. Users can do other # changes to the CIB and push them to the cluster at once. _ensure_live_booth_env(booth_env) resources_section = get_resources(env.get_cib()) id_provider = IdProvider(resources_section) instance_name = booth_env.instance_name # validate if resource.find_for_config(resources_section, booth_env.config_path): report_processor.report( ReportItem.error(reports.messages.BoothAlreadyInCib(instance_name)) ) # verify the config exists and is readable try: booth_env.config.raw_file.read() except RawFileError as e: report_processor.report(raw_file_error_report(e)) if report_processor.has_errors: raise LibraryError() # validation done create_id = partial( resource.create_resource_id, resources_section, instance_name ) create_primitive = partial( primitive.create, env.report_processor, resources_section, id_provider ) agent_factory = ResourceAgentFacadeFactory( env.cmd_runner(), report_processor ) # Group id validation is not needed since create_id creates a new unique # booth group identifier hierarchy.move_resources_to_group( group.append_new(resources_section, create_id("group")), [ create_primitive( create_id("ip"), _get_agent_facade( env.report_processor, agent_factory, allow_absent_resource_agent, ResourceAgentName("ocf", "heartbeat", "IPaddr2"), ), instance_attributes={"ip": ip}, ), create_primitive( create_id("service"), _get_agent_facade( env.report_processor, agent_factory, allow_absent_resource_agent, ResourceAgentName("ocf", "pacemaker", "booth-site"), ), instance_attributes={"config": booth_env.config_path}, ), ], ) env.push_cib()
def setUp(self): self.env_assist, self.config = get_env_tools(test_case=self) standard = "ocf" provider = "heartbeat" agent_type = "Dummy" self.name = ResourceAgentName(standard, provider, agent_type) self.agent_metadata = ResourceAgentMetadataDto( name=ResourceAgentNameDto( standard=standard, provider=provider, type=agent_type, ), shortdesc="Example stateless resource agent: ®", longdesc=( "This is a Dummy Resource Agent for testing utf-8" " in metadata: ®" ), parameters=[ ResourceAgentParameterDto( name="state-®", shortdesc="State file: ®", longdesc="Location to store the resource state in: ®", type="string", default="/var/run/resource-agents/Dummy-®.state", enum_values=None, required=False, advanced=False, deprecated=False, deprecated_by=[], deprecated_desc=None, unique_group="_pcs_unique_group_state-®", reloadable=True, ), ResourceAgentParameterDto( name="trace_ra", shortdesc=( "Set to 1 to turn on resource agent " "tracing (expect large output)" ), longdesc=( "Set to 1 to turn on resource agent tracing" " (expect large output) The trace output will be " "saved to trace_file, if set, or by default to " "$HA_VARRUN/ra_trace/<type>/<id>.<action>." "<timestamp> e.g. $HA_VARRUN/ra_trace/oracle/db." "start.2012-11-27.08:37:08" ), type="integer", default="0", enum_values=None, required=False, advanced=True, deprecated=False, deprecated_by=[], deprecated_desc=None, unique_group=None, reloadable=False, ), ResourceAgentParameterDto( name="trace_file", shortdesc="Path to a file to store resource agent tracing log", longdesc="Path to a file to store resource agent tracing log", type="string", default="", enum_values=None, required=False, advanced=True, deprecated=False, deprecated_by=[], deprecated_desc=None, unique_group=None, reloadable=False, ), ], actions=[ ResourceAgentActionDto( name="start", timeout="20", interval=None, role=None, start_delay=None, depth=None, automatic=False, on_target=False, ), ResourceAgentActionDto( name="stop", timeout="20", interval=None, role=None, start_delay=None, depth=None, automatic=False, on_target=False, ), ResourceAgentActionDto( name="monitor", timeout="20", interval="10", role=None, start_delay=None, depth="0", automatic=False, on_target=False, ), ResourceAgentActionDto( name="meta-data", timeout="5", interval=None, role=None, start_delay=None, depth=None, automatic=False, on_target=False, ), ResourceAgentActionDto( name="validate-all", timeout="20", interval=None, role=None, start_delay=None, depth=None, automatic=False, on_target=False, ), ResourceAgentActionDto( name="custom-®", timeout="20", interval=None, role=None, start_delay=None, depth=None, automatic=False, on_target=False, ), ], )
def test_returns_resource_agent_containing_systemd_instance_short(self): self.assertEqual( ResourceAgentName("service", None, "getty@tty1"), split_resource_agent_name("service:getty@tty1"), )
def test_returns_resource_agent_containing_service_instance(self): self.assertEqual( ResourceAgentName("service", None, "lvm2-pvscan@252:2"), split_resource_agent_name("service:lvm2-pvscan@252:2"), )
def test_returns_resource_agent_containing_sytemd(self): self.assertEqual( ResourceAgentName("systemd", None, "lvm2-pvscan"), split_resource_agent_name("systemd:lvm2-pvscan"), )
def test_returns_resource_agent_name_when_is_valid(self): self.assertEqual( ResourceAgentName("ocf", "heartbeat", "Dummy"), split_resource_agent_name("ocf:heartbeat:Dummy"), )
from pcs.common import report_codes from pcs.lib import reports from pcs.lib.errors import LibraryError from pcs.lib.cib.resource import primitive from pcs.lib.node import ( NodeAddresses, node_addresses_contain_host, node_addresses_contain_name, ) from pcs.lib.resource_agent import ( find_valid_resource_agent_by_name, ResourceAgentName, ) AGENT_NAME = ResourceAgentName("ocf", "pacemaker", "remote") def get_agent(report_processor, cmd_runner): return find_valid_resource_agent_by_name( report_processor, cmd_runner, AGENT_NAME.full_name, ) _IS_REMOTE_AGENT_XPATH_SNIPPET = """ @class="{0}" and @provider="{1}" and @type="{2}" """.format(AGENT_NAME.standard, AGENT_NAME.provider, AGENT_NAME.type) _HAS_SERVER_XPATH_SNIPPET = """