Validation Rules Datasource¶
This datasource loads validation rules, their associated command parsers (called "collectors" in the YAML files), and validation rule groups from YAML files in a Git repository.
Directory Structure¶
The app supports two directory layout conventions. It checks for oc/ first, then falls back to operational-compliance/:
repository_root/
├── oc/ # or operational-compliance/
│ ├── rules/
│ │ ├── routing.yml # one or more YAML files
│ │ ├── interfaces.yml
│ │ └── system.yml
│ └── rule-groups/
│ ├── pre_change.yml
│ └── post_change.yml
- All
.ymland.yamlfiles in therules/directory (and subdirectories) are loaded recursively. - Files containing
samplein the filename are skipped. - The
rule-groups/directory is optional. If it does not exist, only rules are synced.
Validation Rules YAML Format¶
Each YAML file in the rules/ directory contains one or more rules as top-level keys. The key is a slug used to derive the display name if display_name is not provided.
---
# Key: rule slug (underscores become spaces, then title-cased for display_name)
bgp_neighbor_state:
display_name: "BGP Neighbor State" # optional, overrides slug-derived name
rule_type: "exact_match" # required: exact_match, tolerance, parameter_match, regex, or operator
description: "Verify BGP neighbor states" # optional
evaluate_args: # optional: kwargs passed to the jdiff comparison engine
tolerance: 5
collectors: # optional: list of command parsers to create
- name: "textfsm" # parser type: textfsm, napalm, ttp, or json
platform: "cisco_ios" # network_driver value of a Nautobot Platform
command: "show ip bgp summary" # CLI command to run on the device
jmespath: "[*].[$neighbor$, state_pfxrcd]" # JMESPath expression for data extraction
- name: "textfsm"
platform: "arista_eos"
command: "show ip bgp summary"
jmespath: "[*].[$bgp_neigh$, state_pfxrcd]"
Rule Fields¶
| YAML Field | Required | Model Field | Description |
|---|---|---|---|
display_name |
No | ValidationRule.name |
Human-readable name. Defaults to the slug with underscores replaced by spaces and title-cased. |
rule_type |
Yes | ValidationRule.rule_type |
One of: exact_match, tolerance, parameter_match, regex, operator |
description |
No | ValidationRule.description |
Free-text description of the rule |
evaluate_args |
No | ValidationRule.rule_options |
Dict of kwargs passed to jdiff for comparison. Required for tolerance rules (must include tolerance key). See the Rule Types Reference. |
collectors |
No | Creates CommandParser objects |
List of platform-specific command definitions (see below) |
Collector Fields¶
Each entry in the collectors list creates a CommandParser object linked to the parent validation rule.
| YAML Field | Required | Model Field | Description |
|---|---|---|---|
name |
Yes | CommandParser.parser |
Parser type: textfsm, napalm, ttp, or json |
platform |
Yes | CommandParser.platform |
The network_driver value of a Nautobot Platform (e.g., cisco_ios, arista_eos, juniper_junos). If no matching Platform exists, the collector is skipped with a warning. |
command |
No | CommandParser.command |
CLI command to execute on the device |
jmespath |
No | CommandParser.path |
JMESPath expression to extract data from parsed output |
napalm_getter |
No | CommandParser.napalm_getter |
NAPALM getter method name (e.g., get_facts, get_interfaces). Used when name is napalm. |
exclude |
No | CommandParser.exclude |
List of keys to exclude from comparison. Only valid with exact_match rule type. Cannot be combined with jmespath. |
Note
Each validation rule can have at most one collector per platform. The combination of (validation_rule, platform) must be unique.
Example: Validation Rules YAML Files¶
File: oc/rules/routing.yml
---
bgp_neighbor_state:
display_name: "BGP Neighbor State"
rule_type: "exact_match"
description: "Verify all BGP neighbor sessions remain in the same state"
collectors:
- name: "textfsm"
platform: "cisco_ios"
command: "show ip bgp summary"
jmespath: "[*].[$bgp_neigh$, state_pfxrcd]"
- name: "textfsm"
platform: "arista_eos"
command: "show ip bgp summary"
jmespath: "[*].[$bgp_neigh$, state_pfxrcd]"
- name: "textfsm"
platform: "juniper_junos"
command: "show bgp summary"
jmespath: "[*].[$peer_address$, received_routes]"
bgp_prefix_tolerance:
display_name: "BGP Prefix Count"
rule_type: "tolerance"
description: "Allow BGP received prefix counts to fluctuate within tolerance"
evaluate_args:
tolerance: 10
collectors:
- name: "textfsm"
platform: "cisco_ios"
command: "show ip bgp summary"
jmespath: "[*].[$bgp_neigh$, state_pfxrcd]"
ospf_neighbor_state:
display_name: "OSPF Neighbor State"
rule_type: "exact_match"
description: "Ensure OSPF adjacencies remain stable"
collectors:
- name: "textfsm"
platform: "cisco_ios"
command: "show ip ospf neighbor"
jmespath: "[*].[$neighbor_id$, state]"
- name: "textfsm"
platform: "arista_eos"
command: "show ip ospf neighbor"
jmespath: "[*].[$neighbor_id$, state]"
File: oc/rules/interfaces.yml
---
interface_status:
display_name: "Interface Status"
rule_type: "exact_match"
description: "Monitor interface operational state"
collectors:
- name: "napalm"
platform: "cisco_ios"
napalm_getter: "get_interfaces"
jmespath: "*.{is_up: is_up, is_enabled: is_enabled}"
- name: "napalm"
platform: "arista_eos"
napalm_getter: "get_interfaces"
jmespath: "*.{is_up: is_up, is_enabled: is_enabled}"
interface_counters:
display_name: "Interface Counters"
rule_type: "exact_match"
description: "Compare interface data excluding volatile statistics"
collectors:
- name: "napalm"
platform: "cisco_ios"
napalm_getter: "get_interfaces"
exclude:
- "tx_errors"
- "rx_errors"
- "tx_discards"
- "rx_discards"
File: oc/rules/system.yml
---
device_facts:
display_name: "Device Facts"
rule_type: "exact_match"
description: "Verify device facts have not changed"
collectors:
- name: "napalm"
platform: "cisco_ios"
napalm_getter: "get_facts"
jmespath: "{hostname: hostname, model: model, os_version: os_version}"
- name: "napalm"
platform: "arista_eos"
napalm_getter: "get_facts"
jmespath: "{hostname: hostname, model: model, os_version: os_version}"
ntp_sync:
display_name: "NTP Synchronization"
rule_type: "exact_match"
description: "Ensure NTP peers remain consistent"
collectors:
- name: "textfsm"
platform: "cisco_ios"
command: "show ntp associations"
jmespath: "[*].[$address$, ref_clock]"
- name: "textfsm"
platform: "juniper_junos"
command: "show ntp associations"
jmespath: "[*].[$remote$, refid]"
os_version_compliance:
display_name: "OS Version Compliance"
rule_type: "parameter_match"
description: "Check devices are running approved OS version"
evaluate_args:
params:
os_version: "17.12.2"
mode: "match"
collectors:
- name: "napalm"
platform: "cisco_ios"
napalm_getter: "get_facts"
jmespath: "os_version"
Validation Rule Groups YAML Format¶
Each YAML file in the rule-groups/ directory contains one or more groups as top-level keys. Groups reference validation rules by their display name (not the slug).
---
pre_change_checks:
display_name: "Pre-Change Validation" # optional, defaults to slug-derived name
description: "Rules to run before changes" # optional
validation_rules: # list of validation rule display names
- "BGP Neighbor State"
- "OSPF Neighbor State"
- "Interface Status"
- "Device Facts"
Warning
Rules referenced in a group must already exist in the database (i.e., the rules YAML files are processed before groups). If a referenced rule name is not found, a warning is logged and the rule is skipped — the group is still created with the remaining rules.
Group Fields¶
| YAML Field | Required | Model Field | Description |
|---|---|---|---|
display_name |
No | ValidationRuleGroup.name |
Human-readable name. Defaults to the slug with underscores replaced by spaces and title-cased. |
description |
No | ValidationRuleGroup.description |
Free-text description of the group |
validation_rules |
No | ValidationRuleGroup.validation_rules (M2M) |
List of validation rule display names to include in the group |
Example: Validation Rule Groups YAML Files¶
File: oc/rule-groups/change_management.yml
---
pre_change_validation:
display_name: "Pre-Change Validation"
description: "Comprehensive checks to run before a maintenance window"
validation_rules:
- "BGP Neighbor State"
- "OSPF Neighbor State"
- "Interface Status"
- "Device Facts"
- "NTP Synchronization"
routing_health:
display_name: "Routing Health"
description: "Focused routing protocol validation"
validation_rules:
- "BGP Neighbor State"
- "BGP Prefix Count"
- "OSPF Neighbor State"
platform_baseline:
display_name: "Platform Baseline"
description: "Hardware and software compliance checks"
validation_rules:
- "Device Facts"
- "OS Version Compliance"