Advertisement
Guest User

Untitled

a guest
Dec 7th, 2016
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.46 KB | None | 0 0
  1. def json_from_url(url):
  2.     """ Simple function to load json object from url """
  3.  
  4.     from urllib2 import urlopen
  5.     import json
  6.  
  7.     response = urlopen(url)
  8.     data = response.read().decode("utf-8")
  9.     return json.loads(data)
  10.  
  11. class Switch:
  12.     """ Class construct for a switch """
  13.  
  14.     from urllib2 import urlopen
  15.  
  16.     def __init__(self,name):
  17.         self.name = name
  18.  
  19.     def get_vendor(self):
  20.         """ Acquire device vendor by portalAPI """
  21.  
  22.         apiJson = json_from_url( 'https://portal.tower-research.com/portal/api/v1/netdb/device/?username=netops-api' \
  23.                                  '&amp=&api_key=343242343232525325343243reewffgfdgdfgd&limit=0&offset=0&name=%s' \
  24.                                  '&site__dns_prefix=%s' % ( self.name.split(".")[0], self.name.split(".")[1] ) )
  25.         try: return apiJson['objects'][0]['vendor']['name']
  26.         except: return
  27.  
  28.     def get_model(self):
  29.         """ Simple function to strip out model information from hostname """
  30.         try: return self.name.split(".")[0].split("-")[0]
  31.         except: return
  32.  
  33.     def get_version(self):
  34.         """ Wrapper of get_version_eapi and get_version_scrape """
  35.  
  36.         vendor  = self.get_vendor()
  37.         if vendor == 'Arista': return self.get_version_eapi()
  38.         elif vendor == 'Cisco' or vendor == 'Metamako': return self.get_version_scrape()
  39.         else: return
  40.  
  41.     def get_version_eapi(self):
  42.         """Acquires version from Arista platform via eAPI"""
  43.    
  44.         import socket
  45.         from jsonrpclib import Server
  46.         import errno
  47.         import ssl
  48.         import xmlrpclib
  49.  
  50.         try:
  51.             _create_unverified_https_context = ssl._create_unverified_context
  52.         except AttributeError:
  53.             # Legacy Python that doesn't verify HTTPS certificates by default
  54.             pass
  55.         else:
  56.             # Handle target environment that doesn't support HTTPS verification
  57.             ssl._create_default_https_context = _create_unverified_https_context
  58.  
  59.         username = "netops"
  60.         password = "$isg00d"
  61.         socket.setdefaulttimeout(5.0)
  62.         connection = Server( "https://%s:%s@%s/command-api" % (username, password, self.name) )
  63.         try: response = connection.runCmds( 1, ["show version"] )
  64.         except socket.error as msg: return msg
  65.         except xmlrpclib.ProtocolError as err: '%s %s' % ( str(err.errcode), str(err.errmsg) )
  66.         else: return response[0]['version']
  67.  
  68.     def get_version_scrape(self):
  69.         """Acquires version from Cisco/Metamko platform via screen scrape"""
  70.  
  71.         import pexpect
  72.         import socket
  73.  
  74.         username = "test"
  75.         password = "test"
  76.         sshCommand = 'ssh -l %s %s -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \"show version\"' % (username, self.name)
  77.         socket.setdefaulttimeout(5.0)
  78.         p = pexpect.spawn(sshCommand)
  79.  
  80.         connectStatus = p.expect(['[Pp]assword:', pexpect.TIMEOUT, pexpect.EOF])
  81.         if connectStatus == 0:
  82.             p.sendline(password)
  83.             authSuccess = p.expect([pexpect.EOF, '[Pp]assword:'])
  84.             if authSuccess == 0: showVersion = p.before
  85.             if authSuccess == 1: return "[Error: Incorrect credentials]"
  86.         if connectStatus == 1: return "[Error: Timeout]"
  87.         if connectStatus == 2: return "[Error: EOF]"
  88.  
  89.         model = self.get_model()
  90.         if '3064' in model.lower():
  91.             try: return [each.split()[2] for each in showVersion.split("\n") if 'system:' in each][0]
  92.             except IndexError: return "[Error: Index out of range]"
  93.         if '4900' in model.lower():
  94.             try: return showVersion.split("\n")[2].split()[10].strip(",")
  95.             except IndexError: return "[Error: Index out of range]"
  96.         if 'meta' in model.lower():
  97.             try: return showVersion.split("\n")[5].split()[3]
  98.             except IndexError: return "[Error: Index out of range]"
  99.         else:
  100.             try: return showVersion.split("\n")[2].split()[7].strip(",")
  101.             except IndexError: return "[Error: Index out of range]"
  102.  
  103. def get_version_printer(switch_class):
  104.     """ Simple printer for formatting of output """
  105.  
  106.     return '{0:50} {1:40}'.format( switch_class.name, switch_class.get_version() )
  107.  
  108.  
  109. def get_devices_from_portal(vendors=[], models=[], sites=[], live=True):
  110.     """ Function to pull devices down from portalAPI based off filters """
  111.  
  112.     netdbDevices = json_from_url( 'https://portal.tower-research.com/portal/api/v1/netdb/device/' \
  113.                                     '?username=netops-api&amp=&api_key=' \
  114.                                     '2127c497de605b24253cfc7ffd02f5524f85cf33&limit=0&offset=0' )
  115.  
  116.     netdbObjects = netdbDevices['objects']
  117.  
  118.     # Match filters against returned values
  119.     if sites: netdbObjects = [device for device in netdbObjects if device['site']['dns_prefix'] in sites]
  120.     if models: netdbObjects = [device for device in netdbObjects if device['name'].split("-")[0] in models]
  121.     if vendors: netdbObjects = [device for device in netdbObjects if device['vendor']['name'] in vendors]
  122.     if live == True: netdbObjects = [device for device in netdbObjects if device['status'] == 1]
  123.     return [each['name'] + "." + each['site']['dns_prefix'] for each in netdbObjects]
  124.  
  125. def main():
  126.     """ Main function to print output based off user input """
  127.  
  128.     from datetime import datetime
  129.     from multiprocessing.dummy import Pool as ThreadPool
  130.  
  131.     start = datetime.now()
  132.  
  133.     if args:
  134.         print "Default argument provided, excluding filters..."
  135.         print
  136.  
  137.         switches = [Switch(arg) for arg in args]
  138.  
  139.     if not args:
  140.         print "Sites... " + str(opts.sites)
  141.         print "Models... " + str(opts.models)
  142.         print "Vendors... " + str(opts.vendors)
  143.         print
  144.         print "Executing..."
  145.         print
  146.  
  147.         switches = [Switch(each) for each in get_devices_from_portal(opts.vendors, opts.models, opts.sites)]
  148.  
  149.     pool = ThreadPool(100)
  150.     output = pool.map(get_version_printer, switches)
  151.     pool.close()
  152.     pool.join()
  153.  
  154.     print '{0:50} {1:40}'.format( "Hostname", "Version/Error" )
  155.     print '{0:50} {1:40}'.format( "-" * len("Hostname"), "-" * len("Version/Error") )
  156.  
  157.     for each in sorted( output, key=lambda site: site.split(".")[1] ): print each
  158.  
  159.     print
  160.     print "Duration: " + str(datetime.now() - start)
  161.  
  162. if __name__ == '__main__':
  163.  
  164.     import optparse
  165.     import sys
  166.  
  167.     usage = "Usage: getVersion.py [-s site1 -s site2] [-m model1 -m model2] [-v vendor1 -v vendor2] switch1 switch2 switch3"
  168.     parser = optparse.OptionParser(usage=usage)
  169.     parser.add_option('-s', '--sites',
  170.                       default=[],
  171.                       action='append',
  172.                       dest='sites',
  173.                       help='Perform operations on following sites')
  174.     parser.add_option('-v', '--vendors',
  175.                       dest='vendors',
  176.                       default=[],
  177.                       action='append',
  178.                       help='Perform operations on following vendors')
  179.     parser.add_option('-m', '--models',
  180.                       dest='models',
  181.                       default=[],
  182.                       action='append',
  183.                       help='Perform operations on following models. Models are identifed by text leading up to first hyphen')
  184.     opts, args = parser.parse_args()
  185.  
  186.     opts.sites = list( set(opts.sites) )
  187.     opts.vendors = list( set(opts.vendors) )
  188.     opts.models = list( set(opts.models) )
  189.  
  190.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement