Skip to content

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 .yml and .yaml files in the rules/ directory (and subdirectories) are loaded recursively.
  • Files containing sample in 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"