From 676af9fea5126ef1ac5c58ccda029ac448f56275 Mon Sep 17 00:00:00 2001 From: Jay Gheewala Date: Thu, 12 Jan 2017 14:56:22 -0800 Subject: [PATCH 1/6] initial commit for flexswitch --- netbox/dcim/fixtures/dcim.json | 9 +++++++ netbox/dcim/fixtures/initial_data.json | 9 +++++++ netbox/dcim/models.py | 2 ++ netbox/extras/rpc.py | 33 ++++++++++++++++++++++++++ 4 files changed, 53 insertions(+) diff --git a/netbox/dcim/fixtures/dcim.json b/netbox/dcim/fixtures/dcim.json index 7c011eb89..56e3b8243 100644 --- a/netbox/dcim/fixtures/dcim.json +++ b/netbox/dcim/fixtures/dcim.json @@ -1904,6 +1904,15 @@ "rpc_client": "opengear" } }, +{ + "model": "dcim.platform", + "pk": 3, + "fields": { + "name": "SnapRoute FlexSwitch", + "slug": "snaproute-flexswitch", + "rpc_client": "flexswitch" + } +}, { "model": "dcim.device", "pk": 1, diff --git a/netbox/dcim/fixtures/initial_data.json b/netbox/dcim/fixtures/initial_data.json index e765de227..290d682fa 100644 --- a/netbox/dcim/fixtures/initial_data.json +++ b/netbox/dcim/fixtures/initial_data.json @@ -197,5 +197,14 @@ "slug": "opengear", "rpc_client": "opengear" } +}, +{ + "model": "dcim.platform", + "pk": 7, + "fields": { + "name": "SnapRoute FlexSwitch", + "slug": "snaproute-flexswitch", + "rpc_client": "flexswitch" + } } ] diff --git a/netbox/dcim/models.py b/netbox/dcim/models.py index 030de3436..6a4141589 100644 --- a/netbox/dcim/models.py +++ b/netbox/dcim/models.py @@ -182,10 +182,12 @@ CONNECTION_STATUS_CHOICES = [ RPC_CLIENT_JUNIPER_JUNOS = 'juniper-junos' RPC_CLIENT_CISCO_IOS = 'cisco-ios' RPC_CLIENT_OPENGEAR = 'opengear' +RPC_CLIENT_SNAPROUTE_FLEXSWITCH = 'snaproute-flexswitch' RPC_CLIENT_CHOICES = [ [RPC_CLIENT_JUNIPER_JUNOS, 'Juniper Junos (NETCONF)'], [RPC_CLIENT_CISCO_IOS, 'Cisco IOS (SSH)'], [RPC_CLIENT_OPENGEAR, 'Opengear (SSH)'], + [RPC_CLIENT_SNAPROUTE_FLEXSWITCH, 'SnapRoute FlexSwitch (SSH)'], ] diff --git a/netbox/extras/rpc.py b/netbox/extras/rpc.py index b52dd0310..a0403bb2f 100644 --- a/netbox/extras/rpc.py +++ b/netbox/extras/rpc.py @@ -260,10 +260,43 @@ class OpengearSSH(SSHClient): 'modules': [], } +class FlexSwitchSSH(SSHClient): + """ + SSH client for FlexSwitch devices + """ + default_credentials = { + 'username': 'root', + 'password': 'snaproute', + } + def get_lldp_neighbors(self): + print 'flexswitch get lldp' + ''' + try: + stdin, stdout, stderr = self.ssh.exec_command() + rpc_reply = self.manager.dispatch('get-lldp-neighbors-information') + lldp_neighbors_raw = xmltodict.parse(rpc_reply.xml)['rpc-reply']['lldp-neighbors-information']['lldp-neighbor-information'] + + result = [] + for neighbor_raw in lldp_neighbors_raw: + neighbor = dict() + neighbor['local-interface'] = neighbor_raw.get('lldp-local-port-id') + neighbor['name'] = neighbor_raw.get('lldp-remote-system-name') + neighbor['name'] = neighbor['name'].split('.')[0] # Split hostname from domain if one is present + try: + neighbor['remote-interface'] = neighbor_raw['lldp-remote-port-description'] + except KeyError: + # Older versions of Junos report on interface ID instead of description + neighbor['remote-interface'] = neighbor_raw.get('lldp-remote-port-id') + neighbor['chassis-id'] = neighbor_raw.get('lldp-remote-chassis-id') + result.append(neighbor) + + return result + ''' # For mapping platform -> NC client RPC_CLIENTS = { 'juniper-junos': JunosNC, 'cisco-ios': IOSSSH, 'opengear': OpengearSSH, + 'snaproute-flexswitch': FlexSwitchSSH, } From acf2f36cf0a75f7072d5352c3a562ad1c0132a1d Mon Sep 17 00:00:00 2001 From: Jay Gheewala Date: Thu, 12 Jan 2017 23:11:25 +0000 Subject: [PATCH 2/6] fixing rpc client name --- netbox/dcim/fixtures/initial_data.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/netbox/dcim/fixtures/initial_data.json b/netbox/dcim/fixtures/initial_data.json index 290d682fa..b5599cab7 100644 --- a/netbox/dcim/fixtures/initial_data.json +++ b/netbox/dcim/fixtures/initial_data.json @@ -144,6 +144,14 @@ "slug": "super-micro" } }, +{ + "model": "dcim.manufacturer", + "pk": 9, + "fields": { + "name": "Accton", + "slug": "accton" + } +}, { "model": "dcim.platform", "pk": 1, @@ -204,7 +212,7 @@ "fields": { "name": "SnapRoute FlexSwitch", "slug": "snaproute-flexswitch", - "rpc_client": "flexswitch" + "rpc_client": "snaproute-flexswitch" } } ] From 10f16331f3513baab845023c321a6c706c736d13 Mon Sep 17 00:00:00 2001 From: Jay Gheewala Date: Fri, 13 Jan 2017 18:48:48 +0000 Subject: [PATCH 3/6] fixing netbox for flexswitch --- netbox/dcim/models.py | 2 +- netbox/extras/rpc.py | 49 ++++++++++++++++++------------------------- 2 files changed, 21 insertions(+), 30 deletions(-) diff --git a/netbox/dcim/models.py b/netbox/dcim/models.py index 6a4141589..fd24821fa 100644 --- a/netbox/dcim/models.py +++ b/netbox/dcim/models.py @@ -187,7 +187,7 @@ RPC_CLIENT_CHOICES = [ [RPC_CLIENT_JUNIPER_JUNOS, 'Juniper Junos (NETCONF)'], [RPC_CLIENT_CISCO_IOS, 'Cisco IOS (SSH)'], [RPC_CLIENT_OPENGEAR, 'Opengear (SSH)'], - [RPC_CLIENT_SNAPROUTE_FLEXSWITCH, 'SnapRoute FlexSwitch (SSH)'], + [RPC_CLIENT_SNAPROUTE_FLEXSWITCH, 'SnapRoute FlexSwitch (RPC)'], ] diff --git a/netbox/extras/rpc.py b/netbox/extras/rpc.py index a0403bb2f..fb9ab066d 100644 --- a/netbox/extras/rpc.py +++ b/netbox/extras/rpc.py @@ -55,7 +55,7 @@ class RPCClient(object): class SSHClient(RPCClient): def __enter__(self): - + print "trying to connect to %s using %s %s" %(self.host, self.username, self.password) self.ssh = paramiko.SSHClient() self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: @@ -260,43 +260,34 @@ class OpengearSSH(SSHClient): 'modules': [], } -class FlexSwitchSSH(SSHClient): +class FlexSwitchRPC(RPCClient): """ SSH client for FlexSwitch devices """ - default_credentials = { - 'username': 'root', - 'password': 'snaproute', - } + """ + def __init__(self, device, username='', password=''): + print 'flexswitch rpc client instantiated' + super(FlexSwitchRPC, self).__init__(device, username='', password='') + """ + def __enter__(self): + + # Initiate a connection to the device + #self.manager = manager.connect(host=self.host, username=self.username, password=self.password, + # hostkey_verify=False, timeout=CONNECT_TIMEOUT) + + print 'flexswitch rpc enter' + return self + def __exit__(self, exc_type, exc_val, exc_tb): + + # Close the connection to the device + print 'flexswitch rpc exit' def get_lldp_neighbors(self): print 'flexswitch get lldp' - ''' - try: - stdin, stdout, stderr = self.ssh.exec_command() - rpc_reply = self.manager.dispatch('get-lldp-neighbors-information') - lldp_neighbors_raw = xmltodict.parse(rpc_reply.xml)['rpc-reply']['lldp-neighbors-information']['lldp-neighbor-information'] - - result = [] - for neighbor_raw in lldp_neighbors_raw: - neighbor = dict() - neighbor['local-interface'] = neighbor_raw.get('lldp-local-port-id') - neighbor['name'] = neighbor_raw.get('lldp-remote-system-name') - neighbor['name'] = neighbor['name'].split('.')[0] # Split hostname from domain if one is present - try: - neighbor['remote-interface'] = neighbor_raw['lldp-remote-port-description'] - except KeyError: - # Older versions of Junos report on interface ID instead of description - neighbor['remote-interface'] = neighbor_raw.get('lldp-remote-port-id') - neighbor['chassis-id'] = neighbor_raw.get('lldp-remote-chassis-id') - result.append(neighbor) - - return result - ''' # For mapping platform -> NC client RPC_CLIENTS = { 'juniper-junos': JunosNC, 'cisco-ios': IOSSSH, 'opengear': OpengearSSH, - 'snaproute-flexswitch': FlexSwitchSSH, + 'snaproute-flexswitch': FlexSwitchRPC, } From c7889f1f047ded5b97b8484c2d3c1cc5aade6e5e Mon Sep 17 00:00:00 2001 From: Jay Gheewala Date: Fri, 13 Jan 2017 21:18:14 +0000 Subject: [PATCH 4/6] polling lldp information --- netbox/extras/rpc.py | 45 +++++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/netbox/extras/rpc.py b/netbox/extras/rpc.py index fb9ab066d..b4e72c72c 100644 --- a/netbox/extras/rpc.py +++ b/netbox/extras/rpc.py @@ -3,7 +3,8 @@ import paramiko import re import xmltodict import time - +import requests +import json CONNECT_TIMEOUT = 5 # seconds @@ -262,27 +263,41 @@ class OpengearSSH(SSHClient): class FlexSwitchRPC(RPCClient): """ - SSH client for FlexSwitch devices - """ + RPC client for FlexSwitch devices """ def __init__(self, device, username='', password=''): - print 'flexswitch rpc client instantiated' super(FlexSwitchRPC, self).__init__(device, username='', password='') - """ + self.headers = {'Accept' : 'application/json', 'Content-Type' : 'application/json'} + self.httpSuccessCodes = [200, 201, 202, 204] + self.port = 8080 + self.timeout = 15 + self.configUrlBase = 'http://%s:%s/public/v1/config/' % (self.host, self.port) + self.stateUrlBase = 'http://%s:%s/public/v1/state/' % (self.host, self.port) + self.actionUrlBase = 'http://%s:%s/public/v1/action/' % (self.host, self.port) def __enter__(self): - - # Initiate a connection to the device - #self.manager = manager.connect(host=self.host, username=self.username, password=self.password, - # hostkey_verify=False, timeout=CONNECT_TIMEOUT) - - print 'flexswitch rpc enter' return self - def __exit__(self, exc_type, exc_val, exc_tb): - # Close the connection to the device - print 'flexswitch rpc exit' + def __exit__(self, exc_type, exc_val, exc_tb): + return + def get_lldp_neighbors(self): - print 'flexswitch get lldp' + reqUrl = self.stateUrlBase + 'LLDPIntfs' + resp = requests.get(reqUrl, timeout=self.timeout) + if resp.status_code in self.httpSuccessCodes: + data = resp.json() + result = [] + for obj in data['Objects']: + lldpInfo = dict() + lldpInfo['local-interface'] = obj['Object']['IntfRef'] + lldpInfo['name'] = obj['Object']['PeerHostName'] + lldpInfo['remote-interface'] = obj['Object']['PeerPort'] + lldpInfo['chassis-id'] = obj['Object']['PeerMac'] + print lldpInfo + result.append(lldpInfo) + return result + else: + print 'failed querry %s' %(resp.status_code) + return None # For mapping platform -> NC client RPC_CLIENTS = { From 424963e49bffccd8d8c8fe608c3e1cb8454fc3c9 Mon Sep 17 00:00:00 2001 From: Jay Gheewala Date: Fri, 13 Jan 2017 21:19:40 +0000 Subject: [PATCH 5/6] removed debug print --- netbox/extras/rpc.py | 1 - 1 file changed, 1 deletion(-) diff --git a/netbox/extras/rpc.py b/netbox/extras/rpc.py index b4e72c72c..9e3b5a9a1 100644 --- a/netbox/extras/rpc.py +++ b/netbox/extras/rpc.py @@ -56,7 +56,6 @@ class RPCClient(object): class SSHClient(RPCClient): def __enter__(self): - print "trying to connect to %s using %s %s" %(self.host, self.username, self.password) self.ssh = paramiko.SSHClient() self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: From 15b6834c7e565e6482786b7c85f5268f60b584c4 Mon Sep 17 00:00:00 2001 From: Jay Gheewala Date: Fri, 13 Jan 2017 21:30:44 +0000 Subject: [PATCH 6/6] adding chassis-id colunm to lldp information --- netbox/templates/dcim/device_lldp_neighbors.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/netbox/templates/dcim/device_lldp_neighbors.html b/netbox/templates/dcim/device_lldp_neighbors.html index 6a5446c3b..d15d0a5c4 100644 --- a/netbox/templates/dcim/device_lldp_neighbors.html +++ b/netbox/templates/dcim/device_lldp_neighbors.html @@ -16,6 +16,7 @@ Configured Interface LLDP Device LLDP Interface + LLDP Chassis-Id @@ -36,6 +37,7 @@ {% endif %} + {% endfor %} @@ -57,6 +59,7 @@ $(document).ready(function() { // Add LLDP neighbors to table row.children('td.device').html(neighbor['name']); row.children('td.interface').html(neighbor['remote-interface']); + row.children('td.chassis-id').html(neighbor['chassis-id']); // Apply colors to rows if (!configured_device && neighbor['name']) { row.addClass('info');