network-engine icon indicating copy to clipboard operation
network-engine copied to clipboard

Feature request command parser combine multi-command facts into single json hierachy

Open nohir0 opened this issue 6 years ago • 1 comments

ISSUE TYPE

  • Feature Idea

ANSIBLE VERSION

ansible 2.7.5
ansible-network.network-engine, v2.7.2

Network OS

ios
ios-xe
ios-xr
nxos

SUMMARY

Currently one cli command output can be linked with one command parser instance (YAML file) to produce a structured json template structure based on the unstructured ASCII response of that single command. The "extend" directive has been added, which allows to extend an existing facts json structure, but always with a "separate key", right? (hope I did not miss something here)

An extend facts structure might look like this: The command based on the first fact list items is "show interface", the second command is "show interfaces status". Here we see the same key ("0/1") twice, because I extracted the interface ID as root key for both commands...

    "ansible_facts": {
        "device": {
            "extension": {
                "interface_facts": [
                    {
                        "0/1": {
                            "config": {
                                "description": "*** ROUTER ***", 
                                "mac": null, 
                                "mtu": "1500", 
                                "name": "0/1"
                            }, 
                            "stats": {
                                "drops_out": "21059", 
                                "input_errors": "0", 
                                "input_rate": "433000 bits/sec", 
                                "output_errors": "0", 
                                "output_rate": "38000 bits/sec"
                            }
                        }
                    }, 
[output of other interfaces omitted]
                    {
                        "0/1": {
                            "config": {
                                "status": "connected", 
                                "type": "10/100/1000BaseTX", 
                                "vlan": "trunk"
                            }
                        }
                    }, 
[output of other interfaces omitted]

Especially on network interfaces, one show command often do not give all required information for further ansible processing in efficient way. In above example the first command does not indicate if the interface operates as access port or trunk - the second command provides this information.

All these interface related commands have at least one common key together - the interface ID or Name. A new "combine" directive could match on a common key like that and merges the json structure based on that to unique data sets. This makes everything a lot easier for futher processing in ansible (like loops a.s.o)

E.g. a "show cdp neighbor" could also be included as a third show command - it would just be great to have CDP neighbors under the same interface related key. "show mac address-table" is another example.

EXPECTED RESULTS

If the command parser would allow to create a combined json structure based on one common key (like interface ID) using multiple commands - ansible could do things quite out of the box, that no other network mgmt tools can do until today!

    "ansible_facts": {
        "device": {
            "extension": {
                "interface_facts": [
                    {
                        "0/1": {
                            "config": {
                                "description": "*** ROUTER ***", 
                                "mac": null, 
                                "mtu": "1500", 
                                "name": "GigabitEthernet0/1"
                            }, 
                            "mac_addr": {
                                [
                                    "000c.29e3.3204",
                                    "709e.2998.b20c"
                                ]
                            },
                            "cdp_neig": {
                                    "name": router01,
                                    "interface": "GigabitEthernet1/1/1",
                                    "type": "C819G-4G"
                            }
                            "stats": {
                                "drops_out": "21059", 
                                "input_errors": "0", 
                                "input_rate": "433000 bits/sec", 
                                "output_errors": "0", 
                                "output_rate": "38000 bits/sec"
                            }
                        }
                    },
                    [further output omitted]

With this comprehensive facts I could do maximum flexible conditional configuration tasks, for example: Configure only active (up) trunk interfaces with routers as neighbors with setting "spanning-tree portfast trunk" - there are countless usecases...

I apologize my second Feature request in a short time, I currently do deep Ansible eval for network automation and this role is very promising! It makes great things possible without need to develop own modules (which is currently yet a kind of show stopper in regards to Ansible for Networkers)

nohir0 avatar Dec 29 '18 21:12 nohir0

We've managed to combine two IOS commands into a single object with extends. See https://github.com/Roshna-Raman/cisco_ios/blob/remotes/origin/f/parser_show_ip_route/vars/get_facts_command_map.yaml which calls both show ip route and show ip route vrf * to get all routing tables.

You can test it from my fork (https://galaxy.ansible.com/lukedrussell/cisco_ios) which tracks devel + parsers that we haven't got into upstream ansible-network repo yet.

LukeDRussell avatar Feb 06 '19 05:02 LukeDRussell