[PYTHON] I made my own filter plugin for text parsing of Ansible

Introduction

In the previous article, I used a Python parser library called TTP (Template Text Parser) to parse the L2SW Config file and automatically generate a port management table. I tried to automatically generate a port management table from L2SW Config

This time, I took this parser as an Ansible custom filter so that I could parse the show command result obtained by the xxx_command module.

setup

I used Ansible installed in the virtual environment of Python 3.6.7. Initially, I was testing with version 2.9.0, but I am using 2.8.4 because I got multiple Logging error (KeyError) messages.

An additional TTP installation is required.

(venv) [centos@localhost ansible]$ pip install ttp

Custom filter

I created the following Python script.

custom_filters_ttp.py


from ansible.errors import AnsibleError

#Import ttp and json. If the import fails, an error can be output in the subsequent processing.
try:
    from ttp import ttp
    HAS_TTP = True
except ImportError:
    HAS_TTP = False

try:
    import json
    HAS_JSON = True
except ImportError:
    HAS_JSON = False


class FilterModule(object):

    def parse_cli_ttp(self, cli_output, template_file):
        if not HAS_TTP:
            raise AnsibleError('parse_cli_ttp filter requires TTP library to be installed')

        if not HAS_JSON:
            raise AnsibleError('parse_cli_ttp filter requires JSON library to be installed')

        with open(template_file, 'rt') as ft:
            ttp_template = ft.read()

        # create parser object and parse data using template
        parser = ttp(data=cli_output, template=ttp_template)
        parser.parse()

        # return result in JSON format
        results = parser.result(format='json')[0]
        return results

    def filters(self):
        return {
            #The left side is the filter name used in the playbook, and the right side is the function name to be associated.
            'parse_cli_ttp': self.parse_cli_ttp,
        }

According to best practice, I created a filter_plugins directory under the directory where the playbook is stored, and stored this file in it.

In addition, the settings in ansible.cfg have been rewritten as follows so that Ansible can recognize this custom filter.

ansible.cfg


[defaults]
filter_plugins     = [Full path of the playbook storage directory]/filter_plugins

Playbook Get the Running Config in the ʻios_commandmodule, and in the followingdebug` module, get the obtained Config and the [L2 interface setting template] created in the previous article (https://qiita.com/tech_kitara/items/75ec526ff9a27932c565 # 3-l2% E3% 82% A4% E3% 83% B3% E3% 82% BF% E3% 83% BC% E3% 83% 95% E3% 82% A7% E3% 83% BC% E3% 82 % B9% E8% A8% AD% E5% AE% 9A) file path specified. It's simple!

playbook_ttp.yml


---

- hosts: cisco
  gather_facts: no
  connection: network_cli

  tasks:
    - name: run show command on remote devices
      ios_command:
        commands: show running-config
      register: result

    - name: display parsed output
      debug:
        msg: "{{ result.stdout[0] | parse_cli_ttp('catalyst2960_template_ttp2.txt') }}"

Output result

There is a difference in the result because the Config is different from the previous time, but the parse itself is done without problems.

$ ansible-playbook -i inventory_2960.ini playbook_ttp.yml

PLAY [cisco] *************************************************************************************************

TASK [run show command on remote devices] ********************************************************************
ok: [hqdist1A]

TASK [display parsed output] *********************************************************************************
ok: [hqdist1A] => {
    "msg": [
        {
            "l2_interfaces": [
                {
                    "description": "<< Connect hqdist1 and hqdist2 >>",
                    "duplex": "auto",
                    "mode": "trunk",
                    "port_no": "Port-channel1",
                    "portfast": "x",
                    "speed": "auto",
                    "status": "o",
                    "vlan": "1,101"
                },
                {
                    "description": "<< To hqborder1 Fa1 >>",
                    "duplex": "full",
                    "mode": "access",
                    "port_no": "FastEthernet0/1",
                    "portfast": "x",
                    "speed": "100",
                    "status": "o",
                    "vlan": "200"
                },
                {
                    "description": "<< To hqborder2 Fa1 >>",
                    "duplex": "full",
                    "mode": "access",
                    "port_no": "FastEthernet0/2",
                    "portfast": "x",
                    "speed": "100",
                    "status": "o",
                    "vlan": "202"
                },
                {
                    "description": "<< To hqaccess1 Fa0/23 >>",
                    "duplex": "full",
                    "mode": "access",
                    "port_no": "FastEthernet0/3",
                    "portfast": "x",
                    "speed": "100",
                    "status": "o",
                    "vlan": "100"
                },
                {
                    "duplex": "auto",
                    "mode": "trunk",
                    "port_no": "FastEthernet0/4",
                    "portfast": "x",
                    "speed": "auto",
                    "status": "o",
                    "vlan": "1"
                },
                {
                    "duplex": "auto",
                    "mode": "access",
                    "port_no": "FastEthernet0/5",
                    "portfast": "x",
                    "speed": "auto",
                    "status": "x",
                    "vlan": "1"
                },
                {
                    "duplex": "auto",
                    "mode": "access",
                    "port_no": "FastEthernet0/6",
                    "portfast": "x",
                    "speed": "auto",
                    "status": "x",
                    "vlan": "1"
                },
                {
                    "duplex": "auto",
                    "mode": "access",
                    "port_no": "FastEthernet0/7",
                    "portfast": "x",
                    "speed": "auto",
                    "status": "x",
                    "vlan": "1"
                },
                {
                    "duplex": "auto",
                    "mode": "access",
                    "port_no": "FastEthernet0/8",
                    "portfast": "x",
                    "speed": "auto",
                    "status": "x",
                    "vlan": "1"
                },
                {
                    "duplex": "auto",
                    "mode": "access",
                    "port_no": "FastEthernet0/9",
                    "portfast": "x",
                    "speed": "auto",
                    "status": "x",
                    "vlan": "1"
                },
                {
                    "duplex": "auto",
                    "mode": "access",
                    "port_no": "FastEthernet0/10",
                    "portfast": "x",
                    "speed": "auto",
                    "status": "x",
                    "vlan": "1"
                },
                {
                    "duplex": "auto",
                    "mode": "access",
                    "port_no": "FastEthernet0/11",
                    "portfast": "x",
                    "speed": "auto",
                    "status": "x",
                    "vlan": "1"
                },
                {
                    "duplex": "auto",
                    "mode": "access",
                    "port_no": "FastEthernet0/12",
                    "portfast": "x",
                    "speed": "auto",
                    "status": "o",
                    "vlan": "203"
                },
                {
                    "duplex": "auto",
                    "mode": "access",
                    "port_no": "FastEthernet0/13",
                    "portfast": "x",
                    "speed": "auto",
                    "status": "o",
                    "vlan": "100"
                },
                {
                    "duplex": "auto",
                    "mode": "access",
                    "port_no": "FastEthernet0/14",
                    "portfast": "x",
                    "speed": "auto",
                    "status": "x",
                    "vlan": "1"
                },
                {
                    "duplex": "auto",
                    "mode": "access",
                    "port_no": "FastEthernet0/15",
                    "portfast": "x",
                    "speed": "auto",
                    "status": "x",
                    "vlan": "1"
                },
                {
                    "duplex": "auto",
                    "mode": "access",
                    "port_no": "FastEthernet0/16",
                    "portfast": "x",
                    "speed": "auto",
                    "status": "x",
                    "vlan": "1"
                },
                {
                    "duplex": "auto",
                    "mode": "access",
                    "port_no": "FastEthernet0/17",
                    "portfast": "x",
                    "speed": "auto",
                    "status": "x",
                    "vlan": "1"
                },
                {
                    "duplex": "auto",
                    "mode": "access",
                    "port_no": "FastEthernet0/18",
                    "portfast": "x",
                    "speed": "auto",
                    "status": "x",
                    "vlan": "1"
                },
                {
                    "duplex": "auto",
                    "mode": "access",
                    "port_no": "FastEthernet0/19",
                    "portfast": "x",
                    "speed": "auto",
                    "status": "x",
                    "vlan": "1"
                },
                {
                    "duplex": "auto",
                    "mode": "access",
                    "port_no": "FastEthernet0/20",
                    "portfast": "x",
                    "speed": "auto",
                    "status": "x",
                    "vlan": "1"
                },
                {
                    "duplex": "auto",
                    "mode": "access",
                    "port_no": "FastEthernet0/21",
                    "portfast": "x",
                    "speed": "auto",
                    "status": "x",
                    "vlan": "1"
                },
                {
                    "duplex": "auto",
                    "mode": "access",
                    "port_no": "FastEthernet0/22",
                    "portfast": "x",
                    "speed": "auto",
                    "status": "x",
                    "vlan": "1"
                },
                {
                    "description": "<< To hqdist2 Fa0/23 >>",
                    "duplex": "auto",
                    "mode": "trunk",
                    "port_no": "FastEthernet0/23",
                    "portfast": "x",
                    "speed": "auto",
                    "status": "o",
                    "vlan": "1,101"
                },
                {
                    "description": "<< To hqdist2 Fa0/24 >>",
                    "duplex": "auto",
                    "mode": "trunk",
                    "port_no": "FastEthernet0/24",
                    "portfast": "x",
                    "speed": "auto",
                    "status": "o",
                    "vlan": "1,101"
                },
                {
                    "duplex": "auto",
                    "mode": "access",
                    "port_no": "GigabitEthernet0/1",
                    "portfast": "x",
                    "speed": "auto",
                    "status": "o",
                    "vlan": "1"
                },
                {
                    "duplex": "auto",
                    "mode": "access",
                    "port_no": "GigabitEthernet0/2",
                    "portfast": "x",
                    "speed": "auto",
                    "status": "o",
                    "vlan": "1"
                }
            ]
        }
    ]
}

PLAY RECAP ***************************************************************************************************
hqdist1A                   : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

Finally

The plugin I made this time has been uploaded to GitHub / ansible-ttp. Not only Config but also the output results of other show commands can be parsed relatively easily, so please use it.

Recommended Posts

I made my own filter plugin for text parsing of Ansible
I made my own language. (1)
I made my own AML
Python> I made a test code for my own external file
I made my own primitive static site generator
I made my own parallel link robot (software version)
I made my own parallel link robot (mechanical edition)
I made my goimports
I made my own OSS because I wanted to contribute to it
I made a python text
[Python] I made my own library that can be imported dynamically
I made a lot of files for RDP connection with Python
I made my own research tool using the legal API [Smart Roppo]
Since I made my own smart lock, I will summarize the difficult points
I tried how to improve the accuracy of my own Neural Network
I made go language for api and minimum configuration of react for front