0

So here is my current playbook

---
- hosts: SWITCHES
  gather_facts: no

  tasks:
  - name: Show Interface Status
    ios_command:
    commands:
        - show int status 
    register: out

  - debug: var=out.stdout_lines

I basically want to take this script, and then disable all the ports in the "notconnect" state, meaning all the ports with nothing connected to them. Is there a way I can add a "when" statement to this, so that when "show interface status" comes back, it looks at all the ports that are not connected and disables them by applying the "shutdown" command to each interface? I think a "when" statement is what I am needing to do, but not sure where to get started with it. Or is there a better way to accomplish this?

Is there a python script that could accomplish this as well?

Jimmy
  • 31
  • 1
  • 7
  • 1
    Since I seriously doubt that the average users (me included) will have an IOS enabled device to test your above command against and see what the registered data structure looks like, you will get a much better chance to get an answer if you add an output of your debug task to your question. – Zeitounator Oct 13 '20 at 17:07

1 Answers1

1

You should use ios_facts to retrieve a dictionary containing all the interfaces. Then you can iterate over that dictionary to shutdown the interfaces that are not connected.

If you run your playbook using the -vvv switch, you will see the all the variables collected by ios_facts.

I believe in Ansible 2.9 and later, Ansible gathers the actual network device facts if you specify "gather_facts: yes". With Ansible 2.8 or older, you need to use the "ios_facts" module.

---
- hosts: SWITCHES
  gather_facts: no

  tasks:
  - name: gather IOS facts
    ios_facts:

  - name: Shutdown notconnect interfaces
    ios_config:
      lines: shutdown
      parents: "interface {{ item.key }}"
    with_dict: "{{ ansible_net_interfaces }}"
    when: item.value.operstatus == "down"

Here is an example from part of a collected "ansible_net_interfaces" variable:

{
    "ansible_net_interfaces": {
        "GigabitEthernet0/0": {
            "bandwidth": 1000000,
            "description": null,
            "duplex": "Full",
            "ipv4": [],
            "lineprotocol": "down",
            "macaddress": "10b3.d507.5880",
            "mediatype": "RJ45",
            "mtu": 1500,
            "operstatus": "administratively down",
            "type": "RP management port"
        },
        "GigabitEthernet1/0/1": {
            "bandwidth": 1000000,
            "description": null,
            "duplex": null,
            "ipv4": [],
            "lineprotocol": null,
            "macaddress": "10b3.d507.5881",
            "mediatype": "10/100/1000BaseTX",
            "mtu": 1500,
            "operstatus": "down",
            "type": "Gigabit Ethernet"
        },
        "GigabitEthernet1/0/10": {
            "bandwidth": 1000000,
            "description": "Telefon/PC",
            "duplex": null,
            "ipv4": [],
            "lineprotocol": null,
            "macaddress": "null,
            "mediatype": "10/100/1000BaseTX",
            "mtu": 1500,
            "operstatus": "down",
            "type": "Gigabit Ethernet"
        },
        "GigabitEthernet1/0/11": {
            "bandwidth": 1000000,
            "description": null,
            "duplex": null,
            "ipv4": [],
            "lineprotocol": null,
            "macaddress": "10b3.d507.588b",
            "mediatype": "10/100/1000BaseTX",
            "mtu": 1500,
            "operstatus": "down",
            "type": "Gigabit Ethernet"
        }
    }

The value of the "ansible_net_interfaces" variable is a dictionary. Each key in that dictionary is the interface name, and the value is a new dictionary containing new key/value pairs. The "operstatus" key will have a value "down" when the interface is not connected.

Using "with_dict" in the "ios_config" task loops through all top-level key/value pairs in the dictionary, and you can use the variables in each key/value pair by referring to "{{ item.key }}" or "{{ item.value }}".

Using "when" in the "ios_config" task, you set a condition for when the task is to be executed. In this case we only want it to run when "operstatus" has a value of "down".

The "parents" parameter in the "ios_config" task specifies a new section where the configuration is to be entered, in this case the section is the interface configuration mode. The interface name is returned for each interface in the "ansible_net_interfaces" using the "{{ item.key }}" variable.

Refer to Ansibles documentation for these modules to get a better understanding of them: https://docs.ansible.com/ansible/latest/collections/cisco/ios/ios_facts_module.html https://docs.ansible.com/ansible/latest/collections/cisco/ios/ios_config_module.html

Pluppo
  • 71
  • 6
  • 1
    Thank you for your answer; please consider enabling the new (easier) syntax highlighting support by including `yaml` after the three backticks – mdaniel Oct 13 '20 at 19:59
  • 1
    Thanks for the tip, I have edited the post and updated the formatting. – Pluppo Oct 13 '20 at 21:55
  • So gather facts or ios_facts can build a text file and list all the interfaces in the "notconnect" state, and then i add another task to look at that text file and shut down all interfaces in that state, based off the list generated. Is that correct? – Jimmy Oct 14 '20 at 18:50
  • Hi @Jimmy, Ansible will gather "facts" using the "ios_facts" module and store them in memory as variables. To see what is gathered, run a playbook containing the "ios_facts" task only, and run ansible-playbook with -vvv to see all the gathered variables. – Pluppo Oct 15 '20 at 06:45
  • I have edited the post to contain an example from an IOS switch I now have access to. – Pluppo Oct 15 '20 at 07:08
  • Pluppo, thanks a lot! I will go over this and see what I come up with. I am very new to ansible so still trying to understand things. – Jimmy Oct 15 '20 at 11:27