def test_invalid_id(self): self.assertEqual("", lib.sanitize_id("0")) self.assertEqual("", lib.sanitize_id("-")) self.assertEqual("", lib.sanitize_id(".")) self.assertEqual("", lib.sanitize_id(":", "_")) self.assertEqual("dummy", lib.sanitize_id("0dummy")) self.assertEqual("dummy", lib.sanitize_id("-dummy")) self.assertEqual("dummy", lib.sanitize_id(".dummy")) self.assertEqual("dummy", lib.sanitize_id(":dummy", "_")) self.assertEqual("dummy", lib.sanitize_id("dum:my")) self.assertEqual("dum_my", lib.sanitize_id("dum:my", "_"))
def create_subelement_id( context_element: _Element, suffix: str, id_provider: IdProvider ) -> str: proposed_id = sanitize_id( "{0}-{1}".format(context_element.get("id", context_element.tag), suffix) ) return id_provider.allocate_id(proposed_id)
def test_dont_change_valid_id(self): self.assertEqual("d", lib.sanitize_id("d")) self.assertEqual("dummy", lib.sanitize_id("dummy")) self.assertEqual("dum0my", lib.sanitize_id("dum0my")) self.assertEqual("dum-my", lib.sanitize_id("dum-my")) self.assertEqual("dum.my", lib.sanitize_id("dum.my")) self.assertEqual("dum_my", lib.sanitize_id("dum_my")) self.assertEqual("_dummy", lib.sanitize_id("_dummy"))
def _append_port_map(parent_element, id_provider, id_base, port_map_options): if "id" not in port_map_options: id_suffix = None if "port" in port_map_options: id_suffix = port_map_options["port"] elif "range" in port_map_options: id_suffix = port_map_options["range"] if id_suffix: port_map_options["id"] = id_provider.allocate_id( sanitize_id("{0}-port-map-{1}".format(id_base, id_suffix))) port_map_element = etree.SubElement(parent_element, "port-mapping") # Do not add options with empty values. When updating, an empty value means # remove the option. update_attributes_remove_empty(port_map_element, port_map_options) return port_map_element
def location_prefer(lib, argv, modifiers): """ Options: * --force - allow unknown options, allow constraint for any resource type * -f - CIB file """ modifiers.ensure_only_supported("--force", "-f") rsc = argv.pop(0) prefer_option = argv.pop(0) dummy_rsc_type, rsc_value = parse_args.parse_typed_arg( rsc, [RESOURCE_TYPE_RESOURCE, RESOURCE_TYPE_REGEXP], RESOURCE_TYPE_RESOURCE) if prefer_option == "prefers": prefer = True elif prefer_option == "avoids": prefer = False else: raise CmdLineInputError() for nodeconf in argv: nodeconf_a = nodeconf.split("=", 1) if len(nodeconf_a) == 1: node = nodeconf_a[0] if prefer: score = "INFINITY" else: score = "-INFINITY" else: score = nodeconf_a[1] if not utils.is_score(score): utils.err( "invalid score '%s', use integer or INFINITY or -INFINITY" % score) if not prefer: if score[0] == "-": score = score[1:] else: score = "-" + score node = nodeconf_a[0] location_add(lib, [ sanitize_id("location-{0}-{1}-{2}".format(rsc_value, node, score)), rsc, node, score ], modifiers.get_subset("--force", "-f"))
def _append_level_element(tree, level, target_type, target_value, devices): level_el = etree.SubElement(tree, "fencing-level", index=str(level), devices=",".join(devices)) if target_type == TARGET_TYPE_NODE: level_el.set("target", target_value) id_part = target_value elif target_type == TARGET_TYPE_REGEXP: level_el.set("target-pattern", target_value) id_part = target_value elif target_type == TARGET_TYPE_ATTRIBUTE: level_el.set("target-attribute", target_value[0]) level_el.set("target-value", target_value[1]) id_part = target_value[0] level_el.set( "id", find_unique_id(tree, sanitize_id("fl-{0}-{1}".format(id_part, level)))) return level_el
def location_prefer(argv): rsc = argv.pop(0) prefer_option = argv.pop(0) dummy_rsc_type, rsc_value = parse_args.parse_typed_arg( rsc, [RESOURCE_TYPE_RESOURCE, RESOURCE_TYPE_REGEXP], RESOURCE_TYPE_RESOURCE ) if prefer_option == "prefers": prefer = True elif prefer_option == "avoids": prefer = False else: usage.constraint() sys.exit(1) for nodeconf in argv: nodeconf_a = nodeconf.split("=",1) if len(nodeconf_a) == 1: node = nodeconf_a[0] if prefer: score = "INFINITY" else: score = "-INFINITY" else: score = nodeconf_a[1] if not utils.is_score(score): utils.err("invalid score '%s', use integer or INFINITY or -INFINITY" % score) if not prefer: if score[0] == "-": score = score[1:] else: score = "-" + score node = nodeconf_a[0] location_add([ sanitize_id("location-{0}-{1}-{2}".format(rsc_value, node, score)), rsc, node, score ])
def _append_level_element(tree, level, target_type, target_value, devices): level_el = etree.SubElement( tree, "fencing-level", index=str(level), devices=",".join(devices) ) if target_type == TARGET_TYPE_NODE: level_el.set("target", target_value) id_part = target_value elif target_type == TARGET_TYPE_REGEXP: level_el.set("target-pattern", target_value) id_part = target_value elif target_type == TARGET_TYPE_ATTRIBUTE: level_el.set("target-attribute", target_value[0]) level_el.set("target-value", target_value[1]) id_part = target_value[0] level_el.set( "id", find_unique_id(tree, sanitize_id("fl-{0}-{1}".format(id_part, level))) ) return level_el
def test_empty(self): self.assertEqual("", lib.sanitize_id(""))
def create_subelement_id(context_element, suffix, id_provider=None): proposed_id = sanitize_id("{0}-{1}".format(context_element.get("id"), suffix)) if id_provider: return id_provider.allocate_id(proposed_id) return find_unique_id(context_element, proposed_id)
def create_subelement_id(context_element, suffix, id_provider): proposed_id = sanitize_id("{0}-{1}".format(context_element.get("id"), suffix)) return id_provider.allocate_id(proposed_id)
def location_rule(lib, argv, modifiers): """ Options: * -f - CIB file * --force - allow constraint on any resource type, allow duplicate constraints """ del lib modifiers.ensure_only_supported("-f", "--force") if len(argv) < 3: usage.constraint(["location", "rule"]) sys.exit(1) rsc_type, rsc_value = parse_args.parse_typed_arg( argv.pop(0), [RESOURCE_TYPE_RESOURCE, RESOURCE_TYPE_REGEXP], RESOURCE_TYPE_RESOURCE) argv.pop(0) # pop "rule" options, rule_argv = rule_utils.parse_argv(argv, { "constraint-id": None, "resource-discovery": None, }) resource_discovery = ("resource-discovery" in options and options["resource-discovery"]) required_version = None if resource_discovery: required_version = 2, 2, 0 if rsc_type == RESOURCE_TYPE_REGEXP: required_version = 2, 6, 0 if required_version: dom = utils.cluster_upgrade_to_version(required_version) else: dom = utils.get_cib_dom() if rsc_type == RESOURCE_TYPE_RESOURCE: rsc_valid, rsc_error, dummy_correct_id = ( utils.validate_constraint_resource(dom, rsc_value)) if not rsc_valid: utils.err(rsc_error) cib, constraints = getCurrentConstraints(dom) lc = cib.createElement("rsc_location") # If resource-discovery is specified, we use it with the rsc_location # element not the rule if resource_discovery: lc.setAttribute("resource-discovery", options.pop("resource-discovery")) constraints.appendChild(lc) if options.get("constraint-id"): id_valid, id_error = utils.validate_xml_id(options["constraint-id"], 'constraint id') if not id_valid: utils.err(id_error) if utils.does_id_exist(dom, options["constraint-id"]): utils.err("id '%s' is already in use, please specify another one" % options["constraint-id"]) lc.setAttribute("id", options["constraint-id"]) del options["constraint-id"] else: lc.setAttribute( "id", utils.find_unique_id(dom, sanitize_id("location-" + rsc_value))) if rsc_type == RESOURCE_TYPE_RESOURCE: lc.setAttribute("rsc", rsc_value) elif rsc_type == RESOURCE_TYPE_REGEXP: lc.setAttribute("rsc-pattern", rsc_value) rule_utils.dom_rule_add(lc, options, rule_argv) location_rule_check_duplicates(constraints, lc, modifiers.get("--force")) utils.replace_cib_configuration(cib)
def location_rule(argv): if len(argv) < 3: usage.constraint(["location", "rule"]) sys.exit(1) rsc_type, rsc_value = parse_args.parse_typed_arg( argv.pop(0), [RESOURCE_TYPE_RESOURCE, RESOURCE_TYPE_REGEXP], RESOURCE_TYPE_RESOURCE ) argv.pop(0) # pop "rule" options, rule_argv = rule_utils.parse_argv( argv, { "constraint-id": None, "resource-discovery": None, } ) resource_discovery = ( "resource-discovery" in options and options["resource-discovery"] ) required_version = None if resource_discovery: required_version = 2, 2, 0 if rsc_type == RESOURCE_TYPE_REGEXP: required_version = 2, 6, 0 if required_version: dom = utils.cluster_upgrade_to_version(required_version) else: dom = utils.get_cib_dom() if rsc_type == RESOURCE_TYPE_RESOURCE: rsc_valid, rsc_error, correct_id = utils.validate_constraint_resource( dom, rsc_value ) if "--autocorrect" in utils.pcs_options and correct_id: rsc_value = correct_id elif not rsc_valid: utils.err(rsc_error) cib, constraints = getCurrentConstraints(dom) lc = cib.createElement("rsc_location") # If resource-discovery is specified, we use it with the rsc_location # element not the rule if resource_discovery: lc.setAttribute("resource-discovery", options.pop("resource-discovery")) constraints.appendChild(lc) if options.get("constraint-id"): id_valid, id_error = utils.validate_xml_id( options["constraint-id"], 'constraint id' ) if not id_valid: utils.err(id_error) if utils.does_id_exist(dom, options["constraint-id"]): utils.err( "id '%s' is already in use, please specify another one" % options["constraint-id"] ) lc.setAttribute("id", options["constraint-id"]) del options["constraint-id"] else: lc.setAttribute( "id", utils.find_unique_id(dom, sanitize_id("location-" + rsc_value)) ) if rsc_type == RESOURCE_TYPE_RESOURCE: lc.setAttribute("rsc", rsc_value) elif rsc_type == RESOURCE_TYPE_REGEXP: lc.setAttribute("rsc-pattern", rsc_value) rule_utils.dom_rule_add(lc, options, rule_argv) location_rule_check_duplicates(constraints, lc) utils.replace_cib_configuration(cib)
def location_prefer(lib, argv, modifiers): """ Options: * --force - allow unknown options, allow constraint for any resource type * -f - CIB file """ modifiers.ensure_only_supported("--force", "-f") rsc = argv.pop(0) prefer_option = argv.pop(0) dummy_rsc_type, rsc_value = parse_args.parse_typed_arg( rsc, [RESOURCE_TYPE_RESOURCE, RESOURCE_TYPE_REGEXP], RESOURCE_TYPE_RESOURCE) if prefer_option == "prefers": prefer = True elif prefer_option == "avoids": prefer = False else: raise CmdLineInputError() skip_node_check = False if modifiers.is_specified("-f") or modifiers.get("--force"): skip_node_check = True warn(LOCATION_NODE_VALIDATION_SKIP_MSG) else: lib_env = utils.get_lib_env() existing_nodes, report_list = get_existing_nodes_names( corosync_conf=lib_env.get_corosync_conf(), cib=lib_env.get_cib(), ) if report_list: process_library_reports(report_list) report_list = [] parameters_list = [] for nodeconf in argv: nodeconf_a = nodeconf.split("=", 1) node = nodeconf_a[0] if not skip_node_check: report_list += _verify_node_name(node, existing_nodes) if len(nodeconf_a) == 1: if prefer: score = "INFINITY" else: score = "-INFINITY" else: score = nodeconf_a[1] _verify_score(score) if not prefer: if score[0] == "-": score = score[1:] else: score = "-" + score parameters_list.append([ sanitize_id(f"location-{rsc_value}-{node}-{score}"), rsc, node, score ]) if report_list: process_library_reports(report_list) modifiers = modifiers.get_subset("--force", "-f") for parameters in parameters_list: location_add(lib, parameters, modifiers, skip_score_and_node_check=True)
def create_subelement_id(context_element, suffix, id_provider): proposed_id = sanitize_id( "{0}-{1}".format(context_element.get("id"), suffix) ) return id_provider.allocate_id(proposed_id)