diff --git a/netbox/dcim/fixtures/dcim.json b/netbox/dcim/fixtures/dcim.json index 4a9eb15e4..9a5ee5d33 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..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, @@ -197,5 +205,14 @@ "slug": "opengear", "rpc_client": "opengear" } +}, +{ + "model": "dcim.platform", + "pk": 7, + "fields": { + "name": "SnapRoute FlexSwitch", + "slug": "snaproute-flexswitch", + "rpc_client": "snaproute-flexswitch" + } } ] diff --git a/netbox/dcim/models.py b/netbox/dcim/models.py index 59d7a0ef2..99935db3e 100644 --- a/netbox/dcim/models.py +++ b/netbox/dcim/models.py @@ -215,10 +215,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 (RPC)'], ] diff --git a/netbox/extras/rpc.py b/netbox/extras/rpc.py index 208ec20dd..d5f2d2528 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 @@ -55,7 +56,6 @@ class RPCClient(object): class SSHClient(RPCClient): def __enter__(self): - self.ssh = paramiko.SSHClient() self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: @@ -263,10 +263,48 @@ class OpengearSSH(SSHClient): 'items': [], } +class FlexSwitchRPC(RPCClient): + """ + RPC client for FlexSwitch devices + """ + def __init__(self, device, username='', password=''): + 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): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + return + + def get_lldp_neighbors(self): + 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 = { 'juniper-junos': JunosNC, 'cisco-ios': IOSSSH, 'opengear': OpengearSSH, + 'snaproute-flexswitch': FlexSwitchRPC, } diff --git a/netbox/templates/dcim/device_lldp_neighbors.html b/netbox/templates/dcim/device_lldp_neighbors.html index 2b95b0035..3b4bf2253 100644 --- a/netbox/templates/dcim/device_lldp_neighbors.html +++ b/netbox/templates/dcim/device_lldp_neighbors.html @@ -16,6 +16,7 @@