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_add(lib, argv, modifiers): """ Options: * --force - allow unknown options, allow constraint for any resource type * -f - CIB file """ del lib modifiers.ensure_only_supported("--force", "-f") if len(argv) < 4: raise CmdLineInputError() constraint_id = argv.pop(0) rsc_type, rsc_value = parse_args.parse_typed_arg( argv.pop(0), [RESOURCE_TYPE_RESOURCE, RESOURCE_TYPE_REGEXP], RESOURCE_TYPE_RESOURCE) node = argv.pop(0) score = argv.pop(0) options = [] # For now we only allow setting resource-discovery if argv: for arg in argv: if '=' in arg: options.append(arg.split('=', 1)) else: raise CmdLineInputError(f"bad option '{arg}'") if (options[-1][0] != "resource-discovery" and not modifiers.get("--force")): utils.err("bad option '%s', use --force to override" % options[-1][0]) id_valid, id_error = utils.validate_xml_id(constraint_id, 'constraint id') if not id_valid: utils.err(id_error) if not utils.is_score(score): utils.err("invalid score '%s', use integer or INFINITY or -INFINITY" % score) required_version = None if [x for x in options if x[0] == "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) # Verify that specified node exists in the cluster if not (modifiers.is_specified("-f") or modifiers.get("--force")): lib_env = utils.get_lib_env() existing_nodes = get_existing_nodes_names( corosync_conf=lib_env.get_corosync_conf(), cib=lib_env.get_cib(), ) if node not in existing_nodes: raise error(f"Node '{node}' does not seem to be in the cluster" ", use --force to override") else: warn(LOCATION_NODE_VALIDATION_SKIP_MSG) # Verify current constraint doesn't already exist # If it does we replace it with the new constraint dummy_dom, constraintsElement = getCurrentConstraints(dom) elementsToRemove = [] # If the id matches, or the rsc & node match, then we replace/remove for rsc_loc in constraintsElement.getElementsByTagName('rsc_location'): # pylint: disable=too-many-boolean-expressions if (rsc_loc.getAttribute("id") == constraint_id or (rsc_loc.getAttribute("node") == node and ((RESOURCE_TYPE_RESOURCE == rsc_type and rsc_loc.getAttribute("rsc") == rsc_value) or (RESOURCE_TYPE_REGEXP == rsc_type and rsc_loc.getAttribute("rsc-pattern") == rsc_value)))): elementsToRemove.append(rsc_loc) for etr in elementsToRemove: constraintsElement.removeChild(etr) element = dom.createElement("rsc_location") element.setAttribute("id", constraint_id) if rsc_type == RESOURCE_TYPE_RESOURCE: element.setAttribute("rsc", rsc_value) elif rsc_type == RESOURCE_TYPE_REGEXP: element.setAttribute("rsc-pattern", rsc_value) element.setAttribute("node", node) element.setAttribute("score", score) for option in options: element.setAttribute(option[0], option[1]) constraintsElement.appendChild(element) utils.replace_cib_configuration(dom)
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_add(argv, rm=False): if rm: location_remove(argv) return if len(argv) < 4: usage.constraint(["location add"]) sys.exit(1) constraint_id = argv.pop(0) rsc_type, rsc_value = parse_args.parse_typed_arg( argv.pop(0), [RESOURCE_TYPE_RESOURCE, RESOURCE_TYPE_REGEXP], RESOURCE_TYPE_RESOURCE) node = argv.pop(0) score = argv.pop(0) options = [] # For now we only allow setting resource-discovery if len(argv) > 0: for arg in argv: if '=' in arg: options.append(arg.split('=', 1)) else: print("Error: bad option '%s'" % arg) usage.constraint(["location add"]) sys.exit(1) if options[-1][ 0] != "resource-discovery" and "--force" not in utils.pcs_options: utils.err("bad option '%s', use --force to override" % options[-1][0]) id_valid, id_error = utils.validate_xml_id(constraint_id, 'constraint id') if not id_valid: utils.err(id_error) if not utils.is_score(score): utils.err("invalid score '%s', use integer or INFINITY or -INFINITY" % score) required_version = None if [x for x in options if x[0] == "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) # Verify current constraint doesn't already exist # If it does we replace it with the new constraint dummy_dom, constraintsElement = getCurrentConstraints(dom) elementsToRemove = [] # If the id matches, or the rsc & node match, then we replace/remove for rsc_loc in constraintsElement.getElementsByTagName('rsc_location'): if (rsc_loc.getAttribute("id") == constraint_id or (rsc_loc.getAttribute("node") == node and ((RESOURCE_TYPE_RESOURCE == rsc_type and rsc_loc.getAttribute("rsc") == rsc_value) or (RESOURCE_TYPE_REGEXP == rsc_type and rsc_loc.getAttribute("rsc-pattern") == rsc_value)))): elementsToRemove.append(rsc_loc) for etr in elementsToRemove: constraintsElement.removeChild(etr) element = dom.createElement("rsc_location") element.setAttribute("id", constraint_id) if rsc_type == RESOURCE_TYPE_RESOURCE: element.setAttribute("rsc", rsc_value) elif rsc_type == RESOURCE_TYPE_REGEXP: element.setAttribute("rsc-pattern", rsc_value) element.setAttribute("node", node) element.setAttribute("score", score) for option in options: element.setAttribute(option[0], option[1]) constraintsElement.appendChild(element) utils.replace_cib_configuration(dom)
def location_add(argv,rm=False): if rm: location_remove(argv) return if len(argv) < 4: usage.constraint(["location add"]) sys.exit(1) constraint_id = argv.pop(0) rsc_type, rsc_value = parse_args.parse_typed_arg( argv.pop(0), [RESOURCE_TYPE_RESOURCE, RESOURCE_TYPE_REGEXP], RESOURCE_TYPE_RESOURCE ) node = argv.pop(0) score = argv.pop(0) options = [] # For now we only allow setting resource-discovery if len(argv) > 0: for arg in argv: if '=' in arg: options.append(arg.split('=',1)) else: print("Error: bad option '%s'" % arg) usage.constraint(["location add"]) sys.exit(1) if options[-1][0] != "resource-discovery" and "--force" not in utils.pcs_options: utils.err("bad option '%s', use --force to override" % options[-1][0]) id_valid, id_error = utils.validate_xml_id(constraint_id, 'constraint id') if not id_valid: utils.err(id_error) if not utils.is_score(score): utils.err("invalid score '%s', use integer or INFINITY or -INFINITY" % score) required_version = None 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) # Verify current constraint doesn't already exist # If it does we replace it with the new constraint dummy_dom, constraintsElement = getCurrentConstraints(dom) elementsToRemove = [] # If the id matches, or the rsc & node match, then we replace/remove for rsc_loc in constraintsElement.getElementsByTagName('rsc_location'): if ( rsc_loc.getAttribute("id") == constraint_id or ( rsc_loc.getAttribute("node") == node and ( ( RESOURCE_TYPE_RESOURCE == rsc_type and rsc_loc.getAttribute("rsc") == rsc_value ) or ( RESOURCE_TYPE_REGEXP == rsc_type and rsc_loc.getAttribute("rsc-pattern") == rsc_value ) ) ) ): elementsToRemove.append(rsc_loc) for etr in elementsToRemove: constraintsElement.removeChild(etr) element = dom.createElement("rsc_location") element.setAttribute("id",constraint_id) if rsc_type == RESOURCE_TYPE_RESOURCE: element.setAttribute("rsc", rsc_value) elif rsc_type == RESOURCE_TYPE_REGEXP: element.setAttribute("rsc-pattern", rsc_value) element.setAttribute("node",node) element.setAttribute("score",score) for option in options: element.setAttribute(option[0], option[1]) constraintsElement.appendChild(element) utils.replace_cib_configuration(dom)