def main(): parser = argparse.ArgumentParser(description='Displays configuration elements with select hashtag. Hashtags are configured at any level using "set apply-macro ht <hashtag-name>" command.') for key in arguments: parser.add_argument(('-' + key), required=True, help=arguments[key]) args = parser.parse_args() dev = Device() dev.open() dev.timeout = 300 xml_config = dev.rpc.get_config(options={'database':'committed','inherit':'inherit'}) paths = [] #select all elements matching pattern for ht_element in xml_config.findall( './/apply-macro/data/[name=\'{}\']/../'.format( args.hashtag)): #filter by node id just in case if ht_element.text == 'ht': s = build_xml_filter( xml_config, ht_element.getparent().getparent()) paths.append( s) if paths: path = '<configuration>'+"".join( paths)+'</configuration>' #17.x versions of PyEz expect filter_xml to be an etree instance xml_config = dev.rpc.get_config( filter_xml= etree.XML( path),options={'database':'committed','inherit':'inherit', 'format':'text'}) print xml_config.text else: print 'hashtag \'{}\' is not found'.format( args.hashtag) dev.close()
def main(): """Simple main method to enter log entries.""" routers = ['10.11.12.1', '10.11.12.2'] pyez_user = '******' pyez_pass = '******' netdata_db = 'network_data.db' link_down = re.compile('(\w{1,3}\s{1,3}\d{1,2}\s{1,3}\d{1,2}:\d{1,2}:\d{1,2}).*SNMP_TRAP_LINK_DOWN.*ifName ([gax]e-\d{1,2}\/\d{1,2}\/\d{1,2})\n', flags=0) for router in routers: try: device = Device(host=router, user=pyez_user, password=pyez_pass) device.open() logs = device.rpc.get_log(filename='messages') for log_content in logs.iter("file-content"): # print(log_content.text) messages = link_down.finditer(log_content.text) if messages: # print(messages.group(0)) for log in messages: entry = [] # Step 1.1 print(log.group(1)) print(log.group(2)) print(log.group(0)) # Step 1.3 print(log.group(1).replace(' ', '_') + '_' + device.facts['fqdn']) entry.append(log.group(1).replace(' ', '_') + '_' + device.facts['fqdn']) entry.append(device.facts['fqdn']) entry.append(log.group(2)) entry.append(log.group(0)) write_log_to_database(netdata_db, entry) device.close() except Exception as e: print("Uh oh! We had a problem retrieving the messages log file.") print('Here is the error {error}'.format(error=e))
def print_interface_table(hostname): dev = Device(user=username, host=hostname, password=password, gather_facts=False, normalize=True) dev.open() port_table = PhyPortTable(dev).get() for port in port_table: print hostname, port.name, port.macaddr, port.flapped dev.close()
def main(argv): sys.stdout.write("commitment\n\n") if len(sys.argv) != 2: sys.stdout.write("Error: Missing parameter\n") sys.stdout.write("Usage: commitment.py <device-list.txt>\n") sys.exit() username = raw_input('Username: '******'Password (leave blank to use SSH Key): ') hostsfile = open(str(sys.argv[1]),'r') for address in hostsfile: if password != '': dev = Device(host=address.rstrip('\n'),user=username,passwd=password) else: dev = Device(host=address.rstrip('\n'),user=username) print "Opening :" + str(dev.hostname) dev.open() print "Opened :" + str(dev.hostname) print "Opening config" dev.bind(cf=Config) print "Locking config" dev.cf.lock() print "Committing config" dev.cf.commit() print "Unlocking config" dev.cf.unlock print "Closing: " + str(dev.hostname) dev.close() print "Closed :" + str(dev.hostname) hostsfile.close()
class interfaceThread(threading.Thread): def __init__(self, rtr, r): threading.Thread.__init__(self) self.rtr = rtr self.dev = '' self.redis = r def run(self): self.dev = Device(host=self.rtr['ip'], user='******', password='******') self.dev.open() while True: #t0 = time.clock() #t1 = time.time() if self.rtr['name'] == 'houston': continue for intf in self.rtr['interfaces']: try: result = self.dev.rpc.ping({'format': 'json'},host=intf['address'], count='1') latency = { 'timestamp': datetime.datetime.fromtimestamp(time.time()).strftime('%a:%H:%M:%S'), 'from-router': self.rtr['name'], 'to-router': intf['to'], 'rtt-average(ms)': float(result['ping-results'][0]['probe-results-summary'][0]['rtt-average'][0]['data'])/1000.0 } jd = json.dumps(latency) dataset = self.rtr['name'] + ':' + intf['to'] + ':latency' self.redis.lpush(dataset,jd) self.redis.ltrim(dataset, 0, window) except: print self.rtr['name'], intf['address'], ' latency polling failed' continue print self.rtr['name'], ' latency thread exist' time.sleep(self.rtr['nap_time']) self.dev.close()
def main(): globals().update(loadyaml(yamlfile)) hosts = config.get('hosts') for host in hosts: dev = Device(host=host, user=user, password=password) try: dev.open() except Exception as err: print("Cannot connect to device: {}".format(err)) return peerTable = BgpNeighborTable(dev) peerTable.get() for entry in peerTable: peer = dict(entry) print("Neighbor: {}:{}".format(peer["peer-address"], peer["peer-as"])) print(" Description: {}".format(peer["description"])) print(" State: {}".format(peer["peer-state"])) print(" RIB: {}".format(peer["rib-name"])) print(" Stats:") print(" Accepted Prefixes: {}" .format(peer["accepted-prefix"])) print(" Suppressed Prefixes: ", "{}".format(peer["suppressed-prefix"])) print(" Active Prefixes: {}".format(peer["active-prefix"])) print(" Received Prefixes: {}" .format(peer["received-prefix"])) print() dev.close()
def main(device_ip, peer_ip): config = ConfigDictionary() username = config.username() password = config.password() print (device_ip + " logging in as " + username) jdev = Device(user=username, host=device_ip, password=password) jdev.open(gather_facts=False) jdev.timeout=6000 try: resultxml = jdev.rpc.get_route_information(table='inet.0',protocol='bgp',peer=peer_ip,extensive=True) except Exception as err: print "CMD:" etree.dump(err.cmd) print "RSP:" etree.dump(err.rsp) for routexml in resultxml.findall('.//rt'): route = RouteData(routexml) print "destination: " + route.prefix() + "as-path: " + route.aspath() jdev.close()
def getprefixes(ASN, transit, router, auser, keyfile): devcommand = 0 if auser is not None: username = auser devcommand += 1 if keyfile is not None: path2keyfile = keyfile devcommand += 2 if devcommand == 0: dev = Device(router) elif devcommand == 1: dev = Device(router, user=username) elif devcommand == 2: dev = Device(router, ssh_private_key_file=path2keyfile) else: dev = Device(router, user=username, ssh_private_key_file=path2keyfile) dev.open() if transit: ASNprefixes = dev.rpc.get_route_information(aspath_regex=".* " + str(ASN) + " .*") else: ASNprefixes = dev.rpc.get_route_information(aspath_regex=".* " + str(ASN)) dev.close() return ASNprefixes
def deployConfig(my_device_list_dict, my_username, my_password, my_config_template_file): my_hostname="" try: my_hostname=my_device_list_dict["mgmt_ip"] printProgress("INFO",my_hostname,"Connecting to device through netconf.") dev=Device(my_hostname,user=my_username,password=my_password) dev.open() dev.timeout=3*60 cu = Config(dev) printProgress("INFO",my_hostname,"Going to load template the config now.") # Determine if template file is in "set" or "bracketed" format if isSet(my_config_template_file): rsp=cu.load(template_path=my_config_template_file,format='set',template_vars=my_device_list_dict) else: rsp=cu.load(template_path=my_config_template_file,template_vars=my_device_list_dict) printProgress("INFO",my_hostname,"Performing diff between active and candidate config.") cu.pdiff() printProgress("INFO",my_hostname,"Performing commit check") if cu.commit_check(): printProgress("INFO",my_hostname,"commit check was successfull.") printProgress("INFO",my_hostname,"performing commit now.") commit_status=cu.commit() printProgress("INFO",my_hostname,"disconnecting from device.") dev.close() return commit_status else: return False except Exception,err: printProgress("ERROR",my_hostname,"Encountered exception while deploying config") printProgress("ERROR",my_hostname,str(err)) return False
def snap(self): dev = Device(host=self.hostname, user=user, password=password) dev.open() # get basic Node facts node = Node(self.snapshot, self.hostname) node.fqdn = dev.facts['fqdn'] node.hostname = dev.facts['hostname'] node.model = dev.facts['model'] node.personality = dev.facts['personality'] node.serialnumber = dev.facts['serialnumber'] node.switch_style = dev.facts['switch_style'] node.version = dev.facts['version'] node.uptime = dev.facts['RE0']['up_time'] node.reboot_reason = dev.facts['RE0']['last_reboot_reason'] roumiga.session.add(node) roumiga.session.flush() # do the ARP dance import jnpr.junos.op.arp raw_arp = jnpr.junos.op.arp.ArpTable(dev) for a in raw_arp.get(): arp_entry = ArpEntry.from_dict(snapshot, node, a) roumiga.session.add(arp_entry) self.arp.append(arp_entry) # do the BGP dance import jnpr.junos.op.bgppeer raw_bgp = jnpr.junos.op.bgppeer.BgpPeerTable(dev) for b in raw_bgp.get(): bgp_peer = BgpPeer.from_dict(snapshot, node, b) roumiga.session.add(bgp_peer) self.bgp.append(bgp_peer) dev.close()
class TestTable(unittest.TestCase): @classmethod def setUpClass(self): from jnpr.junos import Device self.dev = Device(host='stag.englab.juniper.net', user='******', password='******') self.dev.open() @classmethod def tearDownClass(self): self.dev.close() def test_table_union(self): lldp = LLDPNeighborTable(self.dev) lldp.get('et-0/1/1') self.assertEqual(lldp['et-0/1/1'].local_int, 'et-0/1/1') def test_table_json(self): lldp = LLDPNeighborTable(self.dev) lldp.get('et-0/1/1') json = '{"et-0/1/1": {"remote_port_desc": "et-1/1/1", '\ '"local_int": "et-0/1/1", "remote_sysname": "highlife", '\ '"local_parent": "-", "remote_chassis_id": "4c:96:14:f3:d5:20", '\ '"remote_type": "Mac address"}}' self.assertEqual(lldp.to_json(), json)
def main(): module = AnsibleModule( argument_spec=dict( host=dict(required=True), user=dict(required=False, default=os.getenv('USER')), passwd=dict(required=False, default=None)), supports_check_mode=False) m_args = module.params m_results = dict(changed=False) dev = Device(m_args['host'], user=m_args['user'], passwd=m_args['passwd']) try: dev.open() except Exception as err: msg = 'unable to connect to {}: {}'.format(m_args['host'], str(err)) module.fail_json(msg=msg) return results = {} lldp_results = [] try: lldp = LLDPNeighborTable(dev) lldp.get() lldp = json.loads(json.dumps(lldp, cls=TableJSONEncoder)) except Exception as err: dev.close() module.fail_json(msg=err) return dev.close() module.exit_json(results=lldp)
def main(): """Simple main method to view custom BGP table.""" routers = ['10.11.12.1', '10.11.12.2'] username = '******' password = '******' for router in routers: dev = Device(host=router, user=username, password=password) dev.open() dev_info = BGPNeighborTable(dev) dev_info.get() for key in dev_info.keys(): bgp_info = dev_info[key] print('#' * 60) print('This host : {host}'.format(host=bgp_info.local_address)) print('Belongs to ASN : {ver}'.format(ver=bgp_info.local_as)) print('And peers with : {host}'.format(host=bgp_info.peer_address)) print('In ASN : {ver}'.format(ver=bgp_info.peer_as)) print('The peer type is : {ver}'.format(ver=bgp_info.peer_type)) print('The peer state is : {flap}'.format(flap=bgp_info.peer_state)) print('The peer is advertising : {sent}'.format(sent=bgp_info.nlri_type_peer)) print('We peer are advertising : {recv}'.format(recv=bgp_info.nlri_type_session)) print('We are applying policy : {act}'.format(act=bgp_info.export_policy)) print('With route preference : {recv}'.format(recv=bgp_info.preference)) print('Using holdtime : {acc}'.format(acc=bgp_info.holdtime)) print('#' * 60) dev.close()
class TestCore(unittest.TestCase): @classmethod def setUpClass(self): from jnpr.junos import Device self.dev = Device(host='snuggums.englab.juniper.net', user='******', password='******') self.dev.open() @classmethod def tearDownClass(self): self.dev.close() def test_device_open(self): self.assertEqual(self.dev.connected, True) def test_device_facts(self): assert self.dev.facts['hostname'] == 'snuggums' def test_device_get_timeout(self): assert self.dev.timeout == 30 def test_device_set_timeout(self): self.dev.timeout = 35 assert self.dev.timeout == 35 def test_device_cli(self): self.assertIn('qfx5100', self.dev.cli('show version')) def test_device_rpc(self): sw = self.dev.rpc.get_software_information() hostname = sw.findtext('.//host-name') self.assertEqual(hostname, 'snuggums')
def main(): #iterate over csv for row in devList: #Make Device Connection dev = Device(host=row[1], user=userName, password=userPassword) try: #Print Opening Header for Status now1 = datetime.datetime.now() pprint("Work starts on " + row[0] + " | " + row[1] + " at " + now1.strftime("%Y-%m-%d %H:%M")) #Open Device with Custom Timer dev.open() dev.timeout = 300 except Exception as err: sys.stderr.write('Cannot connect to device: {0}\n'.format(err)) #Do RPC/Work try: #Start Work here #Write Element Seperator print("+++++++++++++++++++++++++++++++++++++++++++++++++") #Close Device dev.close() except Exception as err: sys.stderr.write('Cannot perform RPC on device: ' + row[1] + '\n'.format(err)) print("+++++++++++++++++++++++++++++++++++++++++++++++++")
def login(): error = None if request.method == 'POST': hostname = request.form['hostname'] username = request.form['username'] password = request.form['password'] # # Retrieve device information # dev = Device(hostname,user=username,password=password) try: dev.open() except ConnectAuthError: error = 'Wrong Credentials. Please try again.' return render_template('login.html',error=error) except ConnectTimeoutError: error = 'Timeout. Host not reachable?' return render_template('login.html',error=error) except ConnectError: error = 'Huh... something wrong. Try again?' return render_template('login.html',error=error) print "Login success" # Print device info global device device = dev.facts print "Device Name: ", device['hostname'] print device dev.close() return redirect(url_for('get_device')) return render_template('login.html', error=error)
def main(): module = AnsibleModule( argument_spec=dict( host=dict(required=True), targets=dict(required=False, default=None), checktype=dict(required=False, default='pre'), user=dict(required=False, default=os.getenv('USER')), passwd=dict(required=False, default=None)), supports_check_mode=False) m_args = module.params m_results = dict(changed=False) dev = Device(m_args['host'], user=m_args['user'], passwd=m_args['passwd']) try: dev.open() results = {} ping_results = [] if m_args['checktype'] == 'pre': try: arp = ArpTable(dev) arp.get() arp_json = json.loads(json.dumps(arp, cls=TableJSONEncoder)) for entry in arp_json: ping_results.append(dev.rpc.ping (host=arp_json[entry]['ip_address'], count='3', rapid=True)) for entry in ping_results: ip = entry.findtext('target-ip').replace('\n', '') results[ip] = {} if entry.findtext('ping-success') is not None: results[ip]['success'] = True else: results[ip]['success'] = False except Exception as err: module.fail_json(msg=err) elif m_args['targets'] is not None: import ast m_args['targets'] = ast.literal_eval(m_args['targets']) for entry in m_args['targets']: if m_args['targets'][entry]['success'] == True: ping_results.append(dev.rpc.ping (host=entry, count='3', rapid=True)) for entry in ping_results: ip = entry.findtext('target-ip').replace('\n', '') results[ip] = {} if entry.findtext('ping-success') is not None: results[ip]['success'] = True else: results[ip]['success'] = False else: module.fail_json(msg='You specified a post-check \ but did not specify targets.') except Exception as err: msg = 'unable to connect to {}: {}'.format(m_args['host'], str(err)) module.fail_json(msg=msg) return else: dev.close() module.exit_json(results=results)
def test_can_login_parse_serial(self): config = ConfigDictionary('./etc/example.ini') jdev = Device(user=config.username(), host=config.get_router_ip('rtr1'), password=config.password()) jdev.open(gather_facts=False) inv = jdev.rpc.get_chassis_inventory() print "model: %s" % inv.findtext('.//chassis/description') jdev.close() assert inv.findtext('.//chassis/description') == 'VMX'
def main(): # open a connection with the device and start a NETCONF session try: dev = Device(host=host,user=user,ssh_private_key_file=privateKey) print ("Connecting...") dev.open() print ("Connected.") dev.bind(cu=Config) # Lock the configuration, load configuration changes, and commit print ("Locking the configuration") dev.cu.lock() print ("Loading configuration changes") #dev.cu.load(path=conf_file, merge=True) dev.cu.load(cmd, merge=True) print ("Diff") dev.cu.pdiff() print ("Committing the configuration") dev.cu.commit(comment='Loaded by example.') print ("Unlocking the configuration") dev.cu.unlock() except ConnectError as err: print ("Cannot connect to device: {0}".format(err)) except LockError as err: print ("Unable to lock configuration: {0}".format(err)) except (ConfigLoadError, Exception) as err: print ("Unable to load configuration changes: {0}".format(err)) print ("Unlocking the configuration") try: dev.cu.unlock() except UnlockError: print ("Unable to unlock configuration: {0}".format(err)) except CommitError as err: print ("Unable to commit configuration: {0}".format(err)) print ("Unlocking the configuration") try: dev.cu.unlock() except UnlockError as err: print ("Unable to unlock configuration: {0}".format(err)) except UnlockError as err: print ("Unable to unlock configuration: {0}".format(err)) # End the NETCONF session and close the connection dev.close()
class JunOSDriver(NetworkDriver): def __init__(self, hostname, username, password): self.hostname = hostname self.username = username self.password = password self.device = Device(hostname, user=username, password=password) self.config_replace = False def open(self): self.device.open() self.device.bind(cu=Config) self.device.cu.lock() def close(self): self.device.cu.unlock() self.device.close() def _load_candidate(self, filename, config, overwrite): if filename is None: configuration = config else: with open(filename) as f: configuration = f.read() try: self.device.cu.load(configuration, format='text', overwrite=overwrite) except ConfigLoadError as e: if self.config_replace: raise ReplaceConfigException(e.message) else: raise MergeConfigException(e.message) def load_replace_candidate(self, filename=None, config=None): self.config_replace = True self._load_candidate(filename, config, True) def load_merge_candidate(self, filename=None, config=None): self.config_replace = False self._load_candidate(filename, config, False) def compare_config(self): diff = self.device.cu.diff() if diff is None: return '' else: return diff def commit_config(self): self.device.cu.commit() def discard_config(self): self.device.cu.rollback(rb_id=0) def rollback(self): self.device.cu.rollback(rb_id=1) self.commit_config()
def run(self): self.logfile = open(os.getcwd() + '/' + 'linkfailure_log', 'a') while True: while self.failed() == False: time.sleep(1) # select a router r_number = random.randint(1,len(self.rtr)) - 1 # select a random interface i_number = random.randint(1, len(self.rtr[r_number]['interfaces'])) - 1 #set interfaces ge-1/0/3 disable cmd = 'set interfaces ' + self.rtr[r_number]['interfaces'][i_number]['name'] + ' disable' dev = Device(host=self.rtr[r_number]['ip'], user='******', password='******') dev.open() dev.timeout = 60 cu = Config(dev) cu.lock() cu.load(cmd, format='set', merge=True) cu.commit() cu.unlock() dev.close() link__data = { 'status': 'failed', 'timestamp': datetime.datetime.fromtimestamp(time.time()).strftime('%a:%H:%M:%S'), 'router_id': self.rtr[r_number]['router_id'], 'router_name': self.rtr[r_number]['name'], 'interface_address': self.rtr[r_number]['interfaces'][i_number]['address'], 'interface_name': self.rtr[r_number]['interfaces'][i_number]['name'] } jd = json.dumps(link__data) self.redis.publish('link_event', jd) self.logfile.write("Link failed: " + datetime.datetime.fromtimestamp(time.time()).strftime('%a:%H:%M:%S') + " " + self.rtr[r_number]['name'] + " " + self.rtr[r_number]['ip'] + " " + self.rtr[r_number]['interfaces'][i_number]['name'] + "\n") self.logfile.flush() # now repair the link while self.repaired() == False: time.sleep(1) cmd = 'delete interfaces ' + self.rtr[r_number]['interfaces'][i_number]['name'] + ' disable' dev = Device(host=self.rtr[r_number]['ip'], user='******', password='******') dev.open() dev.timeout = 60 cu = Config(dev) cu.lock() cu.load(cmd, format='set', merge=True) cu.commit() cu.unlock() dev.close() link__data = { 'status': 'healed', 'timestamp': datetime.datetime.fromtimestamp(time.time()).strftime('%a:%H:%M:%S'), 'router_id': self.rtr[r_number]['router_id'], 'router_name': self.rtr[r_number]['name'], 'interface_address': self.rtr[r_number]['interfaces'][i_number]['address'], 'interface_name': self.rtr[r_number]['interfaces'][i_number]['name'] } jd = json.dumps(link__data) self.redis.publish('link_event', jd) self.logfile.write("Link healed: " + datetime.datetime.fromtimestamp(time.time()).strftime('%a:%H:%M:%S') + " " + self.rtr[r_number]['name'] + " " + self.rtr[r_number]['ip'] + " " + self.rtr[r_number]['interfaces'][i_number]['name'] + "\n") self.logfile.flush()
def main(args): '''Acquire necessary input options, interact with SRX device as specified per CLI args.''' parser = argparse.ArgumentParser( description='Interact with specified SRX device as specified') parser.add_argument('--version', action='version', version=__version__) parser.add_argument('-d', '--datafile', help='specify YAML file to read router info from', default=SRX_FILE) parser.add_argument('--prompt', action='store_true', help='prompt for router info (do not try to read in from file)', default=False) parser.add_argument('-v', '--verbose', action='store_true', help='display verbose output', default=False) args = parser.parse_args() # Debugging #if args.verbose: # print 'Args = {}'.format(args) # Initialize data structures mysrx = {} if not args.prompt: mysrx = yaml_input(args.datafile, args.verbose) # Debugging #if args.verbose: # print 'mysrx = {}'.format(mysrx) else: if args.verbose: print 'Prompting specified - asking user for all connection details' check_input(mysrx, args.verbose) mysrx_conn = Device(host=mysrx['HOST'], user=mysrx['USER'], password=mysrx['PASSWORD']) if args.verbose: print 'Opening NETCONF connection to {}...'.format(mysrx['HOST']) mysrx_conn.open() # Set timeout - default of 30 seconds can be problematic, must set after open() mysrx_conn.timeout = TIMEOUT mysrx_cfg = Config(mysrx_conn) # Change 1 if args.verbose: print '\nChange #1' srx_conf(mysrx, mysrx_cfg, SRX_CONF_CHG1, 'set', True, False, verbose=args.verbose) # Change 2 if args.verbose: print '\nChange #2' srx_conf(mysrx, mysrx_cfg, SRX_CONF_FILE, 'text', True, True, 'Temporarily changing hostname.', args.verbose) # Change 3 if args.verbose: print '\nChange #3' srx_conf(mysrx, mysrx_cfg, SRX_XML_FILE, 'xml', True, True, 'Restoring original hostname.', args.verbose) # Cleanup mysrx_conn.close()
class RoutingTestSuite(unittest.TestCase): def setUp(self): self.dev = Device( host='127.0.0.1', user='******', password='******', port='2222' ) self.dev.open() def tearDown(self): self.dev.close()
def process_device(ip, **kwargs): dev = Device(host=ip, **kwargs) try: dev.open() arp_table = ArpTable(dev) arp_table.get() vlan_table = VlanTable(dev) vlan_table.get() switch_table = EthSwitchTable(dev) switch_table.get() switch_interface = EthSwitchInterfaceTable(dev) switch_interface.get() if len(switch_table) > 0: for x in switch_table: for a in arp_table: for v in vlan_table: str = v.l3_interface if ipaddr == a.ip_address and a.mac_address == x.mac_address and str.strip(' (UP)') == a.l3_interface: print_data(ip.rstrip(), x.mac_address, x.interface, a.ip_address, a.l3_interface, v.l3_interface_address, x.tag, x.vlan_name, '') for i in switch_interface: if x.interface == i.interface and x.vlan_name == i.vlan_name: if i.interface_tag == 'untagged': print_data(ip.rstrip(), x.mac_address, x.interface, '', '', '', x.tag, x.vlan_name, untagged_port) elif macaddr == a.mac_address and a.mac_address == x.mac_address and str.strip(' (UP)') == a.l3_interface: print_data(ip.rstrip(), x.mac_address, x.interface, a.ip_address, a.l3_interface, v.l3_interface_address, x.tag, x.vlan_name, '') else: if macaddr == '' and ipaddr == '': if a.mac_address == x.mac_address and str.strip(' (UP)') == a.l3_interface: print_data(ip.rstrip(), x.mac_address, x.interface, a.ip_address, a.l3_interface, v.l3_interface_address, x.tag, x.vlan_name, '') if x.mac_address != '' and macaddr == '' and ipaddr == '': print_data(ip.rstrip(), x.mac_address, x.interface, '', '', '', x.tag, x.vlan_name, '') if macaddr == x.mac_address: for i in switch_interface: if macaddr != '': if x.interface == i.interface and macaddr == x.mac_address and x.vlan_name == i.vlan_name: if i.interface_tag == 'untagged': print_data(ip.rstrip(), x.mac_address, x.interface, '', '', '', x.tag, x.vlan_name, untagged_port) else: print '\nNo table entries for this device: ' + ip.rstrip() + '\n' except RpcError: msg = "{0} was Skipped due to RPC Error. Device is not EX/Branch-SRX Series".format(ip.rstrip()) alldatafile.write(msg + '\n') print msg dev.close() except Exception as err: msg = "{0} was skipped due to unhandled exception.\n{1}".format(ip.rstrip(), err) alldatafile.write(msg + '\n') print msg traceback.print_exc(file=sys.stdout) dev.close()
def procedimiento_arp(ip, user, passwd): print "Tabla ARP para host %s" % ip dev = Device(host=ip, user=user, passwd=passwd) dev.open() arp_list = ArpTable(dev) arp_list.get() for arp_elem in arp_list: print " arp %s asociada a ip %s por interfaz %s" % (arp_elem.mac_address, arp_elem.ip_address, arp_elem.interface_name) print "\n" time.sleep(2) dev.close()
def print_arp(hostname): dev = Device(user=username, host=hostname, password=password) dev.open() arp_table = ArpTable(dev).get() for arp in arp_table: print hostname, arp.interface_name, arp.ip_address, arp.mac_address dev.close()
def InstallOnHost(hostname, username, password, softwareFilePath, rebootTime): dev = Device(host=hostname, user=username, password=password) softw = SW(dev) hash = SW.local_md5(softwareFilePath) softw.install(softwareFilePath, remote_path='/var/tmp', progress=dev, validate=False, checksum=hash, cleanfs=False, no_copy=False, timeout=1800) if rebootTime != 0: softw.reboot(rebootTime) dev.close()
def customize(hostip, switchvars, templatefile="access_switch.j2"): dev = Device(user="******", host=hostip, password="******") dev.open() dev.bind(cu=Config) dev.cu print "Loading template onto: {0} (SN: {1}) @ {2}".format(switchvars['hostname'], switchvars['serial_number'], switchvars['mgmt_ip']) dev.cu.load(template_path=templatefile, template_vars=switchvars, format="set") dev.cu.commit() dev.close()
def bgp_form(): device = session.get('device', None) dev = Device(host=device, user=username, password=password) dev.open() bgp = dev.rpc.get_bgp_neighbor_information() neighbors = bgp.findall('bgp-peer') bgp_peers = {} for neighbor in neighbors: bgp_peers[neighbor.find("peer-address").text] = neighbor.find('peer-state').text dev.close() return render_template("bgp_form.html", bgp_peers=bgp_peers)
def get_conf(host, filter_xml, exclude): dev = Device(host=host,user=user,password=password) dev.open() root = dev.rpc.get_config(filter_xml=filter_xml) dev.close() root.attrib.pop('changed-localtime') root.attrib.pop('changed-seconds') for child in root.findall(".//name"): if child.text in exclude: parent = child.getparent() parent.getparent().remove(parent) return etree.tostring(root)
class Netconf(object): def __init__(self): if not HAS_PYEZ: raise NetworkError( msg= 'junos-eznc >= 1.2.2 is required but does not appear to be installed. ' 'It can be installed using `pip install junos-eznc`') if not HAS_JXMLEASE: raise NetworkError( msg='jxmlease is required but does not appear to be installed. ' 'It can be installed using `pip install jxmlease`') self.device = None self.config = None self._locked = False self._connected = False self.default_output = 'xml' def raise_exc(self, msg): if self.device: if self._locked: self.config.unlock() self.disconnect() raise NetworkError(msg) def connect(self, params, **kwargs): host = params['host'] port = params.get('port') or 830 user = params['username'] passwd = params['password'] try: self.device = Device(host, user=user, passwd=passwd, port=port, gather_facts=False) self.device.open() except ConnectError: exc = get_exception() self.raise_exc('unable to connect to %s: %s' % (host, str(exc))) self.config = Config(self.device) self._connected = True def disconnect(self): try: self.device.close() except AttributeError: pass self._connected = False ### Command methods ### def run_commands(self, commands): responses = list() for cmd in commands: meth = getattr(self, cmd.args.get('command_type')) responses.append(meth(str(cmd), output=cmd.output)) for index, cmd in enumerate(commands): if cmd.output == 'xml': responses[index] = etree.tostring(responses[index]) elif cmd.args.get('command_type') == 'rpc': responses[index] = str(responses[index].text).strip() return responses def cli(self, commands, output='xml'): '''Send commands to the device.''' try: return self.device.cli(commands, format=output, warning=False) except (ValueError, RpcError): exc = get_exception() self.raise_exc('Unable to get cli output: %s' % str(exc)) def rpc(self, command, output='xml'): name, kwargs = rpc_args(command) meth = getattr(self.device.rpc, name) reply = meth({'format': output}, **kwargs) return reply ### Config methods ### def get_config(self, config_format="text"): if config_format not in SUPPORTED_CONFIG_FORMATS: self.raise_exc(msg='invalid config format. Valid options are ' '%s' % ', '.join(SUPPORTED_CONFIG_FORMATS)) ele = self.rpc('get_configuration', output=config_format) if config_format == 'text': return str(ele.text).strip() else: return ele def load_config(self, config, commit=False, replace=False, confirm=None, comment=None, config_format='text'): if replace: merge = False overwrite = True else: merge = True overwrite = False if overwrite and config_format == 'set': self.raise_exc( 'replace cannot be True when config_format is `set`') self.lock_config() try: candidate = '\n'.join(config) self.config.load(candidate, format=config_format, merge=merge, overwrite=overwrite) except ConfigLoadError: exc = get_exception() self.raise_exc('Unable to load config: %s' % str(exc)) diff = self.config.diff() self.check_config() if all((commit, diff)): self.commit_config(comment=comment, confirm=confirm) self.unlock_config() return diff def save_config(self): raise NotImplementedError ### end of Config ### def get_facts(self, refresh=True): if refresh: self.device.facts_refresh() return self.device.facts def unlock_config(self): try: self.config.unlock() self._locked = False except UnlockError: exc = get_exception() raise NetworkError('unable to unlock config: %s' % str(exc)) def lock_config(self): try: self.config.lock() self._locked = True except LockError: exc = get_exception() raise NetworkError('unable to lock config: %s' % str(exc)) def check_config(self): if not self.config.commit_check(): self.raise_exc(msg='Commit check failed') def commit_config(self, comment=None, confirm=None): try: kwargs = dict(comment=comment) if confirm and confirm > 0: kwargs['confirm'] = confirm return self.config.commit(**kwargs) except CommitError: exc = get_exception() raise NetworkError('unable to commit config: %s' % str(exc)) def rollback_config(self, identifier, commit=True, comment=None): self.lock_config() try: self.config.rollback(identifier) except ValueError: exc = get_exception() self.raise_exc('Unable to rollback config: $s' % str(exc)) diff = self.config.diff() if commit: self.commit_config(comment=comment) self.unlock_config() return diff
def main(): dev = Device(host=host, user='******', password='******', gather_facts=False) # open a connection with the device and start a NETCONF session try: dev.open() except ConnectAuthError: print 'ERROR: Authentication failed.' return except ConnectRefusedError: print 'ERROR: Connection refused.' return except ConnectTimeoutError: print 'ERROR: Connection timed out.' return except ConnectError: print 'ERROR: Connection failed.' return print 'Connected to device %s' % (host) dev.bind(cu=Config) # Lock the configuration, load configuration changes, and commit print "Locking the configuration" try: dev.cu.lock() except LockError: print "ERROR: Unable to lock configuration" dev.close() return print "Loading configuration changes" try: dev.cu.load(path=conf_file, merge=True) except IOError: print "ERROR: Unable to open configuration file" return print "Candidate configuration:" dev.cu.pdiff() # user commit confirmation, else rollback commit_config = raw_input('Do you want to commit the configuration(Y/N)? ') if commit_config in ["yes", "Yes", "y", "Y"]: print "Committing the configuration" try: dev.cu.commit() except CommitError: print "ERROR: Unable to commit configuration" print "Unlocking the configuration" try: dev.cu.unlock() except UnlockError: print "ERROR: Unable to unlock configuration" dev.close() return print "Unlocking the configuration" try: dev.cu.unlock() except UnlockError: print "ERROR: Unable to unlock configuration" else: print "Not committing the changes" # End the NETCONF session and close the connection dev.close()
class JunosDevice(BaseDevice): def __init__(self, host, username, password, *args, **kwargs): super(JunosDevice, self).__init__(host, username, password, *args, vendor='juniper', device_type='juniper_junos_netconf', **kwargs) self.native = JunosNativeDevice(*args, host=host, user=username, passwd=password, **kwargs) self.open() self.cu = JunosNativeConfig(self.native) self.fs = JunosNativeFS(self.native) self.sw = JunosNativdSW(self.native) def _file_copy_local_file_exists(self, filepath): return os.path.isfile(filepath) def _file_copy_local_md5(self, filepath, blocksize=2**20): if self._file_copy_local_file_exists(filepath): m = hashlib.md5() with open(filepath, "rb") as f: buf = f.read(blocksize) while buf: m.update(buf) buf = f.read(blocksize) return m.hexdigest() def _file_copy_remote_md5(self, filename): return self.fs.checksum(filename) def _get_interfaces(self): eth_ifaces = EthPortTable(self.native) eth_ifaces.get() loop_ifaces = LoopbackTable(self.native) loop_ifaces.get() ifaces = eth_ifaces.keys() ifaces.extend(loop_ifaces.keys()) return ifaces def _uptime_components(self, uptime_full_string): match_days = re.search(r'(\d+) days?', uptime_full_string) match_hours = re.search(r'(\d+) hours?', uptime_full_string) match_minutes = re.search(r'(\d+) minutes?', uptime_full_string) match_seconds = re.search(r'(\d+) seconds?', uptime_full_string) days = int(match_days.group(1)) if match_days else 0 hours = int(match_hours.group(1)) if match_hours else 0 minutes = int(match_minutes.group(1)) if match_minutes else 0 seconds = int(match_seconds.group(1)) if match_seconds else 0 return days, hours, minutes, seconds def _uptime_to_seconds(self, uptime_full_string): days, hours, minutes, seconds = self._uptime_components(uptime_full_string) seconds += days * 24 * 60 * 60 seconds += hours * 60 * 60 seconds += minutes * 60 return seconds def _uptime_to_string(self, uptime_full_string): days, hours, minutes, seconds = self._uptime_components(uptime_full_string) return '%02d:%02d:%02d:%02d' % (days, hours, minutes, seconds) def backup_running_config(self, filename): with open(filename, 'w') as f: f.write(self.running_config) def checkpoint(self, filename): self.save(filename) def close(self): if self.connected: self.native.close() def config(self, command, format='set'): try: self.cu.load(command, format=format) self.cu.commit() except ConfigLoadError as e: raise CommandError(command, e.message) def config_list(self, commands, format='set'): try: for command in commands: self.cu.load(command, format=format) self.cu.commit() except ConfigLoadError as e: raise CommandListError(commands, command, e.message) @property def connected(self): return self.native.connected @property def facts(self): if hasattr(self, '_facts'): return self._facts native_facts = self.native.facts facts = {} facts['hostname'] = native_facts['hostname'] facts['fqdn'] = native_facts['fqdn'] facts['model'] = native_facts['model'] native_uptime_string = native_facts['RE0']['up_time'] facts['uptime'] = self._uptime_to_seconds(native_uptime_string) facts['uptime_string'] = self._uptime_to_string(native_uptime_string) facts['serial_number'] = native_facts['serialnumber'] facts['interfaces'] = self._get_interfaces() for fact_key in native_facts: if fact_key.startswith('version') and fact_key != 'version_info': facts['os_version'] = native_facts[fact_key] break facts['vendor'] = self.vendor self._facts = facts return self._facts def file_copy(self, src, dest=None, **kwargs): if dest is None: dest = os.path.basename(src) with SCP(self.native) as scp: scp.put(src, remote_path=dest) def file_copy_remote_exists(self, src, dest=None, **kwargs): if dest is None: dest = os.path.basename(src) local_hash = self._file_copy_local_md5(src) remote_hash = self._file_copy_remote_md5(dest) if local_hash is not None: if local_hash == remote_hash: return True return False def get_boot_options(self): return self.facts['os_version'] def open(self): if not self.connected: self.native.open() def reboot(self, timer=0, confirm=False): if confirm: self.sw.reboot(in_min=timer) else: print('Need to confirm reboot with confirm=True') def rollback(self, filename): self.native.timeout = 60 temp_file = NamedTemporaryFile() with SCP(self.native) as scp: scp.get(filename, local_path=temp_file.name) self.cu.load(path=temp_file.name, format='text', overwrite=True) self.cu.commit() temp_file.close() self.native.timeout = 30 @property def running_config(self): return self.show('show config') def save(self, filename=None): if filename is None: self.cu.commit() return temp_file = NamedTemporaryFile() temp_file.write(self.show('show config')) temp_file.flush() with SCP(self.native) as scp: scp.put(temp_file.name, remote_path=filename) temp_file.close() return True def set_boot_options(self, sys): raise NotImplementedError def show(self, command, raw_text=True): if not raw_text: raise ValueError('Juniper only supports raw text output. \ Append " | display xml" to your commands for a structured string.') if not command.startswith('show'): raise CommandError(command, 'Juniper "show" commands must begin with "show".') return self.native.cli(command, warning=False) def show_list(self, commands, raw_text=True): responses = [] for command in commands: responses.append(self.show(command, raw_text=raw_text)) return responses @property def startup_config(self): return self.show('show config')
from jnpr.junos import Device from pprint import pprint switch = {'host': '10.10.10.150', 'user': '******', 'pw': ''} conn = Device(host=switch['host'], user=switch['user'], password=switch['pw']) conn.open() # pprint(conn.facts) hostname = conn.facts['hostname'] style = conn.facts['switch_style'] print(f"{hostname} has the style type of {style}") conn.close()
from pprint import pprint from jnpr.junos import Device from lxml import etree import xmltodict import json junos_device = Device(host='10.4.4.41', user='******', password='******') junos_device.open() output_file1 = open('09-pyez-04-rpc-calls-3-xml-todict.json', 'w') output = junos_device.rpc.get_interface_information(interface_name='fxp0.0') xml_serial = etree.tostring(output) # xml_serial is serialized xml without all the prettin indenting. # Make a dictionary from the serail xml. # xmltodict.unparse for the opposite is available. xml_dict = xmltodict.parse(xml_serial) output_file1.write(json.dumps(xml_dict, indent=4)) print(json.dumps(xml_dict)) junos_device.close()
class TestDevice(unittest.TestCase): @patch('ncclient.manager.connect') def setUp(self, mock_connect): mock_connect.side_effect = self._mock_manager self.dev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) self.dev.open() @patch('ncclient.operations.session.CloseSession.request') def tearDown(self, mock_session): self.dev.close() def test_new_console_return(self): dev = Device(host='1.1.1.1', user='******', password='******', port=23, gather_facts=False) self.assertTrue(isinstance(dev, Console)) @patch('jnpr.junos.device.netconf_ssh') def test_device_ConnectAuthError(self, mock_manager): mock_manager.connect.side_effect = NcErrors.AuthenticationError self.assertRaises(EzErrors.ConnectAuthError, self.dev.open) @patch('jnpr.junos.device.netconf_ssh') def test_device_ConnectRefusedError(self, mock_manager): mock_manager.connect.side_effect = NcErrors.SSHError self.assertRaises(EzErrors.ConnectRefusedError, self.dev.open) @patch('jnpr.junos.device.netconf_ssh') @patch('jnpr.junos.device.datetime') def test_device_ConnectTimeoutError(self, mock_datetime, mock_manager): mock_manager.connect.side_effect = NcErrors.SSHError( "Could not open socket to 1.1.1.1:830") from datetime import timedelta, datetime currenttime = datetime.now() mock_datetime.datetime.now.side_effect = [ currenttime, currenttime + timedelta(minutes=4) ] self.assertRaises(EzErrors.ConnectTimeoutError, self.dev.open) @patch('jnpr.junos.device.netconf_ssh') @patch('jnpr.junos.device.datetime') def test_device_diff_err_message(self, mock_datetime, mock_manager): NcErrors.SSHError.message = 'why are you trying :)' mock_manager.connect.side_effect = NcErrors.SSHError from datetime import timedelta, datetime currenttime = datetime.now() mock_datetime.datetime.now.side_effect = [ currenttime, currenttime + timedelta(minutes=4) ] self.assertRaises(EzErrors.ConnectError, self.dev.open) @patch('jnpr.junos.device.netconf_ssh') def test_device_ConnectUnknownHostError(self, mock_manager): import socket mock_manager.connect.side_effect = socket.gaierror self.assertRaises(EzErrors.ConnectUnknownHostError, self.dev.open) @patch('jnpr.junos.device.netconf_ssh') def test_device_other_error(self, mock_manager): mock_manager.connect.side_effect = TypeError self.assertRaises(EzErrors.ConnectError, self.dev.open) def test_device_probe_error(self): mock_probe = MagicMock() mock_probe.return_value = None self.dev.probe = mock_probe def fn(): self.dev.open(auto_probe=1) self.assertRaises(EzErrors.ProbeError, fn) def test_device_property_logfile_isinstance(self): mock = MagicMock() with patch(builtin_string + '.open', mock): if sys.version > '3': builtin_file = 'io.TextIOWrapper' else: builtin_file = builtin_string + '.file' with patch(builtin_file, MagicMock): handle = open('filename', 'r') self.dev.logfile = handle self.assertEqual(self.dev.logfile, handle) def test_device_host_mand_param(self): self.assertRaises(ValueError, Device, user='******', password='******', gather_facts=False) def test_device_property_logfile_close(self): self.dev._logfile = MagicMock() self.dev._logfile.close.return_value = 0 self.dev.logfile = None self.assertFalse(self.dev._logfile) def test_device_property_logfile_exception(self): try: self.dev.logfile = True except Exception as ex: self.assertEqual(type(ex), ValueError) def test_device_repr(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) self.assertEqual(repr(localdev), 'Device(1.1.1.1)') def test_device_local(self): Device.ON_JUNOS = True localdev = Device() self.assertEqual(localdev._hostname, 'localhost') @patch('jnpr.junos.device.os') @patch(builtin_string + '.open') @patch('paramiko.config.SSHConfig.lookup') def test_device__sshconf_lkup(self, mock_paramiko, open_mock, os_mock): os_mock.path.exists.return_value = True self.dev._sshconf_lkup() mock_paramiko.assert_called_once_with('1.1.1.1') @patch('jnpr.junos.device.os') @patch(builtin_string + '.open') @patch('paramiko.config.SSHConfig.lookup') def test_device__sshconf_lkup_def(self, mock_paramiko, open_mock, os_mock): os_mock.path.exists.return_value = True self.dev._ssh_config = '/home/rsherman/.ssh/config' self.dev._sshconf_lkup() mock_paramiko.assert_called_once_with('1.1.1.1') @patch('os.getenv') def test_device__sshconf_lkup_path_not_exists(self, mock_env): mock_env.return_value = '/home/test' self.assertEqual(self.dev._sshconf_lkup(), None) @patch('os.getenv') def test_device__sshconf_lkup_home_not_defined(self, mock_env): mock_env.return_value = None self.assertEqual(self.dev._sshconf_lkup(), None) mock_env.assert_called_with('HOME') @patch('ncclient.manager.connect') @patch('jnpr.junos.Device.execute') def test_device_open(self, mock_connect, mock_execute): with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat: mock_cat.return_value = """ domain jls.net """ mock_connect.side_effect = self._mock_manager mock_execute.side_effect = self._mock_manager self.dev2 = Device(host='2.2.2.2', user='******', password='******') self.dev2.open() self.assertEqual(self.dev2.connected, True) @patch('jnpr.junos.Device.execute') def test_device_facts(self, mock_execute): with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat: mock_execute.side_effect = self._mock_manager mock_cat.return_value = """ domain jls.net """ self.dev.facts_refresh() self.dev.facts._cache['current_re'] = ['re0'] assert self.dev.facts['version'] == facts['version'] @patch('jnpr.junos.Device.execute') @patch('jnpr.junos.factcache.warnings') def test_device_facts_error(self, mock_warnings, mock_execute): with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat: mock_execute.side_effect = self._mock_manager mock_cat.side_effect = IOError('File cant be handled') self.dev.facts_refresh(warnings_on_failure=True) self.assertTrue(mock_warnings.warn.called) @patch('jnpr.junos.Device.execute') @patch('jnpr.junos.device.warnings') def test_device_facts_error_exception_on_error(self, mock_warnings, mock_execute): with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat: mock_execute.side_effect = self._mock_manager mock_cat.side_effect = IOError('File cant be handled') self.assertRaises(IOError, self.dev.facts_refresh, exception_on_failure=True) @patch('jnpr.junos.Device.execute') @patch('jnpr.junos.device.warnings') def test_device_old_style_facts_error_exception_on_error( self, mock_warnings, mock_execute): self.dev._fact_style = 'old' with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat: mock_execute.side_effect = self._mock_manager mock_cat.side_effect = IOError('File cant be handled') self.assertRaises(IOError, self.dev.facts_refresh, exception_on_failure=True) def test_device_facts_refresh_unknown_fact_style(self): self.dev._fact_style = 'bad' with self.assertRaises(RuntimeError): self.dev.facts_refresh() def test_device_facts_refresh_old_fact_style_with_keys(self): self.dev._fact_style = 'old' with self.assertRaises(RuntimeError): self.dev.facts_refresh(keys='domain') def test_device_hostname(self): self.assertEqual(self.dev.hostname, '1.1.1.1') def test_device_user(self): self.assertEqual(self.dev.user, 'test') def test_device_get_password(self): self.assertEqual(self.dev.password, None) def test_device_set_password(self): self.dev.password = '******' self.assertEqual(self.dev._auth_password, 'secret') def test_device_get_timeout(self): self.assertEqual(self.dev.timeout, 30) def test_device_set_timeout(self): self.dev.timeout = 10 self.assertEqual(self.dev.timeout, 10) def test_device_manages(self): self.assertEqual(self.dev.manages, [], 'By default manages will be empty list') @patch('ncclient.manager.connect') @patch('jnpr.junos.Device.execute') def test_device_open_normalize(self, mock_connect, mock_execute): mock_connect.side_effect = self._mock_manager self.dev2 = Device(host='2.2.2.2', user='******', password='******') self.dev2.open(gather_facts=False, normalize=True) self.assertEqual(self.dev2.transform, self.dev2._norm_transform) def test_device_set_facts_exception(self): try: self.dev.facts = 'test' except RuntimeError as ex: self.assertEqual(RuntimeError, type(ex)) def test_device_ofacts_exception(self): with self.assertRaises(RuntimeError): ofacts = self.dev.ofacts def test_device_set_ofacts_exception(self): with self.assertRaises(RuntimeError): self.dev.ofacts = False @patch('jnpr.junos.Device.execute') def test_device_cli(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual( self.dev.cli('show cli directory', warning=False).tag, 'cli') @patch('jnpr.junos.device.json.loads') def test_device_rpc_json_ex(self, mock_json_loads): self.dev.facts = facts self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) ex = ValueError('Extra data ') ex.message = 'Extra data ' # for py3 as we dont have message thr mock_json_loads.side_effect = [ ex, self._mock_manager( etree.fromstring('<get-route-information format="json"/>')) ] self.dev.rpc.get_route_information({'format': 'json'}) self.assertEqual(mock_json_loads.call_count, 2) @patch('jnpr.junos.Device.execute') def test_device_cli_to_rpc_string(self, mock_execute): mock_execute.side_effect = self._mock_manager data = self.dev.cli_to_rpc_string('show system uptime') self.assertEqual("rpc.get_system_uptime_information()", data) @patch('jnpr.junos.Device.execute') def test_device_cli_to_rpc_string_strip_pipes(self, mock_execute): mock_execute.side_effect = self._mock_manager data = self.dev.cli_to_rpc_string( 'show system uptime | match foo | count') self.assertEqual("rpc.get_system_uptime_information()", data) @patch('jnpr.junos.Device.execute') def test_device_cli_to_rpc_string_complex(self, mock_execute): mock_execute.side_effect = self._mock_manager data = self.dev.cli_to_rpc_string( 'show interfaces ge-0/0/0.0 routing-instance all media') self.assertEqual( "rpc.get_interface_information(routing_instance='all', media=True, interface_name='ge-0/0/0.0')", data) @patch('jnpr.junos.Device.execute') def test_device_cli_to_rpc_string_invalid(self, mock_execute): mock_execute.side_effect = self._mock_manager data = self.dev.cli_to_rpc_string('foo') self.assertEqual(None, data) @patch('jnpr.junos.Device.execute') def test_device_cli_format_json(self, mock_execute): mock_execute.side_effect = self._mock_manager data = self.dev.cli('show interface terse', warning=False, format='json') self.assertEqual(type(data), dict) self.assertEqual( data['interface-information'][0]['physical-interface'][0] ['oper-status'][0]['data'], 'up') @patch('jnpr.junos.Device.execute') def test_device_cli_conf_info(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertTrue( 'ge-0/0/0' in self.dev.cli('show configuration', warning=False)) @patch('jnpr.junos.Device.execute') def test_device_cli_output(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertTrue( 'Alarm' in self.dev.cli('show system alarms', warning=False)) @patch('jnpr.junos.Device.execute') @patch('jnpr.junos.device.warnings') def test_device_cli_output_warning(self, mock_warnings, mock_execute): mock_execute.side_effect = self._mock_manager data = self.dev.cli( 'show interfaces ge-0/0/0.0 routing-instance all media', format='xml') ip = data.findtext('logical-interface[name="ge-0/0/0.0"]/' 'address-family[address-family-name="inet"]/' 'interface-address/ifa-local') self.assertTrue('192.168.100.1' in ip) self.assertTrue(mock_warnings.warn.called) rpc_string = "rpc.get_interface_information(routing_instance='all', media=True, interface_name='ge-0/0/0.0')" self.assertIn(rpc_string, mock_warnings.warn.call_args[0][0]) def test_device_cli_blank_output(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertEqual( '', self.dev.cli('show configuration interfaces', warning=False)) #@patch('jnpr.junos.Device.execute') def test_device_cli_rpc_reply_with_message(self): # , mock_execute): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertEqual( '\nprotocol: operation-failed\nerror: device asdf not found\n', self.dev.cli('show interfaces terse asdf', warning=False)) @patch('jnpr.junos.Device.execute') def test_device_cli_rpc(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual( self.dev.cli('show system uptime| display xml rpc', warning=False).tag, 'get-system-uptime-information') def test_device_cli_exception(self): self.dev.rpc.cli = MagicMock(side_effect=AttributeError) val = self.dev.cli('show version') self.assertEqual(val, 'invalid command: show version') @patch('jnpr.junos.Device.execute') def test_device_cli_rpc_exception(self, mock_execute): mock_execute.side_effect = self._mock_manager val = self.dev.cli('foo') self.assertEqual(val, 'invalid command: foo: RpcError') @patch('jnpr.junos.Device.execute') def test_device_display_xml_rpc(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual( self.dev.display_xml_rpc('show system uptime').tag, 'get-system-uptime-information') @patch('jnpr.junos.Device.execute') def test_device_display_xml_rpc_text(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertIn( '<get-system-uptime-information>', self.dev.display_xml_rpc('show system uptime', format='text')) @patch('jnpr.junos.Device.execute') def test_device_display_xml_exception(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual(self.dev.display_xml_rpc('show foo'), 'invalid command: show foo| display xml rpc') def test_device_execute(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertEqual( self.dev.execute('<get-system-core-dumps/>').tag, 'directory-list') def test_device_execute_topy(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertEqual( self.dev.execute('<get-system-core-dumps/>', to_py=self._do_nothing), 'Nothing') # This test is for the commented out rpc-error code # def test_device_execute_exception(self): # self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) # self.assertRaises(RpcError, self.dev.execute, # '<load-configuration-error/>') @patch('jnpr.junos.device.warnings') def test_device_execute_unknown_exception(self, mock_warnings): class MyException(Exception): pass self.dev._conn.rpc = MagicMock(side_effect=MyException) self.assertRaises(MyException, self.dev.execute, '<get-software-information/>') def test_device_execute_rpc_error(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertRaises(RpcError, self.dev.rpc.get_rpc_error) def test_device_execute_permission_error(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertRaises(EzErrors.PermissionError, self.dev.rpc.get_permission_denied) def test_device_execute_index_error(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertTrue(self.dev.rpc.get_index_error()) def test_device_execute_ValueError(self): self.assertRaises(ValueError, self.dev.execute, None) def test_device_execute_unopened(self): self.dev.connected = False self.assertRaises(EzErrors.ConnectClosedError, self.dev.execute, None) def test_device_execute_timeout(self): self.dev._conn.rpc = MagicMock(side_effect=TimeoutExpiredError) self.assertRaises(EzErrors.RpcTimeoutError, self.dev.rpc.get_rpc_timeout) def test_device_execute_closed(self): self.dev._conn.rpc = MagicMock(side_effect=NcErrors.TransportError) self.assertRaises(EzErrors.ConnectClosedError, self.dev.rpc.get_rpc_close) self.assertFalse(self.dev.connected) def test_device_rpcmeta(self): self.assertEqual(self.dev.rpc.get_software_information.__doc__, 'get-software-information') def test_device_probe_timeout_zero(self): with patch('jnpr.junos.device.socket'): self.assertFalse(self.dev.probe(0)) def test_device_probe_timeout_gt_zero(self): with patch('jnpr.junos.device.socket'): self.assertTrue( self.dev.probe(1), 'probe fn is not working for' ' timeout greater than zero') def test_device_probe_timeout_exception(self): with patch('jnpr.junos.device.socket') as mock_socket: with patch('jnpr.junos.device.time.sleep') as mock_time: mock_socket.socket.return_value.close.side_effect \ = RuntimeError mock_time.return_value = None self.assertFalse(self.dev.probe(.01)) def test_device_bind_varg(self): self.dev.bind() mock = MagicMock() mock.__name__ = 'magic_mock' self.dev.bind(mock) self.assertEqual(self.dev.magic_mock.__name__, 'magic_mock') def test_device_bind_kvarg(self): self.dev.bind() mock = MagicMock() mock.return_value = 'Test' self.dev.bind(kw=mock) self.assertEqual(self.dev.kw, 'Test') def test_device_bind_varg_exception(self): def varg(): self.dev.bind() mock = MagicMock() mock.__name__ = 'magic mock' # for *args self.dev.bind(mock) self.dev.bind(mock) self.assertRaises(ValueError, varg) def test_device_bind_kvarg_exception(self): def kve(): self.dev.bind() mock = MagicMock() mock.__name__ = 'magic mock' # for **kwargs self.dev.bind(kw=mock) self.dev.bind(kw=mock) self.assertRaises(ValueError, kve) def test_device_template(self): # Try to load the template relative to module base try: template = self.dev.Template( 'tests/unit/templates/config-example.xml') except: # Try to load the template relative to test base try: template = self.dev.Template('templates/config-example.xml') except: raise self.assertEqual( template.render({ 'host_name': '1', 'domain_name': '2' }), 'system {\n host-name 1;\n domain-name 2;\n}') def test_device_close(self): def close_conn(): self.dev.connected = False self.dev.close = MagicMock(name='close') self.dev.close.side_effect = close_conn self.dev.close() self.assertEqual(self.dev.connected, False) @patch('ncclient.manager.connect') def test_device_context_manager(self, mock_connect): mock_connect.side_effect = self._mock_manager try: with Device(host='3.3.3.3', user='******', password='******', gather_facts=False) as dev: self.assertTrue(dev.connected) dev._conn = MagicMock(name='_conn') dev._conn.connected = True def close_conn(): dev.connected = False dev.close = MagicMock(name='close') dev.close.side_effect = close_conn raise RpcError except Exception as e: self.assertIsInstance(e, RpcError) self.assertFalse(dev.connected) def _read_file(self, fname): from ncclient.xml_ import NCElement fpath = os.path.join(os.path.dirname(__file__), 'rpc-reply', fname) with open(fpath) as fp: foo = fp.read() if fname == 'get-rpc-error.xml': # Raise ncclient exception for error raise RPCError(etree.XML(foo)) elif fname == 'get-permission-denied.xml': # Raise ncclient exception for error raise RPCError(etree.XML(foo)) elif (fname == 'get-index-error.xml' or fname == 'get-system-core-dumps.xml' or fname == 'load-configuration-error.xml' or fname == 'show-configuration-interfaces.xml' or fname == 'show-interfaces-terse-asdf.xml'): rpc_reply = NCElement( foo, self.dev._conn._device_handler.transform_reply()) elif (fname == 'show-configuration.xml' or fname == 'show-system-alarms.xml'): rpc_reply = NCElement( foo, self.dev._conn._device_handler.transform_reply() )._NCElement__doc elif fname == 'show-interface-terse.json': rpc_reply = json.loads(foo) elif fname == 'get-route-information.json': rpc_reply = NCElement( foo, self.dev._conn._device_handler.transform_reply()) else: rpc_reply = NCElement( foo, self.dev._conn._device_handler.transform_reply() )._NCElement__doc[0] return rpc_reply def _mock_manager(self, *args, **kwargs): if kwargs and 'normalize' not in kwargs: device_params = kwargs['device_params'] device_handler = make_device_handler(device_params) session = SSHSession(device_handler) return Manager(session, device_handler) elif args: if args[0].tag == 'command': if args[0].text == 'show cli directory': return self._read_file('show-cli-directory.xml') if args[0].text == 'show interface terse': return self._read_file('show-interface-terse.json') elif args[0].text == 'show configuration': return self._read_file('show-configuration.xml') elif args[0].text == 'show system alarms': return self._read_file('show-system-alarms.xml') elif args[0].text == 'show system uptime| display xml rpc': return self._read_file('show-system-uptime-rpc.xml') elif args[0].text == 'show configuration interfaces': return self._read_file('show-configuration-interfaces.xml') elif args[0].text == 'show interfaces terse asdf': return self._read_file('show-interfaces-terse-asdf.xml') elif args[0].text == 'show interfaces ge-0/0/0.0 ' \ 'routing-instance all media': return self._read_file( 'show-interfaces-routing-instance-media.xml') elif args[0].text == 'show interfaces ge-0/0/0.0 ' \ 'routing-instance all media| display ' \ 'xml rpc': return self._read_file( 'show-interfaces-routing-instance-media-rpc.xml') else: raise RpcError else: if args[0].attrib.get('format') == 'json': return self._read_file(args[0].tag + '.json') return self._read_file(args[0].tag + '.xml') def _do_nothing(self, *args, **kwargs): return 'Nothing'
def f(x): dev = Device(host=x[1], user="******", password="******") dev.open() print "Working on " + str(x[0]) + " at " + str(x[1][:-1]) + "..." print "" fname = "./mpinvout/" + str(x[0]) + "_" + str(x[1][:-1]) + ".txt" fo = open(fname, "w") ##### PRINT CHASSIS INFORMATION fo.write("\n") fo.write("----- CHASSIS INVENTORY -----\n") fo.write("\n") fp = open("myrpcs/chassis_inv.yaml", 'r') yml = fp.read() fp.close() globals().update(FactoryLoader().load(yaml.load(yml))) ct = ChassisInv(dev).get() chinv = PrettyTable(['Name', 'Description', 'Serial Number']) chinv.padding_width = 1 for y in ct.keys(): chinv.add_row([ct[y]['name'], ct[y]['description'], ct[y]['sn']]) fo.write(str(chinv)) ##### CREATE CHASSIS CSV FOR EXCEL fp = open("myrpcs/chassis_inv.yaml", 'r') yml = fp.read() fp.close() globals().update(FactoryLoader().load(yaml.load(yml))) ct = ChassisInv(dev).get() fcsv = open("chassis_example.csv", 'w') fcsv.write("Name,Description,Serial Number\n") for y in ct.keys(): fcsv.write( str(ct[y]['name']) + "," + str(ct[y]['description']) + "," + str(ct[y]['sn']) + "\n") fcsv.close() ##### PRINT OSPF NEIGHBOR INFORMATION fo.write("\n") fo.write("----- OSPF NEIGHBORS -----\n") fo.write("\n") fp = open("myrpcs/ospf_neigh.yaml", 'r') yml = fp.read() fp.close() globals().update(FactoryLoader().load(yaml.load(yml))) ct = OspfIface(dev).get() chinv = PrettyTable(['Address', 'Interface', 'State']) chinv.padding_width = 1 for y in ct.keys(): chinv.add_row([ct[y]['addr'], ct[y]['iface'], ct[y]['state']]) fo.write(str(chinv)) ##### PRINT INTERFACE TERSE INFORMATION fo.write("\n") fo.write("----- INTERFACE INVENTORY -----\n") fo.write("\n") fp = open("myrpcs/iface_terse.yaml", 'r') yml = fp.read() fp.close() globals().update(FactoryLoader().load(yaml.load(yml))) ct = IfaceTerse(dev).get() chinv = PrettyTable([ 'Name', 'Admin Status', 'Op Status', 'Family', 'Bundle', 'IP Address' ]) chinv.padding_width = 1 for y in ct.keys(): chinv.add_row([ ct[y]['name'], ct[y]['as'], ct[y]['os'], ct[y]['family'], ct[y]['bundle'], ct[y]['add'] ]) fo.write(str(chinv)) ##### PRINT UPTIME SYSTEM INFORMATION fo.write("\n") fo.write("----- SYSTEM UPTIME -----\n") fo.write("\n") tt = PrettyTable(['What', 'When']) resp = dev.rpc.get_system_uptime_information() tt.add_row(["Current time: ", resp.findtext('.//current-time/date-time')]) tt.add_row([ "Device booted from: ", resp.findtext('.//system-booted-time/time-length') ]) tt.add_row([ "Last configuration: ", resp.findtext('.//last-configured-time/date-time') ]) fo.write(str(tt)) ##### PRINT ROUTING ENGINE INFORMATION fo.write("\n") fo.write("----- ROUTING ENGINE -----\n") fo.write("\n") fp = open("myrpcs/re.yaml", 'r') yml = fp.read() fp.close() globals().update(FactoryLoader().load(yaml.load(yml))) ct = RoutingEngine(dev).get() chinv = PrettyTable( ['Slot', 'Role', 'Status', 'Model', 'Serial Number', 'Memory %']) chinv.padding_width = 1 for y in ct.keys(): chinv.add_row([ ct[y]['slot'], ct[y]['role'], ct[y]['status'], ct[y]['model'], ct[y]['sn'], ct[y]['mem'] ]) fo.write(str(chinv)) ##### PRINT ROUTE INSTANCES SUMMARY fo.write("\n") fo.write("----- ROUTE INSTANCE SUMMARY -----\n") fo.write("\n") fp = open("myrpcs/route_instance.yaml", 'r') yml = fp.read() fp.close() globals().update(FactoryLoader().load(yaml.load(yml))) ct = RouteInstance(dev).get() chinv = PrettyTable(['Instance', 'RIB', 'Active', 'HoldDown', 'Hidden']) chinv.padding_width = 1 for y in ct.keys(): fp = open("myrpcs/rib_instance.yaml", 'r') yml = fp.read() fp.close() yml = yml.replace("xxxxx", y) globals().update(FactoryLoader().load(yaml.load(yml))) rt = RibInstance(dev).get() for z in rt.keys(): chinv.add_row( [y, rt[z]['name'], rt[z]['act'], rt[z]['hold'], rt[z]['hid']]) fo.write(str(chinv)) ##### PRINT VLANS ACTIVE ON INTERFACES fo.write("\n") fo.write("----- CONFIGURED VLANS -----\n") fo.write("\n") fp = open("myrpcs/vlans.yaml", 'r') yml = fp.read() fp.close() globals().update(FactoryLoader().load(yaml.load(yml))) ct = IfaceVlan(dev).get() chinv = PrettyTable(['Interface', 'Vlan']) chinv.padding_width = 1 for y in ct.keys(): if ct[y]['vlan'] != None: for c in ct[y]['vlan']: chinv.add_row([ct[y]['name'], c.split(".")[1][:-2]]) fo.write(str(chinv)) dev.close() print "DONE! " + x[0] + "@" + x[1] + "\n" return 1
<name>1500</name> <family> <inet operation="delete"> </inet> </family> </unit> </interface> </interfaces> </configuration>""" device.load(xml, format='xml') device.commit #for line in open("fila"): # device = Config(device) # set_cmd = line # device.load(set_cmd, format='set') # device.pdiff() # device.commit() #for line in open("fila"): # print device.cli(line) #device.cfg.load(template_path=template, template_vars=customer) #device.bind(cu=Config) #device.rpc.open_configuration(private=True,normalize=True) #device.cu.load("set system host-name r0") #device.cu.commit() #device.rpc.close_configuration() device.close()
class JunOSDriver(NetworkDriver): def __init__(self, hostname, username, password, timeout=60, optional_args=None): self.hostname = hostname self.username = username self.password = password self.timeout = timeout self.device = Device(hostname, user=username, password=password) self.config_replace = False def open(self): self.device.open() self.device.timeout = self.timeout self.device.bind(cu=Config) self.device.cu.lock() def close(self): self.device.cu.unlock() self.device.close() def _load_candidate(self, filename, config, overwrite): if filename is None: configuration = config else: with open(filename) as f: configuration = f.read() try: self.device.cu.load(configuration, format='text', overwrite=overwrite) except ConfigLoadError as e: if self.config_replace: raise ReplaceConfigException(e.message) else: raise MergeConfigException(e.message) def load_replace_candidate(self, filename=None, config=None): self.config_replace = True self._load_candidate(filename, config, True) def load_merge_candidate(self, filename=None, config=None): self.config_replace = False self._load_candidate(filename, config, False) def compare_config(self): diff = self.device.cu.diff() if diff is None: return '' else: return diff.strip() def commit_config(self): self.device.cu.commit() def discard_config(self): self.device.cu.rollback(rb_id=0) def rollback(self): self.device.cu.rollback(rb_id=1) self.commit_config() def get_facts(self): output = self.device.facts uptime = 0 if 'RE0' in output: uptime = output['RE0']['up_time'] interfaces = junos_views.junos_iface_table(self.device) interfaces.get() interface_list = interfaces.keys() return { 'vendor': u'Juniper', 'model': unicode(output['model']), 'serial_number': unicode(output['serialnumber']), 'os_version': unicode(output['version']), 'hostname': unicode(output['hostname']), 'fqdn': unicode(output['fqdn']), 'uptime': string_parsers.convert_uptime_string_seconds(uptime), 'interface_list': interface_list } def get_interfaces(self): # init result dict result = {} interfaces = junos_views.junos_iface_table(self.device) interfaces.get() # convert all the tuples to our pre-defined dict structure for iface in interfaces.keys(): result[iface] = { 'is_up': interfaces[iface]['is_up'], 'is_enabled': interfaces[iface]['is_enabled'], 'description': interfaces[iface]['description'] or u'', 'last_flapped': interfaces[iface]['last_flapped'] or -1, 'mac_address': unicode(interfaces[iface]['mac_address']) } result[iface]['last_flapped'] = float( result[iface]['last_flapped']) match = re.search(r'\d+', interfaces[iface]['speed'] or '') if match is not None: result[iface]['speed'] = int(match.group(0)) else: result[iface]['speed'] = -1 return result def get_interfaces_counters(self): query = junos_views.junos_iface_counter_table(self.device) query.get() interface_counters = dict() for interface, counters in query.items(): interface_counters[interface] = { k: v if v is not None else -1 for k, v in counters } return interface_counters def get_environment(self): environment = junos_views.junos_enviroment_table(self.device) routing_engine = junos_views.junos_routing_engine_table(self.device) temperature_thresholds = junos_views.junos_temperature_thresholds( self.device) environment.get() routing_engine.get() temperature_thresholds.get() environment_data = dict() for sensor_object, object_data in environment.items(): structured_object_data = {k: v for k, v in object_data} if structured_object_data['class'] == 'Power': # Create a dict for the 'power' key try: environment_data['power'][sensor_object] = dict() except KeyError: environment_data['power'] = dict() environment_data['power'][sensor_object] = dict() # Set these values to -1, because Junos does not provide them environment_data['power'][sensor_object]['capacity'] = -1.0 environment_data['power'][sensor_object]['output'] = -1.0 if structured_object_data['class'] == 'Fans': # Create a dict for the 'fans' key try: environment_data['fans'][sensor_object] = dict() except KeyError: environment_data['fans'] = dict() environment_data['fans'][sensor_object] = dict() if structured_object_data[ 'status'] == 'OK' and structured_object_data[ 'class'] == 'Power': # If status is Failed, Absent or Testing, set status to False. environment_data['power'][sensor_object]['status'] = True elif structured_object_data[ 'status'] != 'OK' and structured_object_data[ 'class'] == 'Power': environment_data['power'][sensor_object]['status'] = False elif structured_object_data[ 'status'] == 'OK' and structured_object_data[ 'class'] == 'Fans': # If status is Failed, Absent or Testing, set status to False. environment_data['fans'][sensor_object]['status'] = True elif structured_object_data[ 'status'] != 'OK' and structured_object_data[ 'class'] == 'Fans': environment_data['fans'][sensor_object]['status'] = False for temperature_object, temperature_data in temperature_thresholds.items( ): structured_temperature_data = { k: v for k, v in temperature_data } if structured_object_data['class'] == 'Temp': # Create a dict for the 'temperature' key try: environment_data['temperature'][sensor_object] = dict() except KeyError: environment_data['temperature'] = dict() environment_data['temperature'][sensor_object] = dict() environment_data['temperature'][sensor_object][ 'temperature'] = float( structured_object_data['temperature']) # Set a default value (False) to the key is_critical and is_alert environment_data['temperature'][sensor_object][ 'is_alert'] = False environment_data['temperature'][sensor_object][ 'is_critical'] = False # Check if the working temperature is equal to or higher than alerting threshold if structured_temperature_data[ 'red-alarm'] <= structured_object_data[ 'temperature']: environment_data['temperature'][sensor_object][ 'is_critical'] = True environment_data['temperature'][sensor_object][ 'is_alert'] = True elif structured_temperature_data[ 'yellow-alarm'] <= structured_object_data[ 'temperature']: environment_data['temperature'][sensor_object][ 'is_alert'] = True for routing_engine_object, routing_engine_data in routing_engine.items( ): structured_routing_engine_data = { k: v for k, v in routing_engine_data } # Create dicts for 'cpu' and 'memory'. try: environment_data['cpu'] = dict() environment_data['cpu'][routing_engine_object] = dict() environment_data['memory'] = dict() except KeyError: environment_data['cpu'] = dict() environment_data['cpu'][routing_engine_object] = dict() environment_data['memory'] = dict() # Calculate the CPU usage by using the CPU idle value. environment_data['cpu'][routing_engine_object][ '%usage'] = 100.0 - structured_routing_engine_data['cpu-idle'] environment_data['memory'][ 'available_ram'] = structured_routing_engine_data[ 'memory-dram-size'] # Junos gives us RAM in %, so calculation has to be made. # Sadly, bacause of this, results are not 100% accurate to the truth. environment_data['memory']['used_ram'] = ( structured_routing_engine_data['memory-dram-size'] / 100 * structured_routing_engine_data['memory-buffer-utilization']) return environment_data @staticmethod def _get_address_family(table): """ Function to derive address family from a junos table name :params table: The name of the routing table :returns: address family """ address_family_mapping = {'inet': 'ipv4', 'inet6': 'ipv6'} family = table.split('.')[-2] return address_family_mapping[family] def _parse_route_stats(self, neighbor): data = {} if not neighbor['is_up']: pass elif isinstance(neighbor['tables'], list): for idx, table in enumerate(neighbor['tables']): family = self._get_address_family(table) data[family] = {} data[family]['received_prefixes'] = neighbor[ 'received_prefixes'][idx] data[family]['accepted_prefixes'] = neighbor[ 'accepted_prefixes'][idx] data[family]['sent_prefixes'] = neighbor['sent_prefixes'][idx] else: family = self._get_address_family(neighbor['tables']) data[family] = {} data[family]['received_prefixes'] = neighbor['received_prefixes'] data[family]['accepted_prefixes'] = neighbor['accepted_prefixes'] data[family]['sent_prefixes'] = neighbor['sent_prefixes'] return data @staticmethod def _parse_value(value): if isinstance(value, basestring): return unicode(value) elif value is None: return u'' else: return value def get_bgp_neighbors(self): instances = junos_views.junos_route_instance_table(self.device) uptime_table = junos_views.junos_bgp_uptime_table(self.device) bgp_neighbors = junos_views.junos_bgp_table(self.device) keys = [ 'local_as', 'remote_as', 'is_up', 'is_enabled', 'description', 'remote_id' ] bgp_neighbor_data = {} for instance, instance_data in instances.get().items(): if instance.startswith('__'): # junos internal instances continue instance_name = "global" if instance == 'master' else instance bgp_neighbor_data[instance_name] = {'peers': {}} for neighbor, data in bgp_neighbors.get(instance=instance).items(): neighbor_data = {k: v for k, v in data} peer_ip = neighbor.split('+')[0] if 'router_id' not in bgp_neighbor_data[instance_name]: # we only need to set this once bgp_neighbor_data[instance_name]['router_id'] = unicode( neighbor_data['local_id']) peer = { key: self._parse_value(value) for key, value in neighbor_data.iteritems() if key in keys } peer['address_family'] = self._parse_route_stats(neighbor_data) bgp_neighbor_data[instance_name]['peers'][peer_ip] = peer for neighbor, uptime in uptime_table.get( instance=instance).items(): bgp_neighbor_data[instance_name]['peers'][neighbor][ 'uptime'] = uptime[0][1] for key in bgp_neighbor_data.keys(): if not bgp_neighbor_data[key]['peers']: del bgp_neighbor_data[key] return bgp_neighbor_data def get_lldp_neighbors(self): lldp = junos_views.junos_lldp_table(self.device) lldp.get() result = lldp.items() neighbors = dict() for neigh in result: if neigh[0] not in neighbors.keys(): neighbors[neigh[0]] = list() neighbors[neigh[0]].append({x[0]: unicode(x[1]) for x in neigh[1]}) return neighbors
def bgp_summary(host, ipdict, username, password, lock, context_output, filtering, monitor=False): def rpc_to_dict(rpc_element): rpc_xml = etree.tostring(rpc_element, pretty_print=True, encoding='unicode') parsed_dict = jxmlease.parse(rpc_xml) return parsed_dict bgp_neighbor_info = {} junosdriver = get_network_driver('junos') iosdriver = get_network_driver('ios') if ipdict[host]['software'] == 'ios': ipdict[host]['napalm'] = iosdriver(username=username, password=password, hostname=host) if ipdict[host]['software'] == 'junos': ipdict[host]['napalm'] = junosdriver(username=username, password=password, hostname=host) try: if not '--' in ipdict[host][ 'hostname']: # if it is not logical system ipdict[host]['napalm'].open() except Exception as e: prompt = f'INFO: bgp_summary.py via function bgp_summary says: Loading of napalm error {e} for {host}. Confirm if device is synced' print(prompt) context_output[ 'errors'] += f'\n [{host} {ipdict[host]["hostname"]}]\n ' context_output[ 'errors'] += f'Loading of napalm error {e}. Confirm if device is synced\n' return if ipdict[host]['software'] == 'junos': if '--' in ipdict[host]['hostname']: # logical system main_system_ip = ipdict[host]['mainsystemip'] system_name = ipdict[host]['systemname'] router = Device(host=main_system_ip, user=username, passwd=password) router.open() rpc_element = (router.rpc.get_bgp_summary_information( logical_system=system_name)) bgp_data = rpc_to_dict(rpc_element) try: bgp_data = bgp_data['bgp-information'][ 'bgp-peer'] # list of dictionaries except KeyError: # incase bgp_data equals to {'output': 'BGP is not running'} with lock: context_output[ 'errors'] += f'\n [{host} {ipdict[host]["hostname"]}]\n ' context_output['errors'] += str(bgp_data).strip( '\{').strip('\}') + '\n' return for peer in bgp_data: try: if type( peer['bgp-rib'] ) == list: # if the peer has many ribs it is 'prolly a route reflector table = 'inet.0' else: table = peer['bgp-rib'][ 'name'] # vrf is in form of TEST.inet.0 except KeyError: # with virtual olive image the bgp-rib key misses from the peer dict thus cant access peer['bgp-rib'] prompt = f'INFO: bgp_summary.py via function bgp_summary says: Logical system {ipdict[host]["hostname"]} rpc-reply missing bgp-rib key' print(prompt) with lock: context_output[ 'errors'] += f'\n [{host} {ipdict[host]["hostname"]}]\n ' context_output[ 'errors'] += 'Not supported for this system. rpc-reply missing bgp-rib key\n' return if filtering['state'] and bgp_data[peer][ 'peer-state'].lower() == 'established': continue bgp_neighbor_info[peer] = { 'peer': bgp_data[peer]['peer-address'], 'peer_as': bgp_data[peer]['peer-as'], 'state': bgp_data[peer]['peer-state'], 'time': bgp_data[peer]['elapsed-time'], 'vrf': table, 'status': 'Enabled', } # ping the peers that are down if filtering['loss']: for peer in bgp_neighbor_info: table = bgp_neighbor_info[peer]['vrf'] if table == 'inet.0': rpc_ping = router.rpc.ping( rapid=True, host=peer, logical_system=system_name) else: vrf_name = table.split('.')[0] rpc_ping = router.rpc.ping( rapid=True, host=peer, logical_system=system_name, routing_instance=vrf_name) ping_results = rpc_to_dict(rpc_ping) try: packet_loss = ping_results[ 'probe-results-summary']['packet-loss'] packet_loss = f'Loss {packet_loss}%' except KeyError: packet_loss = ping_results['rpc-error'][ 'error-message'][ 0: 9] # take only nine characters of the error statement bgp_neighbor_info[peer]['ping'] = packet_loss # route entries for extracting outgoing interface for peers that are down if filtering['alias']: for peer in bgp_neighbor_info: rpc_show_route = router.rpc.get_route_information( logical_system=system_name, destination=peer, table=bgp_neighbor_info[peer]['vrf']) routes_data = rpc_to_dict(rpc_show_route) routes_data = routes_data['route-information'][ 'route-table'] egress_interface = routes_data['rt']['rt-entry']['nh'][ 'via'] bgp_neighbor_info[peer]['interface'] = egress_interface # arp entries if filtering['arp']: for peer in bgp_neighbor_info: bgp_neighbor_info[peer]['if_arp'] = [] if filtering['alias']: rpc_arp = router.rpc.get_arp_table_information( interface=bgp_neighbor_info[peer]['interface']) arp_data = rpc_to_dict(rpc_arp) arp_table = arp_data['arp-table-information'][ 'arp-table-entry'] if type(arp_table) == list: for arp_entry in arp_table: bgp_neighbor_info[peer]['if_arp'].append( f"{arp_entry['ip-address']}:{arp_entry['mac-address']}" ) else: bgp_neighbor_info[peer]['if_arp'].append( f"{arp_table['ip-address']}:{arp_table['mac-address']}" ) bgp_neighbor_info[peer]['ip_arp'] = [] rpc_arp = router.rpc.get_arp_table_information( hostname=peer) arp_data = rpc_to_dict(rpc_arp) arp_table = arp_data['arp-table-information'][ 'arp-table-entry'] if type(arp_table) == list: for arp_entry in arp_table: bgp_neighbor_info[peer]['ip_arp'].append( f"{arp_entry['ip-address']}:{arp_entry['mac-address']}" ) else: bgp_neighbor_info[peer]['ip_arp'].append( f"{arp_table['ip-address']}:{arp_table['mac-address']}" ) # for presentation purposes when using format.presentation method if not bgp_neighbor_info[peer]['ip_arp']: bgp_neighbor_info[peer]['ip_arp'] = ['-'] if filtering['alias']: if not bgp_neighbor_info[peer]['if_arp']: bgp_neighbor_info[peer]['if_arp'] = ['-'] # consolidate arp entries bgp_neighbor_info[peer]['arp'] = bgp_neighbor_info[ peer]['if_arp'] + bgp_neighbor_info[peer]['ip_arp'] router.close() # close pyez session else: # main system bgp bgp_data = ipdict[host]['napalm'].get_bgp_neighbors() for table in bgp_data: for peer in bgp_data[table]['peers']: state = bgp_data[table]['peers'][peer]['is_up'] if state == True: state = 'Established' else: state = 'Down' if filtering['state'] and state.lower( ) == 'established': continue status = bgp_data[table]['peers'][peer]['is_enabled'] if status == True: status = 'Enabled' else: status = 'Shutdown' duration = str( timedelta(seconds=bgp_data[table]['peers'][peer] ['uptime'])) if 'days' in duration: duration = duration.replace(' days,', 'd') elif 'day' in duration: duration = duration.replace(' day,', 'd') bgp_neighbor_info[peer] = { 'peer': peer, 'peer_as': bgp_data[table]['peers'][peer]['remote_as'], 'state': state, 'status': status, 'time': duration, 'vrf': table } # ping the peers that are down if filtering['loss']: for peer in bgp_neighbor_info: table = bgp_neighbor_info[peer]['vrf'] if table == 'global': table = '' ping_results = ipdict[host]['napalm'].ping(peer, vrf=table) try: packet_loss = ping_results['success'][ 'packet_loss'] packet_loss = 'Loss %d%%' % (packet_loss * 20) except KeyError: try: packet_loss = ping_results['error'] if packet_loss == 'Packet loss 100': packet_loss = 'Loss 100%' else: packet_loss = ping_results['error'][ 0: 9] # take only nine characters of the error statement except: packet_loss = ' ' bgp_neighbor_info[peer]['ping'] = packet_loss # route entries for extracting outgoig interface for peers that are down if filtering['alias']: for peer in bgp_neighbor_info: routes_data = ipdict[host]['napalm'].get_route_to(peer) table = bgp_neighbor_info[peer]['vrf'] if table == 'global': if ':' in peer: table = 'inet6.0' else: table = 'inet.0' egress_interface = [] for route in routes_data: if route != '0.0.0.0/0': for entry in routes_data[route]: if entry['routing_table'].startswith( table): egress_interface.append( entry['outgoing_interface']) try: egress_interface egress_interface = egress_interface[ 0] # take the first entry if there are many except: egress_interface = '' bgp_neighbor_info[peer]['interface'] = egress_interface # arp entries if filtering['arp']: arp_table = ipdict[host]['napalm'].get_arp_table() for peer in bgp_neighbor_info: bgp_neighbor_info[peer]['ip_arp'] = [] bgp_neighbor_info[peer]['if_arp'] = [] for arp_entry in arp_table: if arp_entry['ip'] == peer: bgp_neighbor_info[peer]['ip_arp'].append( f"{arp_entry['ip']}:{arp_entry['mac']}") if filtering['alias']: if arp_entry['interface'] == bgp_neighbor_info[ peer]['interface']: bgp_neighbor_info[peer]['if_arp'].append( f"{arp_entry['ip']}:{arp_entry['mac']}" ) # for presentation purposes when using format.presentation method if not bgp_neighbor_info[peer]['ip_arp']: bgp_neighbor_info[peer]['ip_arp'] = ['-'] if filtering['alias']: if not bgp_neighbor_info[peer]['if_arp']: bgp_neighbor_info[peer]['if_arp'] = ['-'] # consolidate arp entries bgp_neighbor_info[peer]['arp'] = bgp_neighbor_info[ peer]['if_arp'] + bgp_neighbor_info[peer]['ip_arp'] # interface status for both main and logical system if filtering['alias']: try: interfaces = ipdict[host]['napalm'].get_interfaces() except: interfaces = {} # if napalm fails for peer in bgp_neighbor_info: bgp_neighbor_info[peer]['if_description'] = '-' bgp_neighbor_info[peer]['if_oper_status'] = '- ' bgp_neighbor_info[peer]['if_admin_status'] = '- ' # if the interface does not exist there is no intf info if not bgp_neighbor_info[peer]['interface']: bgp_neighbor_info[peer]['interface'] = '- ' continue for interface in interfaces.keys(): if interface == bgp_neighbor_info[peer][ 'interface']: op_state = interfaces[interface]['is_up'] if op_state == True: op_state = 'Up' else: op_state = 'Down' ad_state = interfaces[interface]['is_enabled'] if ad_state == True: ad_state = 'Up' else: ad_state = 'Down' bgp_neighbor_info[peer][ 'if_description'] = interfaces[interface][ 'description'] bgp_neighbor_info[peer][ 'if_oper_status'] = op_state bgp_neighbor_info[peer][ 'if_admin_status'] = ad_state elif ipdict[host]['software'] == 'ios': bgp_txt_dict = ipdict[host]['napalm'].cli( ['show bgp all neighbors']) bgp_txt_data = bgp_txt_dict['show bgp all neighbors'] bgp_data = format.parseCiscoBGP(bgp_txt_data) bgp_neighbor_info = {} for peer in bgp_data: if filtering['state'] and bgp_data[peer]['state'].lower( ) == 'established': continue bgp_neighbor_info[peer] = bgp_data[peer] # ping the peers if filtering['loss']: for peer in bgp_neighbor_info: table = bgp_neighbor_info[peer]['vrf'] ping_results = ipdict[host]['napalm'].ping(peer, vrf=table) try: packet_loss = ping_results['success']['packet_loss'] packet_loss = 'Loss %d%%' % ( packet_loss * 20 ) # napalm sends 5 packets multiply by 20 to get percentage except KeyError: try: packet_loss = ping_results['error'] if packet_loss == 'Packet loss 100': packet_loss = 'Loss 100%' else: packet_loss = ping_results['error'][ 0: 9] # take only nine characters of the error statement except: packet_loss = ' ' bgp_neighbor_info[peer]['ping'] = packet_loss # route entries for extracting outgoig interface if filtering['alias']: for peer in bgp_neighbor_info: table = bgp_neighbor_info[peer]['vrf'] if not table: if ':' in peer: # for ipv6 routes_txt_dict = ipdict[host]['napalm'].cli( ['show ipv6 route ' + peer]) routes_txt_data = routes_txt_dict[ 'show ipv6 route ' + peer] else: routes_txt_dict = ipdict[host]['napalm'].cli( ['show ip route ' + peer]) routes_txt_data = routes_txt_dict['show ip route ' + peer] else: if ':' in peer: # for ipv6 routes_txt_dict = ipdict[host]['napalm'].cli( ['show ipv6 route vrf %s %s' % (table, peer)]) routes_txt_data = routes_txt_dict[ 'show ipv6 route vrf %s %s' % (table, peer)] else: routes_txt_dict = ipdict[host]['napalm'].cli( ['show ip route vrf %s %s' % (table, peer)]) routes_txt_data = routes_txt_dict[ 'show ip route vrf %s %s' % (table, peer)] egress_interface = '' for line in routes_txt_data.split('\n'): # if there is one route entry if re.search(r'^ \*.*via (\S+)', line): egress_interface = (re.findall( r'^ \*.*via (\S+)', line))[0] # if there are multiple entries elif re.search( r'via \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3},', line): egress_interface = line.split()[-1] # for ipv6 elif re.search(r':.*, ', line): egress_interface = line.split()[-1] bgp_neighbor_info[peer]['interface'] = egress_interface # arp entries if filtering['arp']: for peer in bgp_neighbor_info: bgp_neighbor_info[peer]['ip_arp'] = [] bgp_neighbor_info[peer]['if_arp'] = [] table = bgp_neighbor_info[peer]['vrf'] if filtering['alias']: interface = bgp_neighbor_info[peer]['interface'] if not table: ip_arp_txt_dict = ipdict[host]['napalm'].cli( ['show arp ' + peer]) ip_arp_txt_data = ip_arp_txt_dict['show arp ' + peer] if filtering['alias']: if_arp_txt_dict = ipdict[host]['napalm'].cli( ['show arp ' + interface]) if_arp_txt_data = if_arp_txt_dict['show arp ' + interface] else: ip_arp_txt_dict = ipdict[host]['napalm'].cli( ['show arp vrf %s %s' % (table, peer)]) ip_arp_txt_data = ip_arp_txt_dict['show arp vrf %s %s' % (table, peer)] if filtering['alias']: if_arp_txt_dict = ipdict[host]['napalm'].cli( ['show arp vrf %s %s' % (table, interface)]) if_arp_txt_data = if_arp_txt_dict[ 'show arp vrf %s %s' % (table, interface)] arp_table = [] for entry in ip_arp_txt_data.split('\n'): if re.search(r'^Internet', entry): arp_table.append({ 'ip': entry.split()[1], 'mac': entry.split()[3], 'interface': entry.split()[-1] }) for arp_entry in arp_table: if arp_entry['ip'] == peer: bgp_neighbor_info[peer]['ip_arp'].append( f"{arp_entry['ip']}:{arp_entry['mac']}") # for presentation purposes when using format.presentation method if not bgp_neighbor_info[peer]['ip_arp']: bgp_neighbor_info[peer]['ip_arp'] = ['-'] if filtering['alias']: arp_table = [] for entry in if_arp_txt_data.split('\n'): if re.search(r'^Internet', entry): arp_table.append({ 'ip': entry.split()[1], 'mac': entry.split()[3], 'interface': entry.split()[-1] }) for arp_entry in arp_table: if arp_entry['interface'] == bgp_neighbor_info[ peer]['interface']: bgp_neighbor_info[peer]['if_arp'].append( f"{arp_entry['ip']}:{arp_entry['mac']}") # for presentation purposes when using format.presentation method if filtering['alias']: if not bgp_neighbor_info[peer]['if_arp']: bgp_neighbor_info[peer]['if_arp'] = ['-'] # consolidate arp bgp_neighbor_info[peer]['arp'] = bgp_neighbor_info[peer][ 'if_arp'] + bgp_neighbor_info[peer]['ip_arp'] # interface status if filtering['alias']: try: interfaces = ipdict[host]['napalm'].get_interfaces() except: interfaces = [] # if napalm fails for peer in bgp_neighbor_info: bgp_neighbor_info[peer]['if_description'] = '- ' bgp_neighbor_info[peer]['if_oper_status'] = '- ' bgp_neighbor_info[peer]['if_admin_status'] = '- ' # if the interface does not exist there is no intf info if not bgp_neighbor_info[peer]['interface']: bgp_neighbor_info[peer]['interface'] = '- ' continue else: for interface in interfaces.keys(): if interface == bgp_neighbor_info[peer][ 'interface']: op_state = interfaces[interface]['is_up'] if op_state == True: op_state = 'Up' else: op_state = 'Down' ad_state = interfaces[interface]['is_enabled'] if ad_state == True: ad_state = 'Up' else: ad_state = 'Down' bgp_neighbor_info[peer][ 'if_description'] = interfaces[interface][ 'description'] bgp_neighbor_info[peer][ 'if_oper_status'] = op_state bgp_neighbor_info[peer][ 'if_admin_status'] = ad_state else: return #close the session ipdict[host]['napalm'].close() if monitor: context_output['_bgp_neigbor_dict_']['collectors'][host] = {} context_output['_bgp_neigbor_dict_']['collectors'][host][ 'name'] = f'{ipdict[host]["hostname"].replace("_"," ").upper()} {host}' context_output['_bgp_neigbor_dict_']['collectors'][host][ 'peers'] = bgp_neighbor_info context_output['_bgp_neigbor_dict_']['collectors'][host][ 'total-sessions'] = len(bgp_neighbor_info) else: summary = format.presentation(bgp_neighbor_info, filtering=filtering) with lock: try: context_output['_out_'] += '\n[%s %s]' % ( host, ipdict[host]['hostname']) except: context_output['_out_'] += '[%s]' % host context_output['_out_'] += '\n' context_output['_out_'] += '\n' context_output['_out_'] += summary context_output['_out_'] += '\n'
def get_mpls_info(host, user, password, regex, lsys): # Load the classes created by the FactoryLoader with the YAML to the global variables so they can be referenced globals().update(FactoryLoader().load(yaml.load(yml))) dev = Device(host=host, user=user, password=password, gather_facts=False) dev.open() if lsys: if(regex.isspace() or regex == ""): ml = mplsLSPs(dev).get(logical_system=str(lsys)) rs = rsvpSessions(dev).get(logical_system=str(lsys)) else: ml = mplsLSPs(dev).get(str(regex), logical_system=str(lsys)) rs = rsvpSessions(dev).get(str(regex), logical_system=str(lsys)) else: if(regex.isspace() or regex == ""): ml = mplsLSPs(dev).get() rs = rsvpSessions(dev).get() else: ml = mplsLSPs(dev).get(str(regex)) rs = rsvpSessions(dev).get(str(regex)) dev.close() # Move all rsvpSessions information to a defaultdict. We need to be able to get # rsvp sessions information with the LSP name as key. Normally there is more # than 1 rsvp session with the same name, so to get all the sessions in the original # "dict" (OpTable.rsvpSessions) we would have to iterate through it searching # for each sessions called the same as the LSP, for every LSP. This way we do it # all at once, one iteration instead of N (#LSPs) iterations. rsvp_sessions = defaultdict(list) for rskey in rs.keys(): rsvp_sessions[rskey].append(rs[rskey]) #Prepare the string with the information structured as we need it to be displayed in the webpage output = "" for item in ml: output += "\nName: "+item.name + " To: "+ item.destination_address + " State: "+item.lsp_state+ "\n" output += "Route Count: " + str(item.route_count) + " Active Path: " + item.active_path+ "\n" output += "\nPaths: "+ "\n" for path in item.lsp_path: output += "\nPath: "+path.path_name+" ("+path.path_title+")" if path.path_active: output += "* " output += "Include:" + string.translate(str(path.admin_groups),None,"'")+ "\n" output += "ERO: " + string.translate(str(path.path_ero),None,"'") + "\n" if path.path_rro: output += path.path_rro + "\n" output += "\nRSVP info: " + " \n " rsvp_sessionslsp = rsvp_sessions[item.name] for rsvp_session in rsvp_sessionslsp: output += "\nPath: "+rsvp_session.lsp_path_type+" State: "+rsvp_session.lsp_state + "\n" output += "LSP ID: "+rsvp_session.lsp_id+" Tunnel ID: "+rsvp_session.tunnel_id + "\n" if rsvp_session.is_nodeprotection: if rsvp_session.bypass_name: output += "Using: " + rsvp_session.bypass_name + "\n" else: output += "Node-link protection desired. No bypass selected.\n" if rsvp_session.is_fastreroute: if rsvp_session.detour_state: output += "FRR:" + "\n" output += "Detour State: " + rsvp_session.detour_state + "\n" output += "ERO: " + str(rsvp_session.detour_ero) + "\n" output += "RRO: " + str(rsvp_session.detour_rro) + "\n" else: output += "FRR protection desired. Detour not established.\n" output += "------------------------------------------------------------------------------------------" + " \n " return output
class TestConfig(unittest.TestCase): @patch('ncclient.manager.connect') def setUp(self, mock_connect): mock_connect.side_effect = self._mock_manager self.dev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) self.dev.open() self.conf = Config(self.dev) @patch('ncclient.operations.session.CloseSession.request') def tearDown(self, mock_session): self.dev.close() def test_config_constructor(self): self.assertTrue(isinstance(self.conf._dev, Device)) def test_config_confirm_true(self): self.conf.rpc.commit_configuration = MagicMock() self.conf.commit(confirm=True) self.conf.rpc.commit_configuration\ .assert_called_with(confirmed=True) def test_config_commit_confirm(self): self.conf.rpc.commit_configuration = MagicMock() self.conf.commit(confirm=10) self.conf.rpc.commit_configuration\ .assert_called_with(**{'confirm-timeout': '10', 'confirmed': True}) def test_config_commit_comment(self): self.conf.rpc.commit_configuration = MagicMock() self.conf.commit(comment='Test') self.conf.rpc.commit_configuration.assert_called_with(log='Test') def test_config_commit_sync(self): self.conf.rpc.commit_configuration = MagicMock() self.conf.commit(sync=True) self.conf.rpc.commit_configuration\ .assert_called_with(synchronize=True) def test_config_commit_force_sync(self): self.conf.rpc.commit_configuration = MagicMock() self.conf.commit(force_sync=True) self.conf.rpc.commit_configuration\ .assert_called_with(**{'synchronize': True, 'force-synchronize': True}) def test_config_commit_timeout(self): self.conf.rpc.commit_configuration = MagicMock() self.conf.commit(timeout=60) self.conf.rpc.commit_configuration\ .assert_called_with(dev_timeout=60) def test_config_commit_full(self): self.conf.rpc.commit_configuration = MagicMock() self.conf.commit(full=True) self.conf.rpc.commit_configuration\ .assert_called_with(full=True) def test_config_commit_detail(self): self.conf.rpc.commit_configuration = MagicMock() self.conf.rpc.commit_configuration.return_value = '<mockdetail/>' self.assertEqual('<mockdetail/>', self.conf.commit(detail=True)) self.conf.rpc.commit_configuration\ .assert_called_with({'detail': 'detail'}) def test_config_commit_combination(self): self.conf.rpc.commit_configuration = MagicMock() self.conf.rpc.commit_configuration.return_value = '<moredetail/>' self.assertEqual( '<moredetail/>', self.conf.commit(detail=True, force_sync=True, full=True)) self.conf.rpc.commit_configuration\ .assert_called_with({'detail': 'detail'}, **{'synchronize': True, 'full': True, 'force-synchronize': True}) @patch('jnpr.junos.utils.config.JXML.remove_namespaces') def test_config_commit_xml_exception(self, mock_jxml): class MyException(Exception): xml = etree.fromstring('<test/>') self.conf.rpc.commit_configuration = \ MagicMock(side_effect=MyException) self.assertRaises(CommitError, self.conf.commit) def test_config_commit_exception(self): class MyException(Exception): pass self.conf.rpc.commit_configuration = \ MagicMock(side_effect=MyException) self.assertRaises(MyException, self.conf.commit) def test_config_commit_exception_RpcError(self): ex = RpcError(rsp='ok') self.conf.rpc.commit_configuration = MagicMock(side_effect=ex) self.assertTrue(self.conf.commit()) import xml.etree.ElementTree as ET xmldata = """<data><company name="Juniper"> <code>pyez</code> <year>2013</year> </company></data>""" root = ET.fromstring(xmldata) el = root.find('company') ex = RpcError(rsp=el) self.conf.rpc.commit_configuration = MagicMock(side_effect=ex) self.assertRaises(CommitError, self.conf.commit) def test_commit_check(self): self.conf.rpc.commit_configuration = MagicMock() self.assertTrue(self.conf.commit_check()) @patch('jnpr.junos.utils.config.JXML.rpc_error') def test_commit_check_exception(self, mock_jxml): class MyException(Exception): xml = 'test' self.conf.rpc.commit_configuration = MagicMock(side_effect=MyException) # with self.assertRaises(AttributeError): self.conf.commit_check() def test_config_commit_check_exception_RpcError(self): ex = RpcError(rsp='ok') self.conf.rpc.commit_configuration = MagicMock(side_effect=ex) self.assertTrue(self.conf.commit_check()) import xml.etree.ElementTree as ET xmldata = """<data><company name="Juniper"> <code>pyez</code> <year>2013</year> </company></data>""" root = ET.fromstring(xmldata) el = root.find('company') ex = RpcError(rsp=el) self.conf.rpc.commit_configuration = MagicMock(side_effect=ex) self.assertRaises(CommitError, self.conf.commit_check) def test_config_diff(self): self.conf.rpc.get_configuration = MagicMock() self.conf.diff() self.conf.rpc.get_configuration.\ assert_called_with( {'compare': 'rollback', 'rollback': '0', 'format': 'text'}) def test_config_pdiff(self): self.conf.diff = MagicMock(return_value='Stuff') self.conf.pdiff() self.conf.diff.assert_called_once_with(0) def test_config_load(self): self.assertRaises(RuntimeError, self.conf.load) def test_config_load_vargs_len(self): self.assertRaises(RuntimeError, self.conf.load, 'test.xml') def test_config_load_len_with_format_set(self): self.conf.rpc.load_config = \ MagicMock(return_value='rpc_contents') self.assertEqual(self.conf.load('test.xml', format='set'), 'rpc_contents') def test_config_load_len_with_format_xml(self): self.conf.rpc.load_config = \ MagicMock(return_value='rpc_contents') xmldata = """<snmp> <community> <name>iBGP</name> </community> </snmp>""" self.assertEqual(self.conf.load(xmldata, format='xml'), 'rpc_contents') def test_config_load_len_with_format_text(self): self.conf.rpc.load_config = \ MagicMock(return_value='rpc_contents') textdata = """policy-options { prefix-list TEST1-NETS { 100.0.0.0/24; } policy-statement TEST1-NETS { term TEST1 { from { prefix-list TEST1-NETS; } then accept; } term REJECT { then reject; } } }""" self.assertEqual(self.conf.load(textdata), 'rpc_contents') @patch(builtin_string + '.open') def test_config_load_lformat_byext_ValueError(self, mock_open): self.conf.rpc.load_config = \ MagicMock(return_value='rpc_contents') self.assertRaises(ValueError, self.conf.load, path='test.jnpr') def test_config_load_lset_format_ValueError(self): self.conf.rpc.load_config = \ MagicMock(return_value='rpc_contents') self.assertRaises(ValueError, self.conf.load, 'test.xml', format='set', overwrite=True) @patch(builtin_string + '.open') @patch('jnpr.junos.utils.config.etree.XML') def test_config_load_path_xml(self, mock_etree, mock_open): self.conf.dev.Template = MagicMock() mock_etree.return_value = 'rpc_contents' self.conf.rpc.load_config = \ MagicMock(return_value=mock_etree.return_value) self.assertEqual(self.conf.load(path='test.xml'), 'rpc_contents') @patch(builtin_string + '.open') def test_config_load_path_text(self, mock_open): self.conf.rpc.load_config = MagicMock() self.conf.load(path='test.conf') self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'], 'text') @patch(builtin_string + '.open') def test_config_load_path_set(self, mock_open): self.conf.rpc.load_config = MagicMock() self.conf.load(path='test.set') self.assertEqual(self.conf.rpc.load_config.call_args[1]['action'], 'set') @patch(builtin_string + '.open') def test_config_load_try_load_rpcerror(self, mock_open): ex = ConfigLoadError( rsp=etree.fromstring(("""<load-configuration-results> <rpc-error> <error-severity>error</error-severity> <error-message>syntax error</error-message> </rpc-error> </load-configuration-results>"""))) self.conf.rpc.load_config = MagicMock(side_effect=ex) self.assertRaises(ConfigLoadError, self.conf.load, path='config.conf') @patch(builtin_string + '.open') def test_config_load_try_load_rpctimeouterror(self, mock_open): ex = RpcTimeoutError(self.dev, None, 10) self.conf.rpc.load_config = MagicMock(side_effect=ex) self.assertRaises(RpcTimeoutError, self.conf.load, path='config.conf') @patch(builtin_string + '.open') def test_config_try_load_exception(self, mock_open): class OtherException(Exception): pass self.conf.rpc.load_config = MagicMock(side_effect=OtherException()) self.assertRaises(OtherException, self.conf.load, path='config.conf') @patch('jnpr.junos.utils.config.etree.XML') def test_config_load_template_path(self, mock_etree): self.conf.rpc.load_config = MagicMock() self.conf.dev.Template = MagicMock() self.conf.load(template_path='test.xml') self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'], 'xml') def test_config_load_template(self): class Temp: filename = 'abc.xml' render = MagicMock(return_value='<test/>') self.conf.rpc.load_config = MagicMock() self.conf.load(template=Temp) self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'], 'xml') def test_config_diff_exception(self): self.conf.rpc.get_configuration = MagicMock() self.assertRaises(ValueError, self.conf.diff, 51) self.assertRaises(ValueError, self.conf.diff, -1) def test_config_lock(self): self.conf.rpc.lock_configuration = MagicMock() self.assertTrue(self.conf.lock()) @patch('jnpr.junos.utils.config.JXML.rpc_error') def test_config_lock_LockError(self, mock_jxml): ex = RpcError(rsp='ok') self.conf.rpc.lock_configuration = MagicMock(side_effect=ex) self.assertRaises(LockError, self.conf.lock) @patch('jnpr.junos.utils.config.JXML.remove_namespaces') def test_config_lock_exception(self, mock_jxml): class MyException(Exception): xml = 'test' self.conf.rpc.lock_configuration = MagicMock(side_effect=MyException) self.assertRaises(LockError, self.conf.lock) def test_config_unlock(self): self.conf.rpc.unlock_configuration = MagicMock() self.assertTrue(self.conf.unlock()) @patch('jnpr.junos.utils.config.JXML.rpc_error') def test_config_unlock_LockError(self, mock_jxml): ex = RpcError(rsp='ok') self.conf.rpc.unlock_configuration = MagicMock(side_effect=ex) self.assertRaises(UnlockError, self.conf.unlock) @patch('jnpr.junos.utils.config.JXML.remove_namespaces') def test_config_unlock_exception(self, mock_jxml): class MyException(Exception): xml = 'test' self.conf.rpc.unlock_configuration = MagicMock(side_effect=MyException) self.assertRaises(UnlockError, self.conf.unlock) def test_config_rollback(self): self.conf.rpc.load_configuration = MagicMock() self.assertTrue(self.conf.rollback()) def test_config_rollback_exception(self): self.conf.rpc.load_configuration = MagicMock() self.assertRaises(ValueError, self.conf.rollback, 51) self.assertRaises(ValueError, self.conf.rollback, -1) @patch('jnpr.junos.Device.execute') def test_rescue_action_save(self, mock_exec): self.dev.request_save_rescue_configuration = MagicMock() self.assertTrue(self.conf.rescue('save')) @patch('jnpr.junos.Device.execute') def test_rescue_action_get_exception(self, mock_exec): self.dev.rpc.get_rescue_information = MagicMock(side_effect=Exception) self.assertTrue(self.conf.rescue('get') is None) @patch('jnpr.junos.Device.execute') def test_rescue_action_get(self, mock_exec): self.dev.rpc.get_rescue_information = MagicMock() self.dev.rpc.get_rescue_information.return_value = 1 self.assertEqual(self.conf.rescue('get', format='xml'), 1) @patch('jnpr.junos.Device.execute') def test_rescue_action_delete(self, mock_exec): self.dev.rpc.request_delete_rescue_configuration = MagicMock() self.assertTrue(self.conf.rescue('delete')) @patch('jnpr.junos.Device.execute') def test_rescue_action_reload(self, mock_exec): self.dev.rpc.load_configuration = MagicMock() self.dev.rpc.load_configuration.return_value = True self.assertTrue(self.conf.rescue('reload')) @patch('jnpr.junos.Device.execute') def test_rescue_action_reload_exception(self, mock_exec): self.dev.rpc.load_configuration = MagicMock(side_effect=Exception) self.assertFalse(self.conf.rescue('reload')) @patch('jnpr.junos.Device.execute') def test_rescue_action_unsupported_action(self, mock_exec): self.assertRaises(ValueError, self.conf.rescue, 'abc') def test_config_load_lset_from_rexp_xml(self): self.conf.rpc.load_config = MagicMock() conf = """<snmp><name>iBGP</name></snmp>""" self.conf.load(conf) self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'], 'xml') def test_config_load_lset_from_rexp_set(self): self.conf.rpc.load_config = MagicMock() conf = """set system domain-name englab.nitin.net""" self.conf.load(conf) self.assertEqual(self.conf.rpc.load_config.call_args[1]['action'], 'set') def test_config_load_lset_from_rexp_set_delete(self): self.conf.rpc.load_config = MagicMock() conf = """delete snmp""" self.conf.load(conf) self.assertEqual(self.conf.rpc.load_config.call_args[1]['action'], 'set') def test_config_load_lset_from_rexp_conf(self): self.conf.rpc.load_config = MagicMock() conf = """ snmp { location USA; community iBGP { authorization read-only; } }""" self.conf.load(conf) self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'], 'text') def test_config_load_lset_from_rexp_conf_replace_tag(self): self.conf.rpc.load_config = MagicMock() conf = """replace: snmp { location USA; community iBGP { authorization read-only; } }""" self.conf.load(conf) self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'], 'text') self.assertEqual(self.conf.rpc.load_config.call_args[1]['action'], 'replace') def test_config_load_lset_from_rexp_error(self): self.conf.rpc.load_config = MagicMock() conf = """test>""" self.assertRaises(RuntimeError, self.conf.load, conf) def test_load_merge_true(self): self.conf.rpc.load_config = MagicMock() conf = """ snmp { location USA; community iBGP { authorization read-only; } }""" self.conf.load(conf, merge=True) self.assertFalse('action' in self.conf.rpc.load_config.call_args[1]) def test_commit_RpcTimeoutError(self): ex = RpcTimeoutError(self.dev, None, 10) self.dev.rpc.commit_configuration = MagicMock(side_effect=ex) self.assertRaises(RpcTimeoutError, self.conf.commit) def test_commit_check_RpcTimeoutError(self): ex = RpcTimeoutError(self.dev, None, 10) self.dev.rpc.commit_configuration = MagicMock(side_effect=ex) self.assertRaises(RpcTimeoutError, self.conf.commit_check) def test_commit_configuration_multi_rpc_error(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) try: self.dev.rpc.commit_configuration() except Exception as ex: self.assertTrue(isinstance(ex, RpcError)) if ncclient.__version__ > (0, 4, 5): self.assertEqual( ex.message, "error: interface-range 'axp' is not defined\n" "error: interface-ranges expansion failed") self.assertEqual(ex.errs, [{ 'source': None, 'message': "interface-range 'axp' is not defined", 'bad_element': None, 'severity': 'error', 'edit_path': None }, { 'source': None, 'message': 'interface-ranges expansion failed', 'bad_element': None, 'severity': 'error', 'edit_path': None }]) else: self.assertEqual(ex.message, "interface-range 'axp' is not defined") @patch('jnpr.junos.utils.config.Config.lock') @patch('jnpr.junos.utils.config.Config.unlock') def test_config_mode_exclusive(self, mock_unlock, mock_lock): with Config(self.dev, mode='exclusive') as conf: conf.rpc.load_config = MagicMock() conf.load('conf', format='set') self.assertTrue(mock_lock.called and mock_unlock.called) @patch('jnpr.junos.Device.execute') def test_config_mode_batch(self, mock_exec): self.dev.rpc.open_configuration = MagicMock() with Config(self.dev, mode='batch') as conf: conf.load('conf', format='set') self.dev.rpc.open_configuration.assert_called_with(batch=True) @patch('jnpr.junos.Device.execute') def test_config_mode_private(self, mock_exec): self.dev.rpc.open_configuration = MagicMock() with Config(self.dev, mode='private') as conf: conf.load('conf', format='set') self.dev.rpc.open_configuration.assert_called_with(private=True) @patch('jnpr.junos.Device.execute') def test_config_mode_dynamic(self, mock_exec): self.dev.rpc.open_configuration = MagicMock() with Config(self.dev, mode='dynamic') as conf: conf.load('conf', format='set') self.dev.rpc.open_configuration.assert_called_with(dynamic=True) @patch('jnpr.junos.Device.execute') def test_config_mode_close_configuration_ex(self, mock_exec): self.dev.rpc.open_configuration = MagicMock() ex = RpcError(rsp='ok') ex.message = 'Configuration database is not open' self.dev.rpc.close_configuration = MagicMock(side_effect=ex) try: with Config(self.dev, mode='batch') as conf: conf.load('conf', format='set') except Exception as ex: self.assertTrue(isinstance(ex, RpcError)) self.assertTrue(self.dev.rpc.close_configuration.called) @patch('jnpr.junos.Device.execute') def test_config_mode_undefined(self, mock_exec): try: with Config(self.dev, mode='unknown') as conf: conf.load('conf', format='set') except Exception as ex: self.assertTrue(isinstance(ex, ValueError)) @patch('jnpr.junos.Device.execute') def test_config_mode_batch_open_configuration_ex(self, mock_exec): rpc_xml = ''' <rpc-error> <error-severity>warning</error-severity> <error-info><bad-element>bgp</bad-element></error-info> <error-message>syntax error</error-message> </rpc-error> ''' rsp = etree.XML(rpc_xml) obj = RpcError(rsp=rsp) self.dev.rpc.open_configuration = MagicMock(side_effect=obj) with Config(self.dev, mode='batch') as conf: conf.load('conf', format='set') self.dev.rpc.open_configuration.assert_called_with(batch=True) @patch('jnpr.junos.Device.execute') def test_config_mode_private_open_configuration_ex(self, mock_exec): rpc_xml = ''' <rpc-error> <error-severity>warning</error-severity> <error-info><bad-element>bgp</bad-element></error-info> <error-message>syntax error</error-message> </rpc-error> ''' rsp = etree.XML(rpc_xml) obj = RpcError(rsp=rsp) self.dev.rpc.open_configuration = MagicMock(side_effect=obj) with Config(self.dev, mode='private') as conf: conf.load('conf', format='set') self.dev.rpc.open_configuration.assert_called_with(private=True) def _read_file(self, fname): from ncclient.xml_ import NCElement fpath = os.path.join(os.path.dirname(__file__), 'rpc-reply', fname) foo = open(fpath).read() # specific to multi rpc error if fname == 'commit-configuration.xml': raw = etree.XML(foo) obj = RPCReply(raw) obj.parse() if ncclient.__version__ > (0, 4, 5): raise RPCError(etree.XML(foo), errs=obj._errors) else: raise RPCError(etree.XML(foo)) def _mock_manager(self, *args, **kwargs): if kwargs: device_params = kwargs['device_params'] device_handler = make_device_handler(device_params) session = SSHSession(device_handler) return Manager(session, device_handler) elif args: return self._read_file(args[0].tag + '.xml')
def deviceMenu(): deviceOption = 1 device = raw_input("Please enter device hostname or IP address: ") clearScreen() while deviceOption < 7: dev = Device(device, user=username, password=passwd) dev.bind(sw=SW) dev.open() print("DEVICE MENU\n\n") print("What would you like to do?") print(" 1) Get basic device statistics") print(" 2) Get basic information on all interfaces") print(" 3) Get basic information on a single interface") print(" 4) View device inventory") print(" 5) Upgrade this device") print(" 6) Reboot this device") print(" 7) Exit this device") deviceOption = int(raw_input()) if deviceOption == 1: clearScreen() displayFacts(dev) raw_input("Press [Enter] to continue...") elif deviceOption == 2: #Print some physical port statistics phyports = PhyPortTable(dev).get() eths = EthPortTable(dev).get() clearScreen() for port in phyports: print(type(port)) print("Interface: " + port.key) if (port.description is not None): print(" Description: " + port.description) print(" Status: " + port.admin + "/" + port.oper) print(" Flapped: " + port.flapped) raw_input("Press [Enter] to continue...") elif deviceOption == 3: clearScreen() """ port = raw_input("Which port would you like to view?: ") print("Interface: " + port.key) if ( port.description is not None ): print(" Description: "+ port.description) print(" Status: " + port.admin + "/" + port.oper) print(" Flapped: " + port.flapped) raw_input("Press Enter to continue...") """ listToDict #listPorts(dev) individualPort(dev) #eths = EthPortTable(dev).get() #pp(eths.keys()) #raw_input("Press Enter to continue...") #clearScreen() elif deviceOption == 4: viewInventory(dev) elif deviceOption == 5: upgradeJunos(dev) elif deviceOption == 6: rebootDevice(dev) elif deviceOption == 7: dev.close() clearScreen() else: print("Please enter a number 1-4")
class TestDevice(unittest.TestCase): @patch('ncclient.manager.connect') def setUp(self, mock_connect): mock_connect.side_effect = self._mock_manager self.dev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) self.dev.open() @patch('ncclient.operations.session.CloseSession.request') def tearDown(self, mock_session): self.dev.close() @patch('jnpr.junos.device.netconf_ssh') def test_device_ConnectAuthError(self, mock_manager): mock_manager.connect.side_effect = NcErrors.AuthenticationError self.assertRaises(EzErrors.ConnectAuthError, self.dev.open) @patch('jnpr.junos.device.netconf_ssh') def test_device_ConnectRefusedError(self, mock_manager): mock_manager.connect.side_effect = NcErrors.SSHError self.assertRaises(EzErrors.ConnectRefusedError, self.dev.open) @patch('jnpr.junos.device.netconf_ssh') @patch('jnpr.junos.device.datetime') def test_device_ConnectTimeoutError(self, mock_datetime, mock_manager): NcErrors.SSHError.message = 'cannot open' mock_manager.connect.side_effect = NcErrors.SSHError from datetime import timedelta, datetime currenttime = datetime.now() mock_datetime.datetime.now.side_effect = [ currenttime, currenttime + timedelta(minutes=4) ] self.assertRaises(EzErrors.ConnectTimeoutError, self.dev.open) @patch('jnpr.junos.device.netconf_ssh') @patch('jnpr.junos.device.datetime') def test_device_diff_err_message(self, mock_datetime, mock_manager): NcErrors.SSHError.message = 'why are you trying :)' mock_manager.connect.side_effect = NcErrors.SSHError from datetime import timedelta, datetime currenttime = datetime.now() mock_datetime.datetime.now.side_effect = [ currenttime, currenttime + timedelta(minutes=4) ] self.assertRaises(EzErrors.ConnectError, self.dev.open) @patch('jnpr.junos.device.netconf_ssh') def test_device_ConnectUnknownHostError(self, mock_manager): import socket mock_manager.connect.side_effect = socket.gaierror self.assertRaises(EzErrors.ConnectUnknownHostError, self.dev.open) @patch('jnpr.junos.device.netconf_ssh') def test_device_other_error(self, mock_manager): mock_manager.connect.side_effect = TypeError self.assertRaises(EzErrors.ConnectError, self.dev.open) def test_device_probe_error(self): mock_probe = MagicMock() mock_probe.return_value = None self.dev.probe = mock_probe def fn(): self.dev.open(auto_probe=1) self.assertRaises(EzErrors.ProbeError, fn) def test_device_property_logfile_isinstance(self): mock = MagicMock() with patch('__builtin__.open', mock): with patch('__builtin__.file', MagicMock): handle = open('filename', 'r') self.dev.logfile = handle self.assertEqual(self.dev.logfile, handle) def test_device_host_mand_param(self): self.assertRaises(ValueError, Device, user='******', password='******', gather_facts=False) def test_device_property_logfile_close(self): self.dev._logfile = MagicMock() self.dev._logfile.close.return_value = 0 self.dev.logfile = None self.assertFalse(self.dev._logfile) def test_device_property_logfile_exception(self): try: self.dev.logfile = True except Exception as ex: self.assertEqual(type(ex), ValueError) def test_device_repr(self): localdev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) self.assertEqual(repr(localdev), 'Device(1.1.1.1)') def test_device_local(self): Device.ON_JUNOS = True localdev = Device() self.assertEqual(localdev._hostname, 'localhost') @patch('jnpr.junos.device.os') @patch('__builtin__.open') @patch('paramiko.config.SSHConfig.lookup') def test_device__sshconf_lkup(self, os_mock, open_mock, mock_paramiko): os_mock.path.exists.return_value = True self.dev._sshconf_lkup() mock_paramiko.assert_called_any() @patch('jnpr.junos.device.os') @patch('__builtin__.open') @patch('paramiko.config.SSHConfig.lookup') def test_device__sshconf_lkup_def(self, os_mock, open_mock, mock_paramiko): os_mock.path.exists.return_value = True self.dev._ssh_config = '/home/rsherman/.ssh/config' self.dev._sshconf_lkup() mock_paramiko.assert_called_any() @patch('os.getenv') def test_device__sshconf_lkup_path_not_exists(self, mock_env): mock_env.return_value = '/home/test' self.assertEqual(self.dev._sshconf_lkup(), None) @patch('os.getenv') def test_device__sshconf_lkup_home_not_defined(self, mock_env): mock_env.return_value = None self.assertEqual(self.dev._sshconf_lkup(), None) mock_env.assert_called_with('HOME') @patch('ncclient.manager.connect') @patch('jnpr.junos.Device.execute') def test_device_open(self, mock_connect, mock_execute): with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat: mock_cat.return_value = """ domain jls.net """ mock_connect.side_effect = self._mock_manager mock_execute.side_effect = self._mock_manager self.dev2 = Device(host='2.2.2.2', user='******', password='******') self.dev2.open() self.assertEqual(self.dev2.connected, True) @patch('jnpr.junos.Device.execute') def test_device_facts(self, mock_execute): with patch('jnpr.junos.utils.fs.FS.cat') as mock_cat: mock_execute.side_effect = self._mock_manager mock_cat.return_value = """ domain jls.net """ self.dev.facts_refresh() assert self.dev.facts['version'] == facts['version'] def test_device_hostname(self): self.assertEqual(self.dev.hostname, '1.1.1.1') def test_device_user(self): self.assertEqual(self.dev.user, 'rick') def test_device_get_password(self): self.assertEqual(self.dev.password, None) def test_device_set_password(self): self.dev.password = '******' self.assertEqual(self.dev._password, 'secret') def test_device_get_timeout(self): self.assertEqual(self.dev.timeout, 30) def test_device_set_timeout(self): self.dev.timeout = 10 self.assertEqual(self.dev.timeout, 10) def test_device_manages(self): self.assertEqual(self.dev.manages, [], 'By default manages will be empty list') def test_device_set_facts_exception(self): try: self.dev.facts = 'test' except RuntimeError as ex: self.assertEqual(RuntimeError, type(ex)) @patch('jnpr.junos.Device.execute') def test_device_cli(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual(self.dev.cli('show cli directory').tag, 'cli') @patch('jnpr.junos.Device.execute') def test_device_cli_conf_info(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertTrue('ge-0/0/0' in self.dev.cli('show configuration')) @patch('jnpr.junos.Device.execute') def test_device_cli_output(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertTrue('Alarm' in self.dev.cli('show system alarms')) @patch('jnpr.junos.Device.execute') def test_device_cli_rpc(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual( self.dev.cli('show system uptime | display xml rpc').tag, 'get-system-uptime-information') def test_device_cli_exception(self): self.dev.rpc.cli = MagicMock(side_effect=AttributeError) val = self.dev.cli('show version') self.assertEqual(val, 'invalid command: show version') @patch('jnpr.junos.Device.execute') def test_device_display_xml_rpc(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual( self.dev.display_xml_rpc('show system uptime ').tag, 'get-system-uptime-information') @patch('jnpr.junos.Device.execute') def test_device_display_xml_rpc_text(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertIn( '<get-system-uptime-information>', self.dev.display_xml_rpc('show system uptime ', format='text')) @patch('jnpr.junos.Device.execute') def test_device_display_xml_exception(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual(self.dev.display_xml_rpc('show foo'), 'invalid command: show foo| display xml rpc') def test_device_execute(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertEqual( self.dev.execute('<get-system-core-dumps/>').tag, 'directory-list') def test_device_execute_topy(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertEqual( self.dev.execute('<get-system-core-dumps/>', to_py=self._do_nothing), 'Nothing') # This test is for the commented out rpc-error code # def test_device_execute_exception(self): # self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) # self.assertRaises(RpcError, self.dev.execute, # '<load-configuration-error/>') def test_device_execute_unknown_exception(self): class MyException(Exception): pass self.dev._conn.rpc = MagicMock(side_effect=MyException) self.assertRaises(MyException, self.dev.execute, '<get-software-information/>') def test_device_execute_rpc_error(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertRaises(RpcError, self.dev.rpc.get_rpc_error) def test_device_execute_permission_error(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertRaises(EzErrors.PermissionError, self.dev.rpc.get_permission_denied) def test_device_execute_index_error(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertTrue(self.dev.rpc.get_index_error()) def test_device_execute_ValueError(self): self.assertRaises(ValueError, self.dev.execute, None) def test_device_rpcmeta(self): self.assertEqual(self.dev.rpc.get_software_information.func_doc, 'get-software-information') def test_device_probe_timeout_zero(self): with patch('jnpr.junos.device.socket'): self.assertFalse(self.dev.probe(0)) def test_device_probe_timeout_gt_zero(self): with patch('jnpr.junos.device.socket'): self.assertTrue( self.dev.probe(1), 'probe fn is not working for' ' timeout greater than zero') def test_device_probe_timeout_exception(self): with patch('jnpr.junos.device.socket') as mock_socket: with patch('jnpr.junos.device.time.sleep') as mock_time: mock_socket.socket.return_value.close.side_effect \ = RuntimeError mock_time.return_value = None self.assertFalse(self.dev.probe(.01)) def test_device_bind_varg(self): self.dev.bind() mock = MagicMock() mock.__name__ = 'magic_mock' self.dev.bind(mock) self.assertEqual(self.dev.magic_mock.__name__, 'magic_mock') def test_device_bind_kvarg(self): self.dev.bind() mock = MagicMock() mock.return_value = 'Test' self.dev.bind(kw=mock) self.assertEqual(self.dev.kw, 'Test') def test_device_bind_varg_exception(self): def varg(): self.dev.bind() mock = MagicMock() mock.__name__ = 'magic mock' # for *args self.dev.bind(mock) self.dev.bind(mock) self.assertRaises(ValueError, varg) def test_device_bind_kvarg_exception(self): def kve(): self.dev.bind() mock = MagicMock() mock.__name__ = 'magic mock' # for **kwargs self.dev.bind(kw=mock) self.dev.bind(kw=mock) self.assertRaises(ValueError, kve) def test_device_template(self): # Try to load the template relative to module base try: template = self.dev.Template( 'tests/unit/templates/config-example.xml') except: # Try to load the template relative to test base try: template = self.dev.Template('templates/config-example.xml') except: raise self.assertEqual( template.render({ 'host_name': '1', 'domain_name': '2' }), 'system {\n host-name 1;\n domain-name 2;\n}') def test_device_close(self): def close_conn(): self.dev.connected = False self.dev.close = MagicMock(name='close') self.dev.close.side_effect = close_conn self.dev.close() self.assertEqual(self.dev.connected, False) def _read_file(self, fname): from ncclient.xml_ import NCElement fpath = os.path.join(os.path.dirname(__file__), 'rpc-reply', fname) foo = open(fpath).read() if fname == 'get-rpc-error.xml': # Raise ncclient exception for error raise RPCError(etree.XML(foo)) elif fname == 'get-permission-denied.xml': # Raise ncclient exception for error raise RPCError(etree.XML(foo)) elif (fname == 'get-index-error.xml' or fname == 'get-system-core-dumps.xml' or fname == 'load-configuration-error.xml'): rpc_reply = NCElement( foo, self.dev._conn._device_handler.transform_reply()) elif (fname == 'show-configuration.xml' or fname == 'show-system-alarms.xml'): rpc_reply = NCElement( foo, self.dev._conn._device_handler.transform_reply() )._NCElement__doc else: rpc_reply = NCElement( foo, self.dev._conn._device_handler.transform_reply() )._NCElement__doc[0] return rpc_reply def _mock_manager(self, *args, **kwargs): if kwargs: device_params = kwargs['device_params'] device_handler = make_device_handler(device_params) session = SSHSession(device_handler) return Manager(session, device_handler) elif args: if args[0].tag == 'command': if args[0].text == 'show cli directory': return self._read_file('show-cli-directory.xml') elif args[0].text == 'show configuration': return self._read_file('show-configuration.xml') elif args[0].text == 'show system alarms': return self._read_file('show-system-alarms.xml') elif args[0].text == 'show system uptime | display xml rpc': return self._read_file('show-system-uptime-rpc.xml') else: raise RpcError else: return self._read_file(args[0].tag + '.xml') def _do_nothing(self, *args, **kwargs): return 'Nothing'
# Test program for the Device class by Per from jnpr.junos import Device # import base64 # to encrypt password #import myPassword #import base64 try: # Create device object mySRX_password = base64.b64decode(myPassword.getPassword()) print('Testing if device can be created') myDev = Device(host='192.168.1.1', user='******', password=XXX) print('Okay, device is created. Now testing reachable...') myDev.auto_probe = 3 # Test for 3 seconds if device is reachable print('Okay, device is reachable. Now trying to connect...') myDev.open() # Connect to device print('Okay, connected. Sending cli command.') SRX_interface = myDev.cli("show interfaces terse", warning=False) # Disable warnings print(SRX_interface) myDev.close() except Exception as somethingWentWrong: print(somethingWentWrong)
class PyEZ(object): """ Instantiate a connection to a Junos device with the pyez module """ def __init__(self, host, username, password, timeout=5, gather_facts=False): self.host = host self.username = username self.password = password self.timeout = timeout self.gather_facts = gather_facts self.conn = Device(host=self.host, user=self.username, passwd=self.password, timeout=self.timeout, gather_facts=self.gather_facts) try: self.conn.open() except exception.ConnectAuthError as e: raise e except exception.ConnectTimeoutError as e: raise e except exception.ConnectRefusedError as e: raise e self.facts = self.conn.facts self.rpc = self.conn.rpc def open_connection(self): """ Open connection if not already open """ if self.conn.connected: return "Connection to {0} already open".format(self.host) else: self.conn.open() return "Connection to {0} opened".format(self.host) def close_connection(self): """ Close connection if not aleardy closed """ if not self.conn.connected: return "Connection to {0} already closed".format(self.host) else: self.conn.close() return "Connection to {0} closed".format(self.host) def get_facts(self, refresh=False): """ Get device facts :param refresh: refresh the device facts """ if self.gather_facts and not refresh: return self.facts else: self.conn.facts_refresh() self.facts = self.conn.facts self.gather_facts = True return self.facts def cli_command(self, command, warning=True): """ Debugging only, dont use this as part of production workflow """ return self.conn.cli(command=command, warning=warning) def get_rcp_command(self, command, get_xml=False): """ Converts a junos cli command to its rpc equivalent :param command: junos command to convert :param get_xml: return command as xml tree :return: returns rpc comamnd as a string """ result = self.conn.display_xml_rpc(command) if 'invalid command' in result: return 'Invalid command: {0}'.format(command) else: if get_xml: return etree.dump(result) return result.tag.replace('-', '_')
if ok is True: sw.reboot() else: print('Unable to install software') for i in xrange(1020, 0, -1): time.sleep(1) dev.open() re0_version = dev.cli('show version', warning=False) re1_version = dev.cli('show version invoke-on other-routing-engine', warning=False) for i in xrange(5, 0, -1): time.sleep(1) re0_version_check = re0_version.find('17.1R2.7') re1_version_check = re1_version.find('17.1R2.7') if re0_version_check >= 0 and re1_version_check >= 0: print "JunOS Upgrade is successful to 17.1R2.7" else: print "JunOS Upgrade is NOT successful - Abort" sys.exit(1) dev.close()
class TestSW(unittest.TestCase): @patch('ncclient.manager.connect') def setUp(self, mock_connect): mock_connect.side_effect = self._mock_manager self.dev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False) self.dev.open() self.dev.facts = facts self.sw = self.get_sw() @patch('jnpr.junos.Device.execute') def get_sw(self, mock_execute): mock_execute.side_effect = self._mock_manager return SW(self.dev) @patch('ncclient.operations.session.CloseSession.request') def tearDown(self, mock_session): self.dev.close() def test_sw_hashfile(self): with patch(builtin_string + '.open', mock_open(), create=True): import jnpr.junos.utils.sw with open('foo') as h: h.read.side_effect = ('abc', 'a', '') jnpr.junos.utils.sw._hashfile(h, MagicMock()) self.assertEqual(h.read.call_count, 3) @patch('jnpr.junos.Device.execute') def test_sw_constructor_multi_re(self, mock_execute): mock_execute.side_effect = self._mock_manager self.sw = SW(self.dev) self.assertTrue(self.sw._multi_RE) @patch('jnpr.junos.Device.execute') def test_sw_constructor_multi_vc(self, mock_execute): mock_execute.side_effect = self._mock_manager self.sw = SW(self.dev) self.assertFalse(self.sw._multi_VC) @patch(builtin_string + '.open') def test_sw_local_sha256(self, mock_built_open): package = 'test.tgz' self.assertEqual(SW.local_checksum(package, algorithm='sha256'), 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934' 'ca495991b7852b855') @patch(builtin_string + '.open') def test_sw_local_md5(self, mock_built_open): package = 'test.tgz' self.assertEqual(self.sw.local_checksum(package, algorithm='md5'), 'd41d8cd98f00b204e9800998ecf8427e') @patch(builtin_string + '.open') def test_sw_local_sha1(self, mock_built_open): package = 'test.tgz' self.assertEqual(SW.local_checksum(package, algorithm='sha1'), 'da39a3ee5e6b4b0d3255bfef95601890afd80709') def test_sw_local_checksum_unknown_alg(self): self.assertRaises(ValueError, SW.local_checksum, 'foo.tgz', algorithm='foo') def test_sw_progress(self): with self.capture(SW.progress, self.dev, 'running') as output: self.assertEqual('1.1.1.1: running\n', output) @patch('jnpr.junos.Device.execute') @patch('paramiko.SSHClient') @patch('scp.SCPClient.put') def test_sw_progress_true(self, scp_put, mock_paramiko, mock_execute): mock_execute.side_effect = self._mock_manager with self.capture(SW.progress, self.dev, 'testing') as output: self.sw.install('test.tgz', progress=True, checksum=345, cleanfs=False) self.assertEqual('1.1.1.1: testing\n', output) @patch('paramiko.SSHClient') @patch('scp.SCPClient.put') def test_sw_put(self, mock_scp_put, mock_scp): package = 'test.tgz' self.sw.put(package) self.assertTrue( call( 'test.tgz', '/var/tmp') in mock_scp_put.mock_calls) @patch('jnpr.junos.utils.sw.FTP') def test_sw_put_ftp(self, mock_ftp_put): dev = Device(host='1.1.1.1', user='******', password='******', mode='telnet', port=23, gather_facts=False) dev.facts = facts sw = SW(dev) sw.put(package='test.tgz') self.assertTrue( call( 'test.tgz', '/var/tmp') in mock_ftp_put.mock_calls) @patch('jnpr.junos.utils.scp.SCP.__exit__') @patch('jnpr.junos.utils.scp.SCP.__init__') @patch('jnpr.junos.utils.scp.SCP.__enter__') def test_sw_put_progress(self, mock_enter, mock_scp, mock_exit): package = 'test.tgz' mock_scp.side_effect = self._fake_scp with self.capture(self.sw.put, package, progress=self._my_scp_progress) as output: self.assertEqual('test.tgz 100 50\n', output) def _fake_scp(self, *args, **kwargs): progress = kwargs['progress'] progress('test.tgz', 100, 50) @patch('jnpr.junos.Device.execute') def test_sw_pkgadd(self, mock_execute): mock_execute.side_effect = self._mock_manager package = 'test.tgz' self.assertTrue(self.sw.pkgadd(package)) @patch('jnpr.junos.Device.execute') def test_sw_install_single_re_on_multi_re(self, mock_execute): mock_execute.side_effect = self._mock_manager self.sw._multi_RE = True self.assertTrue(self.sw.install('test.tgz', all_re=False, no_copy=True)) @patch('jnpr.junos.Device.execute') def test_sw_install_single_re(self, mock_execute): mock_execute.side_effect = self._mock_manager self.sw._multi_RE = False self.assertTrue(self.sw.install('test.tgz', no_copy=True)) @patch('jnpr.junos.Device.execute') def test_sw_install_no_package_result(self, mock_execute): mock_execute.side_effect = self._mock_manager self.sw._multi_RE = False self.assertTrue(self.sw.install('test_no_result.tgz', no_copy=True)) @patch('jnpr.junos.Device.execute') def test_sw_install_issu(self, mock_execute): mock_execute.side_effect = self._mock_manager package = 'test.tgz' self.assertTrue(self.sw.install(package, issu=True, no_copy=True)) @patch('jnpr.junos.Device.execute') def test_sw_install_nssu(self, mock_execute): mock_execute.side_effect = self._mock_manager package = 'test.tgz' self.assertTrue(self.sw.install(package, nssu=True, no_copy=True)) @patch('jnpr.junos.Device.execute') def test_sw_install_issu_nssu_both_error(self, mock_execute): mock_execute.side_effect = self._mock_manager try: self.sw.install('test.tgz', issu=True, nssu=True) except TypeError as ex: self.assertEqual( str(ex), 'install function can either take issu or nssu not both') @patch('jnpr.junos.Device.execute') def test_sw_install_issu_single_re_error(self, mock_execute): mock_execute.side_effect = self._mock_manager self.sw._multi_RE = False try: self.sw.install('test.tgz', issu=True) except TypeError as ex: self.assertEqual(str(ex), 'ISSU/NSSU requires Multi RE setup') @patch('jnpr.junos.Device.execute') def test_sw_install_issu_nssu_single_re_error(self, mock_execute): mock_execute.side_effect = self._mock_manager package = 'test.tgz' self.sw._multi_RE = False self.assertRaises(TypeError, self.sw.install, package, nssu=True, issu=True) @patch('jnpr.junos.Device.execute') def test_sw_pkgaddISSU(self, mock_execute): mock_execute.side_effect = self._mock_manager package = 'test.tgz' self.assertTrue(self.sw.pkgaddISSU(package)) @patch('jnpr.junos.Device.execute') def test_sw_pkgaddNSSU(self, mock_execute): mock_execute.side_effect = self._mock_manager package = 'test.tgz' self.assertTrue(self.sw.pkgaddNSSU(package)) @patch('jnpr.junos.Device.execute') def test_sw_pkgadd_pkg_set(self, mock_execute): mock_execute.side_effect = self._mock_manager pkg_set = ['abc.tgz', 'pqr.tgz'] self.sw._mixed_VC = True self.sw.pkgadd(pkg_set) self.assertEqual([i.text for i in mock_execute.call_args[0][0].findall('set')], pkg_set) @patch('jnpr.junos.Device.execute') def test_sw_validate(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertTrue(self.sw.validate('package.tgz')) @patch('jnpr.junos.Device.execute') def test_sw_validate_nssu(self, mock_execute): mock_execute.side_effect = self._mock_manager self.sw.log = MagicMock() # get_config returns false self.assertFalse(self.sw.validate('package.tgz', nssu=True)) self.sw.log.assert_called_with( 'Requirement FAILED: GRES is not Enabled in configuration') @patch('jnpr.junos.Device.execute') def test_sw_validate_issu(self, mock_execute): mock_execute.side_effect = self._mock_manager self.dev.rpc.get_config = MagicMock() self.assertTrue(self.sw.validate('package.tgz', issu=True)) @patch('jnpr.junos.Device.execute') def test_sw_val_issu_request_shell_execute_gres_on(self, mock_execute): mock_execute.side_effect = self._mock_manager self.dev.rpc.get_config = MagicMock() self.dev.rpc.request_shell_execute = MagicMock() self.dev.rpc.request_shell_execute.return_value = etree.fromstring( """<rpc-reply> <output>Graceful switchover: On</output> </rpc-reply>""") self.assertTrue(self.sw.validate('package.tgz', issu=True)) @patch('jnpr.junos.Device.execute') def test_sw_validate_issu_2re_false(self, mock_execute): mock_execute.side_effect = self._mock_manager self.dev.facts['2RE'] = False self.assertFalse(self.sw.validate('package.tgz', issu=True)) self.dev.facts['2RE'] = True @patch('paramiko.SSHClient') @patch('jnpr.junos.utils.start_shell.StartShell.wait_for') def test_sw_validate_issu_request_shell_execute(self, mock_ss, mock_ssh): self._issu_test_helper() with patch('jnpr.junos.utils.start_shell.StartShell.run') as ss: ss.return_value = (True, 'Graceful switchover: On') self.assertTrue(self.sw.validate('package.tgz', issu=True)) @patch('paramiko.SSHClient') @patch('jnpr.junos.utils.start_shell.StartShell.wait_for') def test_sw_validate_issu_ss_login_other_re_fail(self, mock_ss, mock_ssh): self._issu_test_helper() with patch('jnpr.junos.utils.start_shell.StartShell.run') as ss: ss.return_value = (False, 'Graceful switchover: On') self.assertFalse(self.sw.validate('package.tgz', issu=True)) self.sw.log.assert_called_with( 'Requirement FAILED: Not able run "show system switchover"') @patch('paramiko.SSHClient') @patch('jnpr.junos.utils.start_shell.StartShell.wait_for') def test_sw_validate_issu_ss_graceful_off(self, mock_ss, mock_ssh): self._issu_test_helper() with patch('jnpr.junos.utils.start_shell.StartShell.run') as ss: ss.return_value = (True, 'Graceful switchover: Off') self.assertFalse(self.sw.validate('package.tgz', issu=True)) self.sw.log.assert_called_with( 'Requirement FAILED: Graceful switchover status is not On') def _issu_test_helper(self): self.sw.log = MagicMock() self.dev.rpc.request_shell_execute = MagicMock() self.dev.rpc = MagicMock() self.dev.rpc.get_routing_task_replication_state.return_value = \ self._read_file('get-routing-task-replication-state.xml') self.dev.rpc.check_in_service_upgrade.return_value = \ self._read_file('check-in-service-upgrade.xml') self.dev.rpc.request_shell_execute.side_effect = \ RpcError(rsp='not ok') @patch('jnpr.junos.Device.execute') def test_sw_validate_issu_stateful_replication_off(self, mock_execute): mock_execute.side_effect = self._mock_manager self.dev.rpc.get_config = MagicMock() self.dev.rpc.get_routing_task_replication_state = MagicMock() self.sw.log = MagicMock() self.assertFalse(self.sw.validate('package.tgz', issu=True)) self.sw.log.assert_called_with( 'Requirement FAILED: Either Stateful Replication is not Enabled or RE mode\nis not Master') @patch('jnpr.junos.Device.execute') def test_sw_validate_issu_commit_sync_off(self, mock_execute): mock_execute.side_effect = self._mock_manager self.dev.rpc.get_config = MagicMock() self.dev.rpc.get_config.return_value = etree.fromstring(""" <configuration> <chassis> <redundancy> <graceful-switchover> </graceful-switchover> </redundancy> </chassis> </configuration>""") self.sw.log = MagicMock() self.assertFalse(self.sw.validate('package.tgz', issu=True)) self.sw.log.assert_called_with( 'Requirement FAILED: commit synchronize is not Enabled in configuration') @patch('jnpr.junos.Device.execute') def test_sw_validate_issu_nonstop_routing_off(self, mock_execute): mock_execute.side_effect = self._mock_manager self.dev.rpc.get_config = MagicMock() self.dev.rpc.get_config.side_effect = iter([etree.fromstring(""" <configuration> <chassis> <redundancy> <graceful-switchover> </graceful-switchover> </redundancy> </chassis> </configuration>"""), etree.fromstring(""" <configuration> <system> <commit> <synchronize/> </commit> </system> </configuration>"""), etree.fromstring("""<configuration> <routing-options></routing-options> </configuration>""")]) self.sw.log = MagicMock() self.assertFalse(self.sw.validate('package.tgz', issu=True)) self.sw.log.assert_called_with( 'Requirement FAILED: NSR is not Enabled in configuration') @patch('jnpr.junos.Device.execute') def test_sw_validate_issu_validation_succeeded(self, mock_execute): rpc_reply = """<rpc-reply><output>mgd: commit complete Validation succeeded </output> <package-result>1</package-result> </rpc-reply>""" mock_execute.side_effect = etree.fromstring(rpc_reply) package = 'package.tgz' self.assertFalse(self.sw.validate(package, issu=True)) @patch('jnpr.junos.Device.execute') def test_sw_remote_checksum_not_found(self, mock_execute): xml = '''<rpc-error> <error-severity>error</error-severity> <error-message> md5: /var/tmp/123: No such file or directory </error-message> </rpc-error>''' mock_execute.side_effect = RpcError(rsp=etree.fromstring(xml)) package = 'test.tgz' self.assertEqual(self.sw.remote_checksum(package), None) @patch('jnpr.junos.Device.execute') def test_sw_remote_checksum_not_rpc_error(self, mock_execute): xml = '''<rpc-error> <error-severity>error</error-severity> <error-message> something else! </error-message> </rpc-error>''' mock_execute.side_effect = RpcError(rsp=etree.fromstring(xml)) package = 'test.tgz' with self.assertRaises(RpcError): self.sw.remote_checksum(package) @patch('jnpr.junos.Device.execute') def test_sw_remote_checksum_md5(self, mock_execute): xml = '''<rpc-reply> <checksum-information> <file-checksum> <computation-method>MD5</computation-method> <input-file>/var/tmp/foo.tgz</input-file> <checksum>8a04cfc475e21507be5145bc0e82ce09</checksum> </file-checksum> </checksum-information> </rpc-reply>''' mock_execute.side_effect = etree.fromstring(xml) package = 'foo.tgz' self.assertEqual(self.sw.remote_checksum(package), '8a04cfc475e21507be5145bc0e82ce09') @patch('jnpr.junos.Device.execute') def test_sw_remote_checksum_sha1(self, mock_execute): xml = '''<rpc-reply> <checksum-information> <file-checksum> <computation-method>SHA1</computation-method> <input-file>/var/tmp/foo.tgz</input-file> <checksum>33c12913e81599452270ee849511e2e7578db00c</checksum> </file-checksum> </checksum-information> </rpc-reply>''' mock_execute.side_effect = etree.fromstring(xml) package = 'foo.tgz' self.assertEqual(self.sw.remote_checksum(package, algorithm='sha1'), '33c12913e81599452270ee849511e2e7578db00c') @patch('jnpr.junos.Device.execute') def test_sw_remote_checksum_sha256(self, mock_execute): xml = '''<rpc-reply> <checksum-information> <file-checksum> <computation-method>SHA256</computation-method> <input-file>/var/tmp/foo.tgz</input-file> <checksum>27bccf64babe4ea6687d3461e6d724d165aa140933e77b582af615dad4f02170</checksum> </file-checksum> </checksum-information> </rpc-reply>''' mock_execute.side_effect = etree.fromstring(xml) package = 'foo.tgz' self.assertEqual(self.sw.remote_checksum(package, algorithm='sha256'), '27bccf64babe4ea6687d3461e6d724d165aa140933e77b582af615dad4f02170') @patch('jnpr.junos.Device.execute') def test_sw_safe_copy(self, mock_execute): mock_execute.side_effect = self._mock_manager package = 'safecopy.tgz' self.sw.put = MagicMock() with patch('jnpr.junos.utils.sw.SW.local_md5'): self.assertTrue(self.sw.safe_copy(package, progress=self._myprogress, cleanfs=True, checksum='96a35ab371e1ca10408c3caecdbd8a67')) @patch('jnpr.junos.Device.execute') @patch('jnpr.junos.utils.sw.SW.local_checksum') def test_sw_safe_copy_missing_local_file(self, mock_checksum, mock_execute): mock_execute.side_effect = self._mock_manager mock_checksum.side_effect = IOError() package = 'foo.tgz' self.assertFalse(self.sw.safe_copy(package, progress=self._myprogress, cleanfs=True)) @patch('jnpr.junos.Device.execute') def test_sw_safe_copy_cleanfs_fail(self, mock_execute): mock_execute.side_effect = RpcError() package = 'foo.tgz' self.assertFalse(self.sw.safe_copy(package, progress=self._myprogress, cleanfs=True, checksum='96a35ab371e1ca10408c3caecdbd8a67')) @patch('jnpr.junos.Device.execute') def test_sw_safe_copy_return_false(self, mock_execute): # not passing checksum value, will get random from magicmock mock_execute.side_effect = self._mock_manager package = 'safecopy.tgz' self.sw.put = MagicMock() with patch('jnpr.junos.utils.sw.SW.local_md5'): self.assertFalse(self.sw.safe_copy(package, progress=self._myprogress, cleanfs=True)) @patch('jnpr.junos.Device.execute') def test_sw_safe_copy_checksum_none(self, mock_execute): mock_execute.side_effect = self._mock_manager package = 'safecopy.tgz' self.sw.put = MagicMock() with patch('jnpr.junos.utils.sw.SW.local_md5', MagicMock(return_value='96a35ab371e1ca10408c3caecdbd8a67')): self.assertTrue(self.sw.safe_copy(package, progress=self._myprogress, cleanfs=True)) @patch('jnpr.junos.Device.execute') def test_sw_safe_install(self, mock_execute): mock_execute.side_effect = self._mock_manager package = 'install.tgz' self.sw.put = MagicMock() with patch('jnpr.junos.utils.sw.SW.local_md5', MagicMock(return_value='96a35ab371e1ca10408c3caecdbd8a67')): self.assertTrue( self.sw.install( package, progress=self._myprogress, cleanfs=True)) @patch('jnpr.junos.utils.sw.SW.safe_copy') def test_sw_safe_install_copy_fail(self, mock_copy): mock_copy.return_value = False self.assertFalse(self.sw.install('file')) @patch('jnpr.junos.utils.sw.SW.validate') def test_sw_install_validate(self, mock_validate): mock_validate.return_value = False self.assertFalse(self.sw.install('file', validate=True, no_copy=True)) @patch(builtin_string + '.print') @patch('jnpr.junos.utils.sw.SW.pkgadd') def test_sw_install_multi_mx(self, mock_pkgadd, mock_print): mock_pkgadd.return_value = True self.sw._multi_RE = True self.sw._multi_MX = True self.assertTrue(self.sw.install('file', no_copy=True, progress=True)) @patch('jnpr.junos.utils.sw.SW.pkgadd') def test_sw_install_multi_vc(self, mock_pkgadd): mock_pkgadd.return_value = True self.sw._multi_RE = True self.sw._multi_VC = True self.sw._RE_list = ('version_RE0', 'version_RE1') self.assertTrue(self.sw.install('file', no_copy=True)) @patch('jnpr.junos.utils.sw.SW.pkgadd') def test_sw_install_mixed_vc(self, mock_pkgadd): mock_pkgadd.return_value = True self.sw._mixed_VC = True self.sw._RE_list = ('version_RE0', 'version_RE1') self.assertTrue(self.sw.install(pkg_set=['abc.tgz', 'pqr.tgz'], no_copy=True)) @patch('jnpr.junos.utils.sw.SW.pkgadd') def test_sw_install_multi_vc_mode_disabled(self, mock_pkgadd): mock_pkgadd.return_value = True self.dev._facts = {'2RE': True, 'domain': None, 'RE1': { 'status': 'OK', 'model': 'RE-EX8208', 'mastership_state': 'backup'}, 'ifd_style': 'SWITCH', 'version_RE1': '12.3R7.7', 'version_RE0': '12.3', 'serialnumber': 'XXXXXX', 'fqdn': 'XXXXXX', 'RE0': {'status': 'OK', 'model': 'RE-EX8208', 'mastership_state': 'master'}, 'switch_style': 'VLAN', 'version': '12.3R5-S3.1', 'master': 'RE0', 'hostname': 'XXXXXX', 'HOME': '/var/home/sn', 'vc_mode': 'Disabled', 'model': 'EX8208', 'vc_capable': True, 'personality': 'SWITCH'} sw = self.get_sw() sw.install(package='abc.tgz', no_copy=True) self.assertFalse(sw._multi_VC) calls = [call('/var/tmp/abc.tgz', dev_timeout=1800, re0=True), call('/var/tmp/abc.tgz', dev_timeout=1800, re1=True)] mock_pkgadd.assert_has_calls(calls) @patch('jnpr.junos.utils.sw.SW.pkgadd') def test_sw_install_mixed_vc_with_copy(self, mock_pkgadd): mock_pkgadd.return_value = True self.sw._mixed_VC = True self.sw.put = MagicMock() self.sw.remote_checksum = MagicMock( return_value='d41d8cd98f00b204e9800998ecf8427e') self.sw._RE_list = ('version_RE0', 'version_RE1') with patch('jnpr.junos.utils.sw.SW.local_md5', MagicMock(return_value='d41d8cd98f00b204e9800998ecf8427e')): self.assertTrue( self.sw.install( pkg_set=[ 'install.tgz', 'install.tgz'], cleanfs=False)) @patch('jnpr.junos.utils.sw.SW.pkgadd') def test_sw_install_mixed_vc_safe_copy_false(self, mock_pkgadd): mock_pkgadd.return_value = True self.sw._mixed_VC = True self.sw.safe_copy = MagicMock(return_value=False) self.sw.remote_checksum = MagicMock( return_value='d41d8cd98f00b204e9800998ecf8427e') self.sw._RE_list = ('version_RE0', 'version_RE1') with patch('jnpr.junos.utils.sw.SW.local_md5', MagicMock(return_value='d41d8cd98f00b204e9800998ecf8427e')): self.assertFalse( self.sw.install( pkg_set=[ 'install.tgz', 'install.tgz'], cleanfs=False)) @patch('jnpr.junos.utils.sw.SW.pkgadd') def test_sw_install_mixed_vc_ValueError(self, mock_pkgadd): mock_pkgadd.return_value = True self.sw._mixed_VC = True self.sw.remote_checksum = MagicMock( return_value='d41d8cd98f00b204e9800998ecf8427e') self.sw._RE_list = ('version_RE0', 'version_RE1') with patch('jnpr.junos.utils.sw.SW.local_md5', MagicMock(return_value='d41d8cd98f00b204e9800998ecf8427e')): self.assertRaises( ValueError, self.sw.install, pkg_set='install.tgz', cleanfs=False) @patch('jnpr.junos.utils.sw.SW.pkgadd') def test_sw_install_mixed_vc_TypeError(self, mock_pkgadd): self.assertRaises(TypeError, self.sw.install, cleanfs=False) @patch('jnpr.junos.Device.execute') def test_sw_install_kwargs_force_host(self, mock_execute): self.sw.install('file', no_copy=True, force_host=True) rpc = [ '<request-package-add><force-host/><no-validate/><re1/><package-name>/var/tmp/file</package-name></request-package-add>', '<request-package-add><package-name>/var/tmp/file</package-name><no-validate/><force-host/><re1/></request-package-add>', '<request-package-add><package-name>/var/tmp/file</package-name><no-validate/><re1/><force-host/></request-package-add>', '<request-package-add><force-host/><no-validate/><package-name>/var/tmp/file</package-name><re1/></request-package-add>', '<request-package-add><force-host/><re1/><no-validate/><package-name>/var/tmp/file</package-name></request-package-add>', '<request-package-add><no-validate/><re1/><package-name>/var/tmp/file</package-name><force-host/></request-package-add>', '<request-package-add><no-validate/><package-name>/var/tmp/file</package-name><force-host/><re1/></request-package-add>', '<request-package-add><force-host/><package-name>/var/tmp/file</package-name><no-validate/><re1/></request-package-add>', '<request-package-add><re1/><no-validate/><package-name>/var/tmp/file</package-name><force-host/></request-package-add>', '<request-package-add><re1/><force-host/><package-name>/var/tmp/file</package-name><no-validate/></request-package-add>', '<request-package-add><re1/><package-name>/var/tmp/file</package-name><force-host/><no-validate/></request-package-add>', '<request-package-add><re1/><force-host/><no-validate/><package-name>/var/tmp/file</package-name></request-package-add>', '<request-package-add><no-validate/><force-host/><re1/><package-name>/var/tmp/file</package-name></request-package-add>', '<request-package-add><package-name>/var/tmp/file</package-name><force-host/><no-validate/><re1/></request-package-add>', '<request-package-add><no-validate/><re1/><force-host/><package-name>/var/tmp/file</package-name></request-package-add>', '<request-package-add><package-name>/var/tmp/file</package-name><force-host/><re1/><no-validate/></request-package-add>', '<request-package-add><no-validate/><force-host/><package-name>/var/tmp/file</package-name><re1/></request-package-add>', '<request-package-add><force-host/><no-validate/><package-name>/var/tmp/file</package-name></request-package-add>', '<request-package-add><force-host/><package-name>/var/tmp/file</package-name><no-validate/></request-package-add>', '<request-package-add><package-name>/var/tmp/file</package-name><no-validate/><force-host/></request-package-add>', '<request-package-add><no-validate/><force-host/><package-name>/var/tmp/file</package-name></request-package-add>', '<request-package-add><no-validate/><package-name>/var/tmp/file</package-name><force-host/></request-package-add>', '<request-package-add><package-name>/var/tmp/file</package-name><force-host/><no-validate/></request-package-add>', '<request-package-add><package-name>/var/tmp/file</package-name><re1/><no-validate/><force-host/></request-package-add>', '<request-package-add><package-name>/var/tmp/file</package-name><re1/><force-host/><no-validate/></request-package-add>', '<request-package-add><force-host/><package-name>/var/tmp/file</package-name><re1/><no-validate/></request-package-add>', '<request-package-add><re1/><package-name>/var/tmp/file</package-name><no-validate/><force-host/></request-package-add>', '<request-package-add><no-validate/><package-name>/var/tmp/file</package-name><re1/><force-host/></request-package-add>', '<request-package-add><re1/><no-validate/><force-host/><package-name>/var/tmp/file</package-name></request-package-add>', '<request-package-add><force-host/><re1/><package-name>/var/tmp/file</package-name><no-validate/></request-package-add>'] self.assertTrue(etree.tostring( mock_execute.call_args[0][0]).decode('utf-8') in rpc) @patch('jnpr.junos.Device.execute') def test_sw_rollback(self, mock_execute): rsp = '<rpc-reply><output>junos-vsrx-12.1X46-D30.2-domestic will become active at next reboot</output></rpc-reply>' mock_execute.side_effect = etree.XML(rsp) msg = 'junos-vsrx-12.1X46-D30.2-domestic will become active at next reboot' self.assertEqual(self.sw.rollback(), msg) @patch('jnpr.junos.Device.execute') def test_sw_rollback_multi(self, mock_execute): mock_execute.side_effect = self._mock_manager msg = {'fpc1': "Junos version 'D10.2' will become active at next reboot", 'fpc0': 'JUNOS version "D10.2" will become active at next reboot'} self.assertEqual(eval(self.sw.rollback()), msg) @patch('jnpr.junos.Device.execute') def test_sw_rollback_multi_exception(self, mock_execute): fname = 'request-package-rollback-multi-error.xml' mock_execute.side_effect = self._read_file(fname) self.assertRaises(SwRollbackError, self.sw.rollback) @patch('jnpr.junos.Device.execute') def test_sw_rollback_exception(self, mock_execute): rsp = '<rpc-reply><output>WARNING: Cannot rollback, /packages/junos.old is not valid</output></rpc-reply>' mock_execute.side_effect = etree.XML(rsp) self.assertRaises(SwRollbackError, self.sw.rollback) def test_sw_inventory(self): self.sw.dev.rpc.file_list = \ MagicMock(side_effect=self._mock_manager) self.assertEqual( self.sw.inventory, { 'current': None, 'rollback': None}) @patch('jnpr.junos.Device.execute') def test_sw_reboot(self, mock_execute): mock_execute.side_effect = self._mock_manager self.sw._multi_MX = True self.assertTrue('Shutdown NOW' in self.sw.reboot()) @patch('jnpr.junos.Device.execute') def test_sw_reboot_at(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertTrue('Shutdown at' in self.sw.reboot(at='201407091815')) @patch('jnpr.junos.Device.execute') def test_sw_reboot_multi_re_vc(self, mock_execute): mock_execute.side_effect = self._mock_manager self.sw._multi_RE = True self.sw._multi_VC = False self.assertTrue('Shutdown NOW' in self.sw.reboot()) @patch('jnpr.junos.Device.execute') def test_sw_reboot_mixed_vc(self, mock_execute): mock_execute.side_effect = self._mock_manager self.sw._mixed_VC = True self.sw._multi_VC = True self.sw.reboot() self.assertTrue('all-members' in (etree.tostring(mock_execute.call_args[0][0]).decode('utf-8'))) @patch('jnpr.junos.Device.execute') def test_sw_reboot_mixed_vc_all_re_false(self, mock_execute): mock_execute.side_effect = self._mock_manager self.sw._mixed_VC = True self.sw._multi_VC = True self.sw.reboot(all_re=False) self.assertTrue('all-members' not in (etree.tostring(mock_execute.call_args[0][0]).decode('utf-8'))) @patch('jnpr.junos.Device.execute') def test_sw_reboot_exception(self, mock_execute): rsp = etree.XML('<rpc-reply><a>test</a></rpc-reply>') mock_execute.side_effect = RpcError(rsp=rsp) self.assertRaises(Exception, self.sw.reboot) @patch('jnpr.junos.Device.execute') def test_sw_reboot_exception_RpcTimeoutError(self, mock_execute): rsp = (self.dev, 'request-reboot', 60) mock_execute.side_effect = RpcTimeoutError(*rsp) self.assertRaises(Exception, self.sw.reboot) @patch('jnpr.junos.Device.execute') def test_sw_poweroff(self, mock_execute): mock_execute.side_effect = self._mock_manager self.sw._multi_MX = True self.assertTrue('Shutdown NOW' in self.sw.poweroff()) @patch('jnpr.junos.Device.execute') def test_sw_poweroff_exception(self, mock_execute): rsp = etree.XML('<rpc-reply><a>test</a></rpc-reply>') mock_execute.side_effect = RpcError(rsp=rsp) self.assertRaises(Exception, self.sw.poweroff) @patch('jnpr.junos.Device.execute') def test_sw_poweroff_multi_re_vc(self, mock_execute): mock_execute.side_effect = self._mock_manager self.sw._multi_RE = True self.sw._multi_VC = False self.assertTrue('Shutdown NOW' in self.sw.poweroff()) def _myprogress(self, dev, report): pass def _my_scp_progress(self, _path, _total, _xfrd): print (_path, _total, _xfrd) @contextmanager def capture(self, command, *args, **kwargs): out, sys.stdout = sys.stdout, StringIO() command(*args, **kwargs) sys.stdout.seek(0) yield sys.stdout.read() sys.stdout = out def _read_file(self, fname): from ncclient.xml_ import NCElement fpath = os.path.join(os.path.dirname(__file__), 'rpc-reply', fname) foo = open(fpath).read() rpc_reply = NCElement( foo, self.dev._conn._device_handler.transform_reply())._NCElement__doc[0] return rpc_reply def _mock_manager(self, *args, **kwargs): if kwargs: # Little hack for mocked execute if 'dev_timeout' in kwargs: if (args and args[0].findtext('package-name') == '/var/tmp/test_no_result.tgz'): return self._read_file(args[0].tag + '.no_result.xml') else: return self._read_file(args[0].tag + '.xml') if 'path' in kwargs: if kwargs['path'] == '/packages': return self._read_file('file-list_dir.xml') device_params = kwargs['device_params'] device_handler = make_device_handler(device_params) session = SSHSession(device_handler) return Manager(session, device_handler) elif args: if args[0].find('at') is not None: return self._read_file('request-reboot-at.xml') else: return self._read_file(args[0].tag + '.xml')
class TestDevice(unittest.TestCase): @patch("ncclient.manager.connect") def setUp(self, mock_connect): mock_connect.side_effect = self._mock_manager self.dev = Device(host="1.1.1.1", user="******", password="******", gather_facts=False) self.dev.open() @patch("ncclient.operations.session.CloseSession.request") def tearDown(self, mock_session): self.dev.close() def test_new_console_return(self): dev = Device( host="1.1.1.1", user="******", password="******", port=23, gather_facts=False, ) self.assertTrue(isinstance(dev, Console)) @patch("jnpr.junos.device.netconf_ssh") def test_device_ConnectAuthError(self, mock_manager): mock_manager.connect.side_effect = NcErrors.AuthenticationError self.assertRaises(EzErrors.ConnectAuthError, self.dev.open) @patch("jnpr.junos.device.netconf_ssh") def test_device_ConnectRefusedError(self, mock_manager): mock_manager.connect.side_effect = NcErrors.SSHError self.assertRaises(EzErrors.ConnectRefusedError, self.dev.open) @patch("jnpr.junos.device.netconf_ssh") @patch("jnpr.junos.device.datetime") def test_device_ConnectTimeoutError(self, mock_datetime, mock_manager): mock_manager.connect.side_effect = NcErrors.SSHError( "Could not open socket to 1.1.1.1:830") from datetime import timedelta, datetime currenttime = datetime.now() mock_datetime.datetime.now.side_effect = [ currenttime, currenttime + timedelta(minutes=4), ] self.assertRaises(EzErrors.ConnectTimeoutError, self.dev.open) @patch("jnpr.junos.device.netconf_ssh") @patch("jnpr.junos.device.datetime") def test_device_diff_err_message(self, mock_datetime, mock_manager): NcErrors.SSHError.message = "why are you trying :)" mock_manager.connect.side_effect = NcErrors.SSHError from datetime import timedelta, datetime currenttime = datetime.now() mock_datetime.datetime.now.side_effect = [ currenttime, currenttime + timedelta(minutes=4), ] self.assertRaises(EzErrors.ConnectError, self.dev.open) @patch("jnpr.junos.device.netconf_ssh") def test_device_ConnectUnknownHostError(self, mock_manager): import socket mock_manager.connect.side_effect = socket.gaierror self.assertRaises(EzErrors.ConnectUnknownHostError, self.dev.open) @patch("jnpr.junos.device.netconf_ssh") def test_device_other_error(self, mock_manager): mock_manager.connect.side_effect = TypeError self.assertRaises(EzErrors.ConnectError, self.dev.open) def test_device_probe_error(self): mock_probe = MagicMock() mock_probe.return_value = None self.dev.probe = mock_probe def fn(): self.dev.open(auto_probe=1) self.assertRaises(EzErrors.ProbeError, fn) def test_device_property_logfile_isinstance(self): mock = MagicMock() with patch(builtin_string + ".open", mock): if sys.version > "3": builtin_file = "io.TextIOWrapper" else: builtin_file = builtin_string + ".file" with patch(builtin_file, MagicMock): handle = open("filename", "r") self.dev.logfile = handle self.assertEqual(self.dev.logfile, handle) def test_device_host_mand_param(self): self.assertRaises(ValueError, Device, user="******", password="******", gather_facts=False) def test_device_property_logfile_close(self): self.dev._logfile = MagicMock() self.dev._logfile.close.return_value = 0 self.dev.logfile = None self.assertFalse(self.dev._logfile) def test_device_property_logfile_exception(self): try: self.dev.logfile = True except Exception as ex: self.assertEqual(type(ex), ValueError) @patch("jnpr.junos.Device.execute") def test_device_uptime(self, mock_execute): localdev = Device(host="1.1.1.1", user="******", password="******", gather_facts=False) mock_execute.side_effect = self._mock_manager self.assertEqual(localdev.uptime, 14234) def test_device_master_is_master(self): localdev = Device(host="1.1.1.1", user="******", password="******", gather_facts=False) localdev.facts._cache["current_re"] = [ "re1", "master", "node", "fwdd", "member", "pfem", ] self.assertEqual(localdev.master, True) def test_device_master_gnf_is_master(self): localdev = Device(host="1.1.1.1", user="******", password="******", gather_facts=False) localdev.facts._cache["current_re"] = ["gnf1-re0", "gnf1-master"] localdev.facts._cache["hostname_info"] = { "bsys-re0": "foo", "bsys-re1": "foo1", "gnf1-re0": "bar", "gnf1-re1": "bar1", } self.assertEqual(localdev.master, True) def test_device_master_is_backup(self): localdev = Device(host="1.1.1.1", user="******", password="******", gather_facts=False) localdev.facts._cache["current_re"] = ["re0", "backup"] self.assertEqual(localdev.master, False) def test_device_master_gnf_is_backup(self): localdev = Device(host="1.1.1.1", user="******", password="******", gather_facts=False) localdev.facts._cache["current_re"] = ["gnf1-re1", "gnf1-backup"] localdev.facts._cache["hostname_info"] = { "bsys-re0": "foo", "bsys-re1": "foo1", "gnf1-re0": "bar", "gnf1-re1": "bar1", } self.assertEqual(localdev.master, False) def test_device_master_is_re0_only(self): localdev = Device(host="1.1.1.1", user="******", password="******", gather_facts=False) localdev.facts._cache["2RE"] = False localdev.facts._cache["RE_hw_mi"] = False localdev.facts._cache["current_re"] = ["re0"] self.assertEqual(localdev.master, True) def test_device_master_is_multi_chassis_non_master1(self): localdev = Device(host="1.1.1.1", user="******", password="******", gather_facts=False) localdev.facts._cache["2RE"] = True localdev.facts._cache["current_re"] = [ "lcc1-re1", "member1-re1", "lcc1-backup", "member1-backup", ] self.assertEqual(localdev.master, False) def test_device_master_is_multi_chassis_non_master2(self): localdev = Device(host="1.1.1.1", user="******", password="******", gather_facts=False) localdev.facts._cache["2RE"] = True localdev.facts._cache["current_re"] = [ "lcc1-re0", "member1-re0", "lcc1-master", "member1-master", "member1", ] self.assertEqual(localdev.master, False) def test_device_master_is_none1(self): localdev = Device(host="1.1.1.1", user="******", password="******", gather_facts=False) localdev.facts._cache["current_re"] = None self.assertEqual(localdev.master, None) def test_device_master_is_none2(self): localdev = Device(host="1.1.1.1", user="******", password="******", gather_facts=False) localdev.facts._cache["2RE"] = True localdev.facts._cache["current_re"] = ["foo", "bar"] self.assertEqual(localdev.master, None) @patch("jnpr.junos.device.warnings") def test_device_master_is_old_facts(self, mock_warn): localdev = Device( host="1.1.1.1", user="******", password="******", fact_style="old", gather_facts=False, ) mock_warn.assert_has_calls([ call.warn( "fact-style old will be removed " "in a future release.", RuntimeWarning, ) ]) self.assertEqual(localdev.master, None) def test_device_master_setter(self): localdev = Device(host="1.1.1.1", user="******", password="******", gather_facts=False) with self.assertRaises(RuntimeError): localdev.master = "foo" def test_device_re_name_is_re0(self): localdev = Device(host="1.1.1.1", user="******", password="******", gather_facts=False) localdev.facts._cache["current_re"] = ["re0", "backup"] localdev.facts._cache["hostname_info"] = { "re0": "tapir", "re1": "tapir1" } self.assertEqual(localdev.re_name, "re0") def test_device_re_name_is_lcc_re1(self): localdev = Device(host="1.1.1.1", user="******", password="******", gather_facts=False) localdev.facts._cache["current_re"] = [ "lcc1-re1", "member1-re1", "lcc1-backup", "member1-backup", ] localdev.facts._cache["hostname_info"] = {"re0": "mj1"} self.assertEqual(localdev.re_name, "lcc1-re1") def test_device_re_name_is_re0_only(self): localdev = Device(host="1.1.1.1", user="******", password="******", gather_facts=False) localdev.facts._cache["current_re"] = ["foo"] localdev.facts._cache["hostname_info"] = {"re0": "mj1"} self.assertEqual(localdev.re_name, "re0") def test_device_re_name_is_bsys_re0(self): localdev = Device(host="1.1.1.1", user="******", password="******", gather_facts=False) localdev.facts._cache["current_re"] = ["re0"] localdev.facts._cache["hostname_info"] = {"bsys-re0": "foo"} self.assertEqual(localdev.re_name, "bsys-re0") def test_device_re_name_is_none1(self): localdev = Device(host="1.1.1.1", user="******", password="******", gather_facts=False) localdev.facts._cache["current_re"] = None self.assertEqual(localdev.re_name, None) def test_device_re_name_is_none2(self): localdev = Device(host="1.1.1.1", user="******", password="******", gather_facts=False) localdev.facts._cache["current_re"] = [ "re1", "master", "node", "fwdd", "member", "pfem", ] localdev.facts._cache["hostname_info"] = None self.assertEqual(localdev.re_name, None) @patch("jnpr.junos.device.warnings") def test_device_re_name_is_old_facts(self, mock_warn): localdev = Device( host="1.1.1.1", user="******", password="******", fact_style="old", gather_facts=False, ) mock_warn.assert_has_calls([ call.warn( "fact-style old will be removed " "in a future release.", RuntimeWarning, ) ]) self.assertEqual(localdev.re_name, None) def test_device_re_name_setter(self): localdev = Device(host="1.1.1.1", user="******", password="******", gather_facts=False) with self.assertRaises(RuntimeError): localdev.re_name = "foo" def test_device_repr(self): localdev = Device(host="1.1.1.1", user="******", password="******", gather_facts=False) self.assertEqual(repr(localdev), "Device(1.1.1.1)") def test_device_local(self): Device.ON_JUNOS = True localdev = Device() self.assertEqual(localdev._hostname, "localhost") @patch("jnpr.junos.device.os") @patch(builtin_string + ".open") @patch("paramiko.config.SSHConfig.lookup") def test_device__sshconf_lkup(self, mock_paramiko, open_mock, os_mock): os_mock.path.exists.return_value = True self.dev._sshconf_lkup() mock_paramiko.assert_called_once_with("1.1.1.1") @patch("jnpr.junos.device.os") @patch(builtin_string + ".open") @patch("paramiko.config.SSHConfig.lookup") def test_device__sshconf_lkup_def(self, mock_paramiko, open_mock, os_mock): os_mock.path.exists.return_value = True self.dev._ssh_config = "/home/rsherman/.ssh/config" self.dev._sshconf_lkup() mock_paramiko.assert_called_once_with("1.1.1.1") @patch("paramiko.config.SSHConfig.lookup") def test_device__sshconf_lkup_sock_fd(self, mock_paramiko): self.dev2 = Device(sock_fd=6) self.dev2._sshconf_lkup() self.assertEqual(self.dev2._sshconf_lkup(), None) @patch("os.path.expanduser") def test_device__sshconf_lkup_path_not_exists(self, mock_path): mock_path.return_value = "/home/test" self.assertEqual(self.dev._sshconf_lkup(), None) @patch("ncclient.manager.connect") @patch("jnpr.junos.Device.execute") def test_device_open(self, mock_connect, mock_execute): with patch("jnpr.junos.utils.fs.FS.cat") as mock_cat: mock_cat.return_value = """ domain jls.net """ mock_connect.side_effect = self._mock_manager mock_execute.side_effect = self._mock_manager self.dev2 = Device(host="2.2.2.2", user="******", password="******") self.dev2.open() self.assertEqual(self.dev2.connected, True) @patch("ncclient.manager.connect") @patch("jnpr.junos.Device.execute") def test_device_outbound(self, mock_connect, mock_execute): with patch("jnpr.junos.utils.fs.FS.cat") as mock_cat: mock_cat.return_value = """ domain jls.net """ mock_connect.side_effect = self._mock_manager mock_execute.side_effect = self._mock_manager self.dev2 = Device(sock_fd=6, user="******", password="******") self.dev2.open() self.assertEqual(self.dev2.connected, True) @patch("jnpr.junos.Device.execute") def test_device_facts(self, mock_execute): with patch("jnpr.junos.utils.fs.FS.cat") as mock_cat: mock_execute.side_effect = self._mock_manager mock_cat.return_value = """ domain jls.net """ self.dev.facts_refresh() self.dev.facts._cache["current_re"] = ["re0"] assert self.dev.facts["version"] == facts["version"] @patch("jnpr.junos.Device.execute") @patch("jnpr.junos.factcache.warnings") def test_device_facts_error(self, mock_warnings, mock_execute): with patch("jnpr.junos.utils.fs.FS.cat") as mock_cat: mock_execute.side_effect = self._mock_manager mock_cat.side_effect = IOError("File cant be handled") self.dev.facts_refresh(warnings_on_failure=True) self.assertTrue(mock_warnings.warn.called) @patch("jnpr.junos.Device.execute") @patch("jnpr.junos.device.warnings") def test_device_facts_error_exception_on_error(self, mock_warnings, mock_execute): with patch("jnpr.junos.utils.fs.FS.cat") as mock_cat: mock_execute.side_effect = self._mock_manager mock_cat.side_effect = IOError("File cant be handled") self.assertRaises(IOError, self.dev.facts_refresh, exception_on_failure=True) @patch("jnpr.junos.Device.execute") @patch("jnpr.junos.device.warnings") def test_device_old_style_facts_error_exception_on_error( self, mock_warnings, mock_execute): self.dev._fact_style = "old" with patch("jnpr.junos.utils.fs.FS.cat") as mock_cat: mock_execute.side_effect = self._mock_manager mock_cat.side_effect = IOError("File cant be handled") self.assertRaises(IOError, self.dev.facts_refresh, exception_on_failure=True) def test_device_facts_refresh_unknown_fact_style(self): self.dev._fact_style = "bad" with self.assertRaises(RuntimeError): self.dev.facts_refresh() def test_device_facts_refresh_old_fact_style_with_keys(self): self.dev._fact_style = "old" with self.assertRaises(RuntimeError): self.dev.facts_refresh(keys="domain") def test_device_hostname(self): self.assertEqual(self.dev.hostname, "1.1.1.1") def test_device_user(self): self.assertEqual(self.dev.user, "test") def test_device_get_password(self): self.assertEqual(self.dev.password, None) def test_device_set_password(self): self.dev.password = "******" self.assertEqual(self.dev._auth_password, "secret") def test_device_get_timeout(self): self.assertEqual(self.dev.timeout, 30) def test_device_set_timeout(self): self.dev.timeout = 10 self.assertEqual(self.dev.timeout, 10) def test_device_set_timeout_string(self): self.dev.timeout = "10" self.assertEqual(self.dev.timeout, 10) def test_device_set_timeout_invalid_string_value(self): with self.assertRaises(RuntimeError): self.dev.timeout = "foo" def test_device_set_timeout_invalid_type(self): with self.assertRaises(RuntimeError): self.dev.timeout = [1, 2, 3, 4] def test_device_manages(self): self.assertEqual(self.dev.manages, [], "By default manages will be empty list") @patch("ncclient.manager.connect") @patch("jnpr.junos.Device.execute") def test_device_open_normalize(self, mock_connect, mock_execute): mock_connect.side_effect = self._mock_manager self.dev2 = Device(host="2.2.2.2", user="******", password="******") self.dev2.open(gather_facts=False, normalize=True) self.assertEqual(self.dev2.transform, self.dev2._norm_transform) def test_device_conn_None_transform(self): self.dev = Device(host="2.2.2.2", user="******", password="******") with self.assertRaises(EzErrors.ConnectError): self.dev.transform def test_device_set_facts_exception(self): try: self.dev.facts = "test" except RuntimeError as ex: self.assertEqual(RuntimeError, type(ex)) def test_device_ofacts_exception(self): with self.assertRaises(RuntimeError): ofacts = self.dev.ofacts def test_device_set_ofacts_exception(self): with self.assertRaises(RuntimeError): self.dev.ofacts = False @patch("jnpr.junos.Device.execute") def test_device_cli(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual( self.dev.cli("show cli directory", warning=False).tag, "cli") @patch("jnpr.junos.device.json.loads") def test_device_rpc_json_ex(self, mock_json_loads): self.dev.facts = facts self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) ex = ValueError("Extra data ") ex.message = "Extra data " # for py3 as we dont have message thr mock_json_loads.side_effect = [ ex, self._mock_manager( etree.fromstring('<get-route-information format="json"/>')), ] self.dev.rpc.get_route_information({"format": "json"}) self.assertEqual(mock_json_loads.call_count, 2) @patch("jnpr.junos.Device.execute") def test_device_cli_to_rpc_string(self, mock_execute): mock_execute.side_effect = self._mock_manager data = self.dev.cli_to_rpc_string("show system uptime") self.assertEqual("rpc.get_system_uptime_information()", data) @patch("jnpr.junos.Device.execute") def test_device_cli_to_rpc_string_strip_pipes(self, mock_execute): mock_execute.side_effect = self._mock_manager data = self.dev.cli_to_rpc_string( "show system uptime | match foo | count") self.assertEqual("rpc.get_system_uptime_information()", data) @patch("jnpr.junos.Device.execute") def test_device_cli_to_rpc_string_complex(self, mock_execute): mock_execute.side_effect = self._mock_manager data = self.dev.cli_to_rpc_string( "show interfaces ge-0/0/0.0 routing-instance all media") self.assertEqual( "rpc.get_interface_information(" "routing_instance='all', media=True, " "interface_name='ge-0/0/0.0')", data, ) @patch("jnpr.junos.Device.execute") def test_device_cli_to_rpc_string_invalid(self, mock_execute): mock_execute.side_effect = self._mock_manager data = self.dev.cli_to_rpc_string("foo") self.assertEqual(None, data) @patch("jnpr.junos.Device.execute") def test_device_cli_format_json(self, mock_execute): mock_execute.side_effect = self._mock_manager data = self.dev.cli("show interface terse", warning=False, format="json") self.assertEqual(type(data), dict) self.assertEqual( data["interface-information"][0]["physical-interface"][0] ["oper-status"][0]["data"], "up", ) @patch("jnpr.junos.Device.execute") def test_device_cli_conf_info(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertTrue( "ge-0/0/0" in self.dev.cli("show configuration", warning=False)) @patch("jnpr.junos.Device.execute") def test_device_cli_output(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertTrue( "Alarm" in self.dev.cli("show system alarms", warning=False)) @patch("jnpr.junos.Device.execute") @patch("jnpr.junos.device.warnings") def test_device_cli_output_warning(self, mock_warnings, mock_execute): mock_execute.side_effect = self._mock_manager data = self.dev.cli( "show interfaces ge-0/0/0.0 routing-instance " "all media", format="xml") ip = data.findtext('logical-interface[name="ge-0/0/0.0"]/' 'address-family[address-family-name="inet"]/' "interface-address/ifa-local") self.assertTrue("192.168.100.1" in ip) self.assertTrue(mock_warnings.warn.called) rpc_string = ("rpc.get_interface_information(routing_instance='all', " "media=True, interface_name='ge-0/0/0.0')") self.assertIn(rpc_string, mock_warnings.warn.call_args[0][0]) def test_device_cli_blank_output(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertEqual( "", self.dev.cli("show configuration interfaces", warning=False)) def test_device_cli_rpc_reply_with_message(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertEqual( "\nprotocol: operation-failed\nerror: device asdf not found\n", self.dev.cli("show interfaces terse asdf", warning=False), ) @patch("jnpr.junos.Device.execute") def test_device_cli_rpc(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual( self.dev.cli("show system uptime| display xml rpc", warning=False).tag, "get-system-uptime-information", ) def test_device_cli_connection_exception(self): self.dev.connected = False self.assertRaises(EzErrors.ConnectClosedError, self.dev.cli, "foo") @patch("jnpr.junos.Device.execute") def test_device_cli_rpc_exception(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertRaises(EzErrors.RpcError, self.dev.cli, "foo") def test_device_cli_timeout_exception(self): self.dev._conn.rpc = MagicMock(side_effect=TimeoutExpiredError) self.assertRaises(EzErrors.RpcTimeoutError, self.dev.cli, "foo") @patch("jnpr.junos.device.warnings") def test_device_cli_unknown_exception(self, mock_warnings): class MyException(Exception): pass self.dev._conn.rpc = MagicMock(side_effect=MyException) self.assertRaises(MyException, self.dev.cli, "foo") @patch("jnpr.junos.Device.execute") def test_device_display_xml_rpc(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual( self.dev.display_xml_rpc("show system uptime").tag, "get-system-uptime-information", ) @patch("jnpr.junos.Device.execute") def test_device_display_xml_rpc_text(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertIn( "<get-system-uptime-information>", self.dev.display_xml_rpc("show system uptime", format="text"), ) @patch("jnpr.junos.Device.execute") def test_device_display_xml_exception(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual( self.dev.display_xml_rpc("show foo"), "invalid command: show foo| display xml rpc", ) def test_device_execute(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertEqual( self.dev.execute("<get-system-core-dumps/>").tag, "directory-list") def test_device_execute_topy(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertEqual( self.dev.execute("<get-system-core-dumps/>", to_py=self._do_nothing), "Nothing", ) # This test is for the commented out rpc-error code # def test_device_execute_exception(self): # self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) # self.assertRaises(RpcError, self.dev.execute, # '<load-configuration-error/>') @patch("jnpr.junos.device.warnings") def test_device_execute_unknown_exception(self, mock_warnings): class MyException(Exception): pass self.dev._conn.rpc = MagicMock(side_effect=MyException) self.assertRaises(MyException, self.dev.execute, "<get-software-information/>") def test_device_execute_rpc_error(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertRaises(RpcError, self.dev.rpc.get_rpc_error) @unittest.skipIf(sys.platform == "win32", "will work for windows in coming days") def test_device_execute_permission_error(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertRaises(EzErrors.PermissionError, self.dev.rpc.get_permission_denied) def test_device_execute_index_error(self): self.dev._conn.rpc = MagicMock(side_effect=self._mock_manager) self.assertTrue(self.dev.rpc.get_index_error()) def test_device_execute_ValueError(self): self.assertRaises(ValueError, self.dev.execute, None) def test_device_execute_unopened(self): self.dev.connected = False self.assertRaises(EzErrors.ConnectClosedError, self.dev.execute, None) def test_device_execute_timeout(self): self.dev._conn.rpc = MagicMock(side_effect=TimeoutExpiredError) self.assertRaises(EzErrors.RpcTimeoutError, self.dev.rpc.get_rpc_timeout) def test_device_execute_closed(self): self.dev._conn.rpc = MagicMock(side_effect=NcErrors.TransportError) self.assertRaises(EzErrors.ConnectClosedError, self.dev.rpc.get_rpc_close) self.assertFalse(self.dev.connected) def test_device_rpcmeta(self): self.assertEqual(self.dev.rpc.get_software_information.__doc__, "get-software-information") def test_device_probe_timeout_zero(self): with patch("jnpr.junos.device.socket"): self.assertFalse(self.dev.probe(0)) def test_device_probe_timeout_gt_zero(self): with patch("jnpr.junos.device.socket"): self.assertTrue( self.dev.probe(1), "probe fn is not working for" " timeout greater than zero", ) def test_device_probe_timeout_exception(self): with patch("jnpr.junos.device.socket") as mock_socket: with patch("jnpr.junos.device.time.sleep") as mock_time: mock_socket.socket.return_value.close.side_effect = RuntimeError mock_time.return_value = None self.assertFalse(self.dev.probe(0.01)) def test_device_bind_varg(self): self.dev.bind() mock = MagicMock() mock.__name__ = "magic_mock" self.dev.bind(mock) self.assertEqual(self.dev.magic_mock.__name__, "magic_mock") def test_device_bind_kvarg(self): self.dev.bind() mock = MagicMock() mock.return_value = "Test" self.dev.bind(kw=mock) self.assertEqual(self.dev.kw, "Test") def test_device_bind_varg_exception(self): def varg(): self.dev.bind() mock = MagicMock() mock.__name__ = "magic mock" # for *args self.dev.bind(mock) self.dev.bind(mock) self.assertRaises(ValueError, varg) def test_device_bind_kvarg_exception(self): def kve(): self.dev.bind() mock = MagicMock() mock.__name__ = "magic mock" # for **kwargs self.dev.bind(kw=mock) self.dev.bind(kw=mock) self.assertRaises(ValueError, kve) def test_device_template(self): # Try to load the template relative to module base try: template = self.dev.Template( "tests/unit/templates/config-example.xml") except: # Try to load the template relative to test base try: template = self.dev.Template("templates/config-example.xml") except: raise self.assertEqual( template.render({ "host_name": "1", "domain_name": "2" }), "system {\n host-name 1;\n domain-name 2;\n}", ) def test_device_close(self): def close_conn(): self.dev.connected = False self.dev.close = MagicMock(name="close") self.dev.close.side_effect = close_conn self.dev.close() self.assertEqual(self.dev.connected, False) @patch("ncclient.manager.connect") def test_device_context_manager(self, mock_connect): mock_connect.side_effect = self._mock_manager try: with Device(host="3.3.3.3", user="******", password="******", gather_facts=False) as dev: self.assertTrue(dev.connected) dev._conn = MagicMock(name="_conn") dev._conn.connected = True def close_conn(): dev.connected = False dev.close = MagicMock(name="close") dev.close.side_effect = close_conn raise RpcError except Exception as e: self.assertIsInstance(e, RpcError) self.assertFalse(dev.connected) def _read_file(self, fname): from ncclient.xml_ import NCElement fpath = os.path.join(os.path.dirname(__file__), "rpc-reply", fname) with open(fpath) as fp: foo = fp.read() if fname == "get-rpc-error.xml": # Raise ncclient exception for error raise RPCError(etree.XML(foo)) elif fname == "get-permission-denied.xml": # Raise ncclient exception for error raise RPCError(etree.XML(foo)) elif (fname == "get-index-error.xml" or fname == "get-system-core-dumps.xml" or fname == "load-configuration-error.xml" or fname == "show-configuration-interfaces.xml" or fname == "show-interfaces-terse-asdf.xml"): rpc_reply = NCElement( foo, self.dev._conn._device_handler.transform_reply()) elif fname == "show-configuration.xml" or fname == "show-system-alarms.xml": rpc_reply = NCElement( foo, self.dev._conn._device_handler.transform_reply() )._NCElement__doc elif fname == "show-interface-terse.json": rpc_reply = json.loads(foo) elif fname == "get-route-information.json": rpc_reply = NCElement( foo, self.dev._conn._device_handler.transform_reply()) else: rpc_reply = NCElement( foo, self.dev._conn._device_handler.transform_reply() )._NCElement__doc[0] return rpc_reply def _mock_manager(self, *args, **kwargs): if kwargs and "normalize" not in kwargs: device_params = kwargs["device_params"] device_handler = make_device_handler(device_params) session = SSHSession(device_handler) return Manager(session, device_handler) elif args: if args[0].tag == "command": if args[0].text == "show cli directory": return self._read_file("show-cli-directory.xml") if args[0].text == "show interface terse": return self._read_file("show-interface-terse.json") elif args[0].text == "show configuration": return self._read_file("show-configuration.xml") elif args[0].text == "show system alarms": return self._read_file("show-system-alarms.xml") elif args[0].text == "show system uptime| display xml rpc": return self._read_file("show-system-uptime-rpc.xml") elif args[0].text == "show configuration interfaces": return self._read_file("show-configuration-interfaces.xml") elif args[0].text == "show interfaces terse asdf": return self._read_file("show-interfaces-terse-asdf.xml") elif (args[0].text == "show interfaces ge-0/0/0.0 " "routing-instance all media"): return self._read_file( "show-interfaces-routing-instance-media.xml") elif (args[0].text == "show interfaces ge-0/0/0.0 " "routing-instance all media| display " "xml rpc"): return self._read_file( "show-interfaces-routing-instance-media-rpc.xml") else: raise RpcError else: if args[0].attrib.get("format") == "json": return self._read_file(args[0].tag + ".json") return self._read_file(args[0].tag + ".xml") def _do_nothing(self, *args, **kwargs): return "Nothing"
def connect(self, hostname, username, password, output_file, config_data=None, action=None, post_snap=None, **kwargs): """ connect to device and calls the function either to generate snapshots or compare them based on option given (--snap, --check, --snapcheck, --diff) :param hostname: ip/ hostname of device :param username: username of device :param password: password to connect to device :param snap_files: file name to store snapshot :return: if snap operation is performed then return true on success if snapcheck or check operation is performed then return test details """ res = None if config_data is None: config_data = self.main_file if 'local' in config_data: self.args.local = True if (self.args.snap is True or action is "snap") or ( (self.args.snapcheck is True or action is "snapcheck") and self.args.local is not True ): self.logger.info( colorama.Fore.BLUE + "Connecting to device %s ................", hostname, extra=self.log_detail) if username is None: if username is None: if sys.version < '3': username = raw_input("\nEnter User name: ") else: username = input("\nEnter User name: ") dev = Device( host=hostname, user=username, passwd=password, gather_facts=False, **kwargs) try: dev.open() except ConnectAuthError as ex: if password is None and action is None: password = getpass.getpass( "\nEnter Password for username <%s> : " % username) self.connect( hostname, username, password, output_file, config_data, action, post_snap, **kwargs) else: self.logger.error(colorama.Fore.RED + "\nERROR occurred %s" % str(ex), extra=self.log_detail) raise Exception(ex) except Exception as ex: self.logger.error(colorama.Fore.RED + "\nERROR occurred %s" % str(ex), extra=self.log_detail) raise Exception(ex) else: res = self.generate_rpc_reply( dev, output_file, hostname, config_data) self.snap_q.put(res) dev.close() if self.args.check is True or self.args.snapcheck is True or self.args.diff is True or action in [ "check", "snapcheck"]: if self.args.local is True and 'local' in config_data: output_file = config_data['local'] res = {} for local_snap in output_file: ret_obj = self.get_test( config_data, hostname, local_snap, post_snap, action) res[local_snap] = ret_obj else: res = self.get_test( config_data, hostname, output_file, post_snap, action) return res
# This section checks if the nodes have Controlled version of # software installed. If not, the script exits ############################################################### CHECKVER_N1 = JunVerTable(N1).get() CHECKVER_N2 = JunVerTable(N2).get() # Check if N1 has MACsec image if 'jcrypto-ex' not in CHECKVER_N1: print("\n\n**************************************************") print(data['N1_IP'] + " does not have MACsec software") print "Exiting Script" print "MACsec configuration aborted" print "**************************************************\n" lgr.info(data['N1_IP'] + " does not have MACsec software") lgr.info('Aborting MACsec Configuration') N1.close() N2.close() sys.exit() # Check if N2 has MACsec image if 'jcrypto-ex' not in CHECKVER_N2: print("\n\n**************************************************") print(data['N2_IP'] + " does not have MACsec software") print "Exiting Script" print "MACsec configuration aborted" print "**************************************************\n" lgr.info(data['N1_IP'] + " does not have MACsec software") lgr.info('Aborting MACsec Configuration') N1.close() N2.close() sys.exit()
class JunosDevice(BaseDevice): def __init__(self, host, username, password, *args, **kwargs): super(JunosDevice, self).__init__(host, username, password, *args, vendor="juniper", device_type="juniper_junos_netconf", **kwargs) self.native = JunosNativeDevice(*args, host=host, user=username, passwd=password, **kwargs) self.open() self.cu = JunosNativeConfig(self.native) self.fs = JunosNativeFS(self.native) self.sw = JunosNativdSW(self.native) def _file_copy_local_file_exists(self, filepath): return os.path.isfile(filepath) def _file_copy_local_md5(self, filepath, blocksize=2**20): if self._file_copy_local_file_exists(filepath): m = hashlib.md5() with open(filepath, "rb") as f: buf = f.read(blocksize) while buf: m.update(buf) buf = f.read(blocksize) return m.hexdigest() def _file_copy_remote_md5(self, filename): return self.fs.checksum(filename) def _get_interfaces(self): eth_ifaces = EthPortTable(self.native) eth_ifaces.get() loop_ifaces = LoopbackTable(self.native) loop_ifaces.get() ifaces = eth_ifaces.keys() ifaces.extend(loop_ifaces.keys()) return ifaces def _image_booted(self, image_name, **vendor_specifics): raise NotImplementedError def _uptime_components(self, uptime_full_string): match_days = re.search(r"(\d+) days?", uptime_full_string) match_hours = re.search(r"(\d+) hours?", uptime_full_string) match_minutes = re.search(r"(\d+) minutes?", uptime_full_string) match_seconds = re.search(r"(\d+) seconds?", uptime_full_string) days = int(match_days.group(1)) if match_days else 0 hours = int(match_hours.group(1)) if match_hours else 0 minutes = int(match_minutes.group(1)) if match_minutes else 0 seconds = int(match_seconds.group(1)) if match_seconds else 0 return days, hours, minutes, seconds def _uptime_to_seconds(self, uptime_full_string): days, hours, minutes, seconds = self._uptime_components( uptime_full_string) seconds += days * 24 * 60 * 60 seconds += hours * 60 * 60 seconds += minutes * 60 return seconds def _uptime_to_string(self, uptime_full_string): days, hours, minutes, seconds = self._uptime_components( uptime_full_string) return "%02d:%02d:%02d:%02d" % (days, hours, minutes, seconds) def _wait_for_device_reboot(self, timeout=3600): start = time.time() while time.time() - start < timeout: try: self.open() return except: pass raise RebootTimeoutError(hostname=self.facts["hostname"], wait_time=timeout) def backup_running_config(self, filename): with open(filename, "w") as f: f.write(self.running_config) def checkpoint(self, filename): self.save(filename) def close(self): if self.connected: self.native.close() def config(self, command, format="set"): try: self.cu.load(command, format=format) self.cu.commit() except ConfigLoadError as e: raise CommandError(command, e.message) def config_list(self, commands, format="set"): try: for command in commands: self.cu.load(command, format=format) self.cu.commit() except ConfigLoadError as e: raise CommandListError(commands, command, e.message) @property def connected(self): return self.native.connected @property def facts(self): if self._facts is None: native_facts = self.native.facts try: native_uptime_string = native_facts["RE0"]["up_time"] except (AttributeError, TypeError): native_uptime_string = None self._facts = { "hostname": native_facts.get("hostname"), "fqdn": native_facts.get("fqdn"), "model": native_facts.get("model"), "uptime": None, "uptime_string": None, "serial_number": native_facts.get("serialnumber"), "interfaces": self._get_interfaces(), "vendor": self.vendor, "version": native_facts.get("version"), } # TODO: Use a more reliable method for determining uptime (show system uptime) if native_uptime_string is not None: self._facts["uptime"] = self._uptime_to_seconds( native_uptime_string) self._facts["uptime_string"] = self._uptime_to_string( native_uptime_string) return self._facts def file_copy(self, src, dest=None, **kwargs): if not self.file_copy_remote_exists(src, dest, **kwargs): if dest is None: dest = os.path.basename(src) with SCP(self.native) as scp: scp.put(src, remote_path=dest) if not self.file_copy_remote_exists(src, dest, **kwargs): raise FileTransferError( message= "Attempted file copy, but could not validate file existed after transfer" ) # TODO: Make this an internal method since exposing file_copy should be sufficient def file_copy_remote_exists(self, src, dest=None, **kwargs): if dest is None: dest = os.path.basename(src) local_hash = self._file_copy_local_md5(src) remote_hash = self._file_copy_remote_md5(dest) if local_hash is not None and local_hash == remote_hash: return True return False def get_boot_options(self): return self.facts["os_version"] def install_os(self, image_name, **vendor_specifics): raise NotImplementedError def open(self): if not self.connected: self.native.open() def reboot(self, timer=0, confirm=False): if confirm: self.sw.reboot(in_min=timer) else: print("Need to confirm reboot with confirm=True") def rollback(self, filename): self.native.timeout = 60 temp_file = NamedTemporaryFile() with SCP(self.native) as scp: scp.get(filename, local_path=temp_file.name) self.cu.load(path=temp_file.name, format="text", overwrite=True) self.cu.commit() temp_file.close() self.native.timeout = 30 @property def running_config(self): return self.show("show config") def save(self, filename=None): if filename is None: self.cu.commit() return temp_file = NamedTemporaryFile() temp_file.write(self.show("show config")) temp_file.flush() with SCP(self.native) as scp: scp.put(temp_file.name, remote_path=filename) temp_file.close() return True def set_boot_options(self, sys): raise NotImplementedError def show(self, command, raw_text=True): if not raw_text: raise ValueError('Juniper only supports raw text output. \ Append " | display xml" to your commands for a structured string.' ) if not command.startswith("show"): raise CommandError( command, 'Juniper "show" commands must begin with "show".') return self.native.cli(command, warning=False) def show_list(self, commands, raw_text=True): responses = [] for command in commands: responses.append(self.show(command, raw_text=raw_text)) return responses @property def startup_config(self): return self.show("show config")
###################################### # Load SSL Proxy cert locally # - This is required for script updates (and other functions) ###################################### print(style.BOLD + "- Copying SSL Proxy Cert to OS Store..." + style.END) system("sudo cp " + export_name + " /usr/local/share/ca-certificates") sleep(3) print(style.BOLD + "- Rebuilding OS Certificate Store..." + style.END) system("sudo update-ca-certificates") sleep(3) ###################################### # Clean up ###################################### dev.close() ## Close Netconf session scp.close() ## Close secure copy session system("rm " + filename) ## Remove cert bundle print print("-------------------------------------------------------------------------------------") print(" SSL Forward Proxy Configuration is complete! --") print print(" -- NEXT STEPS:") print(" Lubuntu:") print(" 1. The vSRX CA cert (sdk-sslproxy-root.crt) is in the current directory. Add this file") print(" to the browsers certificate store & restart the browser before testing.") print print(" vSRX:") print(" 2. Load the partial SSLFP configuration (PARTIAL-SDK-vsrx1-SSLFP.conf)") print
from jnpr.jsnapy import SnapAdmin from pprint import pprint from jnpr.junos import Device config_data = """ tests: - test_file_snapcheck_bgp_states.yml """ js = SnapAdmin() my_devices_list = ["172.30.179.74", "172.30.179.73", "172.30.179.95"] for item in my_devices_list: print "opening a connection to a junos device using pyez" dev_obj = Device(host=item, user='******', password='******') dev_obj.open() print "auditing the device " + dev_obj.facts["hostname"] + " using jsnapy" snapchk = js.snapcheck(config_data, "snap", dev=dev_obj) dev_obj.close() for val in snapchk: print "Tested on", val.device print "Final result: ", val.result print "Total passed: ", val.no_passed print "Total failed:", val.no_failed
def collector(**kwargs): for host in kwargs["host_list"]: kpi_tags={} latest_datapoints={} # if ((db_schema == 1) and (not(use_hostname))): if (not(use_hostname)): latest_datapoints = get_latest_datapoints(host=host) logger.debug("Latest Datapoints are:") logger.debug(pformat(latest_datapoints)) # kpi_tags = get_host_base_tags(host=host) # Check host tag to identify what kind of connections will be used (ej junos / others / etc) if "non_junos_devices" in hosts[host].split(): pass # Reserved for future purposes else: # By default it's a junos device # We need to CATCH errors then print then but we need to continue with next host... connected = False logger.info('Connecting to host: %s', host) target_commands = get_target_commands(host) timestamp_tracking={} timestamp_tracking['collector_start'] = int(datetime.today().strftime('%s')) # Establish connection to hosts user, passwd, authMethod,authKey_file = get_credentials(host) if dynamic_args['test']: #Open an emulated Junos device instead of connecting to the real one _rpc_reply_dict = rpc_reply_dict() _rpc_reply_dict['dir'] = BASE_DIR_INPUT jdev = mocked_device(_rpc_reply_dict) # First collect all kpi in datapoints {} then at the end we insert them into DB (performance improvement) connected = True else: if authMethod in "key": jdev = Device(user=user, host=host, ssh_private_key_file=authKey_file, gather_facts=False, auto_probe=True, port=22) elif authMethod in "enc_key": jdev = Device(user=user, host=host, ssh_private_key_file=authKey_file, password=passwd, gather_facts=False, auto_probe=True, port=22) else: # Default is jdev = Device(user=user, host=host, password=passwd, gather_facts=False, auto_probe=True, port=22) for i in range(1, max_connection_retries+1): try: jdev.open() jdev.timeout = default_junos_rpc_timeout connected = True break except Exception, e: if i < max_connection_retries: logger.error('[%s]: Connection failed %s time(s), retrying....', host, i) time.sleep(1) continue else: logging.exception(e) connected = False # Notify about the specific problem with the host BUT we need to continue with our list # First collect all kpi in datapoints {} then at the end we insert them into DB (performance improvement) if connected: datapoints = [] # By default execute show version in order to get version and platform as default tags for all kpi related to this host kpi_tags = {} target_command = 'show version | display xml' version_xpath = "//package-information/comment" product_model_xpath = "//product-model" logger.info('[%s]: Executing command: %s', host, target_command) result = execute_command(jdev,target_command) if result: logger.debug('[%s]: Parsing command: %s', host, target_command) xml_data = etree.fromstring(result) value_tmp = xml_data.xpath(version_xpath)[0].text.strip() version = re.search('\[(.*?)\]$', value_tmp) if version: kpi_tags['version'] = version.group(1) else: kpi_tags['version'] = 'unknown' value_tmp = xml_data.xpath(product_model_xpath)[0].text.strip() kpi_tags['product-model'] = convert_variable_type(value_tmp) ## Based on parameter defined in config file if use_hostname: hostname_xpth = "//host-name" hostname_tmp = xml_data.xpath(hostname_xpth)[0].text.strip() hostname = convert_variable_type(hostname_tmp) logger.info('[%s]: Host will now be referenced as : %s', host, hostname) host = hostname # if (db_schema == 1): # latest_datapoints = get_latest_datapoints(host=host) # logger.info("Latest Datapoints are:") # logger.info(pformat(latest_datapoints)) latest_datapoints = get_latest_datapoints(host=host) logger.debug("Latest Datapoints are:") logger.debug(pformat(latest_datapoints)) else: logger.info('[%s]: Host will be referenced as : %s', host, host) kpi_tags['device']=host kpi_tags['kpi']="base-info" match={} match["variable-name"]="base-info" # We'll add a dummy kpi in oder to have at least one fixed kpi with version/platform data. get_metadata_and_add_datapoint(datapoints=datapoints,match=match,value_tmp=value_tmp,latest_datapoints=latest_datapoints,host=host,kpi_tags=kpi_tags) # Now we have all hosts tags that all host kpis will inherit # For each target_command execute it, parse it, and insert values into DB timestamp_tracking['collector_cli_start'] = int(datetime.today().strftime('%s')) for target_command in target_commands: logger.info('[%s]: Executing command: %s', host, target_command) # Execute rpc/command on host and get result result = execute_command(jdev,target_command) if result: logger.debug('[%s]: Parsing command: %s', host, target_command) parse_result(host,target_command,result,datapoints,latest_datapoints,kpi_tags) time.sleep(delay_between_commands) try: jdev.close() time.sleep(0.5) except Exception, e: print "ERROR: Something wrong happens when closing the connection with the device" logging.exception(e) timestamp_tracking['collector_cli_ends'] = int(datetime.today().strftime('%s')) logger.info('[%s]: timestamp_tracking - CLI collection %s', host, timestamp_tracking['collector_cli_ends']-timestamp_tracking['collector_cli_start']) timestamp_tracking['collector_ends'] = int(datetime.today().strftime('%s')) # Add open-nti internal kpi collection_time = timestamp_tracking['collector_ends']-timestamp_tracking['collector_start'] #kpi_tags['device']=host kpi_tags['stats']="collection-time" match={} match["variable-name"]="open-nti-stats" value_tmp =collection_time # We'll add a dummy kpi in oder to have at least one fixed kpi with version/platform data. get_metadata_and_add_datapoint(datapoints=datapoints,match=match,value_tmp=value_tmp,latest_datapoints=latest_datapoints,host=host,kpi_tags=kpi_tags) #kpi_tags['device']=host kpi_tags['stats']="collection-successful" match={} match["variable-name"]="open-nti-stats" value_tmp = 1 # We'll add a dummy kpi in oder to have at least one fixed kpi with version/platform data. get_metadata_and_add_datapoint(datapoints=datapoints,match=match,value_tmp=value_tmp,latest_datapoints=latest_datapoints,host=host,kpi_tags=kpi_tags) if datapoints: # Only insert datapoints if there is any :) insert_datapoints(datapoints) logger.info('[%s]: timestamp_tracking - total collection %s', host, collection_time) else: logger.error('[%s]: Skipping host due connectivity issue', host) datapoints = [] latest_datapoints = get_latest_datapoints(host=host) # By default execute show version in order to get version and platform as default tags for all kpi related to this host kpi_tags['device']=host kpi_tags['stats']="collection-failure" match={} match["variable-name"]="open-nti-stats" value_tmp = 1 # We'll add a dummy kpi in oder to have at least one fixed kpi with version/platform data. get_metadata_and_add_datapoint(datapoints=datapoints,match=match,value_tmp=value_tmp,latest_datapoints=latest_datapoints,host=host,kpi_tags=kpi_tags) if datapoints: # Only insert datapoints if there is any :) insert_datapoints(datapoints)
def update_pass(self, hosts, password): for host in hosts: try: utils.colour_print(f'Connecting to device: {host["host_name"]}') utils.line_break() dev = Device(host=host['ip'], user=host['username'], password=self.password) dev.open() except ConnectError as e: utils.error(f'Cannot connect to device: {e}') utils.colour_print(f'Configuration changes for device {host["host_name"]} unsuccessful!') return with Config(dev) as cu: try: cu.lock() except LockError: utils.error('Unable to lock configuration') utils.colour_print( f'Configuration changes for device {host["host_name"]} unsuccessful!', ) return try: cu.load( 'set system login user ' f'{host["username"]} authentication plain-text-password-value {password}') except ConfigLoadError as err: utils.error(f'Unable to load a (colour_cmd)set (colour_clear) command: {err}') utils.colour_print( f'Configuration changes for device {host["host_name"]} unsuccessful!', ) utils.colour_print('Unlocking the configuration') cu.unlock() return try: cu.commit(comment='Update by Rocky on ' + time.ctime()) except CommitError as err: utils.error(f'Unable to commit: {err}') utils.colour_print( f'Configuration changes for device {host["host_name"]}' 'successful but unable to commit!') try: utils.colour_print(f'Rolling back the configuration device {host["host_name"]}') cu.rollback(rb_id=1) utils.colour_print('Committing the configuration') cu.commit() except CommitError as err: utils.error(f'Unable to commit configuration: {err}') cu.unlock() return except RpcError as err: utils.error(f'Unable to rollback configuration changes: {err}') cu.unlock() return try: cu.unlock() except LockError as err: utils.error(f'Unable to unlock configuration: {err}') finally: dev.close() utils.colour_print( '(colour_clear)Password change for junos device {juniper_host_name[i]}' '(colour_success)successful(colour_clear)!') print()
class NetconfAction(ActionBase): """ Uses NetConf to execute the given template Can execute template as an op command or apply the template as a configuration template """ dev = None request_type = "apply_template" result_msg = "" def set_endpoint(self, endpoint): try: # create the required iterator from the endpoint_list self.dev = Device(user=endpoint["username"], password=endpoint["password"], host=endpoint["ip"], port=22) self.dev.open(gather_facts=False) except Exception as err: print "Could not open device %s!" % endpoint["ip"] self.result_msg = str(err) self.dev = None return def execute_template(self, template): """ switches based on request_type chosen from template configuration :param template: :return: String results from the endpoint netconf subsystem """ if self.dev is None: return self.result_msg if self.request_type == "apply_template": return self.apply_template(template) elif self.request_type == "execute_cheat_command": return self.execute_cheat_command(template) elif self.request_type == "assert_set_configuration": return self.assert_set_configuration(template) elif self.request_type == "assert_xpath_configuration": return self.assert_xpath_configuration(template) else: return self.execute_op_command(template) def execute_op_command(self, template): # Django is so very helpful in escaping EVERYTHING, undo the madness before passing to pyez s = self.unescape(template) try: results = self.dev.execute(s) except RpcError as e: print e return "Error executing command: %s" % str(e) finally: print "Closing device handle" self.dev.close() print etree.tostring(results, pretty_print=True) return etree.tostring(results, pretty_print=True) def execute_cheat_command(self, template): try: print "Executing cheat command" results = self.dev.cli(template) return self.format_results(results) finally: print "Closing device handle" self.dev.close() def assert_set_configuration(self, pattern): try: print "Checking set command regex" config = self.dev.cli('show configuration | display set') print config config_pattern = re.compile(pattern) results = "" for line in config.split('\n'): if config_pattern.match(line): results += line + "\n" if results != "": return results finally: print "Closing device handle" self.dev.close() def assert_xpath_configuration(self, xpath): print "Searching xpath" configuration_xml = self.dev.execute( "<get-configuration></get-configuration>") self.dev.close() print configuration_xml if configuration_xml.find(xpath): return "Configuration element: %s is present" % xpath return "not found" def apply_template(self, template): print self.dev # let's ensure we don't have silly dos style line breaks template = template.replace("\r\n", "\n") template = template.replace("\r", "\n") conf_string = template.strip() print conf_string if re.search(r"^<", conf_string): print "Found a encoded string" conf_string = self.unescape(conf_string) print conf_string # try to determine the format of our config_string config_format = "set" if re.search(r"^\s*<.*>$", conf_string, re.MULTILINE): print "found xml style config" config_format = "xml" elif re.search(r"^\s*(set|delete|replace|rename)\s", conf_string): print "found set style config" config_format = "set" elif re.search(r"^[a-z:-]*\s*\w+\s+{", conf_string, re.I) and re.search(r".*}\s*$", conf_string): print "found a text style config" config_format = "text" print "using format: " + config_format cu = Config(self.dev) try: cu.lock() except LockError as le: print "Could not lock database!" print str(le) self.dev.close() return "Failed to lock configuration database! %s" % str(le) try: print "loading config" cu.load(conf_string, format=config_format) except Exception as e: print "Could not load configuration" print str(e) try: cu.unlock() except UnlockError as ue: print str(ue) self.dev.close() return "Failed, could not load the configuration template. %s" % str( e) diff = cu.diff() print diff if diff is not None: try: cu.commit_check() print "Committing config!" cu.commit(comment="Commit via a_frame") except CommitError as ce: print "Could not load config! %s" % str(ce) cu.rollback() try: print "Unlocking database!" cu.unlock() except UnlockError as ue: print "Could not unlock database" print str(ue) print repr(ce) self.dev.close() return "Failed, commit check failed. %s" % str(ce) else: # nothing to commit print "Nothing to commit - no diff found" cu.unlock() self.dev.close() return "Nothing to commit!" try: print "Unlocking database!" cu.unlock() except UnlockError as ue: print "Could not unlock database" print str(ue) return "Committed, but could not unlock db" finally: print "Closing device handle" self.dev.close() return "Completed with diff: %s" % diff @staticmethod def format_results(results): """ detects string format (xml || json) and formats appropriately :param results: string from urlopen :return: formatted string output """ # print results try: if type(results) is str: results = etree.fromstring(results) print "found valid xml, formatting and returning" # use pretty_print if we have an xml document returned return etree.tostring(results, pretty_print=True) except XMLSyntaxError: pass except ValueError: pass except TypeError: pass # is the result valid json? try: json_string = json.loads(results) print "Found JSON results" return json.dumps(json_string, indent=4) except ValueError: pass except TypeError: pass print "no special formatting, returning" return results
from jnpr.junos import Device from jnpr_devices import srx2 from lxml import etree from pprint import pprint srx2_dev = Device(**srx2) srx2_dev.open(normalize=True) xml_out = srx2_dev.rpc.get_software_information() print(etree.tostring(xml_out, pretty_print=True).decode()) print("-----------------------") xml_out = srx2_dev.rpc.get_interface_information(terse=True) print(etree.tostring(xml_out, pretty_print=True).decode()) print("-----------------------") xml_out = srx2_dev.rpc.get_interface_information(terse=True, interface_name="fe-0/0/7") print(etree.tostring(xml_out, pretty_print=True).decode()) srx2_dev.close()
print "Diff : " print "#" * 30 print dev1.cu.diff() print "#" * 30 print "Commit Check : ", if dev1.cu.commit_check(): print Fore.GREEN + "OK" else: print Fore.RED + "Error" print Fore.YELLOW + "Do you commit? y/n" choice = raw_input().lower() if choice == "y": dev1.cu.commit() print "Commit candidate config : " + Fore.GREEN + "OK" else: dev1.cu.rollback() print "Rollback : " + Fore.GREEN + "OK" dev1.cu.unlock() dev1.close() dev1.open() print "Hostname : ", print Fore.YELLOW + dev1.facts["hostname"] dev1.close() print "##### Operation : End #####"
class NetconfCollector(): def __init__(self, host=None, address=None, credential={}, test=False, timeout=15, retry=3, use_hostname=True, parsers=None, context=None, collect_facts=True): self.__is_connected = False self.__is_test = test self.__use_hostname = use_hostname self.__timeout = timeout self.__retry = retry self.__collect_facts = collect_facts self.host = address self.hostname = host if context: self.context = {k: v for i in context for k, v in i.items()} else: self.context = None self.__credential = credential self.pyez = None self.facts = {} self.parsers = parsers def __add_datapoints(self): return True def connect(self): logger.info('Connecting to host: %s', self.hostname) ## TODO Cleanup # target_commands = get_target_commands(host) # timestamp_tracking={} # timestamp_tracking['collector_start'] = int(datetime.today().strftime('%s')) # Establish connection to hosts if self.__is_test: #Open an emulated Junos device instead of connecting to the real one # _rpc_reply_dict = rpc_reply_dict() # _rpc_reply_dict['dir'] = BASE_DIR_INPUT # # self.pyez = mocked_device(_rpc_reply_dict) # # First collect all kpi in datapoints {} then at the end we insert them into DB (performance improvement) self.__is_connected = True return self.__is_connected ## Define connection parameter if self.__credential['method'] in "key": self.pyez = Device( user=self.__credential['username'], host=self.host, ssh_private_key_file=self.__credential['key_file'], gather_facts=False, auto_probe=True, port=self.__credential['port']) elif self.__credential['method'] in "enc_key": self.pyez = Device( user=self.__credential['username'], host=self.host, ssh_private_key_file=self.__credential['key_file'], password=self.__credential['password'], gather_facts=False, auto_probe=True, port=self.__credential['port']) else: # Default is self.pyez = Device(user=self.__credential['username'], host=self.host, password=self.__credential['password'], gather_facts=False, auto_probe=True, port=self.__credential['port']) ## Try to open connection for i in range(1, self.__retry + 1): try: self.pyez.open() self.pyez.timeout = self.__timeout self.__is_connected = True break except Exception as e: if i < self.__retry: logger.error( '[%s]: Connection failed %s time(s), retrying....', self.hostname, i) time.sleep(1) continue else: logging.exception(e) self.__is_connected = False # Notify about the specific problem with the host BUT we need to continue with our list def collect_facts(self): if not self.__is_connected: return # Collect Facts about the device (if enabled) if self.__collect_facts: logger.info('[%s]: Collection Facts on device', self.hostname) self.pyez.facts_refresh() if self.pyez.facts['version']: self.facts['version'] = self.pyez.facts['version'] else: self.facts['version'] = 'unknown' self.facts['product-model'] = self.pyez.facts['model'] ## Based on parameter defined in config file if self.__use_hostname and self.pyez.facts[ 'hostname'] != self.hostname: hostname = self.pyez.facts['hostname'] logger.info('[%s]: Host will now be referenced as : %s', self.hostname, hostname) self.hostname = hostname else: logger.info('[%s]: Host will be referenced as : %s', self.hostname, self.hostname) self.facts['device'] = self.hostname return True def execute_command(self, command=None): try: logger.debug('[%s]: execute : %s', self.hostname, command) # the data returned is already in etree format command_result = self.pyez.rpc.cli(command, format="xml") except RpcError as err: rpc_error = err.__repr__() logger.error( "Error found on <%s> executing command: %s, error: %s:", self.hostname, command, rpc_error) return None return command_result def collect(self, command=None): # find the command to execute from the parser directly parser = self.parsers.get_parser_for(command) data = self.execute_command(parser['data']['parser']['command']) if data is None: return None if parser['data']['parser']['type'] == 'textfsm': data = etree.tostring(data) datapoints = self.parsers.parse(input=command, data=data) if datapoints is not None: measurement = self.parsers.get_measurement_name(input=command) timestamp = time.time_ns() for datapoint in datapoints: if not datapoint['fields']: continue if datapoint['measurement'] == None: datapoint['measurement'] = measurement datapoint['tags'].update(self.facts) if self.context: datapoint['tags'].update(self.context) datapoint['timestamp'] = timestamp yield datapoint else: logger.warn('No parser found for command > %s', command) return None def is_connected(self): return self.__is_connected def close(self): if self.__is_connected: self.pyez.close()