def get_crm_config(tree: Element) -> Element: """ Return 'crm_config' element from tree, raise LibraryError if missing tree -- cib etree node """ return sections.get(tree, sections.CRM_CONFIG)
def test_get_existing_mandatory(self): self.assert_element_content( sections.get(self.tree, sections.CONFIGURATION), """ <configuration> <acls/> </configuration> """)
def get_resources(tree: Element) -> Element: """ Return the 'resources' element from the tree tree -- cib etree node """ return sections.get(tree, sections.RESOURCES)
def _defaults_create( env: LibraryEnvironment, cib_section_name: str, validator_options: Mapping[str, Any], nvpairs: Mapping[str, str], nvset_options: Mapping[str, str], nvset_rule: Optional[str] = None, force_flags: Optional[Container] = None, ) -> None: if force_flags is None: force_flags = set() force = (reports.codes.FORCE in force_flags) or (reports.codes.FORCE_OPTIONS in force_flags) required_cib_version = None nice_to_have_cib_version = None if nvset_rule: # Parse the rule to see if we need to upgrade CIB schema. All errors # would be properly reported by a validator called bellow, so we can # safely ignore them here. try: rule_tree = parse_rule(nvset_rule) if has_rsc_or_op_expression(rule_tree): required_cib_version = Version(3, 4, 0) if has_node_attr_expr_with_type_integer(rule_tree): nice_to_have_cib_version = Version(3, 5, 0) except RuleParseError: pass cib = env.get_cib( minimal_version=required_cib_version, nice_to_have_version=nice_to_have_cib_version, ) id_provider = IdProvider(cib) validator = nvpair_multi.ValidateNvsetAppendNew( id_provider, nvpairs, nvset_options, nvset_rule=nvset_rule, **validator_options, ) if env.report_processor.report_list( validator.validate(force_options=force)).has_errors: raise LibraryError() nvpair_multi.nvset_append_new( sections.get(cib, cib_section_name), id_provider, get_pacemaker_version_by_which_cib_was_validated(cib), nvpair_multi.NVSET_META, nvpairs, nvset_options, nvset_rule=validator.get_parsed_rule(), ) env.report_processor.report( ReportItem.warning(reports.messages.DefaultsCanBeOverriden())) env.push_cib()
def test_raises_on_no_existing_mandatory_section(self): assert_raise_library_error( lambda: sections.get(self.tree, sections.NODES), (severities.ERROR, report_codes.CIB_CANNOT_FIND_MANDATORY_SECTION, { "section": "configuration/nodes", }), )
def test_get_existing_mandatory(self): self.assert_element_content( sections.get(self.tree, sections.CONFIGURATION), """ <configuration> <acls/> </configuration> """ )
def _defaults_config( env: LibraryEnvironment, cib_section_name: str, ) -> List[CibNvsetDto]: return [ nvpair_multi.nvset_element_to_dto(nvset_el) for nvset_el in nvpair_multi.find_nvsets( sections.get(env.get_cib(), cib_section_name)) ]
def _defaults_remove(env: LibraryEnvironment, cib_section_name: str, nvset_id_list: Iterable[str]) -> None: if not nvset_id_list: return nvset_elements, report_list = nvpair_multi.find_nvsets_by_ids( sections.get(env.get_cib(), cib_section_name), nvset_id_list) if env.report_processor.report_list(report_list).has_errors: raise LibraryError() nvpair_multi.nvset_remove(nvset_elements) env.push_cib()
def _defaults_config( cib: _Element, nvset_tag: nvpair_multi.NvsetTag, cib_section_name: str, rule_evaluator: RuleInEffectEval, ) -> List[CibNvsetDto]: return [ nvpair_multi.nvset_element_to_dto(nvset_el, rule_evaluator) for nvset_el in nvpair_multi.find_nvsets( sections.get(cib, cib_section_name), nvset_tag) ]
def test_raises_on_no_existing_mandatory_section(self): assert_raise_library_error( lambda: sections.get(self.tree, sections.NODES), ( severities.ERROR, report_codes.CIB_CANNOT_FIND_MANDATORY_SECTION, { "section": "configuration/nodes", } ), )
def test_get_no_existing_optinal(self): self.assert_element_content(sections.get(self.tree, sections.ALERTS), "<alerts/>") self.assert_element_content( self.tree, """ <cib> <configuration> <acls/> <alerts/> </configuration> </cib> """)
def test_get_no_existing_optinal(self): self.assert_element_content( sections.get(self.tree, sections.ALERTS), "<alerts/>" ) self.assert_element_content( self.tree, """ <cib> <configuration> <acls/> <alerts/> </configuration> </cib> """ )
def _defaults_create( env: LibraryEnvironment, cib_section_name: str, validator_options: Mapping[str, Any], nvpairs: Mapping[str, str], nvset_options: Mapping[str, str], nvset_rule: Optional[str] = None, force_flags: Optional[Container] = None, ) -> None: if force_flags is None: force_flags = set() force = (reports.codes.FORCE in force_flags) or (reports.codes.FORCE_OPTIONS in force_flags) required_cib_version = None if nvset_rule: required_cib_version = Version(3, 4, 0) cib = env.get_cib(required_cib_version) id_provider = IdProvider(cib) validator = nvpair_multi.ValidateNvsetAppendNew( id_provider, nvpairs, nvset_options, nvset_rule=nvset_rule, **validator_options, ) if env.report_processor.report_list( validator.validate(force_options=force)).has_errors: raise LibraryError() nvpair_multi.nvset_append_new( sections.get(cib, cib_section_name), id_provider, nvpair_multi.NVSET_META, nvpairs, nvset_options, nvset_rule=validator.get_parsed_rule(), ) env.report_processor.report( ReportItem.warning(reports.messages.DefaultsCanBeOverriden())) env.push_cib()
def _set_any_defaults(section_name, env, options): """ string section_name -- determine the section of defaults LibraryEnvironment env -- provides access to outside environment dict options -- are desired options with its values; when value is empty the option have to be removed """ env.report_processor.process(reports.defaults_can_be_overriden()) if not options: return defaults_section = sections.get(env.get_cib(), section_name) arrange_first_meta_attributes(defaults_section, options, new_id="{0}-options".format(section_name)) remove_when_pointless(defaults_section) env.push_cib()
def _defaults_config(env: LibraryEnvironment, cib_section_name: str, evaluate_expired: bool) -> List[CibNvsetDto]: runner = env.cmd_runner() cib = env.get_cib() if evaluate_expired: if has_rule_in_effect_status_tool(): in_effect_eval: RuleInEffectEval = RuleInEffectEvalOneByOne( cib, runner) else: in_effect_eval = RuleInEffectEvalDummy() env.report_processor.report( ReportItem.warning(reports.messages. RuleInEffectStatusDetectionNotSupported())) else: in_effect_eval = RuleInEffectEvalDummy() return [ nvpair_multi.nvset_element_to_dto(nvset_el, in_effect_eval) for nvset_el in nvpair_multi.find_nvsets( sections.get(cib, cib_section_name)) ]
def _set_any_defaults(section_name, env: LibraryEnvironment, options): """ string section_name -- determine the section of defaults env -- provides access to outside environment dict options -- are desired options with its values; when value is empty the option have to be removed """ # Do not ever remove the nvset element, even if it is empty. There may be # ACLs set in pacemaker which allow "write" for nvpairs (adding, changing # and removing) but not nvsets. In such a case, removing the nvset would # cause the whole change to be rejected by pacemaker with a "permission # denied" message. # https://bugzilla.redhat.com/show_bug.cgi?id=1642514 env.report_processor.report( ReportItem.warning(reports.messages.DefaultsCanBeOverriden())) if not options: return cib = env.get_cib() # Do not create new defaults element if we are only removing values from it. only_removing = True for value in options.values(): if value != "": only_removing = False break if only_removing and not sections.exists(cib, section_name): return defaults_section = sections.get(cib, section_name) arrange_first_meta_attributes( defaults_section, options, IdProvider(cib), new_id="{0}-options".format(section_name), ) env.push_cib()
def _set_any_defaults(section_name, env, options): """ string section_name -- determine the section of defaults LibraryEnvironment env -- provides access to outside environment dict options -- are desired options with its values; when value is empty the option have to be removed """ # Do not ever remove the nvset element, even if it is empty. There may be # ACLs set in pacemaker which allow "write" for nvpairs (adding, changing # and removing) but not nvsets. In such a case, removing the nvset would # cause the whole change to be rejected by pacemaker with a "permission # denied" message. # https://bugzilla.redhat.com/show_bug.cgi?id=1642514 env.report_processor.process(reports.defaults_can_be_overriden()) if not options: return cib = env.get_cib() # Do not create new defaults element if we are only removing values from it. only_removing = True for value in options.values(): if value != "": only_removing = False break if only_removing and not sections.exists(cib, section_name): return defaults_section = sections.get(cib, section_name) arrange_first_meta_attributes( defaults_section, options, IdProvider(cib), new_id="{0}-options".format(section_name), ) env.push_cib()
def get_constraints(tree): """ Return 'constraint' element from tree tree cib etree node """ return sections.get(tree, sections.CONSTRAINTS)
def get_fencing_topology(tree): """ Return the 'fencing-topology' element from the tree tree -- cib etree node """ return sections.get(tree, sections.FENCING_TOPOLOGY)
def get_acls(tree): """ Return 'acls' element from tree, create a new one if missing tree cib etree node """ return sections.get(tree, sections.ACLS)
def get_alerts(tree): """ Return 'alerts' element from tree, create a new one if missing tree -- cib etree node """ return sections.get(tree, sections.ALERTS)
def get_configuration(tree): """ Return 'configuration' element from tree, raise LibraryError if missing tree cib etree node """ return sections.get(tree, sections.CONFIGURATION)
def _defaults_update( env: LibraryEnvironment, cib_section_name: str, nvset_id: Optional[str], nvpairs: Mapping[str, str], pcs_command: reports.types.PcsCommand, ) -> None: cib = env.get_cib() id_provider = IdProvider(cib) if nvset_id is None: # Backward compatibility code to support an old use case where no id # was requested and provided and the first meta_attributes nvset was # created / updated. However, we check that there is only one nvset # present in the CIB to prevent breaking the configuration with # multiple nvsets in place. # This is to be supported as it provides means of easily managing # defaults if only one set of defaults is needed. # TODO move this to a separate lib command. if not nvpairs: return # Do not create new defaults element if we are only removing values # from it. only_removing = True for value in nvpairs.values(): if value != "": only_removing = False break if only_removing and not sections.exists(cib, cib_section_name): env.report_processor.report( ReportItem.warning(reports.messages.DefaultsCanBeOverriden())) return nvset_elements = nvpair_multi.find_nvsets( sections.get(cib, cib_section_name)) if len(nvset_elements) > 1: env.report_processor.report( reports.item.ReportItem.error( reports.messages.CibNvsetAmbiguousProvideNvsetId( pcs_command))) raise LibraryError() env.report_processor.report( ReportItem.warning(reports.messages.DefaultsCanBeOverriden())) if len(nvset_elements) == 1: nvpair_multi.nvset_update(nvset_elements[0], id_provider, nvpairs) elif only_removing: # do not create new nvset if there is none and we are only removing # nvpairs return else: nvpair_multi.nvset_append_new( sections.get(cib, cib_section_name), id_provider, nvpair_multi.NVSET_META, nvpairs, {}, ) env.push_cib() return nvset_elements, report_list = nvpair_multi.find_nvsets_by_ids( sections.get(cib, cib_section_name), [nvset_id]) if env.report_processor.report_list(report_list).has_errors: raise LibraryError() nvpair_multi.nvset_update(nvset_elements[0], id_provider, nvpairs) env.report_processor.report( ReportItem.warning(reports.messages.DefaultsCanBeOverriden())) env.push_cib()
def test_get_existing_optinal(self): self.assert_element_content( sections.get(self.tree, sections.ACLS), "<acls/>" )
def get_tags(tree): """ Return 'tags' element from tree, create a new one if missing tree -- cib etree node """ return sections.get(tree, sections.TAGS)
def get_nodes(tree): """ Return 'nodes' element from the tree tree cib etree node """ return sections.get(tree, sections.NODES)
def get_resources(tree): """ Return the 'resources' element from the tree tree -- cib etree node """ return sections.get(tree, sections.RESOURCES)
def test_get_existing_optinal(self): self.assert_element_content(sections.get(self.tree, sections.ACLS), "<acls/>")