def test_renormalize_xml_obj_ids(stc): root = etree.fromstring(get_test_xml()) xml_utils.renormalize_xml_obj_ids(root) vlan_ele_list = root.findall(".//VlanIf") assert len(vlan_ele_list) == 2 # VlanIf IDs should be 13 and 14 obj_id_list = [] for vlan_ele in vlan_ele_list: obj_id_list.append(vlan_ele.get("id")) assert len(obj_id_list) == 2 assert "13" in obj_id_list assert "14" in obj_id_list # Ipv4If should be 11 ipv4if_ele = root.find(".//Ipv4If") assert ipv4if_ele is not None assert ipv4if_ele.get("id") == "11" stacked_on_rel = None user_tag_rel = None for child in ipv4if_ele: if child.tag != "Relation": continue if child.get("type") == "StackedOnEndpoint": stacked_on_rel = child elif child.get("type") == "UserTag": user_tag_rel = child assert stacked_on_rel is not None assert user_tag_rel is not None # Should be stacked on 14 (one of the VlanIfs) assert stacked_on_rel.get("target") == "14" # Should be tagged with 8 (TopLevelIf tag) assert user_tag_rel.get("target") == "8" # Check the tag tag_ele_list = root.findall(".//Tag") assert len(tag_ele_list) == 5 top_level_if_tag = None for tag_ele in tag_ele_list: if tag_ele.get("Name") == "TopLevelIf": top_level_if_tag = tag_ele break assert top_level_if_tag is not None assert top_level_if_tag.get("id") == "8"
def run( StmTemplateConfig, SrcTagList, TargetTagList, TagPrefix, TemplateXml, TemplateXmlFileName, EnableLoadFromFileName ): plLogger = PLLogger.GetLogger("methodology") plLogger.LogDebug("run MergeTemplateCommand") hnd_reg = CHandleRegistry.Instance() temp_conf = hnd_reg.Find(StmTemplateConfig) if temp_conf is None: plLogger.LogError("ERROR: Failed to find a valid StmTemplateConfig") return False # Get the template XML (target XML) and renormalize the IDs template = temp_conf.Get("TemplateXml") target_root = etree.fromstring(template) # FIXME: # RENORMALIZE must ALSO remove invalid relations and potentially invalid # property values (for type handle). Otherwise, renumbering the objects # may end up relating things that shouldn't be related. # Example: # <Relation type="DefaultSelection" target="15"/> # Object with ID 15 doesn't exist if the XML was stripped incorrectly # but it will probably exist when the objects are renumbered. xml_utils.renormalize_xml_obj_ids(target_root) # Get the new current object ID (1 + maximum object ID) curr_id = xml_utils.get_max_object_id(target_root, 0) + 1 # Find the target elements target_ele_list = find_tagged_filtered_elements(target_root, TargetTagList) if len(target_ele_list) < 1: plLogger.LogError( "Found no target elements in the " + "StmTemplateConfig in to which the " + "new XML should be merged into." ) return False # Get the source XML merge_xml = None if not EnableLoadFromFileName: merge_xml = TemplateXml if merge_xml == "": plLogger.LogError("No valid XML Template String defined.") return False elif TemplateXmlFileName != "": merge_xml = xml_utils.load_xml_from_file(TemplateXmlFileName) if merge_xml is None: plLogger.LogError("No valid XML Template File defined.") return False source_root = etree.fromstring(merge_xml) # Find the source elements src_ele_list = find_tagged_filtered_elements(source_root, SrcTagList) if len(src_ele_list) < 1: plLogger.LogError( "Found no source elements in the input XML " + "from which XML should be copied into the " + "StmTemplateConfig from." ) return False # FIXME: # Source elements should not contain other source elements # Need to prevent this from happening # Find the Tags object in the target XML target_tags_ele = target_root.find(".//Tags") if target_tags_ele is None: plLogger.LogError("ERROR: Target XML has no Tags element!") return False # Merge Tag objects from the XML source if necessary copy_src_tag_list = [] for src_ele in src_ele_list: tag_ele_list = src_ele.findall(".//Relation") for tag_ele in tag_ele_list: if tag_ele.get("type") == "UserTag": copy_src_tag_list.append(tag_ele.get("target")) copy_src_tag_list = set(copy_src_tag_list) plLogger.LogDebug("copy_src_tag_list: " + str(copy_src_tag_list)) # Find the tags in the source XML and extract the ones of interest copy_src_tag_ele_list = [] src_tag_ele_list = source_root.findall(".//Tag") for src_tag_ele in src_tag_ele_list: if src_tag_ele.get("id") in copy_src_tag_list: copy_src_tag_ele_list.append(src_tag_ele) plLogger.LogDebug("copy_src_tag_ele_list: " + str(copy_src_tag_ele_list)) # Store the mappings between the old ID, new ID, old and new name # These will be used later to update relations and # StmPropertyModifier objects new_src_tag_id_map = {} new_src_tag_name_map = {} for src_tag_ele in copy_src_tag_ele_list: src_tag_ele_copy = xml_utils.get_etree_copy(src_tag_ele) # Update the tag's Name if the TagPrefix is defined old_name = src_tag_ele_copy.get("Name") if TagPrefix != "": new_name = TagPrefix + old_name else: new_name = old_name src_tag_ele_copy.set("Name", new_name) # Update the ID old_id = src_tag_ele_copy.get("id") src_tag_ele_copy.set("id", str(curr_id)) # Store both for use later new_src_tag_id_map[old_id] = curr_id new_src_tag_name_map[old_name] = new_name target_tags_ele.append(src_tag_ele_copy) xml_utils.create_relation_element(target_tags_ele, "UserTag", str(curr_id)) curr_id = curr_id + 1 plLogger.LogDebug("new_src_tag_id_map: " + str(new_src_tag_id_map)) plLogger.LogDebug("new_src_tag_name_map: " + str(new_src_tag_name_map)) # Merge the sources into the target(s) for target_ele in target_ele_list: for src_ele in src_ele_list: plLogger.LogInfo("merging " + str(src_ele) + " into " + str(target_ele)) # Renumber the object IDs src_ele_copy = xml_utils.get_etree_copy(src_ele) xml_utils.renormalize_xml_obj_ids(src_ele_copy, start_id=curr_id) # Update the tag IDs (should have been lost # unless src_ele is Tags...which is not allowed). update_relation_targets(src_ele_copy, new_src_tag_id_map) # Update the StmPropertyModifiers update_property_modifier_tag_names(src_ele_copy, new_src_tag_name_map) plLogger.LogInfo(" src_ele_copy: " + etree.tostring(src_ele_copy)) target_ele.append(src_ele_copy) # Increment the current max ID curr_id = curr_id + 1 # Clean up the invalid handles xml_utils.remove_invalid_stc_handles(target_root) xml_value = etree.tostring(target_root) plLogger.LogInfo("FINAL xml_value: " + etree.tostring(target_root)) temp_conf.Set("TemplateXml", xml_value) return True