Ansible to connect to certain switchports on Cisco 2960

I am working on a project that would require me to bump (shutdown and re-enable) switchports that are connected to an Access Point.

I have created a playbook to run a command “show cdp neighbours” on the switch, and that output would look like:

What I want to do, is to use ansible to only run a command (ansible play) on Gig 1/0/19 in this case. For other switches, it may be more switchports and maybe in different format (eg. Gi 2/0/35).

Is there a way to filter ansible output by looking for ‘AIR-AP280’ and then extract that corresponding Local Interface (switchport number)?

Or if there is another way to get done what I want, then great.

Any suggestions/recommendations?

It is over 50 switches, so it would be great if ansible can do what I want to do.

I would use the genie module and run the show cdp neighbor command. Then set fact and use that with the when command.

(attachments)

Thanks. If you don’t mind me asking because I am not familiar with this, can you give me an example of how to use the set fact and when statement for my case?

Something like that I suppose.

#Sets a varaiable for cdp neighbor detail

  • name: Run show cdp neighbors command
    ios_command:
    commands:
  • show cdp neighbors detail
    register: neighbors

Using the Genie Filter Plugin from the Genie Parse Role

Set pyats_neighbors as a dictionary

  • name: Set fact with Genie Filter Plugin
    set_fact:
    pyats_neighbors: “{{ neighbors[‘stdout’][0] | clay584.genie.parse_genie(command=‘show cdp neighbors detail’, os=‘ios’) }}”

  • name: Add interface desription
    ios_interfaces:
    config:

  • name: “{{ item.value.local_interface }}”
    description: “{{ item.value.device_id }} - {{ item.value.port_id }}”
    state: merged
    loop: “{{ q(‘dict’, pyats_neighbors.index) }}”

when: item.value.port_id is “AIR-AP280”

Thanks alot.

I have been getting this error for the past few days when trying to use genie:

fatal: [SW1]: FAILED! => {
“msg”: “template error while templating string: no filter named ‘clay584.genie.parse_genie’. String: {{ neighbors[‘stdout’][0] | clay584.genie.parse_genie(command=‘show cdp neighbors’, os=‘ios’) }}”
}

This is my playbook (what you sent but I needed to import the role first):

  • hosts: uwioc-switches
    gather_facts: no
    tasks:

  • name: Import role
    include_role:
    name: clay584.parse_genie

  • name: Run show cdp neighbors
    ios_command:
    commands:

  • show cdp neighbors
    register: neighbors

Using the Genie Filter Plugin from the Genie Parse Role

Set pyats_neighbors as a dictionary

  • name: Set fact with Genie

  • name: Import role
    include_role:
    name: clay584.parse_genie

  • name: Run show cdp neighbors
    ios_command:
    commands:

  • show cdp neighbors
    register: neighbors

Using the Genie Filter Plugin from the Genie Parse Role

Set pyats_neighbors as a dictionary

  • name: Set fact with Genie Filter Plugin
    set_fact:
    pyats_neighbors: “{{ neighbors[‘stdout’][0] | clay584.genie.parse_genie(command=‘show cdp neighbors’, os=‘ios’) }}”

  • name: Add interface description
    ios_interfaces:
    config:

  • name: “{{ item.value.local_interface }}”
    description: “{{ item.value.device_id }} - {{ item.value.port_id }}”
    state: merged
    loop: “{{ q(‘dict’, pyats_neighbors.index) }}”
    when: item.value.port_id is “AIR-AP280”

My python version is 3.6.8 and Ansible is 2.9.9

I followed this guide to install the necessary libraries:
https://developer.cisco.com/codeexchange/github/repo/clay584/parse_genie/

The error still persists. Also posted the issue on GitHub. Not sure if it is bug in the parsing library.

Any assistance would greatly be appreciated.

Thanks.

I am using the collection not the role. So it looks like this at the top. Had to add the interpreter variable because Ansible kept using Python 2

This error shows:

fatal: [SW1]: FAILED! => {“msg”: “template error while templating string: no filter named ‘clay584.genie.parse_genie’. String: {{ neighbors[‘stdout’][0] | clay584.genie.parse_genie(command=‘show cdp neighbors’, os=‘ios’) }}”}

This is the full playbook I am using:

Not sure it seems like it is looking for the filter. Have you used a collection before? Is the collections_path defined in the ansible.cfg?

No I have never used a collection before. So my ansible.cfg is currently to the default

You need to add a new line under [defaults]

collections_paths = /path/to/collections

I added it. Now this shows:

fatal: [SW1]: FAILED! => {
“msg”: “parse_genie: Genie package is not installed. To install, run ‘pip install genie’.”
}

When I do pip or pip3 install genie, it says requirements already satisfied (as I already installed it).

Just to show you what my directories look like:

And under [defaults] in my ansible.cfg:

collections_paths = /etc/ansible/collections/ansible_collections/

Tried putting a less specific and then a more specifc path to the collections folder also. (= /etc/ansible/collections, = /etc/ansible/collections/ansible_collections/clay584/genie)

Prior to this, I did a ansible-galaxy collection install clay584.genie to install the collection and it said this:
Installing ‘clay584.genie:0.1.11’ to ‘/root/.ansible/collections/ansible_collections/clay584/genie’

Did I do anything wrong?

Well at this point I would probably remove genie. Then create a virtual python environment. Run the pip install commands and see if that works for you. If you are still running into issues I would reach out to the guys who made genie - I think Clay is in the group there too.

https://eurl.io/#r18UzrQVr

(attachments)