### Install TTP from source Source: https://ttp.readthedocs.io/en/latest/Installation These snippets demonstrate how to install TTP by downloading the source code from GitHub. This involves unzipping the code, navigating to the directory, and then running the installation script. It offers flexibility for development or offline installations. ```bash python setup.py install ``` ```bash python -m pip install . ``` -------------------------------- ### Install TTP with all optional dependencies Source: https://ttp.readthedocs.io/en/latest/Installation This command installs TTP along with all its optional dependencies, enabling all features. It's a convenient way to ensure all necessary libraries for various output formats and functions are available. ```bash pip install ttp[full] ``` -------------------------------- ### Example Configuration Files Source: https://ttp.readthedocs.io/en/latest/Inputs/index These snippets show example configuration file contents for network devices. One is in INI-like format for interface configurations, and the others are plain text files with similar interface configurations. ```ini [sw-1.conf] interface GigabitEthernet3/7 switchport access vlan 700 ! interface GigabitEthernet3/8 switchport access vlan 800 ! ``` ```text [sw-1.txt] interface GigabitEthernet3/2 switchport access vlan 500 ! interface GigabitEthernet3/3 switchport access vlan 600 ! ``` ```text [sw-2.txt] interface Vlan221 ip address 10.8.14.130/25 interface Vlan223 ip address 10.10.15.130/25 ``` ```text [sw3.txt] interface Vlan220 ip address 10.9.14.130/24 interface Vlan230 ip address 10.11.15.130/25 ``` -------------------------------- ### Parse Data with TTP as a CLI Tool Source: https://ttp.readthedocs.io/en/latest/Quick%20start Illustrates using TTP as a command-line interface (CLI) tool to parse data from files. It requires specifying the data file, template file, and desired output format (e.g., JSON). ```bash ttp --data "path/to/data_to_parse.txt" --template "path/to/ttp_template.txt" --outputter json ``` -------------------------------- ### Install TTP from GitHub master branch Source: https://ttp.readthedocs.io/en/latest/Installation This command installs the latest development version of TTP directly from its GitHub master branch. It requires Git to be installed on the system and is useful for accessing the newest features or bug fixes. ```bash python -m pip install git+https://github.com/dmulyalin/ttp ``` -------------------------------- ### Install TTP using pip Source: https://ttp.readthedocs.io/en/latest/Installation This snippet shows the basic command to install the TTP library using pip, the standard Python package installer. This is the most straightforward method for most users. ```bash pip install ttp ``` -------------------------------- ### Parse Data with TTP as a Python Module Source: https://ttp.readthedocs.io/en/latest/Quick%20start Demonstrates parsing structured data using TTP as a Python module. It takes raw data and a template to extract information, outputting results in JSON or CSV format. Ensure the 'ttp' library is installed. ```python from ttp import ttp data_to_parse = """ interface Loopback0 description Router-id-loopback ip address 192.168.0.113/24 ! interface Vlan778 description CPE_Acces_Vlan ip address 2002::fd37/124 ip vrf CPE1 ! " ttp_template = """ interface {{ interface }} ip address {{ ip }}/{{ mask }} description {{ description }} ip vrf {{ vrf }} "" # create parser object and parse data using template: parser = ttp(data=data_to_parse, template=ttp_template) parser.parse() # print result in JSON format results = parser.result(format='json')[0] print(results) # or in csv format csv_results = parser.result(format='csv')[0] print(csv_results) ``` -------------------------------- ### Example of validate_yangson Usage with Example Data Source: https://ttp.readthedocs.io/en/latest/Outputs/Functions This example demonstrates how to use the validate_yangson function with sample interface data and YANG modules. It shows the expected input data structures (Python strings for configurations) and the YANG module directory structure. The example also includes a Jinja2 template used for parsing and the expected output format, including detailed error messages when validation fails due to invalid IP address formats. ```python data1 = """ interface GigabitEthernet1/3.251 description Customer #32148 encapsulation dot1q 251 ip address 172.16.10 255.255.255.128 shutdown ! interface GigabitEthernet1/4 description vCPEs access control ip address 172.16.33.10 255.255.255.128 ! interface GigabitEthernet1/5 description Works data ip mtu 9000 ! interface GigabitEthernet1/7 description Works data v6 ipv6 address 2001::1/64 ipv6 address 2001:1::1/64 ! """ data2 = """ interface GigabitEthernet1/3.254 description Customer #5618 encapsulation dot1q 251 ip address 172.16.33.11 255.255.255.128 shutdown ! """ # Example template structure (as provided in the text) # # def add_iftype(data): # if "eth" in data.lower(): # return data, {"type": "iana-if-type:ethernetCsmacd"} # return data, {"type": None} # # # interface {{ name | macro(add_iftype) }} # description {{ description | re(".+") }} # shutdown {{ enabled | set(False) | let("admin-status", "down") }} # {{ link-up-down-trap-enable | set(enabled) }} # {{ admin-status | set(up) }} # {{ enabled | set(True) }} # {{ if-index | set(1) }} # {{ statistics | set({"discontinuity-time": "1970-01-01T00:00:00+00:00"}) }} # {{ oper-status | set(unknown) }} # # ip mtu {{ mtu | to_int }} # # # ip address {{ ip | _start_ }} {{ netmask }} # ip address {{ ip | _start_ }} {{ netmask }} secondary # {{ origin | set(static) }} # # # ipv6 address {{ ip | _start_ }}/{{ prefix-length | to_int }} # {{ origin | set(static) }} # # # # validate_yangson="yang_mod_dir='./yang_modules/', yang_mod_lib='./yang_modules/library/yang-library.json'" # # Example of calling the function (assuming the template is processed and results are available) # results = validate_yangson(yang_mod_dir='./yang_modules/', yang_mod_lib='./yang_modules/library/yang-library.json') # print(results) ``` -------------------------------- ### Example Usage of to_ip Filter with ipaddress Module Functions Source: https://ttp.readthedocs.io/en/latest/_sources/Match%20Variables/Functions.rst This example demonstrates how the `to_ip` filter, combined with ipaddress module functions like `with_prefixlen` and `with_netmask`, can parse and reformat IP address configurations from network device output. It shows converting an IP address with a subnet mask to CIDR notation and vice versa. ```jinja interface Loopback0 ip address 1.0.0.3 255.255.255.0 ! interface Vlan777 ip address 192.168.0.1/24 ! interface {{ interface }} ip address {{ ip | PHRASE | to_ip | with_prefixlen }} ip address {{ ip | to_ip | with_netmask }} ``` -------------------------------- ### Parse IP Addresses with Comments and Disabled Status Source: https://ttp.readthedocs.io/en/latest/FAQ This example demonstrates parsing IP address configurations, including optional comments and a 'disabled' status. It uses TTP's ORPHRASE and strip functions to handle complex comment formats and remove unwanted quotes. The `_start_` indicator is used to denote the start of a regex. ```python parser = ttp(data=data, template=template, log_level="ERROR") parser.parse() res = parser.result(structure="flat_list") pprint.pprint(res, width=200) ``` -------------------------------- ### Parse IP Addresses with Comments and Disabled State using TTP Source: https://ttp.readthedocs.io/en/latest/_sources/FAQ.rst Demonstrates parsing IP address configurations, including optional comments and a disabled status. It uses TTP's templating features with functions like `ORPHRASE` and `strip` for advanced data extraction and cleanup. The example assumes TTP is installed and configured. ```python from ttp import ttp from pprint import pprint data = ''' /ip address add address=10.4.1.245/32 disabled=no interface=lo0 network=10.4.1.245 /ip address add address=10.4.1.246/32 disabled=no interface=lo1 network=10.4.1.246 /ip address add address=10.9.48.241/29 comment="SITEMON" disabled=no interface=ether2 network=10.9.48.240 /ip address add address=10.9.48.233/29 comment="Camera" disabled=no interface=vlan205@bond1 network=10.9.48.232 /ip address add address=10.9.49.1/24 comment="SM-Management" disabled=no interface=vlan200@bond1 network=10.9.49.0 /ip address add address=10.4.1.130/30 comment="to core01" disabled=no interface=vlan996@bond4 network=10.4.1.128 /ip address add address=10.4.250.28/29 comment="BH 01" disabled=no interface=vlan210@bond1 network=10.4.250.24 /ip address add address=10.9.50.13/30 comment="Cust: site01-PE" disabled=no interface=vlan11@bond1 network=10.9.50.12 /ip address add address=10.0.0.2/30 comment="" disabled=yes interface=bridge:customer99 network=10.0.0.0 /ip address add address=169.254.1.100/24 comment="Cambium" disabled=yes interface=vlan200@bond1 network=169.254.1.0 /ip address add address=10.4.248.20/29 comment="Backhaul to AGR (Test Segment)" disabled=yes interface=vlan209@bond1 network=10.4.248.16 ''' template = ''' /ip address add address={{ ip | _start_ }}/{{ mask }} comment={{ comment | ORPHRASE | exclude("disabled=") | strip('"') }} disabled={{ disabled }} interface={{ interface }} network={{ network }} ''' parser = ttp(data=data, template=template, log_level="ERROR") parser.parse() res = parser.result(structure="flat_list") pprint(res, width=200) assert res == [{'comment': '', 'disabled': False, 'interface': 'lo0', 'ip': '10.4.1.245', 'network': '10.4.1.245'}, {'comment': '', 'disabled': False, 'interface': 'lo1', 'ip': '10.4.1.246', 'network': '10.4.1.246'}, {'comment': 'SITEMON', 'disabled': False, 'interface': 'ether2', 'ip': '10.9.48.241', 'mask': '29', 'network': '10.9.48.240'}, {'comment': 'Camera', 'disabled': False, 'interface': 'vlan205@bond1', 'ip': '10.9.48.233', 'mask': '29', 'network': '10.9.48.232'}, {'comment': 'SM-Management', 'disabled': False, 'interface': 'vlan200@bond1', 'ip': '10.9.49.1', 'mask': '24', 'network': '10.9.49.0'}, {'comment': 'to core01', 'disabled': False, 'interface': 'vlan996@bond4', 'ip': '10.4.1.130', 'mask': '30', 'network': '10.4.1.128'}, {'comment': 'BH 01', 'disabled': False, 'interface': 'vlan210@bond1', 'ip': '10.4.250.28', 'mask': '29', 'network': '10.4.250.24'}, {'comment': 'Cust: site01-PE', 'disabled': False, 'interface': 'vlan11@bond1', 'ip': '10.9.50.13', 'mask': '30', 'network': '10.9.50.12'}, {'comment': '', 'disabled': 'yes', 'interface': 'bridge:customer99', 'ip': '10.0.0.2', 'mask': '30', 'network': '10.0.0.0'}, {'comment': 'Cambium', 'disabled': 'yes', 'interface': 'vlan200@bond1', 'ip': '169.254.1.100', 'mask': '24', 'network': '169.254.1.0'}, {'comment': 'Backhaul to AGR (Test Segment)', 'disabled': 'yes', 'interface': 'vlan209@bond1', 'ip': '10.4.248.20', 'mask': '29', 'network': '10.4.248.16'}] ``` -------------------------------- ### TTP Example: Nested List Output with '*' Formatters Source: https://ttp.readthedocs.io/en/latest/Forming%20Results%20Structure/Path%20formatters Provides a concrete example of TTP parsing with '*' formatters applied to 'interfaces' and 'L3'. This results in a nested list structure for both 'interfaces' and 'L3' levels in the output JSON. ```json [ { "interfaces": [ { "vlan": { "L3": [ { "vrf-enabled": { "description": "Management", "interface": "Vlan777", "ip": "192.168.0.1", "mask": "24", "vrf": "MGMT" } } ] } } ] } ] ``` -------------------------------- ### Template Result Structure Examples (Textual) Source: https://ttp.readthedocs.io/en/latest/API%20reference These examples illustrate different ways template results can be structured and returned, depending on settings like 'template results' (per_input, per_template) and 'structure' (list, dictionary, flat_list). These are conceptual representations of output formats. ```text [ [ template_1_input_1_results, template_1_input_2_results, ... template_1_input_N_results ], [ template_2_input_1_results, template_2_input_2_results, ... ] [ [ template_1_input_1_2...N_joined_results ], [ template_2_input_1_2...N_joined_results ] ] { template_1_name: [ input_1_results, input_2_results, ... input_N_results ], template_2_name: [ input_1_results, input_2_results ], ... } { template_1_name: input_1_2...N_joined_results, template_2_name: input_1_2...N_joined_results } [[{'interface': 'Lo0', 'ip': '192.168.0.1', 'mask': '32'}, {'interface': 'Lo1', 'ip': '1.1.1.1', 'mask': '32'}], [{'interface': 'Lo2', 'ip': '2.2.2.2', 'mask': '32'}, {'interface': 'Lo3', 'ip': '3.3.3.3', 'mask': '32'}]] [{'interface': 'Lo0', 'ip': '192.168.0.1', 'mask': '32'}, {'interface': 'Lo1', 'ip': '1.1.1.1', 'mask': '32'}, {'interface': 'Lo2', 'ip': '2.2.2.2', 'mask': '32'}, {'interface': 'Lo3', 'ip': '3.3.3.3', 'mask': '32'}] ``` -------------------------------- ### rlookup Example Input Data Source: https://ttp.readthedocs.io/en/latest/Match%20Variables/Functions This is the sample data used in the rlookup filter example. It contains BGP neighbor configurations with descriptions that follow a naming convention indicating physical location and role. ```text router bgp 65100 neighbor 10.145.1.9 description vic-mel-core1 ! neighbor 192.168.101.1 description qld-bri-core1 ``` -------------------------------- ### Doc Tag Example in TTP Template Source: https://ttp.readthedocs.io/en/latest/Doc%20Tag/Doc%20Tag This snippet demonstrates how to use the `` tag within a TTP template to provide explanatory notes and usage instructions for the template. It includes an example of invoking the template using Netmiko. ```ttp TTP template to parse Cisco IOS "show ip arp" output. Template can be invoked using Netmiko run_ttp method like this: import pprint from netmiko import ConnectHandler net_connect = ConnectHandler( device_type="cisco_ios", host="1.2.3.4", username="admin", password="admin", ) res = net_connect.run_ttp("ttp://misc/netmiko/cisco.ios.arp.txt", res_kwargs={"structure": "flat_list"}) pprint.pprint(res) commands = [ "show ip arp" ] {{ protocol }} {{ ip | IP }} {{ age | replace("-", "-1") }} {{ mac | mac_eui }} {{ type | let("interface", "Uncknown") }} {{ protocol }} {{ ip | IP }} {{ age | replace("-", "-1") }} {{ mac | mac_eui }} {{ type }} {{ interface | resuball("short_interface_names") }} ``` -------------------------------- ### dict_to_list output comparison example Source: https://ttp.readthedocs.io/en/latest/Outputs/Functions This example contrasts the output of the `dict_to_list` function with the raw parsing results. It highlights how `dict_to_list` flattens nested dictionary data into a more manageable list format, as shown in the first result block. ```json [ [ [ { "description": "SomeDescription glob1", "interface": "ge-0/0/110", "ip": "10.0.40.121/31" }, { "description": "Routing Loopback", "interface": "lo00", "ip": "10.6.4.4/32" } ] ] ] ``` ```json [ [ { "ge-0/0/110": { "description": "SomeDescription glob1", "ip": "10.0.40.121/31" }, "lo00": { "description": "Routing Loopback", "ip": "10.6.4.4/32" } } ] ] ``` -------------------------------- ### Replaceall Filter for String Replacement in Jinja2 (Specific New Value) Source: https://ttp.readthedocs.io/en/latest/_sources/Match%20Variables/Functions.rst This 'replaceall' filter example shows replacing specific substrings with new ones. Multiple old/new value pairs can be provided to perform several replacements in a single operation. ```jinja2 interface {{ interface | replaceall('Ge', 'GigabitEthernet', 'GigEth', 'Ethernet') }} ``` -------------------------------- ### TTP Template Example: Coloring Terminal Output Source: https://ttp.readthedocs.io/en/latest/_sources/Outputs/Returners.rst This TTP template illustrates how to format output to the terminal with color highlighting. It parses interface descriptions and applies conditional logic to set boolean variables, demonstrating the potential for colorization based on output content. ```xml interface Port-Channel11 description Storage Management interface Loopback0 description RID interface Vlan777 description Management interface {{ interface | contains("Port-Channel") }} description {{ description }} {{ is_lag | set(True) }} {{ is_loopback| set(False) }} interface {{ interface | contains("Loop") }} description {{ description }} {{ is_lag | set(False) }} {{ is_loopback| set(True) }} ``` -------------------------------- ### TTP Template Example: Saving Interface Data to Files Source: https://ttp.readthedocs.io/en/latest/_sources/Outputs/Returners.rst This TTP template demonstrates saving interface configuration data to separate files for each device. It utilizes the 'file' returner, specifying an output directory and dynamically generating filenames based on the device's hostname, retrieved from TTP variables. ```xml switch-sw1# show run interfaces interface Port-Chanel2 vlan 100 interface Loopback1 vlan 200 switch-sw2# show run interfaces interface Port-Chanel11 vlan 10 interface Loopback0 vlan 20 host_name = "gethostname" interface {{ interface }} vlan {{ vlan | to_int }} returner="file" url="./Output/" filename="{host_name}_interfaces.txt" ``` -------------------------------- ### TTP Group 'record' Functionality: Capturing Variables Source: https://ttp.readthedocs.io/en/latest/Groups/Functions Demonstrates the use of the TTP group 'record' function to capture variable values during parsing. This example shows how the 'record' attribute on a group captures the 'vrf' variable. Note that in this specific setup, the last matched value ('VRF2') overrides previous ones due to how the template is structured. ```xml router bgp 65123 ! address-family ipv4 vrf VRF1 neighbor 10.1.100.212 activate exit-address-family ! address-family ipv4 vrf VRF2 neighbor 10.6.254.67 activate exit-address-family router bgp {{ bgp_asn }} address-family {{ afi }} vrf {{ vrf | record(vrf) }} neighbor {{ neighbor | let("afi_activated", True) }} activate {{ vrf | set(vrf) }} exit-address-family {{ _end_ }} ``` -------------------------------- ### Classify Hostnames with Glob Pattern Lookup (gpvlookup) Source: https://ttp.readthedocs.io/en/latest/_sources/Match%20Variables/Functions.rst This example uses the 'gpvlookup' function to classify hostnames into network domains based on glob patterns. The results are added as a new field 'Network Domains' to each device entry. It showcases basic 'gpvlookup' usage with a Python dictionary for lookup data. ```ttp hostname DC1-SW-2 hostname A1-CORP-SW-2 hostname WIFI-CORE-RT-1 hostname DC2-CORP-FW-02 { "NETWORK_DOMAINS": { "corporate": ["*CORP*", "WIFI-*"], "datacentre": ["DC1-*", "DC2-*"] } } hostname {{ hostname | gpvlookup("domains.NETWORK_DOMAINS", add_field="Network Domains") }} ``` -------------------------------- ### Interface Configuration Data Example (YAML) Source: https://ttp.readthedocs.io/en/latest/Outputs/Functions This snippet demonstrates the structure of interface configuration data, likely in YAML format. It includes details for a specific interface like administrative status, description, IP addressing, and operational status. Note that 'enabled' is set to False, and 'oper-status' is 'unknown'. ```yaml { 'ietf-interfaces:interfaces': { 'interface': [ { 'admin-status': 'down', 'description': 'Customer #5618', 'enabled': False, 'ietf-ip:ipv4': { 'address': [ { 'ip': '172.16.33.11', 'netmask': '255.255.255.128', 'origin': 'static' } ] }, 'if-index': 1, 'link-up-down-trap-enable': 'enabled', 'name': 'GigabitEthernet1/3.254', 'oper-status': 'unknown', 'statistics': { 'discontinuity-time': '1970-01-01T00:00:00+00:00' }, 'type': 'iana-if-type:ethernetCsmacd' } ] }, 'valid': { 0: False, 1: True } } ``` -------------------------------- ### Install ttp_templates Python Package Source: https://ttp.readthedocs.io/en/latest/TTP%20Templates%20Collection This snippet shows the command to install the ttp_templates Python package using pip. Ensure you have pip installed and accessible in your environment. ```bash pip install ttp_templates ``` -------------------------------- ### Filter: Check if string does not start with a regex pattern Source: https://ttp.readthedocs.io/en/latest/Match%20Variables/Functions The `notstartswith_re` filter uses Python's `re.search` to determine if a string does not start with the provided regular expression pattern. It returns False if the string starts with the pattern, and True otherwise. ```ttp {{ name | notstartswith_re('pattern') }} ``` -------------------------------- ### Replace Interface Prefixes with Dictionary Mapping using replaceall Source: https://ttp.readthedocs.io/en/latest/_sources/Match%20Variables/Functions.rst Illustrates using 'replaceall' with a dictionary to map various interface name patterns to shorter prefixes. The filter iterates through the dictionary, applying replacements based on the provided keys and list of values. This allows for more complex and organized substitutions. ```jinja intf_replace = { 'Ge': ['GigabitEthernet', 'GigEthernet', 'GeEthernet'], 'Lo': ['Loopback'], 'Te': ['TenGigabitEth', 'TeGe', '10GE'] } interface {{ interface | replaceall('intf_replace') }} ``` -------------------------------- ### Load Template from Local File System Source: https://ttp.readthedocs.io/en/latest/Extend%20Tag/Extend%20Tag Shows how to load a template from the local file system using a relative or absolute path. This is useful for organizing parsing logic into separate files. ```ttp vlan {{ vlan }} name {{ name }} ``` -------------------------------- ### TTP equal Function Example: Filtering Interfaces Source: https://ttp.readthedocs.io/en/latest/Groups/Functions This example demonstrates the 'equal' function to filter network interfaces based on their 'description' attribute. It groups interfaces where the description is exactly 'Foo'. ```text interface FastEthernet1/0/1 description Foo ! interface FastEthernet1/0/2 description wlap2 ! interface {{ interface }} description {{ description }} ``` -------------------------------- ### Matching Variations in Output with TTP Templates Source: https://ttp.readthedocs.io/en/latest/_sources/FAQ.rst Provides a TTP template example designed to match several variations of IP address entries, including those with and without comments, and handling quoted versus unquoted comments. It utilizes default values and the `ORPHRASE` and `strip` filters for robust parsing. ```xml default_values = { "comment": "", "disabled": False } ## not disabled and no comment /ip address add address={{ ip | _start_ }} interface={{ interface }} network={{ network }} ## not disabled and comment with/without quotes /ip address add address={{ ip | _start_ }}/{{ mask }} comment={{ comment | ORPHRASE | exclude("disabled=") | strip('"')}} interface={{ interface }} network={{ network }} ## disabled no comment ``` -------------------------------- ### TTP Jinja 'default' Filter Example 2 Source: https://ttp.readthedocs.io/en/latest/Match%20Variables/Functions Illustrates the use of the 'default' filter for a '_start_' match variable ('server' and 'source'). It shows how to provide default values ('Unconfigured', 'undefined') when the 'ntp server' or 'ntp source' lines are missing in the input data. ```jinja interface Port-Channel11 description Staff ports ntp server {{ server | default('Unconfigured') }} ntp source {{ source | default("undefined") }} ``` -------------------------------- ### TTP Path Formatter Example: Enforcing List Structures Source: https://ttp.readthedocs.io/en/latest/_sources/Forming%20Results%20Structure/Path%20formatters.rst Demonstrates the use of '*' and '**' path formatters in TTP's group name attribute. The '*' suffix forces the next level to be a list, while '**' (though not explicitly shown in this specific example's output structure, it's mentioned in the text) would enforce a dictionary. This example shows how 'interfaces*' and 'L3*' create nested lists in the final parsed output. ```ttp interface {{ interface }} description {{ description }} ip address {{ ip }}/{{ mask }} vrf {{ vrf }} ``` -------------------------------- ### Parsing Network Interface Data with Jinja2 Templates Source: https://ttp.readthedocs.io/en/latest/_sources/Forming%20Results%20Structure/Dynamic%20path%20with%20path%20formatters.rst This example demonstrates parsing hierarchical network interface data using Jinja2 templating. It shows how to define a template to extract specific fields like description, IP address, and VRF, handling optional fields and nested structures. The output is a structured JSON array. ```jinja interface {{ interface }} description {{ description }} ip address {{ ip }}/{{ mask }} vrf {{ vrf }} ``` -------------------------------- ### Check if String Does Not Start with Pattern (notstartswith_re) Source: https://ttp.readthedocs.io/en/latest/_sources/Match%20Variables/Functions.rst Evaluates if a string value does not start with a given pattern using Python's re module. It returns False if there is a match and True otherwise. The pattern can be a literal string or a variable name from a tag. ```jinja {{ name | notstartswith_re('pattern') }} ``` -------------------------------- ### Load Template from TTP Repository Source: https://ttp.readthedocs.io/en/latest/Extend%20Tag/Extend%20Tag Demonstrates loading a template from the TTP Templates repository using a URL. This allows for modular parsing by extending functionality from shared templates. ```ttp vlan {{ vlan }} name {{ name }} ``` -------------------------------- ### TTP to_int Example 2: List of Integers Conversion Source: https://ttp.readthedocs.io/en/latest/Groups/Functions This example demonstrates the 'intlist=True' option within 'to_int'. It converts a comma-separated string of VLANs into a list of integers. Non-numeric values in the list remain as strings. ```text interface GigabitEthernet1/1 switchport trunk allowed vlan 1,2,3,4 ! interface GigabitEthernet1/2 switchport trunk allowed vlan 123 ! interface GigabitEthernet1/3 switchport trunk allowed vlan foo,bar ! interface GigabitEthernet1/4 ! interface {{ name }} switchport trunk allowed vlan {{ trunk_vlan | split(',') }} ``` -------------------------------- ### TTP to_int Example 1: General and Specific Conversions Source: https://ttp.readthedocs.io/en/latest/Groups/Functions This example shows two uses of 'to_int': 'all_to_int' converts all applicable fields to integers (or floats), while 'some_to_int' specifically targets 'version' and 'Subpacket_Version' for conversion. ```text Subscription ID = 1 Version = 1 Num Subpackets = 1 Subpacket[0] Subpacket ID = PDCP PDU with Ciphering (0xC3) Subpacket Version = 26.1 Subpacket Size = 60,5 bytes SRB Cipher Algo = LTE AES DRB Cipher Algo = LTE AES Num PDUs = 1 Subscription ID = {{ Subscription_ID }} Version = {{ version }} Num Subpackets = {{ Num_Subpackets }} Subpacket ID = {{ Subpacket_ID | PHRASE }} Subpacket Version = {{ Subpacket_Version }} Subpacket Size = {{ Subpacket_Size | PHRASE }} SRB Cipher Algo = {{ SRB_Cipher_Algo | PHRASE }} DRB Cipher Algo = {{ DRB_Cipher_Algo | PHRASE }} Num PDUs = {{ Num_PDUs }} Subscription ID = {{ Subscription_ID }} Version = {{ version }} Num Subpackets = {{ Num_Subpackets }} Subpacket ID = {{ Subpacket_ID | PHRASE }} Subpacket Version = {{ Subpacket_Version }} Subpacket Size = {{ Subpacket_Size | PHRASE }} SRB Cipher Algo = {{ SRB_Cipher_Algo | PHRASE }} DRB Cipher Algo = {{ DRB_Cipher_Algo | PHRASE }} Num PDUs = {{ Num_PDUs }} ``` -------------------------------- ### Load Template using TTP_TEMPLATES_DIR Environment Variable Source: https://ttp.readthedocs.io/en/latest/Extend%20Tag/Extend%20Tag Explains how to load templates by referencing their filenames directly when the TTP_TEMPLATES_DIR environment variable is set. This simplifies template paths for files within a designated directory. ```ttp ``` -------------------------------- ### Indicating Group Start with _start_ Indicator Source: https://ttp.readthedocs.io/en/latest/Match%20Variables/Indicators The _start_ indicator explicitly marks the beginning of a group, allowing the parser to match specific lines or multiple lines as the start of a data block. It can be used standalone as {{ _start_ }} or within a match variable. ```text ------------------------- {{ _start_ }} Device ID: {{ peer_hostname }} Entry address(es): IP address: {{ peer_ip }} ``` ```text interface GigabitEthernet{{ if_id | _start_ }} description {{ description }} ``` -------------------------------- ### Network Interface Configuration Data Example Source: https://ttp.readthedocs.io/en/latest/Outputs/Functions This snippet showcases a sample network interface configuration, including details like interface name, description, enabled status, IP addressing (both IPv4 and IPv6), operational status, and statistics. It is representative of data used in network management systems. ```json { "#32148": "some_value", "enabled": false, "ietf-ip:ipv4": { "address": [ { "ip": "172.16.10", "netmask": "255.255.255.128", "origin": "static" } ] }, "if-index": 1, "link-up-down-trap-enable": "enabled", "name": "GigabitEthernet1/3.251", "oper-status": "unknown", "statistics": { "discontinuity-time": "1970-01-01T00:00:00+00:00" }, "type": "iana-if-type:ethernetCsmacd" } ``` ```json { "admin-status": "up", "description": "vCPEs access control", "enabled": true, "ietf-ip:ipv4": { "address": [ { "ip": "172.16.33.10", "netmask": "255.255.255.128", "origin": "static" } ] }, "if-index": 1, "link-up-down-trap-enable": "enabled", "name": "GigabitEthernet1/4", "oper-status": "unknown", "statistics": { "discontinuity-time": "1970-01-01T00:00:00+00:00" }, "type": "iana-if-type:ethernetCsmacd" } ``` ```json { "admin-status": "up", "description": "Works data", "enabled": true, "ietf-ip:ipv4": { "mtu": 9000 }, "if-index": 1, "link-up-down-trap-enable": "enabled", "name": "GigabitEthernet1/5", "oper-status": "unknown", "statistics": { "discontinuity-time": "1970-01-01T00:00:00+00:00" }, "type": "iana-if-type:ethernetCsmacd" } ``` ```json { "admin-status": "up", "description": "Works data v6", "enabled": true, "ietf-ip:ipv6": { "address": [ { "ip": "2001::1", "origin": "static", "prefix-length": 64 }, { "ip": "2001:1::1", "origin": "static", "prefix-length": 64 } ] }, "if-index": 1, "link-up-down-trap-enable": "enabled", "name": "GigabitEthernet1/7", "oper-status": "unknown", "statistics": { "discontinuity-time": "1970-01-01T00:00:00+00:00" } } ``` -------------------------------- ### Template with YAML and Python Inputs Source: https://ttp.readthedocs.io/en/latest/Inputs/index This snippet demonstrates how to configure template inputs using both YAML and Python definitions. It specifies data sources, file extensions for filtering, and regular expressions for matching filenames, assigning them to specific groups for processing. ```xml ``` -------------------------------- ### Loading Variables Data with Different Loaders Source: https://ttp.readthedocs.io/en/latest/_sources/Template%20Variables/Attributes.rst Demonstrates how to load variables data using different 'load' attributes, specifying loaders such as text, python, yaml, json, ini, and csv. Each loader processes data in its respective format. ```html interface GigabitEthernet1/1 ip address 192.168.123.1 255.255.255.0 ! python_domains = ['.lab.local', '.static.on.net', '.abc'] yaml_domains: - '.lab.local' - '.static.on.net' - '.abc' { "json_domains": [ ".lab.local", ".static.on.net", ".abc" ] } [ini_domains] 1: '.lab.local' 2: '.static.on.net' 3: '.abc' id, domain 1, .lab.local 2, .static.on.net 3, .abc ``` -------------------------------- ### Example YANGSON Validation with List Data Source: https://ttp.readthedocs.io/en/latest/_sources/Outputs/Functions.rst This example demonstrates using `validate_yangson` to validate a list of parsed data against YANG modules. The first data item contains an invalid IP address, which will be flagged during validation. The output includes a 'valid' key for each item in the list. ```python data1 = """ interface GigabitEthernet1/3.251 description Customer #32148 encapsulation dot1q 251 ip address 172.16.10 255.255.255.128 shutdown ! interface GigabitEthernet1/4 description vCPEs access control ip address 172.16.33.10 255.255.255.128 ! interface GigabitEthernet1/5 description Works data ip mtu 9000 ! interface GigabitEthernet1/7 description Works data v6 ipv6 address 2001::1/64 ipv6 address 2001:1::1/64 ! """ data2 = """ interface GigabitEthernet1/3.254 description Customer #5618 encapsulation dot1q 251 ip address 172.16.33.11 255.255.255.128 shutdown ! """ def add_iftype(data): if "eth" in data.lower(): ``` -------------------------------- ### dict_to_list function example for data transformation Source: https://ttp.readthedocs.io/en/latest/Outputs/Functions The `dict_to_list` function transforms dictionary data into a list of dictionaries, typically used for flattening nested structures. This example demonstrates how to convert interface configuration data from a dictionary format to a list, using 'interface' as the key name. ```xml some.user@router-fw-host> show configuration interfaces | display set set interfaces ge-0/0/11 unit 0 description "SomeDescription glob1" set interfaces ge-0/0/11 unit 0 family inet address 10.0.40.121/31 set interfaces lo0 unit 0 description "Routing Loopback" set interfaces lo0 unit 0 family inet address 10.6.4.4/32 set interfaces {{ interface }} unit {{ unit }} family inet address {{ ip }} set interfaces {{ interface }} unit {{ unit }} description "{{ description | ORPHRASE }}" ``` -------------------------------- ### Dynamic Path Formation with 'name' Attribute Source: https://ttp.readthedocs.io/en/latest/_sources/Template%20Variables/Attributes.rst Illustrates how the 'name' attribute can dynamically construct paths in the results structure, using string formatting and wildcards like '*' and '**'. This allows for flexible organization of variables based on runtime data. ```html # path will be formaed dynamically hostname='switch-1' serial='AS4FCVG456' model='WS-3560-PS' # variables that will be saved under {'vars': {'ip': []}} path IP="Undefined" MASK="255.255.255.255" # set of vars in yaml format that will not be included in results intf_mode: "layer3" interface Vlan777 description Management ip address 192.168.0.1 24 vrf MGMT ! interface {{ interface }} description {{ description }} ip address {{ ip | record("IP") }} {{ mask }} vrf {{ vrf }} {{ mode | set("intf_mode") }} ``` -------------------------------- ### DeepDiff Comparison with Jinja2 Templates Source: https://ttp.readthedocs.io/en/latest/Outputs/Functions This example demonstrates comparing hierarchical data using Jinja2 templates and DeepDiff. It defines input data for two states ('data_before' and 'data_after') and uses the 'output deepdiff' directive to highlight changes, specifically focusing on IP address modifications in network interfaces. ```jinja ``` -------------------------------- ### Conditional CSV Output Example in Python Source: https://ttp.readthedocs.io/en/latest/_sources/Outputs/Attributes.rst Demonstrates how to conditionally run a CSV output formatter using the 'condition' attribute in TTP. It shows setting a template variable to control whether the CSV output is generated. This example requires the TTP library and Python's pprint for output. ```python from ttp import ttp import pprint data = """ interface GigabitEthernet1/3.251 description Customer #32148 encapsulation dot1q 251 ip address 172.16.33.10 255.255.255.128 shutdown ! interface GigabitEthernet1/4 description vCPEs access control ip address 172.16.33.10 255.255.255.128 " " template = """ interface {{ interface }} description {{ description }} encapsulation dot1q {{ vlan }} ip address {{ ip }} {{ mask }} """ parser1 = ttp(data=data, template=template, vars={"convert_to_csv": False}) parser1.parse() res1 = parser1.result() parser2 = ttp(data=data, template=template, vars={"convert_to_csv": True}) parser2.parse() res2 = parser2.result() pprint.pprint(res1) # prints: # [[[{'interface': 'GigabitEthernet1/3.251', # 'ip': '172.16.33.10', # 'mask': '255.255.255.128', # 'vlan': '251'}, # {'interface': 'GigabitEthernet1/4', # 'ip': '172.16.33.10', # 'mask': '255.255.255.128'}]]] pprint.pprint(res2) # prints: # '"interface","ip","mask","vlan"\n' # '"GigabitEthernet1/3.251","172.16.33.10","255.255.255.128","251"\n' # '"GigabitEthernet1/4","172.16.33.10","255.255.255.128",""' ```