Skip to content
This repository has been archived by the owner on Apr 20, 2021. It is now read-only.

Network Interfaces Resource Module #1

Open
trishnaguha opened this issue Mar 6, 2019 · 1 comment
Open

Network Interfaces Resource Module #1

trishnaguha opened this issue Mar 6, 2019 · 1 comment
Assignees

Comments

@trishnaguha
Copy link
Member

trishnaguha commented Mar 6, 2019

Proposal: network interfaces resource module

Author: Trishna Guha <@trishnaguha>

Date: 2019-03-06

Motivation

  • Increase adoption through consistency, transparency and adaptability by returning the resource as currently configured on the device by way of the Ansible Facts system and making modules idempotent.
  • Focus on network operations

Problems

Implementing resource module with a Provider Role

  • Requires most of the command generation logic to be added in jinja2 template
  • For adding more options in module argspec requires adding complex programming logic within jinja2 template/yaml.

Solution Proposal

Model

{{ ansible_network_os }}_interfaces:
  state: { default: merged, choices: [merged, replaced, overriden, deleted] }
  config:
    - name: {required=True}
      description: { type: str }
      enable: { type: bool }
      speed: { type: str }
      mtu: { type: str }
      duplex: { type: str, choices: [full, half, auto] }
      mode: { type: str, choices: [layer2, layer3])

Module has a parent “config” and “operation” key

argument_spec = {
  'state: dict(default='merged', choices=['merged', 'replaced', 'overriden', 'deleted']),
  'config': dict(type='list', elements='dict', options=config_spec)
}

"State"

  • merged: the provided config with the current
  • replaced: the current config with the provided
  • overriden: Replace current, add new, remove missing
  • deleted: Remove properties of the interface

Playbook

- hosts: nxos
  connection: network_cli
  gather_facts: yes
  #gather_subset: net_configuration_interfaces

- nxos_interfaces:
    state: merged
    # config: "{{ ansible_facts['net_configuration']['interfaces'] }}"
    config:
      - name: Ethernet1/1
        description: 'Configured by Ansible'
        enable: False
      - name: Ethernet1/2
        mode: layer3

Return

  • The exact commands issued on the device (mask sensitive/disable)
  • The before and after resource configuration as structured data
{
  commands: [
    'interface Ethernet1/1,
    'description Configured by Ansible',
    'shutdown'
  ],
  before: [
    {
      "description": null, 
      "duplex": null, 
      "enable": true, 
      "mode": null, 
      "mtu": null, 
      "name": "Ethernet1/1", 
      "speed": null
    }
  ],
  after: [
    {
      "description": Configured by Ansible,
      "duplex": null, 
      "enable": false, 
      "mode": null, 
      "mtu": null, 
      "name": "Ethernet1/1", 
      "speed": null
    }
  ]
}

Gathered Facts
Facts gathered when gather_facts or gather_subset is enabled.

gather_subset: net_configuration_interfaces

"ansible_facts": {
        "net_configuration": {
            "interfaces": [
                {
                    "description": "Configured by Ansible", 
                    "duplex": null, 
                    "enable": false, 
                    "fabric_forwarding_anycast_gateway": null, 
                    "ip_forward": null, 
                    "mode": null, 
                    "mtu": null, 
                    "name": "Ethernet1/1", 
                    "speed": null
                },
                {
                    "description": "Configured by Ansible Network", 
                    "duplex": null, 
                    "enable": false, 
                    "fabric_forwarding_anycast_gateway": null, 
                    "ip_forward": null, 
                    "mode": null, 
                    "mtu": null, 
                    "name": "Ethernet1/2", 
                    "speed": null
                },
                {
                    "description": null, 
                    "duplex": null, 
                    "enable": true, 
                    "fabric_forwarding_anycast_gateway": null, 
                    "ip_forward": null, 
                    "mode": layer2, 
                    "mtu": null, 
                    "name": "Ethernet1/3", 
                    "speed": null
                }
            ]
        }
  }

Implementation

  • Entry point of module -> modules/network/{{ ansible_network_os }}/{{ ansible_network_os }}_interfaces.py
  • Define argspec in a shared space for the module and facts gathering.
  • Module Implementation -> module_utils/network/{{ ansible_network_os }}/config/interfaces/interfaces.py
  • Facts Implementation -> module_utils/network/{{ ansible_network_os }}/facts/interfaces/interfaces.py
  • Write action plugin for each platform that would call platform specific _facts module to generate Facts with subset e.g, [interfaces]. This guarantees that we have unified ansible_facts data model across both facts generated at play level or task level in module calls and do not need to get config and parse within the module by just reusing facts implementation.
  • Generate Commands based on the diff between candidate and gathered facts.
  • If changed, generate after and before resource facts.
  • If not changed, generate only before resource facts.
@ganeshrn
Copy link
Member

ganeshrn commented Mar 7, 2019

Since the operational and configuration facts are different can we have separate top level keys to store the facts?
For eg.

{ 
    ansible_net_operational: 
        {
             interfaces: [...],
             bgp: [...]
        }
      ansible_net_configuration:
        {
            interfaces: [...],
            bgp: [....]
        }
}

This also is in sync with the two prompt modes supported by most vendors (operational and configuration mode) on the device.

The facts extracted from show commands (except show running-config) executed in the operational mode (eg. show interfaces) can be stored under ansible_net_operational

and the facts extracted from show commands executed under config mode including show running-config can be stored under ansible_net_configuration key.

The proposed resource modules will provide the individual configuration facts in the module arspec pattern that can be stored in ansible_net_configuration key within ansible_facts.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants