def get_all_recipients(alert): """ Returns list of all recipient of specified alert. Format: [ { "id": <id of recipient>, "value": <value of recipient>, "description": <recipient description>, "instance_attributes": <list of nvpairs>, "meta_attributes": <list of nvpairs> } ] alert -- parent element of recipients to return """ recipient_list = [] for recipient in alert.findall("./recipient"): recipient_list.append({ "id": recipient.get("id"), "value": recipient.get("value"), "description": recipient.get("description", ""), "instance_attributes": get_nvset(get_sub_element(recipient, "instance_attributes")), "meta_attributes": get_nvset(get_sub_element(recipient, "meta_attributes")) }) return recipient_list
def get_all_alerts(tree): """ Returns list of all alerts specified in tree. Format: [ { "id": <id of alert>, "path": <path to script>, "description": <alert description>, "instance_attributes": <list of nvpairs>, "meta_attributes": <list of nvpairs>, "recipients_list": <list of alert's recipients> } ] tree -- cib etree node """ alert_list = [] for alert in get_alerts(tree).findall("./alert"): alert_list.append({ "id": alert.get("id"), "path": alert.get("path"), "description": alert.get("description", ""), "instance_attributes": get_nvset(get_sub_element(alert, "instance_attributes")), "meta_attributes": get_nvset(get_sub_element(alert, "meta_attributes")), "recipient_list": get_all_recipients(alert) }) return alert_list
def get_all_recipients(alert): """ Returns list of all recipient of specified alert. Format: [ { "id": <id of recipient>, "value": <value of recipient>, "description": <recipient description>, "instance_attributes": <list of nvpairs>, "meta_attributes": <list of nvpairs> } ] alert -- parent element of recipients to return """ recipient_list = [] for recipient in alert.findall("./recipient"): recipient_list.append({ "id": recipient.get("id"), "value": recipient.get("value"), "description": recipient.get("description", ""), "instance_attributes": get_nvset( get_sub_element(recipient, "instance_attributes") ), "meta_attributes": get_nvset( get_sub_element(recipient, "meta_attributes") ) }) return recipient_list
def get_all_alerts(tree): """ Returns list of all alerts specified in tree. Format: [ { "id": <id of alert>, "path": <path to script>, "description": <alert description>, "instance_attributes": <list of nvpairs>, "meta_attributes": <list of nvpairs>, "recipients_list": <list of alert's recipients> } ] tree -- cib etree node """ alert_list = [] for alert in get_alerts(tree).findall("./alert"): alert_list.append({ "id": alert.get("id"), "path": alert.get("path"), "description": alert.get("description", ""), "instance_attributes": get_nvset( get_sub_element(alert, "instance_attributes") ), "meta_attributes": get_nvset( get_sub_element(alert, "meta_attributes") ), "recipient_list": get_all_recipients(alert) }) return alert_list
def test_new_last(self): lib.get_sub_element(self.root, "new_element", "new_id", None) assert_xml_equal( """ <root> <sub_element/> <new_element id="new_id"/> </root> """, etree_to_str(self.root))
def test_new_last(self): lib.get_sub_element(self.root, "new_element", "new_id", None) assert_xml_equal( """ <root> <sub_element/> <new_element id="new_id"/> </root> """, etree.tostring(self.root).decode())
def test_new_last(self): lib.get_sub_element(self.root, "new_element", "new_id", None) assert_xml_equal( """ <root> <sub_element/> <new_element id="new_id"/> </root> """, etree_to_str(self.root) )
def update(id_provider, bundle_el, container_options, network_options, port_map_add, port_map_remove, storage_map_add, storage_map_remove, meta_attributes): """ Modify an existing bundle (does not touch encapsulated resources) IdProvider id_provider -- elements' ids generator and uniqueness checker etree bundle_el -- the bundle to be updated dict container_options -- container options to modify dict network_options -- network options to modify list of dict port_map_add -- list of port mapping options to add list of string port_map_remove -- list of port mapping ids to remove list of dict storage_map_add -- list of storage mapping options to add list of string storage_map_remove -- list of storage mapping ids to remove dict meta_attributes -- meta attributes to update """ bundle_id = bundle_el.get("id") update_attributes_remove_empty(_get_container_element(bundle_el), container_options) network_element = get_sub_element(bundle_el, "network") if network_options: update_attributes_remove_empty(network_element, network_options) # It's crucial to remove port maps prior to appending new ones: If we are # adding a port map which in any way conflicts with another one and that # another one is being removed in the very same command, the removal must # be done first, otherwise the conflict would manifest itself (and then # possibly the old mapping would be removed) if port_map_remove: _remove_map_elements(network_element.findall("port-mapping"), port_map_remove) for port_map_options in port_map_add: _append_port_map(network_element, id_provider, bundle_id, port_map_options) storage_element = get_sub_element(bundle_el, "storage") # See the comment above about removing port maps prior to adding new ones. if storage_map_remove: _remove_map_elements(storage_element.findall("storage-mapping"), storage_map_remove) for storage_map_options in storage_map_add: _append_storage_map(storage_element, id_provider, bundle_id, storage_map_options) if meta_attributes: arrange_first_meta_attributes(bundle_el, meta_attributes) # remove empty elements with no attributes # meta attributes are handled in their own function remove_when_pointless(network_element) remove_when_pointless(storage_element)
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)
def get(tree, section_name): """ Return the element which represents section 'section_name' in the tree. If the section is mandatory and is not found in the tree this function raises. If the section is optional and is not found in the tree this function creates new section. lxml.etree.Element tree -- is tree in which the section is looked up string section_name -- name of desired section; it is strongly recommended to use constants defined in this module """ if section_name in __MANDATORY_SECTIONS: section = tree.find(".//{0}".format(section_name)) if section is not None: return section raise LibraryError( ReportItem.error( reports.messages.CibCannotFindMandatorySection(section_name))) if section_name in __OPTIONAL_SECTIONS: return get_sub_element(get(tree, CONFIGURATION), section_name) raise AssertionError("Unknown cib section '{0}'".format(section_name))
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)
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)
def test_new_no_id(self): assert_xml_equal( '<new_element/>', etree_to_str(lib.get_sub_element(self.root, "new_element"))) assert_xml_equal( """ <root> <sub_element/> <new_element/> </root> """, etree_to_str(self.root))
def test_new_no_id(self): assert_xml_equal( '<new_element/>', etree.tostring(lib.get_sub_element(self.root, "new_element")).decode()) assert_xml_equal( """ <root> <sub_element/> <new_element/> </root> """, etree.tostring(self.root).decode())
def test_new_not_append(self): subelement = lib.get_sub_element(self.root, "new_element", "new_id", append_if_missing=False) assert_xml_equal( """ <root> <sub_element/> </root> """, etree_to_str(self.root)) assert_xml_equal("""<new_element id="new_id" />""", etree_to_str(subelement))
def get_nvset_as_dict(tag_name, context_element): """ Returns nvset with specified tag_name in context_element as dictionary tag_name string -- tag of nvset element which values shold be returned context_element etree.Element -- element in which required nvset is specified """ return { nvpair["name"]: nvpair["value"] for nvpair in get_nvset( get_sub_element(context_element, tag_name, append_if_missing=False) ) }
def test_new_with_id(self): assert_xml_equal( '<new_element id="new_id"/>', etree_to_str( lib.get_sub_element(self.root, "new_element", "new_id")), ) assert_xml_equal( """ <root> <sub_element/> <new_element id="new_id"/> </root> """, etree_to_str(self.root), )
def test_new_not_append(self): subelement = lib.get_sub_element( self.root, "new_element", "new_id", append_if_missing=False ) assert_xml_equal( """ <root> <sub_element/> </root> """, etree_to_str(self.root) ) assert_xml_equal( """<new_element id="new_id" />""", etree_to_str(subelement) )
def test_new_with_id(self): assert_xml_equal( '<new_element id="new_id"/>', etree_to_str( lib.get_sub_element(self.root, "new_element", "new_id") ) ) assert_xml_equal( """ <root> <sub_element/> <new_element id="new_id"/> </root> """, etree_to_str(self.root) )
def get(tree, section_name): """ Return the element which represents section 'section_name' in the tree. If the section is mandatory and is not found in the tree this function raises. If the section is optional and is not found in the tree this function creates new section. lxml.etree.Element tree -- is tree in which the section is looked up string section_name -- name of desired section; it is strongly recommended to use constants defined in this module """ if section_name in __MANDATORY_SECTIONS: section = tree.find(".//{0}".format(section_name)) if section is not None: return section raise LibraryError(reports.cib_missing_mandatory_section(section_name)) if section_name in __OPTIONAL_SECTIONS: return get_sub_element(get(tree, CONFIGURATION), section_name) raise AssertionError("Unknown cib section '{0}'".format(section_name))
def test_sub_element_exists(self): self.assertEqual( self.sub, lib.get_sub_element(self.root, "sub_element") )
def test_sub_element_exists(self): self.assertEqual(self.sub, lib.get_sub_element(self.root, "sub_element"))
def update( id_provider, bundle_el, container_options, network_options, port_map_add, port_map_remove, storage_map_add, storage_map_remove, meta_attributes, ): # pylint: disable=too-many-arguments, too-many-locals """ Modify an existing bundle (does not touch encapsulated resources) IdProvider id_provider -- elements' ids generator and uniqueness checker etree bundle_el -- the bundle to be updated dict container_options -- container options to modify dict network_options -- network options to modify list of dict port_map_add -- list of port mapping options to add list of string port_map_remove -- list of port mapping ids to remove list of dict storage_map_add -- list of storage mapping options to add list of string storage_map_remove -- list of storage mapping ids to remove dict meta_attributes -- meta attributes to update """ # Do not ever remove meta_attributes, network and storage elements, even if # they are empty. There may be ACLs set in pacemaker which allow "write" # for their children (adding, changing and removing) but not themselves. In # such a case, removing those elements would cause the whole change to be # rejected by pacemaker with a "permission denied" message. # https://bugzilla.redhat.com/show_bug.cgi?id=1642514 bundle_id = bundle_el.get("id") update_attributes_remove_empty(_get_container_element(bundle_el), container_options) network_element = get_sub_element(bundle_el, "network", append_if_missing=False) if network_options: update_attributes_remove_empty(network_element, network_options) # It's crucial to remove port maps prior to appending new ones: If we are # adding a port map which in any way conflicts with another one and that # another one is being removed in the very same command, the removal must # be done first, otherwise the conflict would manifest itself (and then # possibly the old mapping would be removed) if port_map_remove: _remove_map_elements(network_element.findall("port-mapping"), port_map_remove) if port_map_add: for port_map_options in port_map_add: _append_port_map(network_element, id_provider, bundle_id, port_map_options) append_when_useful(bundle_el, network_element) storage_element = get_sub_element(bundle_el, "storage", append_if_missing=False) # See the comment above about removing port maps prior to adding new ones. if storage_map_remove: _remove_map_elements(storage_element.findall("storage-mapping"), storage_map_remove) if storage_map_add: for storage_map_options in storage_map_add: _append_storage_map(storage_element, id_provider, bundle_id, storage_map_options) append_when_useful(bundle_el, storage_element) if meta_attributes: arrange_first_meta_attributes(bundle_el, meta_attributes, id_provider)
def get_status(tree): """ Return the 'status' element from the tree tree -- cib etree node """ return get_sub_element(tree, "status")
def get_fencing_topology(tree): """ Return the 'fencing-topology' element from the tree tree -- cib etree node """ return get_sub_element(get_configuration(tree), "fencing-topology")
def get_alerts(tree): """ Return 'alerts' element from tree, create a new one if missing tree -- cib etree node """ return get_sub_element(get_configuration(tree), "alerts")