Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[proposal] Plugin to validate network configuration against a predefined rule set #15

Closed
NilashishC opened this issue Jun 5, 2021 · 1 comment
Labels
proposal proposal for network collections

Comments

@NilashishC
Copy link
Contributor

Proposal:

Add support for a config validation plugin that evaluates network configurations against a predefined set of rules and renders warnings/failures based on the outcome of the validation task. This is aimed to precede *_config tasks in a playbook and would allow us to catch potential errors in the candidate config before the succeeding tasks make configuration changes on the target. The rule set(s) are expected to be implemented by the users based on their exact needs and target platforms.

  • Status: New
  • Proposal type: Action Plugin
  • Targeted Release:
  • Associated PR:

Motivation

Describe the reasons for this proposal.
Have the ability to determine the "correctness" of the configuration to be pushed and ensure a more predictable outcome from the *_config modules.

Problems

As a user of the *_config modules:

  • I want to ensure that the candidate configuration is properly linted to minimize idempotence issues.
  • I want to ensure that every candidate configuration pushed to the target device is in terms with a rule set.

Solution proposal

Playbook:

- hosts: sw01
  gather_facts: no
  tasks:
  - name: Validate candidate config against a pre-defined set of rules
    ansible.utils.validate_config:
      config: "{{ lookup('file', 'candidate.cfg') }}"
      rules: "{{ role_path }}/rules/rules.yaml"

candidate.cfg:

interface Eth1/1
  description test-description-too-long
  no switchport

interface Ethernet1/2
  description intf-2

interface port-channel1
  description po-1

interface po2.1
  description po2

interface Loopback 10
  description lo10

rules.yaml:

---
- name: 1. Interface description should not be more than 8 chars
  example: "Matches description this-is-a-long-description"
  rule: 'description\s(.{9,})'
  action: warn

- name: Ethernet interface names should be in format Ethernet[Slot/chassis number].[sub-intf number (optional)]
  example: "Matches interface Eth1/1, interface Eth 1/1, interface Ethernet 1/1, interface Ethernet 1/1.100"
  rule: 'interface\sE(?!\w{7}\d/\d(.\d+)?)'
  action: fail

- name: Ethernet interface names should be in format Ethernet[Slot/chassis number].[sub-intf number (optional)]
  example: "Matches interface eth1/1, interface eth 1/1, interface ethernet 1/1, interface ethernet 1/1.100"
  rule: 'interface\se(?!\w{7}\d/\d(.\d+)?)'
  action: fail

- name: Loopback interface names should be in format loopback[Virtual Interface Number]
  example: "Matches interface Lo10, interface Loopback 10"
  rule: 'interface\sl(?!\w{7}\d)'
  action: fail

- name: Loopback interface names should be in format loopback[Virtual Interface Number]
  example: "Matches interface lo10, interface loopback 10"
  rule: 'interface\sL(?!\w{7}\d)'
  action: fail

- name: Port Channel names should be in format port-channel[Port Channel number].[sub-intf number (optional)]
  example: "Matches interface port-channel 10, interface po10, interface port-channel 10.1"
  rule: 'interface\sp(?!\w{3}-\w{7}\d(.\d+)?)'
  action: fail

- name: Port Channel names should be in format port-channel[Port Channel number].[sub-intf number (optional)]
  example: "Matches interface Port-channel 10, interface Po10, interface Port-channel 10.1"
  rule: 'interface\sP(?!\w{3}-\w{7}\d(.\d+)?)'
  action: fail

Result:

result: {
  failures: [
    {
        "name": Ethernet interface names should be in format Ethernet[Slot/chassis number].[sub-intf number (optional)],
        "rule": 'interface\sE(?!\w{7}\d/\d(.\d+)?)',
        "config_line": "interface Eth1/1",
    },
    {
        "name": Port Channel names should be in format port-channel[Port Channel number].[sub-intf number (optional)],
        "rule": 'interface\sp(?!\w{3}-\w{7}\d(.\d+)?)',
        "config_line": "interface po2.1",
    },
    {
        "name": Loopback interface names should be in format loopback[Virtual Interface Number],
        "rule": 'interface\sL(?!\w{7}\d)',
        "config_line": "interface Loopback 10",
    },
  ],
  warnings: [
    {
        "name": "Interface description should not be more than 8 chars",
        "rule": "description\s(.{9,})",
        "config_line": "description test-description-too-long", 
    },
  ]
}
@NilashishC NilashishC added the proposal proposal for network collections label Jun 5, 2021
@ganeshrn
Copy link
Member

ganeshrn commented Jun 7, 2021

I think it should implement as a sub-plugin of validate plugin
For example:

- hosts: sw01
  gather_facts: no
  tasks:
  - name: Validate candidate config against a pre-defined set of rules
    ansible.utils.validate:
      data: "{{ lookup('file', 'candidate.cfg') }}"
      engine: "ansible.netcommon.native_validator".   # name subject to bikeshedding :-)
      criteria:
      - "{{ role_path }}/rules/rules.yaml"

ansible-zuul bot pushed a commit to ansible-collections/ansible.utils that referenced this issue Jan 28, 2022
New validate sub-plugin "config"

SUMMARY


Implement ansible-collections/ansible.network#15 as a validate sub-plugin.
ISSUE TYPE


Feature Pull Request

COMPONENT NAME

validate

Reviewed-by: Ganesh Nalawade <None>
Reviewed-by: Nilashish Chakraborty <nilashishchakraborty8@gmail.com>
Reviewed-by: Nathaniel Case <this.is@nathanielca.se>
Reviewed-by: None <None>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal proposal for network collections
Projects
None yet
Development

No branches or pull requests

2 participants