Parsing Command Output
Tom can parse raw command output into structured data using TextFSM or TTP templates.
Specifying a Template
To parse command output, specify a template explicitly:
curl -X POST "http://localhost:8000/api/device/router1/send_command" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"command": "show version",
"wait": true,
"parse": true,
"template": "cisco_ios_show_version.textfsm"
}'
This returns structured JSON instead of raw text.
Choosing a Parser
Tom supports two parsing engines:
- TextFSM (default) - Regex-based, includes 900+ templates from ntc-templates
- TTP - Template Text Parser, more readable template syntax. Includes 19 templates from ttp-templates plus support for custom templates with auto-discovery.
Specify with the parser field:
{
"command": "show version",
"wait": true,
"parse": true,
"parser": "ttp",
"template": "my_template.ttp"
}
Built-in Template Libraries
Tom includes two template libraries:
- TextFSM: ntc-templates - over 900 templates covering common commands across Cisco, Arista, Juniper, and many other platforms
- TTP: ttp-templates - 19 templates for Cisco IOS/XR, Arista, Huawei, and Juniper
Listing Available Templates
curl "http://localhost:8000/api/templates/textfsm" \
-H "X-API-Key: your-api-key"
Automatic Template Matching
If you specify parse=true but don't specify a template, Tom will attempt to find one automatically based on:
- Platform (from your inventory's
adapter_driver) - Command being executed
For example, show ip interface brief on a cisco_ios device automatically matches cisco_ios_show_ip_interface_brief.textfsm:
curl -X POST "http://localhost:8000/api/device/router1/send_command" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"command": "show ip interface brief",
"wait": true,
"parse": true
}'
If no matching template is found, parsing fails with an error.
Both TextFSM (via ntc-templates) and TTP (via ttp-templates) support automatic template discovery based on platform and command.
Template Source Selection
By default, when looking for a template Tom checks custom templates first, then falls back to the built-in library (ntc-templates for TextFSM, ttp-templates for TTP). You can override this with the template_source parameter to force loading from a specific source.
Valid values depend on the parser:
- TextFSM:
"custom"or"ntc" - TTP:
"custom"or"ttp_templates"
This is useful when you have a custom template with the same name as a built-in one and need to explicitly select which one to use:
{
"command": "show version",
"wait": true,
"parse": true,
"template": "cisco_ios_show_version.textfsm",
"template_source": "ntc"
}
template_source works with both explicit template names and auto-discovery. When used with auto-discovery (no template specified), it restricts which index is searched:
{
"command": "show version",
"wait": true,
"parse": true,
"template_source": "custom"
}
This would only search the custom template index, skipping ntc-templates entirely. If no match is found in the specified source, parsing fails rather than falling back.
The template_source parameter is available on all parsing-related endpoints and request models, including send_command, send_commands (both per-command and as a default), raw endpoints, job result retrieval, and the /parse/test endpoint.
Response Metadata
When parsing succeeds, the response includes _metadata indicating which source the template came from:
{
"parsed": [...],
"_metadata": {
"template_source": "ntc",
"template_name": "cisco_ios_show_version.textfsm"
}
}
Using Custom Templates
To add your own templates:
- Create a directory with your template files
- Mount it into the controller container at
/app/templates/textfsm/(for TextFSM) or/app/templates/ttp/(for TTP)
In your docker-compose:
services:
controller:
volumes:
- ./my-templates:/app/templates/textfsm
Custom templates take precedence over built-in templates with the same name.
Template Index Files
For auto-discovery to work with custom templates, you need an index file in your template directory. The index maps platform/command combinations to template files:
Template, Hostname, Platform, Command
custom_show_version.textfsm, .*, cisco_ios, show version
datacenter_bgp.textfsm, dc-.*, cisco_ios, show ip bgp.*
Each column:
- Template: Filename of the template in the same directory
- Hostname: Regex to match device hostname (use
.*for all devices) - Platform: Device platform (must match exactly, e.g.,
cisco_ios) - Command: Regex to match the command
When you create templates via the API with platform and command fields, the index is updated automatically. When you delete a template via the API, its index entry is also removed.
Template Naming Convention
For automatic matching to work with custom templates, follow the NTC naming convention:
{platform}_{command_with_underscores}.textfsm
Example: cisco_ios_show_ip_route.textfsm
You'll never guess how you should name your TTP templates!
Creating Templates via the API
You can create custom templates through the API instead of mounting files:
curl -X POST "http://localhost:8000/api/templates/textfsm" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"name": "custom_show_vlan.textfsm",
"content": "Value VLAN_ID (\\d+)\nValue NAME (\\S+)\n\nStart\n ^${VLAN_ID}\\s+${NAME} -> Record\n",
"platform": "cisco_ios",
"command": "show vlan"
}'
When platform and command are provided, the template is automatically registered in the index file for auto-discovery. You can also specify a hostname pattern (defaults to .*).
Including Raw Output
To get both parsed and raw output:
{
"command": "show ip interface brief",
"wait": true,
"parse": true,
"include_raw": true
}
Returns:
{
"parsed": [...],
"raw": "Interface IP-Address OK? Method Status..."
}