Ejemplo n.º 1
0
def location_show(lib, argv, modifiers):
    """
    Options:
      * --all - print expired constraints
      * --full - print all details
      * -f - CIB file
    """
    del lib
    modifiers.ensure_only_supported("-f", "--full", "--all")
    by_node = False

    if argv and argv[0] == "nodes":
        by_node = True

    if len(argv) > 1:
        if by_node:
            valid_noderes = argv[1:]
        else:
            valid_noderes = [
                parse_args.parse_typed_arg(
                    arg, [RESOURCE_TYPE_RESOURCE, RESOURCE_TYPE_REGEXP],
                    RESOURCE_TYPE_RESOURCE) for arg in argv[1:]
            ]
    else:
        valid_noderes = []

    (dummy_dom, constraintsElement) = getCurrentConstraints()
    print("\n".join(
        location_lines(
            constraintsElement,
            showDetail=modifiers.get("--full"),
            byNode=by_node,
            valid_noderes=valid_noderes,
            show_expired=modifiers.get("--all"),
        )))
Ejemplo n.º 2
0
def stonith_level_parse_node(arg):
    target_type_candidate, target_value_candidate = parse_args.parse_typed_arg(
        arg, target_type_map_cli_to_lib.keys(), "node")
    target_type = target_type_map_cli_to_lib[target_type_candidate]
    if target_type == TARGET_TYPE_ATTRIBUTE:
        target_value = parse_args.split_option(target_value_candidate)
    else:
        target_value = target_value_candidate
    return target_type, target_value
Ejemplo n.º 3
0
def stonith_level_parse_node(arg):
    target_type_candidate, target_value_candidate = parse_args.parse_typed_arg(
        arg,
        target_type_map_cli_to_lib.keys(),
        "node"
    )
    target_type = target_type_map_cli_to_lib[target_type_candidate]
    if target_type == TARGET_TYPE_ATTRIBUTE:
        target_value = parse_args.split_option(target_value_candidate)
    else:
        target_value = target_value_candidate
    return target_type, target_value
Ejemplo n.º 4
0
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"))
Ejemplo n.º 5
0
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
        ])
Ejemplo n.º 6
0
 def assert_parse(self, arg, parsed):
     self.assertEqual(parse_typed_arg(arg, ["t0", "t1", "t2"], "t0"),
                      parsed)
Ejemplo n.º 7
0
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)
Ejemplo n.º 8
0
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)
Ejemplo n.º 9
0
 def assert_parse(self, arg, parsed):
     self.assertEqual(
         parse_typed_arg(arg, ["t0", "t1", "t2"], "t0"),
         parsed
     )
Ejemplo n.º 10
0
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)
Ejemplo n.º 11
0
def location_show(argv):
    if (len(argv) != 0 and argv[0] == "nodes"):
        byNode = True
        showDetail = False
    elif "--full" in utils.pcs_options:
        byNode = False
        showDetail = True
    else:
        byNode = False
        showDetail = False

    if len(argv) > 1:
        if byNode:
            valid_noderes = argv[1:]
        else:
            valid_noderes = [
                parse_args.parse_typed_arg(
                    arg, [RESOURCE_TYPE_RESOURCE, RESOURCE_TYPE_REGEXP],
                    RESOURCE_TYPE_RESOURCE) for arg in argv[1:]
            ]
    else:
        valid_noderes = []

    (dummy_dom, constraintsElement) = getCurrentConstraints()
    nodehashon = {}
    nodehashoff = {}
    rschashon = {}
    rschashoff = {}
    ruleshash = defaultdict(list)
    all_loc_constraints = constraintsElement.getElementsByTagName(
        'rsc_location')

    print("Location Constraints:")
    for rsc_loc in all_loc_constraints:
        if rsc_loc.hasAttribute("rsc-pattern"):
            lc_rsc_type = RESOURCE_TYPE_REGEXP
            lc_rsc_value = rsc_loc.getAttribute("rsc-pattern")
            lc_name = "Resource pattern: {0}".format(lc_rsc_value)
        else:
            lc_rsc_type = RESOURCE_TYPE_RESOURCE
            lc_rsc_value = rsc_loc.getAttribute("rsc")
            lc_name = "Resource: {0}".format(lc_rsc_value)
        lc_rsc = lc_rsc_type, lc_rsc_value, lc_name
        lc_id = rsc_loc.getAttribute("id")
        lc_node = rsc_loc.getAttribute("node")
        lc_score = rsc_loc.getAttribute("score")
        lc_role = rsc_loc.getAttribute("role")
        lc_resource_discovery = rsc_loc.getAttribute("resource-discovery")

        for child in rsc_loc.childNodes:
            if child.nodeType == child.ELEMENT_NODE and child.tagName == "rule":
                ruleshash[lc_rsc].append(child)


# NEED TO FIX FOR GROUP LOCATION CONSTRAINTS (where there are children of
# rsc_location)
        if lc_score == "":
            lc_score = "0"

        if lc_score == "INFINITY":
            positive = True
        elif lc_score == "-INFINITY":
            positive = False
        elif int(lc_score) >= 0:
            positive = True
        else:
            positive = False

        if positive == True:
            nodeshash = nodehashon
            rschash = rschashon
        else:
            nodeshash = nodehashoff
            rschash = rschashoff

        hash_element = {
            "id": lc_id,
            "rsc_type": lc_rsc_type,
            "rsc_value": lc_rsc_value,
            "rsc_label": lc_name,
            "node": lc_node,
            "score": lc_score,
            "role": lc_role,
            "resource-discovery": lc_resource_discovery,
        }
        if lc_node in nodeshash:
            nodeshash[lc_node].append(hash_element)
        else:
            nodeshash[lc_node] = [hash_element]
        if lc_rsc in rschash:
            rschash[lc_rsc].append(hash_element)
        else:
            rschash[lc_rsc] = [hash_element]

    nodelist = sorted(set(list(nodehashon.keys()) + list(nodehashoff.keys())))
    rsclist = sorted(set(list(rschashon.keys()) + list(rschashoff.keys())),
                     key=lambda item: ({
                         RESOURCE_TYPE_RESOURCE: 1,
                         RESOURCE_TYPE_REGEXP: 0,
                     }[item[0]], item[1]))

    if byNode == True:
        for node in nodelist:
            if len(valid_noderes) != 0:
                if node not in valid_noderes:
                    continue
            print("  Node: " + node)

            nodehash_label = ((nodehashon, "    Allowed to run:"),
                              (nodehashoff, "    Not allowed to run:"))
            for nodehash, label in nodehash_label:
                if node in nodehash:
                    print(label)
                    for options in nodehash[node]:
                        line_parts = [("      " + options["rsc_label"] + " (" +
                                       options["id"] + ")")]
                        if options["role"]:
                            line_parts.append("(role: {0})".format(
                                options["role"]))
                        if options["resource-discovery"]:
                            line_parts.append(
                                "(resource-discovery={0})".format(
                                    options["resource-discovery"]))
                        line_parts.append("Score: " + options["score"])
                        print(" ".join(line_parts))
        show_location_rules(ruleshash, showDetail)
    else:
        for rsc in rsclist:
            if len(valid_noderes) != 0:
                if rsc[0:2] not in valid_noderes:
                    continue
            print("  {0}".format(rsc[2]))
            rschash_label = (
                (rschashon, "    Enabled on:"),
                (rschashoff, "    Disabled on:"),
            )
            for rschash, label in rschash_label:
                if rsc in rschash:
                    for options in rschash[rsc]:
                        if not options["node"]:
                            continue
                        line_parts = [
                            label,
                            options["node"],
                            "(score:{0})".format(options["score"]),
                        ]
                        if options["role"]:
                            line_parts.append("(role: {0})".format(
                                options["role"]))
                        if options["resource-discovery"]:
                            line_parts.append(
                                "(resource-discovery={0})".format(
                                    options["resource-discovery"]))
                        if showDetail:
                            line_parts.append("(id:{0})".format(options["id"]))
                        print(" ".join(line_parts))
            miniruleshash = {}
            miniruleshash[rsc] = ruleshash[rsc]
            show_location_rules(miniruleshash, showDetail, True)
Ejemplo n.º 12
0
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)
Ejemplo n.º 13
0
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)
Ejemplo n.º 14
0
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)
Ejemplo n.º 15
0
def location_show(argv):
    if (len(argv) != 0 and argv[0] == "nodes"):
        byNode = True
        showDetail = False
    elif "--full" in utils.pcs_options:
        byNode = False
        showDetail = True
    else:
        byNode = False
        showDetail = False

    if len(argv) > 1:
        if byNode:
            valid_noderes = argv[1:]
        else:
            valid_noderes = [
                parse_args.parse_typed_arg(
                    arg,
                    [RESOURCE_TYPE_RESOURCE, RESOURCE_TYPE_REGEXP],
                    RESOURCE_TYPE_RESOURCE
                )
                for arg in argv[1:]
            ]
    else:
        valid_noderes = []

    (dummy_dom,constraintsElement) = getCurrentConstraints()
    nodehashon = {}
    nodehashoff = {}
    rschashon = {}
    rschashoff = {}
    ruleshash = defaultdict(list)
    all_loc_constraints = constraintsElement.getElementsByTagName('rsc_location')

    print("Location Constraints:")
    for rsc_loc in all_loc_constraints:
        if rsc_loc.hasAttribute("rsc-pattern"):
            lc_rsc_type = RESOURCE_TYPE_REGEXP
            lc_rsc_value = rsc_loc.getAttribute("rsc-pattern")
            lc_name = "Resource pattern: {0}".format(lc_rsc_value)
        else:
            lc_rsc_type = RESOURCE_TYPE_RESOURCE
            lc_rsc_value = rsc_loc.getAttribute("rsc")
            lc_name = "Resource: {0}".format(lc_rsc_value)
        lc_rsc = lc_rsc_type, lc_rsc_value, lc_name
        lc_id = rsc_loc.getAttribute("id")
        lc_node = rsc_loc.getAttribute("node")
        lc_score = rsc_loc.getAttribute("score")
        lc_role = rsc_loc.getAttribute("role")
        lc_resource_discovery = rsc_loc.getAttribute("resource-discovery")

        for child in rsc_loc.childNodes:
            if child.nodeType == child.ELEMENT_NODE and child.tagName == "rule":
                ruleshash[lc_rsc].append(child)

# NEED TO FIX FOR GROUP LOCATION CONSTRAINTS (where there are children of
# rsc_location)
        if lc_score == "":
            lc_score = "0"

        if lc_score == "INFINITY":
            positive = True
        elif lc_score == "-INFINITY":
            positive = False
        elif int(lc_score) >= 0:
            positive = True
        else:
            positive = False

        if positive == True:
            nodeshash = nodehashon
            rschash = rschashon
        else:
            nodeshash = nodehashoff
            rschash = rschashoff

        hash_element = {
            "id": lc_id,
            "rsc_type": lc_rsc_type,
            "rsc_value": lc_rsc_value,
            "rsc_label": lc_name,
            "node": lc_node,
            "score": lc_score,
            "role": lc_role,
            "resource-discovery": lc_resource_discovery,
        }
        if lc_node in nodeshash:
            nodeshash[lc_node].append(hash_element)
        else:
            nodeshash[lc_node] = [hash_element]
        if lc_rsc in rschash:
            rschash[lc_rsc].append(hash_element)
        else:
            rschash[lc_rsc] = [hash_element]

    nodelist = sorted(set(list(nodehashon.keys()) + list(nodehashoff.keys())))
    rsclist = sorted(
        set(list(rschashon.keys()) + list(rschashoff.keys())),
        key=lambda item: (
            {
                RESOURCE_TYPE_RESOURCE: 1,
                RESOURCE_TYPE_REGEXP: 0,
            }[item[0]],
            item[1]
        )
    )

    if byNode == True:
        for node in nodelist:
            if len(valid_noderes) != 0:
                if node not in valid_noderes:
                    continue
            print("  Node: " + node)

            nodehash_label = (
                (nodehashon, "    Allowed to run:"),
                (nodehashoff, "    Not allowed to run:")
            )
            for nodehash, label in nodehash_label:
                if node in nodehash:
                    print(label)
                    for options in nodehash[node]:
                        line_parts = [(
                            "      " + options["rsc_label"]
                            + " (" + options["id"] + ")"
                        )]
                        if options["role"]:
                            line_parts.append(
                                "(role: {0})".format(options["role"])
                            )
                        if options["resource-discovery"]:
                            line_parts.append(
                                "(resource-discovery={0})".format(
                                    options["resource-discovery"]
                                )
                            )
                        line_parts.append("Score: " + options["score"])
                        print(" ".join(line_parts))
        show_location_rules(ruleshash, showDetail)
    else:
        for rsc in rsclist:
            if len(valid_noderes) != 0:
                if rsc[0:2] not in valid_noderes:
                    continue
            print("  {0}".format(rsc[2]))
            rschash_label = (
                (rschashon, "    Enabled on:"),
                (rschashoff, "    Disabled on:"),
            )
            for rschash, label in rschash_label:
                if rsc in rschash:
                    for options in rschash[rsc]:
                        if not options["node"]:
                            continue
                        line_parts = [
                            label,
                            options["node"],
                            "(score:{0})".format(options["score"]),
                        ]
                        if options["role"]:
                            line_parts.append(
                                "(role: {0})".format(options["role"])
                            )
                        if options["resource-discovery"]:
                            line_parts.append(
                                "(resource-discovery={0})".format(
                                    options["resource-discovery"]
                                )
                            )
                        if showDetail:
                            line_parts.append("(id:{0})".format(options["id"]))
                        print(" ".join(line_parts))
            miniruleshash={}
            miniruleshash[rsc] = ruleshash[rsc]
            show_location_rules(miniruleshash, showDetail, True)