Overview
The Arista eAPI give you the ability to interact with a switch over standard HTTPS and return structured JSON. Here a section of Python code to populate a database table to automatically generate a network diagram based on LLDP neighbor relationships.
Requirements
Arista EOS
Python 2.7
Postgresql
pyeapi
Database Tables
CREATE TABLE report.control
(
id serial NOT NULL,
"switchName" text NOT NULL,
"interfaceName" text NOT NULL,
"interfaceType" text,
monitor boolean,
description text NOT NULL,
"remoteSwitchName" text,
"remoteSwitchPort" text,
"lineProtocolStatus" text,
"interfaceStatus" text,
site text,
CONSTRAINT pk_report_control PRIMARY KEY ("switchName", "interfaceName")
)
Sample Python Code
Populating our database table with Switch and Interface information.
import pyeapi
pyeapi.load_config('nodes.conf')
def control_insert_lldp(switchName, interfaceName, remoteSwitchName, remoteSwitchPort):
try:
conn = psycopg2.connect(conn_string)
cursor = conn.cursor()
sql = '''
UPDATE report.control
SET "remoteSwitchName" = %s, "remoteSwitchPort" = %s
WHERE "switchName" = %s AND "interfaceName" = %s
'''
data = (remoteSwitchName, remoteSwitchPort, switchName, interfaceName, )
cursor.execute(sql, data, )
except psycopg2.IntegrityError:
conn.rollback()
else:
conn.commit()
return 0
for switch in switches:
node = pyeapi.connect_to(switch['deviceName'])
try:
output = node.enable('show lldp neighbors')
neighbors = output[0]['result']['lldpNeighbors']
for neighbor in neighbors:
neighborDevice = removedomain(neighbor['neighborDevice'])
control_insert_lldp(hostname, neighbor['port'], neighborDevice, neighbor['neighborPort'])
except Exception as e:
print(e)
Getting a list of switches from our database table.
def network_switches():
conn = psycopg2.connect(conn_string)
cursor = conn.cursor(cursor_factory=RealDictCursor)
sql = '''
SELECT
DISTINCT(control."switchName") as "name",
site."siteDescription" as group
FROM
report.control
WHERE
"remoteSwitchName" != ''
ORDER BY
control."switchName"
'''
cursor.execute(sql, )
results = cursor.fetchall()
return results
Returning a LLDP neighbor value if we have one for each switch interface.
def network_lldp_neighbors(switchName):
conn = psycopg2.connect(conn_string)
cursor = conn.cursor(cursor_factory=RealDictCursor)
sql = '''
SELECT
DISTINCT(control."remoteSwitchName") as "remoteName"
FROM
report.control
WHERE
"switchName" = %s AND
"remoteSwitchName" != ''
ORDER BY "remoteSwitchName"
'''
data = (switchName, )
cursor.execute(sql, data, )
results = cursor.fetchall()
return results
Create a JSON string for D3.js Force-Directed Graph.
def d3_lldp(element):
links = []
value = 1
nodes = network_switches()
idCount = 0
for row in nodes:
row['id'] = idCount
# row['group'] = 1
idCount += 1
for node in nodes:
lldpswitches = network_lldp_neighbors(node['name'])
source = node['id']
for connection in lldpswitches:
for row in nodes:
if row['name'] == connection['remoteName']:
target = row['id']
result = {'source': source, 'target': target, 'value': value}
links.append(result)
result = {'nodes': nodes, 'links': links}
return json.dumps(result)