def ensure_cib_version(runner, cib, version): """ This method ensures that specified cib is verified by pacemaker with version 'version' or newer. If cib doesn't correspond to this version, method will try to upgrade cib. Returns cib which was verified by pacemaker version 'version' or later. Raises LibraryError on any failure. CommandRunner runner etree cib cib tree tuple version tuple of integers (<major>, <minor>, <revision>) """ current_version = get_pacemaker_version_by_which_cib_was_validated(cib) if current_version >= version: return None _upgrade_cib(runner) new_cib_xml = get_cib_xml(runner) try: new_cib = parse_cib_xml(new_cib_xml) except (etree.XMLSyntaxError, etree.DocumentInvalid) as e: raise LibraryError(reports.cib_upgrade_failed(str(e))) current_version = get_pacemaker_version_by_which_cib_was_validated(new_cib) if current_version >= version: return new_cib raise LibraryError( reports.unable_to_upgrade_cib_to_required_version( current_version, version))
def ensure_cib_version(runner, cib, version): """ This method ensures that specified cib is verified by pacemaker with version 'version' or newer. If cib doesn't correspond to this version, method will try to upgrade cib. Returns cib which was verified by pacemaker version 'version' or later. Raises LibraryError on any failure. CommandRunner runner -- runner etree cib -- cib tree pcs.common.tools.Version version -- required cib version """ current_version = get_pacemaker_version_by_which_cib_was_validated(cib) if current_version >= version: return None _upgrade_cib(runner) new_cib_xml = get_cib_xml(runner) try: new_cib = parse_cib_xml(new_cib_xml) except (etree.XMLSyntaxError, etree.DocumentInvalid) as e: raise LibraryError( ReportItem.error(reports.messages.CibUpgradeFailed(str(e)))) current_version = get_pacemaker_version_by_which_cib_was_validated(new_cib) if current_version >= version: return new_cib raise LibraryError( ReportItem.error( reports.messages.CibUpgradeFailedToMinimalRequiredVersion( str(current_version), str(version))))
def ensure_cib_version(runner, cib, version): """ This method ensures that specified cib is verified by pacemaker with version 'version' or newer. If cib doesn't correspond to this version, method will try to upgrade cib. Returns cib which was verified by pacemaker version 'version' or later. Raises LibraryError on any failure. CommandRunner runner etree cib cib tree tuple version tuple of integers (<major>, <minor>, <revision>) """ current_version = get_pacemaker_version_by_which_cib_was_validated(cib) if current_version >= version: return None _upgrade_cib(runner) new_cib_xml = get_cib_xml(runner) try: new_cib = parse_cib_xml(new_cib_xml) except (etree.XMLSyntaxError, etree.DocumentInvalid) as e: raise LibraryError(reports.cib_upgrade_failed(str(e))) current_version = get_pacemaker_version_by_which_cib_was_validated(new_cib) if current_version >= version: return new_cib raise LibraryError(reports.unable_to_upgrade_cib_to_required_version( current_version, version ))
def ensure_cib_version( runner: CommandRunner, cib: _Element, version: Version, fail_if_version_not_met: bool = True, ) -> Tuple[_Element, bool]: """ Make sure CIB complies to specified schema version (or newer), upgrade CIB if necessary. Raise on error. Raise if CIB cannot be upgraded enough to meet the required version unless fail_if_version_not_met is set to False. Return tuple(upgraded_cib, was_upgraded) This method ensures that specified cib is verified by pacemaker with version 'version' or newer. If cib doesn't correspond to this version, method will try to upgrade cib. Returns cib which was verified by pacemaker version 'version' or later. Raises LibraryError on any failure. runner -- runner cib -- cib tree version -- required cib version fail_if_version_not_met -- allows a 'nice to have' cib upgrade """ version_pre_upgrade = get_pacemaker_version_by_which_cib_was_validated(cib) if version_pre_upgrade >= version: return cib, False _upgrade_cib(runner) new_cib_xml = get_cib_xml(runner) try: new_cib = parse_cib_xml(new_cib_xml) except (etree.XMLSyntaxError, etree.DocumentInvalid) as e: raise LibraryError( ReportItem.error(reports.messages.CibUpgradeFailed(str(e))) ) from e version_post_upgrade = get_pacemaker_version_by_which_cib_was_validated( new_cib ) if version_post_upgrade >= version or not fail_if_version_not_met: return new_cib, version_post_upgrade > version_pre_upgrade raise LibraryError( ReportItem.error( reports.messages.CibUpgradeFailedToMinimalRequiredVersion( str(version_post_upgrade), str(version) ) ) )
def test_with_revision(self): self.assertEqual( (1, 2, 3), lib.get_pacemaker_version_by_which_cib_was_validated( etree.XML('<cib validate-with="pacemaker-1.2.3"/>') ) )
def test_with_revision(self): self.assertEqual( Version(1, 2, 3), lib.get_pacemaker_version_by_which_cib_was_validated( etree.XML('<cib validate-with="pacemaker-1.2.3"/>') ) )
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_invalid_version_at_end(self): assert_raise_library_error( lambda: lib.get_pacemaker_version_by_which_cib_was_validated( etree.XML('<cib validate-with="pacemaker-1.2.3x"/>')), (severities.ERROR, report_codes.CIB_LOAD_ERROR_BAD_FORMAT, { "reason": "the attribute 'validate-with' of the element" " 'cib' has an invalid value: 'pacemaker-1.2.3x'" }))
def test_missing_attribute(self): assert_raise_library_error( lambda: lib.get_pacemaker_version_by_which_cib_was_validated( etree.XML("<cib/>")), (severities.ERROR, report_codes.CIB_LOAD_ERROR_BAD_FORMAT, { "reason": "the attribute 'validate-with' of the element" " 'cib' is missing" }))
def test_invalid_version(self): assert_raise_library_error( lambda: lib.get_pacemaker_version_by_which_cib_was_validated( etree.XML('<cib validate-with="something-1.2.3"/>') ), ( severities.ERROR, report_codes.CIB_LOAD_ERROR_BAD_FORMAT, {} ) )
def test_missing_attribute(self): assert_raise_library_error( lambda: lib.get_pacemaker_version_by_which_cib_was_validated( etree.XML("<cib/>") ), ( severities.ERROR, report_codes.CIB_LOAD_ERROR_BAD_FORMAT, {} ) )
def test_invalid_version_at_end(self): assert_raise_library_error( lambda: lib.get_pacemaker_version_by_which_cib_was_validated( etree.XML('<cib validate-with="pacemaker-1.2.3x"/>') ), ( severities.ERROR, report_codes.CIB_LOAD_ERROR_BAD_FORMAT, { "reason": "the attribute 'validate-with' of the element" " 'cib' has an invalid value: 'pacemaker-1.2.3x'" } ) )
def test_missing_attribute(self): assert_raise_library_error( lambda: lib.get_pacemaker_version_by_which_cib_was_validated( etree.XML("<cib/>") ), ( severities.ERROR, report_codes.CIB_LOAD_ERROR_BAD_FORMAT, { "reason": "the attribute 'validate-with' of the element" " 'cib' is missing" } ) )
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, get_pacemaker_version_by_which_cib_was_validated(cib), 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()