def testValues_replace_children_01(self):
     # We have to parse multiple times because of replacements
     for config, args, result_correct in self.replace_children_Values:
         cfg = CiscoConfParse(config)
         test_result = cfg.replace_children(**args)
         self.assertEqual(result_correct, test_result)
def convert_cfg_file(config, device_type, out_path, conversion_matrix):
    """Convert cfg file to other cfg file"""

    import os
    import re
    from ciscoconfparse import CiscoConfParse

    # Check if device type exist in conversion matrix
    if device_type in conversion_matrix:
        # Determine new filename
        new_filename = os.path.join(out_path, os.path.basename(config))
        if os.path.isfile(new_filename):  # Remove CFG if it exist
            os.remove(new_filename)

        # Parse cisco configuration with Ciscoconfparse
        parse = CiscoConfParse(config)

        # DELETE
        for item in conversion_matrix[device_type]["delete"]:
            if item[1] == None:  # Check required fields
                continue
            elif item[0] != None:  # Parent cmd is mentionned
                parent_object = parse.find_objects(item[0])
                for parent in parent_object:
                    # Delete child object in parent object
                    parent.delete_children_matching(item[1])
            else:  # parent cmd is not mentionned
                cli_objects = parse.find_objects(item[1])
                for cli_object in cli_objects:
                    # Delete object and all child objects if exist
                    cli_object.delete()

        # ADD
        for item in conversion_matrix[device_type]["add"]:
            if item[2] == None:  # Check required fields
                continue
            elif item[0] != None:  # parent cmd is mentionned
                parent_object = parse.find_objects(item[0])
                parent_object_done = list(
                )  # This is to avoid duplicate added entries
                for parent in parent_object:
                    parent_re = re.compile(parent.text)
                    if parent.has_children == True:  # Add space to child if they are child
                        if parent.text not in parent_object_done:  # Avoid duplicates entries
                            nb_space = len(parent.text) - len(
                                parent.text.lstrip()) + 1
                            parse.insert_after(parent_re,
                                               insertstr=" " * nb_space +
                                               item[2])
                            parent_object_done.append(parent.text)
                    else:  # Entry is at the root of cfg, no space added
                        parse.insert_after(parent_re, insertstr=item[2])
            else:  # parent cmd is not mentionned
                parse.append_line(item[2])  # Write line at the end of the file

        # REPLACE
        for item in conversion_matrix[device_type]["replace"]:
            if item[1] == None or item[2] == None:  # Check required fields
                continue
            if item[0] != None:  # parent cmd is mentionned
                initial_cmd = re.compile(item[1])
                parse.replace_children(item[0], initial_cmd, item[2])
            else:  # parent cmd is not mentionned
                initial_cmd = re.compile(item[1])
                parse.replace_lines(initial_cmd, item[2])

        # Write output to out_file
        parse.save_as(new_filename)
    else:
        new_filename = "Skipped (model unknown)"

    return new_filename