Junos Automation (Scripting)
Highlighted
Junos Automation (Scripting)

JUNOS LLDP OUTPUT ONTO JSON

‎02-19-2019 09:04 PM

Hi Experts,

I run simple code send 'show lldp neighbors' to the router and return the output like example below

Local Interface   Parent Interface   Chassis Id          Port info    System Name
xe-3/0/4.0        ae31.0             b0:c6:9a:63:80:40   xe-0/0/0.0   host.jnpr.net
xe-3/0/5.0        ae31.0             b0:c6:9a:63:80:40   xe-0/0/1.0   host.jnpr.net
xe-3/0/6.0        ae31.0             b0:c6:9a:63:80:40   xe-0/0/2.0   host.jnpr.net
xe-3/0/7.0        ae31.0             b0:c6:9a:63:80:40   xe-0/0/3.0   host.jnpr.net
xe-3/0/0.0        ae31.0             b0:c6:9a:63:80:40   xe-0/1/0.0   host.jnpr.net
xe-3/0/1.0        ae31.0             b0:c6:9a:63:80:40   xe-0/1/1.0   host.jnpr.net
xe-3/0/2.0        ae31.0             b0:c6:9a:63:80:40   xe-0/1/2.0   host.jnpr.net
xe-3/0/3.0        ae31.0             b0:c6:9a:63:80:40   xe-0/1/3.0   host.jnpr.net

Im looking to traslate the info onto JSON format like below

"node_lldp_neighbors": [

   {

   "local-port": "xe-3/0/4.0",

   "parent-interface": "ae31.0",

   "chassis-id": "b0:c6:9a:63:80:40",

   "port-info": "xe-0/0/0/0.0",

   "system-name": "host.jnpr.net"

  }

This might be simple to you guyz but not me, a sample code of how it can be turn onto json would be a good start for me to understand it. No fancy code, just how can the output above can be translate to json. Appreciate help.

Thank you for your support and kind assistance.

 

 

 

5 REPLIES 5
Junos Automation (Scripting)

Re: JUNOS LLDP OUTPUT ONTO JSON

‎02-21-2019 12:01 AM

by using 

dev.rpc.get_lldp_neighbors_information()

print (etree.tostring(resp,encoding='unicode'))

I can get the details in XML format and do some python code to convert to json file. 

 

 

Junos Automation (Scripting)

Re: JUNOS LLDP OUTPUT ONTO JSON

‎02-21-2019 12:19 AM

You can have Junos output this in json without any conversion yourself by adding "| display json" to your command. Example below.

 

user@fw> show lldp neighbors
Local Interface    Parent Interface    Chassis Id          Port info          System Name
ge-0/0/1           -                   88:a2:5e:9d:a5:00   FW ge-0/0/1        SwitchX

user@fw> show lldp neighbors | display json
{
    "lldp-neighbors-information" : [
    {
        "attributes" : {"junos:style" : "brief"},
        "lldp-neighbor-information" : [
        {
            "lldp-local-port-id" : [
            {
                "data" : "ge-0/0/1"
            }
            ],
            "lldp-local-parent-interface-name" : [
            {
                "data" : "-"
            }
            ],
            "lldp-remote-chassis-id-subtype" : [
            {
                "data" : "Mac address"
            }
            ],
            "lldp-remote-chassis-id" : [
            {
                "data" : "88:a2:5e:9d:a5:00"
            }
            ],
            "lldp-remote-port-description" : [
            {
                "data" : "FW ge-0/0/1"
            }
            ],
            "lldp-remote-system-name" : [
            {
                "data" : "SwitchX"
            }
            ]
        }
        ]
    }
    ]
}

--
Best regards,

Jonas Hauge Jensen
Systems Engineer, SEC DATACOM A/S (Denmark)
Junos Automation (Scripting)

Re: JUNOS LLDP OUTPUT ONTO JSON

[ Edited ]
‎02-21-2019 01:05 AM

Hi sir, noted and thanks. 

The output yes... it is in json but the structure is not as what require. My finding seems that the xml output is given semilar structure as what i want after converted onto json format. Thats why i use xml as origin.

This is the json structure that i would like to get

"node_lldp_neighbors": [

   {

   "local-port": "xe-3/0/4.0",

   "parent-interface": "ae31.0",

   "chassis-id": "b0:c6:9a:63:80:40",

   "port-info": "xe-0/0/0/0.0",

   "system-name": "host.jnpr.net"

  }

Thank you for your response sir.

Junos Automation (Scripting)

Re: JUNOS LLDP OUTPUT ONTO JSON

‎02-21-2019 07:55 PM

Hi Expert,

How do you extract lldp data onto json file (not using json display)

from

Local Interface   Parent Interface   Chassis Id          Port info    System Name
xe-3/0/4.0        ae31.0             b0:c6:9a:63:80:40   xe-0/0/0.0   host.jnpr.net
xe-3/0/5.0        ae31.0             b0:c6:9a:63:80:40   xe-0/0/1.0   host.jnpr.net
xe-3/0/6.0        ae31.0             b0:c6:9a:63:80:40   xe-0/0/2.0   host.jnpr.net
xe-3/0/7.0        ae31.0             b0:c6:9a:63:80:40   xe-0/0/3.0   host.jnpr.net
xe-3/0/0.0        ae31.0             b0:c6:9a:63:80:40   xe-0/1/0.0   host.jnpr.net
xe-3/0/1.0        ae31.0             b0:c6:9a:63:80:40   xe-0/1/1.0   host.jnpr.net
xe-3/0/2.0        ae31.0             b0:c6:9a:63:80:40   xe-0/1/2.0   host.jnpr.net
xe-3/0/3.0        ae31.0             b0:c6:9a:63:80:40   xe-0/1/3.0   host.jnpr.net

To JSON structure

"node_lldp_neighbors": [
   {
    "local-port": "xe-3/0/4.0",
    "parent-interface": "ae31.0",
    "chassis-id": "b0:c6:9a:63:80:40",
    "port-info": "xe-0/0/0/0.0",
    "system-name": "host.jnpr.net"
  }

I have test show lldp neighbors | display json and it doest not as my expection output. I have tried xml...but unfortunately when i convert to json the format also as not expected.

 

May I know how you guyz do it? I have go thro the net and still not able to do it...feel loss...

Junos Automation (Scripting)

Re: JUNOS LLDP OUTPUT ONTO JSON

[ Edited ]
‎03-06-2019 04:38 PM

Dear jar.


I understood the solution proposed by Jonas Hauge is not sufficient and you want the output formatted exactly as specified. I tried to fiddle around with Python scripts, RPC calls and created script with output close to your demands.

 

The device output:

 

user@QFX5100_VC> show lldp neighbors
Local Interface    Parent Interface    Chassis Id          Port info          System Name
ge-1/0/30          ae2                 40:a6:77:9a:b3:08   ge-1/0/0           MX5_UP
ge-0/0/30          ae2                 40:a6:77:9a:b3:08   ge-1/1/0           MX5_UP

 

 

The script output (JSON structure is named "node_lldp_neighbors"):

 

[
    {
        "local-port": "ge-1/0/30",
        "parent-interface": "ae2",
        "chassis-id": "40:a6:77:9a:b3:08",
        "port-info": "ge-1/0/0",
        "system-name": "MX5_UP"
    },
    {
        "local-port": "ge-0/0/30",
        "parent-interface": "ae2",
        "chassis-id": "40:a6:77:9a:b3:08",
        "port-info": "ge-1/1/0",
        "system-name": "MX5_UP"
    }
]

 

The Python script to produce the output is following (is bit clumsy, I will try to walk through the code down below):

#!/usr/bin/python3
from jnpr.junos import Device
from lxml import etree
import json

dev=Device(host='QFX', user='user', passwd='Pwd12345')
dev.open()
neighbors=dev.rpc.get_lldp_neighbors_information()
i=0
lldp_neighbors=[]
for neigh in neighbors.iter("lldp-local-port-id","lldp-local-parent-interface-name", "lldp-remote-chassis-id","lldp-remote-port-description", "lldp-remote-system-name"):
       if (i % 5) == 0:
           lldp_neighbors.append({"local-port":neigh.text})
       elif (i % 5) == 1:
           lldp_neighbors[int(i/5)]["parent-interface"]=neigh.text
       elif (i % 5) == 2:
           lldp_neighbors[int(i/5)]["chassis-id"]=neigh.text
       elif (i % 5) == 3:
           lldp_neighbors[int(i/5)]["port-info"]=neigh.text
       elif (i % 5) == 4:
           lldp_neighbors[int(i/5)]["system-name"]=neigh.text
       i = i+1
node_lldp_neighbors=json.dumps(lldp_neighbors, indent=3)
print(node_lldp_neighbors)
dev.close()

 

Script walk through:

  1. We open connection to device, retrieve LLDP neighbors via RPC call as object "neighbors" which is  'lxml.etree._Element' class instance. Connection to device could be opened using:
    with Device(host='QFX', user='user', passwd='Pwd12345') as dev:
    as well which will take care about opening and closing connection to device automagically.

    Note: I used hardcoded credentials just for demonstration purposes. Use secure ways in production environment!
  2. We create index variable "i" with value 0 and empty list variable named "lldp_neighbors" which we will populate with LLDP neighbor data later on.
  3. The "for" cycle is used to iterize through LLDP neighbors structure while filtering for specific tags (the ones needed in output structure).

    See documentation of LXML  library for details how to iterize:
    https://lxml.de/tutorial.html#tree-iteration 

    The if /elif structure solves the "logic" behind filling the output list with values of LXML structure. The each neighbor element has subelements for port-id, chassis-id, etc.  The iteration is going first through each subelements of each neighbor, then the next neighbor subelements are iterized.  The 5 tags used by iterization cycle are in immutable order in LXML structure hence modulo 5  ( i %5  = reminder after division by 5) operation to select tag. 

    We first append new item to list which value is key /value pair (custom key name  + element text/value). The next key /value pair is inserted to list item with newly created index number (it is changed each fifth iteration of for cycle => another neighbor entry ).
  4. We convert the Python list of dictionaries to JSON structure "node_lldp_neighbors" using json.dumps() method with indent of three characters. JSON structure could be directly printed if further processing is not needed.

Find the Python file attached (UNIX end of lines encoding).

 

Versions of libraries and OS used for testing:

Ubuntu 18.04.1 LTS
Python 3.6.7
PyEZ 2.2.0
lxml 4.3.2

 

Script /solution can be done in more elegant and optimized way however I hope this will help you though.


Let us know if the answer was what you were looking for and if it solved your needs.

 

Have a nice day.

Regards
Luděk Matoušek
JNCIS-ENT, JNCIS-SP, JNCIP-SEC, JNCIA-DevOps

Attachments