Example #1
0
 def _export_node_attr(self, parent_el: _Element,
                       expr: NodeAttrExpr) -> _Element:
     element = etree.SubElement(
         parent_el,
         "expression",
         {
             "id": create_subelement_id(parent_el, "expr",
                                        self.id_provider),
             "attribute": expr.attr_name,
             "operation": expr.operator.lower(),
         },
     )
     if expr.attr_value:
         element.attrib["value"] = expr.attr_value
     if expr.attr_type:
         # rhbz#1869399
         # Pcs was always accepting 'integer', while CIB was only supporting
         # 'number' (and 'string' and 'version'). Pacemaker was documenting
         # it as 'integer' and was treating it as integer (not float). With
         # CIB schema 3.5.0, both 'integer' and 'number' are accepted by
         # CIB. For older schemas, we turn 'integer' to 'number'.
         if (self.cib_schema_version < Version(3, 5, 0)
                 and expr.attr_type == NODE_ATTR_TYPE_INTEGER):
             element.attrib["type"] = "number"
         else:
             element.attrib["type"] = expr.attr_type.lower()
     return element
Example #2
0
def append_new_nvset(
        tag_name, context_element, nvpair_dict, id_provider,
        enforce_append=False
    ):
    """
    Append new nvset_element comprising nvpairs children (corresponding
    nvpair_dict) to the context_element

    string tag_name should be "instance_attributes" or "meta_attributes"
    etree.Element context_element is element where new nvset will be appended
    dict nvpair_dict contains source for nvpair children
    IdProvider id_provider -- elements' ids generator
    bool enforce_append -- append element wo usefulness check if flag is True
    """
    nvset_element = etree.Element(
        tag_name,
        {
            "id": create_subelement_id(context_element, tag_name, id_provider)
        }
    )
    for name, value in sorted(nvpair_dict.items()):
        _append_new_nvpair(nvset_element, name, value, id_provider)
    if enforce_append:
        context_element.append(nvset_element)
    else:
        append_when_useful(context_element, nvset_element)
Example #3
0
 def _export_datespec(self, parent_el: _Element,
                      expr: DatespecExpr) -> _Element:
     element = etree.SubElement(
         parent_el,
         "date_expression",
         {
             "id": create_subelement_id(parent_el, "expr",
                                        self.id_provider),
             "operation": "date_spec",
         },
     )
     datespec_attrs = dict(expr.date_parts)
     datespec_attrs["id"] = create_subelement_id(element, "datespec",
                                                 self.id_provider)
     etree.SubElement(element, "date_spec", datespec_attrs)
     return element
Example #4
0
def arrange_first_nvset(
    tag_name, context_element, nvpair_dict, id_provider, new_id=None
):
    """
    Put nvpairs to the first tag_name nvset in the context_element.

    If the nvset does not exist, it will be created.

    WARNING: does not solve multiple nvsets (with the same tag_name) in the
    context_element! Consider carefully if this is your use case. Probably not.
    There could be more than one nvset.
    This function is DEPRECATED. Try to use update_nvset etc.

    string tag_name -- tag name of nvset element
    etree context_element -- parent element of nvset
    dict nvpair_dict -- dictionary of nvpairs
    IdProvider id_provider -- elements' ids generator
    """
    if not nvpair_dict:
        return

    nvset_element = get_sub_element(
        context_element,
        tag_name,
        new_id=(new_id if new_id else create_subelement_id(
            context_element, tag_name, id_provider
        )),
        append_if_missing=False
    )
    update_nvset(nvset_element, nvpair_dict, id_provider)
    append_when_useful(context_element, nvset_element, index=0)
Example #5
0
 def test_parent_has_no_id(self):
     context = etree.fromstring("<cib><a/></cib>")
     self.assertEqual(
         "a-name",
         lib.create_subelement_id(context.find(".//a"), "name",
                                  lib.IdProvider(context)),
     )
Example #6
0
 def test_create_decorated_id_when_conflicting_id_there(self):
     context = etree.fromstring('<cib><a id="b"><c id="b-name"/></a></cib>')
     self.assertEqual(
         "b-name-1",
         lib.create_subelement_id(context.find(".//a"), "name",
                                  lib.IdProvider(context)),
     )
Example #7
0
def arrange_first_nvset(
    tag_name, context_element, nvpair_dict, id_provider, new_id=None
):
    """
    Put nvpairs to the first tag_name nvset in the context_element.

    If the nvset does not exist, it will be created.

    WARNING: does not solve multiple nvsets (with the same tag_name) in the
    context_element! Consider carefully if this is your use case. Probably not.
    There could be more than one nvset.
    This function is DEPRECATED. Try to use update_nvset etc.

    string tag_name -- tag name of nvset element
    etree context_element -- parent element of nvset
    dict nvpair_dict -- dictionary of nvpairs
    IdProvider id_provider -- elements' ids generator
    """
    if not nvpair_dict:
        return

    nvset_element = get_sub_element(
        context_element,
        tag_name,
        new_id=(
            new_id
            if new_id
            else create_subelement_id(context_element, tag_name, id_provider)
        ),
        append_if_missing=False,
    )
    update_nvset(nvset_element, nvpair_dict, id_provider)
    append_when_useful(context_element, nvset_element, index=0)
Example #8
0
def arrange_first_nvset(tag_name, context_element, nvpair_dict):
    """
    Put nvpairs to the first tag_name nvset in the context_element.

    If the nvset does not exist, it will be created.

    WARNING: does not solve multiple nvsets (with the same tag_name) in the
    context_element! Consider carefully if this is your use case. Probably not.
    There could be more than one nvset.
    This function is DEPRECATED. Try to use update_nvset etc.

    string tag_name -- tag name of nvset element
    etree context_element -- parent element of nvset
    dict nvpair_dict -- dictionary of nvpairs
    """
    if not nvpair_dict:
        return

    nvset_element = get_sub_element(context_element,
                                    tag_name,
                                    create_subelement_id(
                                        context_element, tag_name),
                                    new_index=0)

    update_nvset(nvset_element, nvpair_dict)
Example #9
0
def arrange_first_nvset(tag_name, context_element, nvpair_dict):
    """
    Arrange to context_element contains some nvset (with tag_name) with nvpairs
    corresponing to nvpair_dict.

    WARNING: does not solve multiple nvset (with tag_name) under
    context_element! Consider carefully if this is your case. Probably not.
    There could be more than one nvset.
    This function is DEPRECATED. Try to use update_nvset etc.

    This method updates nvset specified by tag_name. If specified nvset
    doesn't exist it will be created. Returns updated nvset element or None if
    nvpair_dict is empty.

    tag_name -- tag name of nvset element
    context_element -- parent element of nvset
    nvpair_dict -- dictionary of nvpairs
    """
    if not nvpair_dict:
        return

    nvset_element = get_sub_element(
        context_element,
        tag_name,
        create_subelement_id(context_element, tag_name),
        new_index=0
    )

    update_nvset(nvset_element, nvpair_dict)
Example #10
0
def nvset_append_new(
    parent_element: _Element,
    id_provider: IdProvider,
    nvset_tag: NvsetTag,
    nvpair_dict: Mapping[str, str],
    nvset_options: Mapping[str, str],
    nvset_rule: Optional[RuleRoot] = None,
) -> _Element:
    """
    Create new nvset and append it to CIB

    parent_element -- the created nvset will be appended into this element
    id_provider -- elements' ids generator
    nvset_tag -- type and actual tag of the nvset
    nvpair_dict -- nvpairs to be put into the new nvset
    nvset_options -- additional attributes of the created nvset
    nvset_rule -- optional rule describing when the created nvset applies
    """
    nvset_options = dict(nvset_options)  # make a copy which we can modify
    if "id" not in nvset_options or not nvset_options["id"]:
        nvset_options["id"] = create_subelement_id(parent_element, nvset_tag,
                                                   id_provider)

    nvset_el = etree.SubElement(parent_element, nvset_tag)
    for name, value in nvset_options.items():
        if value != "":
            nvset_el.attrib[name] = value
    if nvset_rule:
        rule_to_cib(nvset_el, id_provider, nvset_rule)
    for name, value in nvpair_dict.items():
        _set_nvpair(nvset_el, id_provider, name, value)
    return nvset_el
Example #11
0
def arrange_first_nvset(tag_name, context_element, attribute_dict):
    """
    Arrange to context_element contains some nvset (with tag_name) with nvpairs
    corresponing to attribute_dict.

    WARNING: does not solve multiple nvset (with tag_name) under
    context_element! Consider carefully if this is your case. Probably not.
    There could be more than one nvset.
    This function is DEPRECATED. Try to use update_nvset etc.

    This method updates nvset specified by tag_name. If specified nvset
    doesn't exist it will be created. Returns updated nvset element or None if
    attribute_dict is empty.

    tag_name -- tag name of nvset element
    context_element -- parent element of nvset
    attribute_dict -- dictionary of nvpairs
    """
    if not attribute_dict:
        return

    nvset_element = get_sub_element(
        context_element,
        tag_name,
        create_subelement_id(context_element, tag_name),
        new_index=0
    )

    update_nvset(nvset_element, attribute_dict)
Example #12
0
def append_new_nvset(tag_name,
                     context_element,
                     nvpair_dict,
                     id_provider,
                     enforce_append=False):
    """
    Append new nvset_element comprising nvpairs children (corresponding
    nvpair_dict) to the context_element

    string tag_name should be "instance_attributes" or "meta_attributes"
    etree.Element context_element is element where new nvset will be appended
    dict nvpair_dict contains source for nvpair children
    IdProvider id_provider -- elements' ids generator
    bool enforce_append -- append element wo usefulness check if flag is True
    """
    nvset_element = etree.Element(
        tag_name,
        {"id": create_subelement_id(context_element, tag_name, id_provider)},
    )
    for name, value in sorted(nvpair_dict.items()):
        _append_new_nvpair(nvset_element, name, value, id_provider)
    if enforce_append:
        context_element.append(nvset_element)
    else:
        append_when_useful(context_element, nvset_element)
Example #13
0
 def test_create_plain_id_when_no_confilicting_id_there(self):
     context = etree.fromstring('<cib><a id="b"/></cib>')
     self.assertEqual(
         "b-name",
         lib.create_subelement_id(
             context.find(".//a"), "name", lib.IdProvider(context)
         )
     )
Example #14
0
 def test_create_plain_id_when_no_confilicting_id_there(self):
     context = etree.fromstring('<cib><a id="b"/></cib>')
     self.assertEqual(
         "b-name",
         lib.create_subelement_id(
             context.find(".//a"), "name", lib.IdProvider(context)
         )
     )
Example #15
0
 def test_create_decorated_id_when_conflicting_id_there(self):
     context = etree.fromstring(
         '<cib><a id="b"><c id="b-name"/></a></cib>'
     )
     self.assertEqual(
         "b-name-1",
         lib.create_subelement_id(context.find(".//a"), "name")
     )
Example #16
0
def create_id(context_element, name, interval):
    """
    Create id for op element.
    etree context_element is used for the name building
    string name is the name of the operation
    mixed interval is the interval attribute of operation
    """
    return create_subelement_id(context_element,
                                "{0}-interval-{1}".format(name, interval))
Example #17
0
def create_id(context_element, name, interval):
    """
    Create id for op element.
    etree context_element is used for the name building
    string name is the name of the operation
    mixed interval is the interval attribute of operation
    """
    return create_subelement_id(
        context_element,
        "{0}-interval-{1}".format(name, interval)
    )
Example #18
0
 def _export_date_inrange(self, parent_el: _Element,
                          expr: DateInRangeExpr) -> _Element:
     element = etree.SubElement(
         parent_el,
         "date_expression",
         {
             "id": create_subelement_id(parent_el, "expr",
                                        self.id_provider),
             "operation": "in_range",
         },
     )
     if expr.date_start:
         element.attrib["start"] = expr.date_start
     if expr.duration_parts:
         duration_attrs = dict(expr.duration_parts)
         duration_attrs["id"] = create_subelement_id(
             element, "duration", self.id_provider)
         etree.SubElement(element, "duration", duration_attrs)
     elif expr.date_end:
         element.attrib["end"] = expr.date_end
     return element
Example #19
0
def __export_bool(parent_el: _Element, boolean: BoolExpr,
                  id_provider: IdProvider) -> _Element:
    element = etree.SubElement(
        parent_el,
        "rule",
        {
            "id": create_subelement_id(parent_el, "rule", id_provider),
            "boolean-op": boolean.operator.lower(),
        },
    )
    for child in boolean.children:
        __export_part(element, child, id_provider)
    return element
Example #20
0
def _append_new_nvpair(nvset_element, name, value):
    """
    Create nvpair with name and value as subelement of nvset_element.

    etree.Element nvset_element is context of new nvpair
    string name is name attribute of new nvpair
    string value is value attribute of new nvpair
    """
    etree.SubElement(nvset_element,
                     "nvpair",
                     id=create_subelement_id(nvset_element, name),
                     name=name,
                     value=value)
Example #21
0
def __export_op(parent_el: _Element, op: OpExpr,
                id_provider: IdProvider) -> _Element:
    element = etree.SubElement(
        parent_el,
        "op_expression",
        {
            "id": create_subelement_id(parent_el, f"op-{op.name}",
                                       id_provider),
            "name": op.name,
        },
    )
    if op.interval:
        element.attrib["interval"] = op.interval
    return element
Example #22
0
def append_new_nvset(tag_name, context_element, nvpair_dict):
    """
    Append new nvset_element comprising nvpairs children (corresponding
    nvpair_dict) to the context_element

    string tag_name should be "instance_attributes" or "meta_attributes"
    etree.Element context_element is element where new nvset will be appended
    dict nvpair_dict contains source for nvpair children
    """
    nvset_element = etree.SubElement(context_element, tag_name, {
        "id": create_subelement_id(context_element, tag_name)
    })
    for name, value in sorted(nvpair_dict.items()):
        _append_new_nvpair(nvset_element, name, value)
Example #23
0
def _append_new_nvpair(nvset_element, name, value, id_provider=None):
    """
    Create nvpair with name and value as subelement of nvset_element.

    etree.Element nvset_element is context of new nvpair
    string name is name attribute of new nvpair
    string value is value attribute of new nvpair
    IdProvider id_provider -- elements' ids generator
    """
    etree.SubElement(nvset_element,
                     "nvpair",
                     id=create_subelement_id(nvset_element, name, id_provider),
                     name=name,
                     value=value)
Example #24
0
def append_new_nvset(tag_name, context_element, nvpair_dict):
    """
    Append new nvset_element comprising nvpairs children (corresponding
    nvpair_dict) to the context_element

    string tag_name should be "instance_attributes" or "meta_attributes"
    etree.Element context_element is element where new nvset will be appended
    dict nvpair_dict contains source for nvpair children
    """
    nvset_element = etree.SubElement(
        context_element, tag_name,
        {"id": create_subelement_id(context_element, tag_name)})
    for name, value in sorted(nvpair_dict.items()):
        _append_new_nvpair(nvset_element, name, value)
Example #25
0
def __export_rsc(parent_el: _Element, rsc: RscExpr,
                 id_provider: IdProvider) -> _Element:
    id_part = "-".join(filter(None, [rsc.standard, rsc.provider, rsc.type]))
    element = etree.SubElement(
        parent_el,
        "rsc_expression",
        {"id": create_subelement_id(parent_el, f"rsc-{id_part}", id_provider)},
    )
    if rsc.standard:
        element.attrib["class"] = rsc.standard
    if rsc.provider:
        element.attrib["provider"] = rsc.provider
    if rsc.type:
        element.attrib["type"] = rsc.type
    return element
Example #26
0
def _append_new_nvpair(nvset_element, name, value):
    """
    Create nvpair with name and value as subelement of nvset_element.

    etree.Element nvset_element is context of new nvpair
    string name is name attribute of new nvpair
    string value is value attribute of new nvpair
    """
    etree.SubElement(
        nvset_element,
        "nvpair",
        id=create_subelement_id(nvset_element, name),
        name=name,
        value=value
    )
Example #27
0
def _append_new_nvpair(nvset_element, name, value, id_provider):
    """
    Create nvpair with name and value as subelement of nvset_element.

    etree.Element nvset_element is context of new nvpair
    string name is name attribute of new nvpair
    string value is value attribute of new nvpair
    IdProvider id_provider -- elements' ids generator
    """
    etree.SubElement(
        nvset_element,
        "nvpair",
        id=create_subelement_id(nvset_element, name, id_provider),
        name=name,
        value=value
    )
Example #28
0
 def _export_date_unary(self, parent_el: _Element,
                        expr: DateUnaryExpr) -> _Element:
     element = etree.SubElement(
         parent_el,
         "date_expression",
         {
             "id": create_subelement_id(parent_el, "expr",
                                        self.id_provider),
             "operation": expr.operator.lower(),
         },
     )
     if expr.operator == DATE_OP_GT:
         element.attrib["start"] = expr.date
     elif expr.operator == DATE_OP_LT:
         element.attrib["end"] = expr.date
     return element
Example #29
0
def _set_nvpair(nvset_element: Element, id_provider: IdProvider, name: str,
                value: str) -> None:
    """
    Ensure name-value pair is set / removed in specified nvset

    nvset_element -- container for nvpair elements to update
    id_provider -- elements' ids generator
    name -- name of the nvpair to be set
    value -- value of the nvpair to be set, if "" the nvpair will be removed
    """
    nvpair_el_list = cast(
        # The xpath method has a complicated return value, but we know our xpath
        # expression returns only elements.
        List[Element],
        cast(_Element, nvset_element).xpath("./nvpair[@name=$name]",
                                            name=name),
    )

    if not nvpair_el_list:
        if value != "":
            etree.SubElement(
                cast(_Element, nvset_element),
                "nvpair",
                {
                    "id":
                    create_subelement_id(
                        nvset_element,
                        # limit id length to prevent excessively long ids
                        name[:20],
                        id_provider,
                    ),
                    "name":
                    name,
                    "value":
                    value,
                },
            )
        return

    if value != "":
        nvpair_el_list[0].set("value", value)
    else:
        nvset_element.remove(nvpair_el_list[0])
    for nvpair_el in nvpair_el_list[1:]:
        nvset_element.remove(nvpair_el)
Example #30
0
def __export_bool(parent_el: _Element, boolean: BoolExpr,
                  id_provider: IdProvider) -> _Element:
    element = etree.SubElement(
        parent_el,
        "rule",
        {
            "id": create_subelement_id(parent_el, "rule", id_provider),
            "boolean-op": boolean.operator.lower(),
            # Score or score-attribute is required for nested rules, otherwise
            # the CIB is not valid. Pacemaker doesn't use the score of nested
            # rules. Score for the top rule, which is used by pacemaker, is
            # supposed to be set in the export function above.
            "score": "0",
        },
    )
    for child in boolean.children:
        __export_part(element, child, id_provider)
    return element
Example #31
0
def set_nvpair_in_nvset(nvset_element, name, value):
    """
    Update nvpair, create new if it doesn't yet exist or remove existing
    nvpair if value is empty.

    nvset_element -- element in which nvpair should be added/updated/removed
    name -- name of nvpair
    value -- value of nvpair
    """
    nvpair = nvset_element.find("./nvpair[@name='{0}']".format(name))
    if nvpair is None:
        if value:
            etree.SubElement(
                nvset_element,
                "nvpair",
                id=create_subelement_id(nvset_element, name),
                name=name,
                value=value
            )
    else:
        if value:
            nvpair.set("value", value)
        else:
            nvset_element.remove(nvpair)