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

Network Interfaces Resource Module #1

@trishnaguha

Description

@trishnaguha

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.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions