Generating a Compliance Report

Overview

The compliance report is generated based on a YAML-formatted validation file that describes the desired state of the network. The input data is organized into three primary dictionaries, each of which can define the entire feature set or a subset of features.

  • hosts: Host name dictionaries containing sub-dicts of host-specific features to be validated

  • groups: Group name dictionaries of group-specific features to be validated

  • all: Dictionary of variables defining features that apply across all hosts

Note

The hostname or group name must match exactly those defined in the Nornir inventory. In cases where there are conflicts between feature definitions, groups take precedence over all and hosts over groups (hosts > groups > all).

Validation Examples

The following validation file example demonstrates the inheritance mechanism, it would validate:

  • The port-channel state and port membership for all devices

  • The image version for devices in the iosxe group

  • The OSPF interfaces and neighbors on host HME-RTR01

all:
  intf_bonded:
    port_channel:
      Po2:
        protocol: LACP
        members: [Gi0/15, Gi0/16]
groups:
  iosxe:
    system:
      image: 16.6.2
hosts:
  HME-RTR01:
    route_protocol:
      ospf_intf_nbr:
        Gi1/1:
          pid: 1
          area: 0
        Vl120:
          pid: 1
          area: 0
          nbr: [192.168.10.2, 192.168.10.3]

Comprehensive examples for all supported operating systems and features can be found in the example_validation_files directory.

Running Nornir Validate

The validate method is imported directly into a script leveraging the existing Nornir inventory. A customised version of nornir_rich is used to print the result so that the sub-feature names can be incorporated into the printed results.

import yaml
from nornir import InitNornir
from nornir_validate import validate, print_result_val

nr = InitNornir(config_file="config.yml")

with open("input_val_data.yml") as tmp_data:
    input_data = yaml.load(tmp_data, Loader=yaml.Loader)

result = nr.run(task=validate, input_data=input_data)
print_result_val(result)

Alternatively, you can just feed the data in direct rather than loading it from a file.

input_data = {
    "groups": {
        "ios": {
            "intf_bonded": {
                "port_channel": {
                    "Po1": {"protocol": "LACP", "members": ["Gi0/2", "Gi0/3"]}
                }
            },
        }
    }
}
result = nr.run(task=validate, input_data=input_data)
print_result_val(result)

By default the compliance report is printed to screen only if the validation fails (Nornir task marked as failed), add the print_report=True argument to also print the report if the validation passes. The report can also be saved to file (hostname_compliance_report_YYYYMMDD-HHMM.json), add save_report= with an explicit directory path or "" for the current directory.

result = nr.run(task=validate, input_data=input_data, print_report=True, save_report="")

Compliance Report

The compliance report compares desired and actual state via napalm-validate (are iterated through it), producing sub-feature-level compliance entries that aggregate into an overall compliance status. Any failure (strict mismatch, missing peer, etc.) marks the report as non-compliant.

Failed compliance report example

Example of a failed report due to global routing table missing 1 route (all other validations comply)