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)