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(): #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("+++++++++++++++++++++++++++++++++++++++++++++++++")
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(): """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 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 main(): ''' For each of the SRX's interfaces, display: the operational state, packets-in, and packets-out. You will probably want to use EthPortTable for this. ''' pwd = getpass() try: a_device = Device(host='184.105.247.76', user='******', password=pwd) a_device.open() ports = EthPortTable(a_device) ports.get() print "\n"*2 for port in ports.keys(): print "#"*80 print "Operational state, Packets-in and Packets-out for Port {0} are :".format(port) print "#"*80 print "Operational state is : {0}".format(ports[port]['oper']) print "Packets-in are : {0}".format(ports[port]['rx_packets']) print " Packets-out are : {0}".format(ports[port]['tx_packets']) print "*"*80 print "\n"*2 print except: print print "Authentication Error" print
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()
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 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()
def main(): pwd = getpass() juniper = { "host": "50.76.53.27", "user": "******", "password": pwd } a_device = Device(**juniper) a_device.open() table = RouteTable(a_device) table.get() print print "Juniper SRX Routing Table" print for route, rtable in table.items(): rtable = dict(rtable) #print stats nexthop = rtable['nexthop'] age = rtable['age'] via = rtable['via'] protocol = rtable['protocol'] print route print " NextHop %s" % (nexthop) print " age %s" % (age) print " via %s" % (via) print " protocol %s" % (protocol) print
def get_connected_device(self, requester_name, device): LOGGER.debug('get_connected_device, request by [%s]', requester_name) time1 = time.time() dev_name = device.get('ip_address') password_encoded = self.config.get('password_encoded', False) if password_encoded: pwd = utils.decrypt_passwd(device.get('password')) else: pwd = device.get('password') try: dev = Device(host=dev_name, user=device.get('user'), password=pwd, port=device.get('port', 22), gather_facts=False, auto_probe=5) rpc_timeout = self.config.get('rpc_timeout', 1) * 60 dev.open() if dev.connected: dev.timeout = rpc_timeout return dev except Exception as e: LOGGER.error( 'connect, for device [%s, %s] failed', dev_name, e) finally: LOGGER.debug( 'connect, for device %s %d(s)', dev_name, (time.time() - time1)) return None
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()
def device(connect_string): """Return a connected device. This should be run as a context. Devices will be kept open and reused. If a device is already in use, entering the context will block until the device is ready. """ with device_lock: device, lock = device_list.get(connect_string, (None, None)) if device is None: # Parse the connect string mo = connect_re.match(connect_string) if not mo: raise ValueError("unparsable host string") args = {k: v for k, v in mo.groupdict().items() if v is not None} device = Device(**args) lock = threading.Lock() device_list[connect_string] = device, lock with lock: if not device.connected: device.open(gather_facts=False, attempts=3) device.timeout = 60 yield device
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()
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 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 getdevice(ip_address, username, password): """ Retrieve and return device class. """ device = Device(host=ip_address, user=username, password=password) device.open() return device
def connect(module): host = get_param(module, 'host') kwargs = { 'port': get_param(module, 'port') or 830, 'user': get_param(module, 'username') } if get_param(module, 'password'): kwargs['passwd'] = get_param(module, 'password') if get_param(module, 'ssh_keyfile'): kwargs['ssh_private_key_file'] = get_param(module, 'ssh_keyfile') kwargs['gather_facts'] = False try: device = Device(host, **kwargs) device.open() device.timeout = get_param(module, 'timeout') or 10 except ConnectError: exc = get_exception() module.fail_json('unable to connect to %s: %s' % (host, str(exc))) return device
def ConnectJuniper(): global dev print '\n\n' + "Establish connection to Juniper System..." + '\t\t\n', dev=Device(host='Insert_Device', user="******", password="******") dev.open()
def ConnectJuniper(jhost, juser, jpassword): global dev dev=Device(host=jhost, user=juser, password=jpassword) dev.open() print "Established connection to Juniper System..."
def mocked_device(rpc_reply_dict, mock_connect): """Juniper PyEZ Device Fixture""" def mock_manager(*args, **kwargs): if 'device_params' in kwargs: # open connection device_params = kwargs['device_params'] device_handler = make_device_handler(device_params) session = SSHSession(device_handler) return Manager(session, device_handler) elif args: # rpc request rpc_request = args[0].tag rpc_command = str(args[0].text) rpc_command = rpc_command.strip() rpc_command = rpc_command.replace(" ", "_") if rpc_request in rpc_reply_dict: xml = rpc_reply_dict[rpc_request] elif 'dir' in rpc_reply_dict: fname = os.path.join(rpc_reply_dict['dir'], 'rpc-reply', rpc_command, rpc_request + '.xml') with open(fname, 'r') as f: xml = f.read() else: _rpc_reply_dict['dir'] fname = os.path.join(os.path.dirname(__file__), 'rpc-reply', rpc_command, rpc_request + '.xml') with open(fname, 'r') as f: xml = f.read() rpc_reply = NCElement(xml, dev._conn._device_handler.transform_reply()) return rpc_reply mock_connect.side_effect = mock_manager dev = Device(host='1.1.1.1', user='******', gather_facts=False) dev.open() dev._conn.rpc = MagicMock(side_effect=mock_manager) dev.close = MagicMock() return dev
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 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(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 main(): ''' Connect to Juniper device using PyEZ. Display the routing table. ''' pwd = getpass() ip_addr = raw_input("Enter Juniper SRX IP: ") ip_addr = ip_addr.strip() juniper_srx = { "host": ip_addr, "user": "******", "password": pwd } print "\n\nConnecting to Juniper SRX...\n" a_device = Device(**juniper_srx) a_device.open() routes = RouteTable(a_device) routes.get() print "\nJuniper SRX Routing Table: " for a_route, route_attr in routes.items(): print "\n" + a_route for attr_desc, attr_value in route_attr: print " {} {}".format(attr_desc, attr_value) print "\n"
def test_ftp_open_erors(self, mock_connect, mock_ftpconnect): dev2 = Device(host='1.1.1.1', user="******", passwd="testpasswd", gather_facts=False) dev2.open() dev_ftp = jnpr.junos.utils.ftp.FTP(dev2) self.assertRaises(Exception, dev_ftp.open)
def connectToDevice(self): ''' :param dict deviceInfo: ip: ip address of the device username: device credential username :returns Device: Device, handle to device connection. ''' if self.device.managementIp == None or self.device.username == None: raise DeviceConnectFailed('Device: %s, ip: %s, username: %s' % (self.device.id, self.device.managementIp, self.device.username)) if self.device.encryptedPassword == None: raise DeviceConnectFailed('Device: %s, , ip: %s, password is None' % (self.device.id, self.device.managementIp)) try: deviceIp = self.device.managementIp.split('/')[0] devicePassword = self.device.getCleartextPassword() deviceConnection = DeviceConnection(host=deviceIp, user=self.device.username, password=devicePassword, port=22) deviceConnection.open() logger.debug('Connected to device: %s' % (self.device.managementIp)) self.deviceConnectionHandle = deviceConnection return deviceConnection except ConnectError as exc: logger.error('Device connection failure, %s' % (exc)) self.deviceConnectionHandle = None raise DeviceConnectFailed(self.device.managementIp, exc) except Exception as exc: logger.error('Unknown error, %s' % (exc)) logger.debug('StackTrace: %s' % (traceback.format_exc())) self.deviceConnectionHandle = None raise DeviceConnectFailed(self.device.managementIp, exc)
class TestSrxCluster(unittest.TestCase): @patch('ncclient.manager.connect') @patch('jnpr.junos.device.warnings') def setUp(self, mock_warnings, mock_connect): mock_connect.side_effect = self._mock_manager self.dev = Device(host='1.1.1.1', user='******', password='******', gather_facts=False, fact_style='old') self.dev.open() self.facts = {} @patch('jnpr.junos.Device.execute') def test_srx_cluster(self, mock_execute): mock_execute.side_effect = self._mock_manager self.facts['personality'] = 'SRX' self.facts['master'] = ['RE0'] srx_cluster(self.dev, self.facts) self.assertTrue(self.facts['srx_cluster']) @patch('jnpr.junos.device.warnings') def test_srx_cluster_none(self, mock_warnings): self.facts['personality'] = 'MX' self.assertEqual(srx_cluster(self.dev, self.facts), None) @patch('jnpr.junos.Device.execute') def test_srx_cluster_no_node(self, mock_execute): mock_execute.side_effect = self._mock_manager self.facts['personality'] = 'SRX' srx_cluster(self.dev, self.facts) self.assertTrue(self.facts['srx_cluster']) @patch('jnpr.junos.Device.execute') def test_srx_cluster_node(self, mock_execute): mock_execute.side_effect = self._mock_manager self.facts['personality'] = 'SRX' self.facts['master'] = ['RE1'] srx_cluster(self.dev, self.facts) self.assertTrue(self.facts['srx_cluster']) 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: device_params = kwargs['device_params'] device_handler = make_device_handler(device_params) session = SSHSession(device_handler) return Manager(session, device_handler) if args: return self._read_file(args[0].tag + '.xml')
def main(): ''' Connect to Juniper device using PyEZ. Display operational state and pkts_in, pkts_out for all of the interfaces. ''' #pwd = getpass() pwd = '88newclass' #ip_addr = raw_input("Enter Juniper SRX IP: ") ip_addr = '50.76.53.27' ip_addr = ip_addr.strip() juniper_srx = { "host": ip_addr, "user": "******", "password": pwd } print "\n\nConnecting to Juniper SRX...\n" a_device = Device(**juniper_srx) a_device.open() eth_ports = EthPortTable(a_device) eth_ports.get() print "{:>15} {:>12} {:>12} {:>12}".format("INTF", "OPER STATE", "IN PACKETS", "OUT PACKETS") for intf, eth_stats in eth_ports.items(): eth_stats = dict(eth_stats) oper_state = eth_stats['oper'] pkts_in = eth_stats['rx_packets'] pkts_out = eth_stats['tx_packets'] print "{:>15} {:>12} {:>12} {:>12}".format(intf, oper_state, pkts_in, pkts_out) print
class TestSwver(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.facts = {} self.facts['vc_capable'] = False def test_get_swver_vc(self): self.dev.rpc.cli = MagicMock() self.facts['vc_capable'] = True _get_swver(self.dev, self.facts) self.dev.rpc.cli.assert_called_with('show version all-members', format='xml') def test_get_swver_vc_capable_standalone(self): def raise_ex(*args): if args[0] == 'show version all-members': raise RpcError() self.dev.rpc.cli = MagicMock( side_effect=lambda *args, **kwargs: raise_ex(*args)) self.facts['vc_capable'] = True _get_swver(self.dev, self.facts) self.dev.rpc.cli.assert_called_with( 'show version invoke-on all-routing-engines', format='xml') @patch('jnpr.junos.Device.execute') def test_swver(self, mock_execute): mock_execute.side_effect = self._mock_manager self.facts['master'] = 'RE0' software_version(self.dev, self.facts) self.assertEqual(self.facts['version'], '12.3R6.6') @patch('jnpr.junos.Device.execute') def test_swver_f_master_list(self, mock_execute): mock_execute.side_effect = self._mock_manager self.facts['master'] = ['RE0', 'RE1'] software_version(self.dev, self.facts) self.assertEqual(self.facts['version'], '12.3R6.6') @patch('jnpr.junos.Device.execute') def test_swver_hostname_none(self, mock_execute): mock_execute.side_effect = self._mock_manager self.facts['master'] = 'RE5' self.facts['version_RE5'] = '15.3R6.6' software_version(self.dev, self.facts) self.assertEqual(self.facts['version'], '15.3R6.6') @patch('jnpr.junos.Device.execute') def test_swver_txp_master_list(self, mock_execute): mock_execute.side_effect = self._mock_manager self.facts['master'] = ['RE0', 'RE0', 'RE1', 'RE2', 'RE3'] self.facts['version_RE0-RE0'] = '14.2R4' software_version(self.dev, self.facts) self.assertEqual(self.facts['version'], '14.2R4') # --> JLS, there should always be a facts['master'] assigned. # @patch('jnpr.junos.Device.execute') # def test_swver_master_none(self, mock_execute): # mock_execute.side_effect = self._mock_manager # self.facts['master'] = None # software_version(self.dev, self.facts) # self.assertEqual(self.facts['version'], '12.3R6.6') @patch('jnpr.junos.Device.execute') @patch('jnpr.junos.facts.swver.re.findall') def test_swver_exception_handling(self, mock_re_findall, mock_execute): mock_execute.side_effect = self._mock_manager mock_re_findall.side_effect = IndexError self.facts['master'] = 'RE0' software_version(self.dev, self.facts) self.assertEqual(self.facts['version'], '0.0I0.0') 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: device_params = kwargs['device_params'] device_handler = make_device_handler(device_params) session = SSHSession(device_handler) return Manager(session, device_handler) if args: if 'version_RE0-RE0' in self.facts: return self._read_file(args[0].tag + '_RE0-RE0.xml') return self._read_file(args[0].tag + '.xml')
def get_data(router, options ): jdev = Device(host=router, user=options.username, password=options.password) jdev.open() data = BGPNeighborTableJNPR(jdev).get() return data
class JunosDevice(): """ JunosDevice Args: :host: string containing the host to connect to :username: string containing the username to authenticate with :password: string contining the password to authenticate with Examples: Basic device connection: .. code-block:: python from pyJunosManager import JunosDevice dev = JunosDevice(host="1.2.3.4",username="******",password="******") dev.open() print dev.get_facts() dev.close() """ def __init__(self, host="", username="", password=""): self.dev = Device(host=host, user=username, password=password) self.dev.bind(cu=Config) def open(self): """ Opens a NETCONF session to the specified Junos-based device Example: .. code-block:: python from pyJunosManager import JunosDevice //creates a connection to the Junos device dev = JunosDevice(host="1.2.3.4",username="******",password="******") dev.open() """ try: self.dev.open() except Exception as err: print err def close(self): """ Closes a NETCONF session to the specified device Example: .. code-block:: python from pyJunosManager import JunosDevice dev = JunosDevice(host="1.2.3.4",username="******",password="******") dev.open() dev.close() """ try: self.dev.close() except Exception as err: print err def get_facts(self): """ Returns the device facts as a Python dict Example: .. code-block:: python from pyJunosManager import JunosDevice import pprint dev = JunosDevice(host="1.2.3.4",username="******",password="******") dev.open() facts = dev.get_facts() dev.close() pprint facts """ return self.dev.facts def open_config(self, type="shared"): """ Opens the configuration of the currently connected device Args: :type: The type of configuration you want to open. Any string can be provided, however the standard supported options are: **exclusive**, **private**, and **shared**. The default mode is **shared**. Examples: .. code-block:: python #Open shared config from pyJunosManager import JunosDevice dev = JunosDevice(host="1.2.3.4",username="******",password="******") dev.open() dev.open_config() dev.close_config() dev.close() #Open private config from pyJunosManager import JunosDevice dev = JunosDevice(host="1.2.3.4",username="******",password="******") dev.open() dev.open_config("private") dev.close_config() dev.close() """ try: #attempt to open a configuration output = self.dev.rpc( "<open-configuration><{0}/></open-configuration>".format(type)) except Exception as err: #output an error if the configuration is not availble print err def close_config(self): """ Closes the exiting opened configuration Example: .. code-block:: python from pyJunosManager import JunosDevice dev = JunosDevice(host="1.2.3.4",username="******",password="******") dev.open() dev.open_config() dev.close_config() dev.close() """ try: self.dev.rpc.close_configuration() except Exception as err: print err def load_config_template(self, template, template_vars, type="text"): """ :template: A templated string using Jinja2 templates :template_vars: A dict containing the vars used in the :template: string :type: The type of configuration to load. The default is "text" or a standard Junos config block. Other options are: "set" for set style commands, "xml" for xml configs Uses standard `Jinja2`_ Templating. .. _`Jinja2`: http://jinja.pocoo.org/ Example: .. code-block:: python from pyJunosManager import JunosDevice config_template = "system { host-name {{ hostname }}; }" dev = JunosDevice(host="1.2.3.4",username="******",password="******") dev.open() dev.open_config() dev.load_config_template(config_template,hostname="foo") dev commit_and_quit() dev.close() """ new_template = Template(template) final_template = new_template.render(template_vars) try: output = self.dev.cu.load(final_template, format=type, merge=True) except Exception as err: print err def commit_config(self): """ Commits exiting configuration Example: .. code-block:: python from pyJunosManager import JunosDevice dev = JunosDevice(host="1.2.3.4",username="******",password="******") dev.open() dev.open_config() dev.commit_config() dev.close_config() dev.close() """ try: self.dev.rpc.commit_configuration() except Exception as err: print err def commit_and_quit(self): """ Commits and closes the currently open configration. Saves a step by not needing to manually close the config. Example: .. code-block:: python from pyJunosManager import JunosDevice dev = JunosDevice(host="1.2.3.4",username="******",password="******") dev.open() dev.load_config_template("system{ host-name {{ hostname }};}",hostname="foo") dev commit_and_quit() dev.close() """ try: self.dev.rpc.commit_configuration() self.close_config() except Exception as err: print err
#!/usr/bin/env python3 # Script to run RPC's using PyEZ. from jnpr.junos import Device from lxml import etree jdev = Device(host='192.168.122.10', user='******', passwd='junOSxp') #fitering filter = ''' <filter> <configuration xmlns="http://xml.juniper.net/xnm!!! <interfaces></interfaces> </configuration> </filter> ''' # Opens a connection with remote device jdev.open() # Run rpc #xml_rsp = jdev.rpc.get_software_information() print(etree.tostring(jdev.rpc.get_software_information())) print( etree.tostring( jdev.rpc.get_config( filter_xml='<configuration><interfaces/></configuration>'))) # Close the connection jdev.close()
import os from getpass import getpass from jnpr.junos import Device from pprint import pprint password = os.getenv("JNPR_PASSWORD") if password is None: password = getpass("Enter vMX password: "******"vmx1.lasthop.io", user="******", password=password) my_dev.open() print() print("device facts") pprint(my_dev.facts)
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_diff_exception(self): self.conf.rpc.get_configuration = MagicMock(side_effect=RpcError( rsp='ok')) self.assertRaises(RpcError, self.conf.diff) def test_config_diff_exception_severity_warning(self): rpc_xml = ''' <rpc-error> <error-severity>warning</error-severity> <error-info><bad-element>bgp</bad-element></error-info> <error-message>mgd: statement must contain additional statements</error-message> </rpc-error> ''' rsp = etree.XML(rpc_xml) self.conf.rpc.get_configuration = MagicMock(side_effect=RpcError( rsp=rsp)) self.assertEqual(self.conf.diff(), "Unable to parse diff from response!") def test_config_diff_exception_severity_warning_still_raise(self): rpc_xml = ''' <rpc-error> <error-severity>warning</error-severity> <error-info><bad-element>bgp</bad-element></error-info> <error-message>statement not found</error-message> </rpc-error> ''' rsp = etree.XML(rpc_xml) self.conf.rpc.get_configuration = MagicMock(side_effect=RpcError( rsp=rsp)) self.assertRaises(RpcError, self.conf.diff) 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') def test_config_load_with_format_json(self): self.conf.rpc.load_config = \ MagicMock(return_value=etree.fromstring("""<load-configuration-results> <ok/> </load-configuration-results>""")) op = self.conf.load('test.json', format='json') self.assertEqual(op.tag, 'load-configuration-results') self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'], 'json') @patch(builtin_string + '.open') def test_config_load_with_format_json_from_file_ext(self, mock_open): self.conf.rpc.load_config = \ MagicMock(return_value=etree.fromstring("""<load-configuration-results> <ok/> </load-configuration-results>""")) op = self.conf.load(path='test.json') self.assertEqual(op.tag, 'load-configuration-results') self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'], 'json') @patch(builtin_string + '.open') def test_config_load_update(self, mock_open): self.conf.rpc.load_config = \ MagicMock(return_value=etree.fromstring("""<load-configuration-results> <ok/> </load-configuration-results>""")) op = self.conf.load(path='test.conf', update=True) self.assertEqual(op.tag, 'load-configuration-results') self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'], 'text') def test_config_load_update_merge_overwrite(self): self.assertRaises(ValueError, self.conf.load, path='test.jnpr', update=True, merge=True, overwrite=True) @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_json(self): self.conf.rpc.load_config = MagicMock() conf = """{ "configuration" : { "system" : { "services" : { "telnet" : [null] } } } }""" self.conf.load(conf) self.assertEqual(self.conf.rpc.load_config.call_args[1]['format'], 'json') 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') @patch('jnpr.junos.utils.config.warnings') def test_config_mode_batch_open_configuration_ex(self, mock_warnings, 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') @patch('jnpr.junos.utils.config.warnings') def test_config_mode_private_open_configuration_ex(self, mock_warnings, 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 test__enter__private_exception_RpcTimeoutError(self): ex = RpcTimeoutError(self.dev, None, 10) self.conf.rpc.open_configuration = MagicMock(side_effect=ex) self.assertRaises(RpcTimeoutError, Config.__enter__, Config(self.dev, mode='private')) def test__enter__private_exception_RpcError(self): rpc_xml = """<rpc-error> <error-severity>error</error-severity> <error-message>syntax error</error-message> </rpc-error>""" rsp = etree.XML(rpc_xml) self.conf.rpc.open_configuration = \ MagicMock(side_effect=RpcError(rsp=rsp)) self.assertRaises(RpcError, Config.__enter__, Config(self.dev, mode='private')) def test__enter__dyanamic_exception_RpcError(self): rpc_xml = """<rpc-error> <error-severity>error</error-severity> <error-message>syntax error</error-message> </rpc-error>""" rsp = etree.XML(rpc_xml) self.conf.rpc.open_configuration = \ MagicMock(side_effect=RpcError(rsp=rsp)) self.assertRaises(RpcError, Config.__enter__, Config(self.dev, mode='dynamic')) def test__enter__batch_exception_RpcTimeoutError(self): ex = RpcTimeoutError(self.dev, None, 10) self.conf.rpc.open_configuration = MagicMock(side_effect=ex) self.assertRaises(RpcTimeoutError, Config.__enter__, Config(self.dev, mode='batch')) def test__enter__batch_exception_RpcError(self): rpc_xml = """<rpc-error> <error-severity>error</error-severity> <error-message>syntax error</error-message> </rpc-error>""" rsp = etree.XML(rpc_xml) self.conf.rpc.open_configuration = \ MagicMock(side_effect=RpcError(rsp=rsp)) self.assertRaises(RpcError, Config.__enter__, Config(self.dev, mode='batch')) def _read_file(self, fname): 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')
from jnpr.junos import Device from jnpr.junos.utils.config import Config #template variables are added to a dict or dictionary. A dict is simply a key/value store data structure my_variables = {"hostname":"JNPRConfig-ez","enc_password":"******","ssh_root_login":"******"} #now lets connect to the device, load the template, and commit the changes #first we instantiate an instance of the device junos_dev = Device(host='172.16.237.128', user='******', password='******' ) #We must bind an empty configuration to the device junos_dev.bind(cu=Config) #now we can connect to the device junos_dev.open() #lets go ahead and load the configuration. We are reading fromt he local directory and specifying the jnpr-config.conf file #the file exension specifies the config type of config stored in the file junos_dev.cu.load(template_path="./jnpr-config.conf",merge=True,template_vars=my_variables) #commit and close the config commit_result = junos_dev.cu.commit() #Show that the commit worked True means it worked, false means it failed print commit_result #lastly we close the connection to the device junos_dev.close()
from jnpr.junos import Device from lxml import etree dev1 = Device(host='192.168.34.16', user='******', password='******') dev1.open() cli = dev1.rpc.ping(host="192.168.35.1") print etree.tostring(cli) cli = dev1.rpc.traceroute(host="192.168.35.1") print etree.tostring(cli)
def changepassword(ip_address, u_name, pwd): print( 'The currently configured password is one of the commonly used ones.\nWe suggest you to change the password, otherwise it maybe compromised in the future' ) while True: b = input('Do you want to change the password for IP address: ' + ip_address + ' and Username: '******'? Y(yes), N (no): ') if b == 'y' or b == 'Y' or b == 'n' or b == 'N' or b == 'yes' or b == 'Yes': break else: print('Invalid input. Please try again') if b == 'y' or b == 'Y' or b == 'yes' or b == 'YES': if netconf.configure_netconf(ip_address, u_name, pwd) == False: print( 'User does not have the correct permissions to change the configuration.\nPlease change the user class and try again.' ) return else: print('Enabling netconf') try: dev = Device(host=ip_address, user=u_name, passwd=pwd) dev.open() except ConnectError as err: print("Cannot connect to device: {0}".format(err)) return while True: pd = getpass("New password:"******"Retype new password:"******"set system login user " + u_name + " class " + cls + " authentication plain-text-password-value " + pd dev.bind(cu=Config) # Lock the configuration, load configuration changes, and commit print("Locking the configuration") try: dev.cu.lock() except LockError as err: print("Unable to lock configuration: {0}".format(err)) dev.close() return print("Loading configuration changes") try: dev.cu.load(command, format='set') 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)) dev.close() return print("Committing the configuration") try: dev.cu.commit(comment='Loaded by example.') 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)) dev.close() return print("Unlocking the configuration") try: dev.cu.unlock() except UnlockError as err: print("Unable to unlock configuration: {0}".format(err)) # End the NETCONF session and close the connection dev.close() print('Deleting netconf') del_netconf.delete_netconf(ip_address, u_name, pd)
class TestFS(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.fs = FS(self.dev) def test_cat_wrong_path_return_none(self): path = 'test/report' self.assertEqual(self.fs.cat(path), None) def test_cat(self): self.fs._dev.rpc.file_show = MagicMock(side_effect=self._mock_manager) path = 'test/cat.txt' self.assertTrue('testing cat functionality' in self.fs.cat(path)) self.fs._dev.rpc.file_show.assert_called_with(filename='test/cat.txt') def test_cwd(self): self.fs._dev.rpc.set_cli_working_directory = MagicMock() folder = 'test/report' self.fs.cwd(folder) self.fs._dev.rpc.set_cli_working_directory.\ assert_called_with(directory='test/report') @patch('jnpr.junos.Device.execute') def test_pwd(self, mock_execute): mock_execute.side_effect = MagicMock(side_effect=self._mock_manager) self.fs.pwd() self.assertEqual(self.fs.pwd(), '/cf/var/home/rick') def test_checksum_return_none(self): path = 'test/report' self.assertEqual(self.fs.checksum(path), None) def test_checksum_unknown_calc(self): path = 'test/report' self.assertRaises(ValueError, self.fs.checksum, path=path, calc='abc') def test_checksum_return_rsp(self): self.fs.dev.rpc.get_sha256_checksum_information = \ MagicMock(side_effect=self._mock_manager) path = 'test/checksum' self.assertEqual(self.fs.checksum(path, 'sha256'), 'xxxx') self.fs.dev.rpc.get_sha256_checksum_information.\ assert_called_with(path='test/checksum') def test_stat_calling___decode_file(self): path = 'test/stat/decode_file' self.fs.dev.rpc.file_list = \ MagicMock(side_effect=self._mock_manager) self.assertEqual(self.fs.stat(path), {'owner': 'pqr', 'path': '/var/abc.sh', 'permissions': 755, 'permissions_text': '-rwxr-xr-x', 'size': 2, 'ts_date': 'Mar 13 06:54', 'ts_epoc': '1394693680', 'type': 'file'}) def test_stat_calling___decode_dir(self): path = 'test/stat/decode_dir' self.fs.dev.rpc.file_list = \ MagicMock(side_effect=self._mock_manager) self.assertEqual(self.fs.stat(path), {'path': '/var', 'type': 'dir', 'file_count': 1, 'size': 2}) def test_stat_return_none(self): path = 'test/abc' self.fs.dev.rpc.file_list = MagicMock() self.fs.dev.rpc.file_list.find.return_value = 'output' self.assertEqual(self.fs.stat(path), None) def test_ls_calling___decode_file(self): path = 'test/stat/decode_file' self.fs.dev.rpc.file_list = \ MagicMock(side_effect=self._mock_manager) self.assertEqual(self.fs.ls(path), {'owner': 'pqr', 'path': '/var/abc.sh', 'permissions': 755, 'permissions_text': '-rwxr-xr-x', 'size': 2, 'ts_date': 'Mar 13 06:54', 'ts_epoc': '1394693680', 'type': 'file'}) def test_ls_calling___decode_dir(self): path = 'test/stat/decode_dir' self.fs.dev.rpc.file_list = \ MagicMock(side_effect=self._mock_manager) self.assertEqual(self.fs.ls(path), {'files': {'abc': {'permissions_text': 'drwxr-xr-x', 'ts_date': 'Feb 17 15:30', 'ts_epoc': '1392651039', 'owner': 'root', 'path': 'abc', 'size': 2, 'type': 'dir', 'permissions': 555}}, 'path': '/var', 'type': 'dir', 'file_count': 1, 'size': 2}) def test_ls_return_none(self): path = 'test/abc' self.fs.dev.rpc.file_list = MagicMock() self.fs.dev.rpc.file_list.find.return_value = 'output' self.assertEqual(self.fs.ls(path), None) @patch('jnpr.junos.utils.fs.FS._decode_file') def test_ls_link_path_false(self, mock_decode_file): mock_decode_file.get.return_value = False path = 'test/stat/decode_file' self.fs.dev.rpc.file_list = \ MagicMock(side_effect=self._mock_manager) self.fs.ls(path, followlink=False) mock_decode_file.assert_has_calls(call().get('link')) def test_ls_brief_true(self): path = 'test/stat/decode_dir' self.fs.dev.rpc.file_list = \ MagicMock(side_effect=self._mock_manager) self.assertEqual(self.fs.ls(path, brief=True), {'files': ['abc'], 'path': '/var', 'type': 'dir', 'file_count': 1, 'size': 2}) def test_ls_calling___decode_dir_type_symbolic_link(self): path = 'test/stat/decode_symbolic_link' self.fs.dev.rpc.file_list = \ MagicMock(side_effect=self._mock_manager) self.assertEqual(self.fs.ls(path), {'files': {'abc': {'permissions_text': 'drwxr-xr-x', 'ts_date': 'Feb 17 15:30', 'link': 'symlink test', 'ts_epoc': '1392651039', 'owner': 'root', 'path': 'abc', 'size': 2, 'type': 'link', 'permissions': 555}}, 'path': '/var', 'type': 'dir', 'file_count': 1, 'size': 2}) def test_rm_return_true(self): self.fs.dev.rpc.file_delete = MagicMock(return_value=True) path = 'test/abc' self.assertTrue(self.fs.rm(path)) self.fs.dev.rpc.file_delete.assert_called_once_with( path='test/abc') def test_rm_return_false(self): path = 'test/abc' self.fs.dev.rpc.file_delete = MagicMock(return_value=False) self.assertFalse(self.fs.rm(path)) self.fs.dev.rpc.file_delete.assert_called_once_with( path='test/abc') def test_copy_return_true(self): self.fs.dev.rpc.file_copy = MagicMock() initial = 'test/abc' final = 'test/xyz' self.assertTrue(self.fs.cp(initial, final)) self.fs.dev.rpc.file_copy.assert_called_once_with( source='test/abc', destination='test/xyz') def test_copy_return_false(self): initial = 'test/abc' final = 'test/xyz' self.fs.dev.rpc.file_copy = MagicMock(side_effect=Exception) self.assertFalse(self.fs.cp(initial, final)) self.fs.dev.rpc.file_copy.assert_called_once_with( source='test/abc', destination='test/xyz') def test_move_return_true(self): self.fs.dev.rpc.file_rename = MagicMock(return_value=True) initial = 'test/abc' final = 'test/xyz' self.assertTrue(self.fs.mv(initial, final)) self.fs.dev.rpc.file_rename.assert_called_once_with( source='test/abc', destination='test/xyz') def test_move_return_false(self): initial = 'test/abc' final = 'test/xyz' self.fs.dev.rpc.file_rename = MagicMock(return_value=False) self.assertFalse(self.fs.mv(initial, final)) self.fs.dev.rpc.file_rename.assert_called_once_with( source='test/abc', destination='test/xyz') def test_tgz_return_true(self): src = 'test/tgz.txt' dst = 'test/xyz' self.fs.dev.rpc.file_archive = MagicMock(return_value=True) self.assertTrue(self.fs.tgz(src, dst)) self.fs.dev.rpc.file_archive.assert_called_once_with( source='test/tgz.txt', destination='test/xyz', compress=True) @patch('jnpr.junos.Device.execute') def test_tgz_return_error(self, mock_execute): mock_execute.side_effect = self._mock_manager src = 'test/tgz.txt' dst = 'test/xyz' self.assertTrue('testing tgz' in self.fs.tgz(src, dst)) @patch('jnpr.junos.utils.fs.StartShell') def test_rmdir(self, mock_StartShell): path = 'test/rmdir' print(self.fs.rmdir(path)) calls = [ call().__enter__(), call().__enter__().run('rmdir test/rmdir'), call().__exit__(None, None, None)] mock_StartShell.assert_has_calls(calls) @patch('jnpr.junos.utils.fs.StartShell') def test_mkdir(self, mock_StartShell): path = 'test/mkdir' print(self.fs.mkdir(path)) calls = [ call().__enter__(), call().__enter__().run('mkdir -p test/mkdir'), call().__exit__(None, None, None)] mock_StartShell.assert_has_calls(calls) @patch('jnpr.junos.utils.fs.StartShell') def test_symlink(self, mock_StartShell): src = 'test/tgz.txt' dst = 'test/xyz' print(self.fs.symlink(src, dst)) calls = [ call().__enter__(), call().__enter__().run('ln -sf test/tgz.txt test/xyz'), call().__exit__(None, None, None)] mock_StartShell.assert_has_calls(calls) @patch('jnpr.junos.Device.execute') def test_storage_usage(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual(self.fs.storage_usage(), {'/dev/abc': {'avail_block': 234234, 'used_blocks': 2346455, 'used_pct': '1', 'mount': '/', 'total_blocks': 567431, 'avail': '2F', 'used': '481M', 'total': '4F'}}) @patch('jnpr.junos.Device.execute') def test_storage_cleanup(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual(self.fs.storage_cleanup(), {'/var/abc.txt': {'ts_date': 'Apr 25 10:38', 'size': 11}}) @patch('jnpr.junos.Device.execute') def test_storage_cleanup_check(self, mock_execute): mock_execute.side_effect = self._mock_manager self.assertEqual(self.fs.storage_cleanup_check(), {'/var/abc.txt': {'ts_date': 'Apr 25 10:38', 'size': 11}}) 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' or fname == 'get-index-error.xml' or fname == 'get-system-core-dumps.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: # if 'path' in kwargs and 'detail' in kwargs: # return self._read_file('dir_list_detail.xml') if 'path' in kwargs: if kwargs['path'] == 'test/stat/decode_dir': return self._read_file('file-list_dir.xml') elif kwargs['path'] == 'test/stat/decode_file': return self._read_file('file-list_file.xml') elif kwargs['path'] == 'test/checksum': return self._read_file('checksum.xml') elif kwargs['path'] == 'test/stat/decode_symbolic_link': return self._read_file('file-list_symlink.xml') if 'filename' in kwargs: if kwargs['filename'] == 'test/cat.txt': return self._read_file('file-show.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].tag == 'command': if args[0].text == 'show cli directory': return self._read_file('show-cli-directory.xml') elif args[0].tag == 'get-system-storage': return self._read_file('get-system-storage.xml') elif args[0].tag == 'request-system-storage-cleanup': return self._read_file('request-system-storage-cleanup.xml') elif args[0].tag == 'file-archive': return self._read_file('file-archive.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() @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('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') 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') def test_device_execute_exception(self): class MyException(Exception): rpc_err = """ <rpc-error xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/12.1X46/junos" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> <error-severity>error</error-severity> <error-info> <bad-element>get-bgp-summary-information</bad-element> </error-info> <error-message>permission denied</error-message> </rpc-error> """ xml = etree.XML(rpc_err) self.dev._conn.rpc = MagicMock(side_effect=MyException) self.assertRaises(RpcError, 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_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') except: # Try to load the template relative to test base try: template = self.dev.Template('templates/config-example') 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' or fname == 'get-index-error.xml' or fname == 'get-system-core-dumps.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'
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'] kwargs = dict() kwargs['port'] = params.get('port') or 830 kwargs['user'] = params['username'] if params['password']: kwargs['passwd'] = params['password'] if params['ssh_keyfile']: kwargs['ssh_private_key_file'] = params['ssh_keyfile'] kwargs['gather_facts'] = False try: self.device = Device(host, **kwargs) self.device.open() self.device.timeout = params['timeout'] 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] = xml_to_json(responses[index]) elif cmd.args.get('command_type') == 'rpc': responses[index] = str(responses[index].text).strip() elif 'RpcError' in responses[index]: raise NetworkError(responses[index]) 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 unicode(ele.text).strip() else: return ele def load_config(self, config, commit=False, replace=False, confirm=None, comment=None, config_format='text', overwrite=False): if all([replace, overwrite]): self.raise_exc( 'setting both replace and overwrite to True is invalid') if replace: merge = False overwrite = False elif overwrite: 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 confirm_commit(self, checkonly=False): try: resp = self.rpc('get_commit_information') needs_confirm = 'commit confirmed, rollback' in resp[0][4].text if checkonly: return needs_confirm return self.commit_config() except IndexError: # if there is no comment tag, the system is not in a commit # confirmed state so just return pass 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
#!/usr/bin/python from jnpr.junos import Device from pprint import pprint device1 = Device(host='10.1.2.3', user='******', password='******') device1.open() pprint(device1.facts)
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.config_replace = False if optional_args is None: optional_args = {} self.port = optional_args.get('port', 22) self.device = Device(hostname, user=username, password=password, port=self.port) 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 get_lldp_neighbors_detail(self, interface=''): lldp_neighbors = dict() lldp_table = junos_views.junos_lldp_neighbors_detail_table(self.device) lldp_table.get() lldp_items = lldp_table.items() for lldp_item in lldp_items: interface = lldp_item[0] if interface not in lldp_neighbors.keys(): lldp_neighbors[interface] = list() lldp_neighbors[interface].append( {elem[0]: elem[1] for elem in lldp_item[1]}) return lldp_neighbors
def main(): # initialize logging logging.basicConfig(filename=logfile, level=logging.INFO, format='%(asctime)s:%(name)s: %(message)s') logging.getLogger().name = host logging.getLogger().addHandler(logging.StreamHandler()) logging.info('Information logged in {0}'.format(logfile)) # verify package1 exists if not (os.path.isfile(package1)): msg = 'Software package1 does not exist: {0}. '.format(package1) logging.error(msg) sys.exit() dev = Device(host=host, user=user, passwd=passwd) try: dev.open() except ConnectError as err: logging.error('Cannot connect to device: {0}\n'.format(err)) return # Create an instance of SW sw = SW(dev) try: logging.info( 'Starting the software upgrade process: {0}'.format(package1)) ok = True #ok = sw.install(package=package1, remote_path=remote_path,progress=update_progress, validate=validate) except Exception as err: msg = 'Unable to install software, {0}'.format(err) logging.error(msg) ok = False if ok is True: logging.info('Software installation complete. Rebooting') rsp = sw.reboot() logging.info('Upgrade pending reboot cycle, please be patient.') logging.info(rsp) else: msg = 'Unable to install software, {0}'.format(ok) logging.error(msg) #dev=None #dev = Device(host=host, user=user, passwd=passwd) # End the NETCONF session and close the connection time.sleep(20) rebootOK = False while not rebootOK: try: print("try open") time.sleep(15) rebootOK = True dev.open() except ConnectError as err: print("Not open") rebootOK = False #"--------------firmware--------------" # verify package2 exists if not (os.path.isfile(package2)): msg = 'Software package2 does not exist: {0}. '.format(package2) logging.error(msg) sys.exit() # Create an instance of SW sw = SW(dev) try: logging.info( 'Starting the software upgrade process: {0}'.format(package2)) #ok = True ok = sw.install(package=package2, remote_path=remote_path, progress=update_progress, validate=validate) except Exception as err: msg = 'Unable to install software, {0}'.format(err) logging.error(msg) ok = False if ok is True: logging.info('Software installation complete.') dev.cli("request system firmware upgrade pic pic-slot 0 fpc-slot 1") else: msg = 'Unable to install software, {0}'.format(ok) logging.error(msg) time.sleep(20) rsp = sw.reboot() print("last reboot") time.sleep(20) rebootOK = False while not rebootOK: try: print("try open") time.sleep(15) rebootOK = True dev.open() except ConnectError as err: print("Not open") rebootOK = False #dev.timeout = 600 #dev.rpc.request_snapshot(slice='alternate') #dev.cli("request system snapshot slice alternate") print "close device" dev.close()
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.info("Latest Datapoints are:") logger.info(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 = get_credentials(host) 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.info("Latest Datapoints are:") logger.info(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) jdev.close() 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']) if datapoints: # Only insert datapoints if there is any :) insert_datapoints(datapoints) timestamp_tracking['collector_ends'] = int( datetime.today().strftime('%s')) logger.info( '[%s]: timestamp_tracking - total collection %s', host, timestamp_tracking['collector_ends'] - timestamp_tracking['collector_start']) else: logger.error('[%s]: Skipping host due connectivity issue', host)
lbnhidbyterate.append(round((int(nhidrate[5])*100.00)/totalbyterate[i],1)) lbnhidbyte.append(nhidrate[5]) i+=1 for lb in xrange(len(lbnhid)): print "PFE %s , NHID %s , PKTrate %s , Percentage of PKTrate %s , Byterate %s , Percentage of Byterate %s " % (lbpfe[lb],lbnhid[lb],lbnhidpkt[lb],lbnhidpktrate[lb],lbnhidbyte[lb],lbnhidbyterate[lb]) lbshowfile.write("PFE %s , NHID %s , PKTrate %s , Percentage of PKTrate %s , Byterate %s , Percentage of Byterate %s ,\n" % (lbpfe[lb],lbnhid[lb],lbnhidpkt[lb],lbnhidpktrate[lb],lbnhidbyte[lb],lbnhidbyterate[lb])) if __name__ == '__main__': parser = argparse.ArgumentParser(description="Enter Device information") parser.add_argument('-f', action='store',dest='LBfile', help="Enter File Name for LB") parser.add_argument('-a', action='store',dest='Address', help="Enter IP Address for device to monitor") parser.add_argument('-u', action='store',dest='unilistnh', help="Enter Unilist NHDB ID to monitor") result = parser.parse_args() print "IP Address %s" % (result.Address) dev = Device(host=result.Address, user="******", passwd="lab123") dev.open() onlinefpcs = onlinefpcs(dev) print onlinefpcs testunilistlb(dev,onlinefpcs,result.unilistnh,result.LBfile)
class TestFtp(unittest.TestCase): @patch("ftplib.FTP.connect") @patch("ftplib.FTP.login") @patch("ftplib.FTP.close") @patch("ncclient.manager.connect") def setUp(self, mock_connect, mock_ftp_connect, mock_ftpconnect, mock_ftplogin): self.dev = Device(host="1.1.1.1", user="******", passwd="testpasswd", gather_facts=False) self.dev.open() self.dev._facts = {"hostname": "1.1.1.1"} self.dev_ftp = jnpr.junos.utils.ftp.FTP(self.dev) def test_ftp_open(self): assert isinstance(self.dev_ftp, ftplib.FTP) @patch("ftplib.FTP.login") @patch("ftplib.FTP.connect") def test_ftp_open_erors(self, mock_ftpconnect, mock_ftplogin): jnpr.junos.utils.ftp.FTP(self.dev) mock_ftplogin.assert_called_with("testuser", "testpasswd", "") # @patch("ftplib.FTP.close") def test_ftp_close(self, mock_close): self.dev_ftp.open() self.dev_ftp.close() mock_close.assert_called() @patch("ftplib.FTP.connect") @patch("ftplib.FTP.login") @patch("ftplib.FTP.close") def test_ftp_context(self, mock_ftpconnect, mock_ftplogin, mock_ftpclose): with jnpr.junos.utils.ftp.FTP(self.dev) as dev_ftp: assert isinstance(dev_ftp, ftplib.FTP) @patch(builtin_string + ".open") def test_ftp_upload_file_errors(self, mock_open): self.assertEqual(self.dev_ftp.put(local_file="testfile"), False) self.assertEqual(self.dev_ftp.put(local_file="/var/testfile"), False) @patch("ftplib.FTP.storbinary") @patch(builtin_string + ".open") def test_ftp_upload_file(self, mock_ftpstore, mock_open): self.assertEqual(self.dev_ftp.put(local_file="testfile"), True) @patch(builtin_string + ".open") def test_ftp_dnload_file_errors(self, mock_open): self.assertEqual( self.dev_ftp.get(local_path="testfile", remote_file="testfile"), False) @patch(builtin_string + ".open") def test_ftp_dnload_file_get(self, mock_open): self.assertEqual(self.dev_ftp.get(remote_file="/var/tmp/testfile"), False) @patch("ftplib.FTP.retrbinary") @patch(builtin_string + ".open") def test_ftp_dnload_file_get_retr(self, mock_open, mock_ftpretr): self.assertEqual(self.dev_ftp.get(remote_file="/var/tmp/testfile"), True) @patch("ftplib.FTP.retrbinary") @patch(builtin_string + ".open") def test_ftp_dnload_file_get_rf_filename(self, mock_open, mock_ftpretr): self.assertEqual(self.dev_ftp.get(remote_file="testfile.txt"), True) @patch("ftplib.FTP.retrbinary") @patch(builtin_string + ".open") def test_ftp_dnload_file(self, mock_ftpretr, mock_open): self.assertEqual( self.dev_ftp.get(local_path="testfile", remote_file="testfile"), True) @patch("ftplib.FTP.connect") @patch("ftplib.FTP.login") @patch("ftplib.FTP.retrbinary") def test_ftp_dnload_file_get_rf_filename_cb( self, mock_ftp_connect, mock_ftp_login, mock_ftp_retrbinary, ): def callback(): pass kwargs = {"callback": callback} dev_ftp = jnpr.junos.utils.ftp.FTP(self.dev, **kwargs) self.assertEqual(dev_ftp.get(remote_file="/var/tmp/testfile"), True) @patch("ftplib.FTP.storbinary") @patch(builtin_string + ".open") def test_ftp_upload_file_rem_path(self, mock_open, mock_ftpstore): self.assertEqual( self.dev_ftp.put(local_file="/var/tmp/conf.txt", remote_path="/var/tmp"), True, ) self.assertEqual( tuple(mock_ftpstore.call_args)[1]["cmd"], "STOR /var/tmp/conf.txt") @patch("ftplib.FTP.storbinary") @patch(builtin_string + ".open") def test_ftp_upload_file_rem_full_path(self, mock_open, mock_ftpstore): self.assertEqual( self.dev_ftp.put( local_file=os.path.abspath("/var/tmp/conf.txt"), remote_path=os.path.abspath("/var/tmp/test.txt"), ), True, ) self.assertEqual( tuple(mock_ftpstore.call_args)[1]["cmd"], "STOR " + os.path.abspath("/var/tmp/test.txt"), ) @patch("ftplib.FTP.storbinary") @patch(builtin_string + ".open") def test_ftp_upload_file_rem_path_create(self, mock_open, mock_ftpstore): self.assertEqual( self.dev_ftp.put(local_file="conf.txt", remote_path=os.path.abspath("/var/tmp")), True, ) self.assertEqual( tuple(mock_ftpstore.call_args)[1]["cmd"], "STOR " + os.path.abspath("/var/tmp/conf.txt"), )
# template to configure junos f=open('configure_junos/junos.j2') my_template = Template(f.read()) f.close() # get devices list. each item has an ip, name, username, password. f=open('inventory.yml', 'r') devices_list = load(f.read())['devices_list'] f.close() # get junos variables: interfaces, asn, .... f=open('configure_junos/junos.yml', 'r') junos_vars = load(f.read()) f.close() for item in devices_list: device=Device (host=item['host'], user=item['authentication']['password']['username'], password=item['authentication']['password']['password']) host_vars = junos_vars[item['device-id']] f=open('configure_junos/' + item['device-id'] + '.conf','w') f.write(my_template.render(host_vars)) f.close() junos_conf = 'configure_junos/' + item['device-id'] + '.conf' device.open() cfg=Config(device) cfg.load(path=junos_conf, format='text') cfg.commit() device.close() print 'configured device ' + item['device-id']
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')
def populate_db(hostname): """ Function to: Connect to a device Grab config in XML format Search through the config Upload relevant parameters to database """ db = mysql.connector.connect(pool_name="mypool", user=private.mysqluser, password=private.mysqlpw, host=private.mysqlhost, database=private.mysqldb) cur = db.cursor() try: logger.info('Working on: {}'.format(hostname.strip())) dev = Device(host=hostname.strip(), user=private.deviceuser, password=private.devicepw, port=22) dev.open(auto_probe=5) model = dev.facts['model'] config = dev.rpc.get_config() dev.close() except Exception as e: logger.warning('Error: {}'.format(e)) if config.findall( 'interfaces/interface') is not None and model[:2] == 'EX': interfaces = config.findall('interfaces/interface') for item in interfaces: """ If the interface is an ae bundle member, use the main interface number and description and record the bundle number """ if item.find('ether-options/ieee-802.3ad/bundle') is not None: interface = item.find('name').text interface_details = { 'device_int': '{}_{}'.format(hostname.strip(), interface), 'bundle': item.find('ether-options/ieee-802.3ad/bundle').text } if item.find('description') is not None: interface_details['description'] = item.find( 'description').text else: interface_details['description'] = None logger.debug(interface_details) try: db_do( cur.execute( 'insert into interfaces (device_int_unit, description, bundle) values (%s, %s, %s)', (interface_details['device_int'], interface_details['description'], interface_details['bundle']))) except Exception as e: logger.warning('Error: {}'.format(e)) db_do(db.commit()) elif item.find('name').text.split('-')[0][:2] in ('ge', 'xe', 'ae', 'ir', 'lo', 'sp', 'em'): # create a variable for the main interface number interface = item.find('name').text interface_details = { 'device_int': '{}_{}'.format(hostname.strip(), interface) } if item.find('unit/family/ethernet-switching/port-mode' ) is not None: interface_details['port_mode'] = item.find( 'unit/family/ethernet-switching/port-mode').text else: interface_details['port_mode'] = None if item.find('description') is not None: main_description = item.find('description').text interface_details['description'] = item.find( 'description').text else: interface_details['description'] = None logger.debug(interface_details) try: db_do( cur.execute( 'insert into interfaces (device_int_unit, description, port_mode) values (%s, %s, %s)', (interface_details['device_int'], interface_details['description'], interface_details['port_mode']))) except Exception as e: logger.warning('Error: {}'.format(e)) db_do(db.commit()) if item.find('unit/family/ethernet-switching/vlan/members' ) is not None: members = item.findall( 'unit/family/ethernet-switching/vlan/members') if item.find('unit/family/ethernet-switching/port-mode' ) is not None: interface_encapsulation = item.find( 'unit/family/ethernet-switching/port-mode').text else: interface_encapsulation = None for member in members: if '-' in member.text: member_list = breakup_hyphen(member.text) for member in member_list: interface_details = { 'device_int_vlan': '{}_{}.{}'.format(hostname.strip(), interface, member) } interface_details[ 'description'] = main_description interface_details[ 'port_mode'] = interface_encapsulation interface_details['vlan_outer'] = member logger.debug(interface_details) try: db_do( cur.execute( 'insert into interfaces (device_int_unit, description, port_mode, vlan_outer) values (%s, %s, %s, %s)', (interface_details[ 'device_int_vlan'], interface_details['description'], interface_details['port_mode'], interface_details['vlan_outer']))) except Exception as e: logger.warning('Error: {}'.format(e)) db_do(db.commit()) else: interface_details = { 'device_int_vlan': '{}_{}.{}'.format(hostname.strip(), interface, member.text) } interface_details[ 'port_mode'] = interface_encapsulation interface_details['description'] = main_description interface_details['vlan_outer'] = member.text logger.debug(interface_details) try: db_do( cur.execute( 'insert into interfaces (device_int_unit, description, port_mode, vlan_outer) values (%s, %s, %s, %s)', (interface_details['device_int_vlan'], interface_details['description'], interface_details['port_mode'], interface_details['vlan_outer']))) except Exception as e: logger.warning('Error: {}'.format(e)) db_do(db.commit()) elif item.find('name').text in ('vlan', ): if item.find('unit/name') is not None: interface_details = { 'device_int_unit': '{}_vlan.{}'.format(hostname.strip(), item.find('unit/name').text) } if item.find('unit/description') is not None: interface_details['description'] = item.find( 'unit/description').text else: interface_details['description'] = None if item.find('unit/family/inet/address/name') is not None: interface_details['ip'] = item.find( 'unit/family/inet/address/name').text else: interface_details['ip'] = None logger.debug(interface_details) try: db_do( cur.execute( 'insert into interfaces (device_int_unit, description, ip) values (%s, %s, %s)', (interface_details['device_int_unit'], interface_details['description'], interface_details['ip']))) except Exception as e: logger.warning('Error: {}'.format(e)) db_do(db.commit()) if config.findall( 'interfaces/interface') is not None and model[:2] != 'EX': interfaces = config.findall('interfaces/interface') for item in interfaces: """ If the interface is an ae bundle member, use the main interface number and description and record the bundle number """ if item.find('gigether-options/ieee-802.3ad/bundle') is not None: interface = item.find('name').text interface_details = { 'device_int_unit': '{}_{}'.format(hostname.strip(), interface), 'bundle': item.find('gigether-options/ieee-802.3ad/bundle').text } if item.find('description') is not None: interface_details['description'] = item.find( 'description').text else: interface_details['description'] = None logger.debug(interface_details) try: db_do( cur.execute( 'insert into interfaces (device_int_unit, description, bundle) values (%s, %s, %s)', (interface_details['device_int_unit'], interface_details['description'], interface_details['bundle']))) except Exception as e: logger.warning('Error: {}'.format(e)) db_do(db.commit()) elif item.find('ether-options/ieee-802.3ad/bundle') is not None: interface = item.find('name').text interface_details = { 'device_int_unit': '{}_{}'.format(hostname.strip(), interface), 'bundle': item.find('ether-options/ieee-802.3ad/bundle').text } if item.find('description') is not None: interface_details['description'] = item.find( 'description').text else: interface_details['description'] = None logger.debug(interface_details) try: db_do( cur.execute( 'insert into interfaces (device_int_unit, description, bundle) values (%s, %s, %s)', (interface_details['device_int_unit'], interface_details['description'], interface_details['bundle']))) except Exception as e: logger.warning('Error: {}'.format(e)) db_do(db.commit()) elif item.find('name').text.split('-')[0][:2] in ('ge', 'xe', 'ae', 'ir', 'lo', 'sp', 'em'): # create a variable for the main interface number interface = item.find('name').text # create a variable for the main interface description, if present if item.find('description') is not None: main_description = item.find('description').text else: main_description = None for units in item.iter('unit'): interface_details = { 'device_int_unit': '{}_{}.{}'.format(hostname.strip(), interface, units.find('name').text) } ''' if the unit has no description use the main interface description ''' if units.find('description') is None: interface_details['description'] = main_description else: interface_details['description'] = units.find( 'description').text if units.find('encapsulation') is not None: interface_details['encapsulation'] = units.find( 'encapsulation').text else: interface_details['encapsulation'] = 'ENET' if units.find('vlan-id') is None and units.find( 'vlan-tags') is None: interface_details['vlan_outer'] = None interface_details['vlan_inner'] = None if units.find('vlan-id') is not None: interface_details['vlan_outer'] = units.find( 'vlan-id').text interface_details['vlan_inner'] = None if units.find('vlan-tags') is not None: if units.find('vlan-tags/outer') is not None: interface_details['vlan_outer'] = units.find( 'vlan-tags/outer').text if units.find('vlan-tags/inner') is not None: interface_details['vlan_inner'] = units.find( 'vlan-tags/inner').text else: interface_details['vlan_inner'] = None if units.find('family/inet/address/name') is not None: interface_details['ip'] = units.find( 'family/inet/address/name').text else: interface_details['ip'] = None interface_details['bundle'] = None logger.debug(interface_details) try: db_do( cur.execute( 'insert into interfaces (device_int_unit, description, encapsulation, vlan_outer, vlan_inner, bundle, ip) values (%s, %s, %s, %s, %s, %s, %s)', (interface_details['device_int_unit'], interface_details['description'], interface_details['encapsulation'], interface_details['vlan_outer'], interface_details['vlan_inner'], interface_details['bundle'], interface_details['ip']))) except Exception as e: logger.warning('Error: {}'.format(e)) db_do(db.commit()) elif item.find('name').text.split('-')[0][:2] in ('fx', ): continue elif item.find('name').text in ('vlan', ): if item.find('unit/name') is not None: interface_details = { 'device_int_unit': '{}_vlan.{}'.format(hostname.strip(), item.find('unit/name').text) } if item.find('unit/description') is not None: interface_details['description'] = item.find( 'unit/description').text else: interface_details['description'] = None if item.find('unit/family/inet/address/name') is not None: interface_details['ip'] = item.find( 'unit/family/inet/address/name').text else: interface_details['ip'] = None logger.debug(interface_details) try: db_do( cur.execute( 'insert into interfaces (device_int_unit, description, ip) values (%s, %s, %s)', (interface_details['device_int_unit'], interface_details['description'], interface_details['ip']))) except Exception as e: logger.warning('Error: {}'.format(e)) db_do(db.commit()) else: logger.warning( 'Interface type does not match any recognised type: {}'. format(item.find('name').text)) if config.findall('interfaces/interface-set') is not None: interface_sets = config.findall('interfaces/interface-set') for set in interface_sets: set_name = set.find('name').text int_name = set.find('interface/name').text for unit in set.iter('unit'): unit_name = unit.find('name').text interface = '{}_{}.{}'.format(hostname.strip(), int_name, unit_name) try: db_do( cur.execute( 'update interfaces set interface_set = %s where device_int_unit = %s', (set_name, interface))) except Exception as e: logger.warning('Error: {}'.format(e)) logger.debug('{} {}_{}.{}'.format(set_name, hostname.strip(), int_name, unit_name)) db_do(db.commit()) if config.find('routing-instances') is not None: conf_ris = config.find('routing-instances') for item in conf_ris: ri_details = {} if item.find('name') is not None: ri_details = { 'instance_name': '{}_{}'.format(hostname.strip(), item.find('name').text) } else: ri_details['instance_name'] = None if item.find('instance-type') is not None: ri_details['type'] = item.find('instance-type').text else: ri_details['type'] = None if item.find('route-distinguisher/rd-type') is not None: ri_details['rd'] = item.find( 'route-distinguisher/rd-type').text else: ri_details['rd'] = None if item.find('vrf-target/community') is not None: ri_details['rt'] = item.find('vrf-target/community').text else: ri_details['rt'] = None if item.find('protocols/bgp') is not None: ri_details['protocol'] = 'BGP' elif item.find('protocols/rip') is not None: ri_details['protocol'] = 'RIP' elif item.find('protocols/ospf') is not None: ri_details['protocol'] = 'OSPF' elif item.find('protocols/vpls') is not None: ri_details['protocol'] = 'VPLS' elif item.find('protocols/l2vpn') is not None: ri_details['protocol'] = 'L2VPN' else: ri_details['protocol'] = None if item.find( 'forwarding-options/dhcp-relay/server-group/server-group/address' ) is not None: forwarders = item.findall( 'forwarding-options/dhcp-relay/server-group/server-group/address' ) IPS = [] for forwarder in forwarders: IPS.append(forwarder.find('name').text) if len(IPS) == 1: ri_details['dhcp_forwarder1'] = IPS[0] ri_details['dhcp_forwarder2'] = None if len(IPS) > 1: ri_details['dhcp_forwarder1'] = IPS[0] ri_details['dhcp_forwarder2'] = IPS[1] else: ri_details['dhcp_forwarder1'] = None ri_details['dhcp_forwarder2'] = None try: db_do( cur.execute( 'insert into routing_instances (instance_name, type, rd, rt, protocol, dhcp_forwarder1, dhcp_forwarder2) values (%s, %s, %s, %s, %s, %s, %s)', (ri_details['instance_name'], ri_details['type'], ri_details['rd'], ri_details['rt'], ri_details['protocol'], ri_details['dhcp_forwarder1'], ri_details['dhcp_forwarder2']))) except Exception as e: logger.warning('Error: {}'.format(e)) logger.debug(ri_details) db_do(db.commit()) for interface in item.findall('interface'): int_name = '{}_{}'.format(hostname.strip(), interface.find('name').text) try: db_do( cur.execute( 'update interfaces set routing_instance = %s where device_int_unit = %s', (item.find('name').text, int_name))) except Exception as e: logger.warning('Error: {}'.format(e)) db_do(db.commit()) logger.debug('{}_{}'.format(item.find('name').text, int_name)) if config.find('bridge-domains') is not None: bridge_domains = config.find('bridge-domains') for bridge in bridge_domains: if bridge.find('name') is not None: bridge_details = { 'domain_name': '{}_{}'.format(hostname.strip(), bridge.find('name').text) } else: bridge_details = {'domain_name': None} if bridge.find('description') is not None: bridge_details['description'] = bridge.find('description').text else: bridge_details['description'] = None if bridge.find('domain-type') is not None: bridge_details['type'] = bridge.find('domain-type').text else: bridge_details['type'] = None if bridge.find('vlan-id') is not None: bridge_details['vlan_id'] = bridge.find('vlan-id').text else: bridge_details['vlan_id'] = None try: db_do( cur.execute( 'insert into bridge_domains (domain_name, description, type, vlan_id) values (%s, %s, %s, %s)', (bridge_details['domain_name'], bridge_details['description'], bridge_details['type'], bridge_details['vlan_id']))) except Exception as e: logger.warning('Error: {}'.format(e)) logger.debug(bridge_details) db_do(db.commit()) if bridge.find('routing-interface') is not None: int_name = '{}_{}'.format( hostname.strip(), bridge.find('routing-interface').text) try: cur.execute( 'update interfaces set bridge_domain = %s where device_int_unit = %s', (bridge.find('name').text, int_name)) except Exception as e: logger.warning('Error: {}'.format(e)) db_do(db.commit()) logger.debug('{}_{}'.format( bridge.find('name').text, int_name)) for int in bridge.iter('interface'): int_name = '{}_{}'.format(hostname.strip(), int.find('name').text) try: cur.execute( 'update interfaces set bridge_domain = %s where device_int_unit = %s', (bridge.find('name').text, int_name)) except Exception as e: logger.warning('Error: {}'.format(e)) db_do(db.commit()) logger.debug('{}_{}'.format( bridge.find('name').text, int_name)) if config.find('class-of-service/schedulers') is not None: schedulers = config.findall('class-of-service/schedulers') for scheduler in schedulers: scheduler_details = { 'name': '{}_{}'.format(hostname.strip(), scheduler.find('name').text) } if scheduler.find('shaping-rate/rate') is not None: scheduler_details['shaping_rate'] = scheduler.find( 'shaping-rate/rate').text else: scheduler_details['shaping_rate'] = None if scheduler.find('transmit-rate/percent') is not None: scheduler_details['transmit_rate'] = '{}{}'.format( scheduler.find('transmit-rate/percent').text, '%') elif scheduler.find('transmit-rate/rate') is not None: scheduler_details['transmit_rate'] = scheduler.find( 'transmit-rate/rate').text else: scheduler_details['transmit_rate'] = None if scheduler.find('priority') is not None: scheduler_details['priority'] = scheduler.find('priority').text else: scheduler_details['priority'] = None logger.debug(scheduler_details) try: db_do( cur.execute( 'insert into schedulers (name, shaping_rate, transmit_rate, priority) values (%s, %s, %s, %s)', (scheduler_details['name'], scheduler_details['shaping_rate'], scheduler_details['transmit_rate'], scheduler_details['priority']))) except Exception as e: logger.warning('Error: {}'.format(e)) db_do(db.commit()) if config.find('class-of-service/forwarding-classes') is not None: forwarding_classes = config.findall( 'class-of-service/forwarding-classes/queue') for forwarding_class in forwarding_classes: forwarding_details = { 'name': '{}_{}'.format(hostname.strip(), forwarding_class.find('class-name').text) } if forwarding_class.find('name') is not None: forwarding_details['queue'] = forwarding_class.find( 'name').text else: forwarding_details['queue'] = None if forwarding_class.find('priority') is not None: forwarding_details['priority'] = forwarding_class.find( 'priority').text else: forwarding_details['priority'] = None logger.debug(forwarding_details) try: db_do( cur.execute( 'insert into forwarding_classes (name, queue, priority) values (%s, %s, %s)', (forwarding_details['name'], forwarding_details['queue'], forwarding_details['priority']))) except Exception as e: logger.warning('Error: {}'.format(e)) db_do(db.commit()) if config.find('class-of-service/scheduler-maps') is not None: scheduler_maps = config.findall('class-of-service/scheduler-maps') for scheduler_map in scheduler_maps: if scheduler_map.find('name') is not None: scheduler_map_details = { 'name': '{}_{}'.format(hostname.strip(), scheduler_map.find('name').text) } try: db_do( cur.execute( 'insert into scheduler_maps (name) values (%s)', (scheduler_map_details['name'], ))) except Exception as e: logger.warning('Error: {}'.format(e)) db_do(db.commit()) if scheduler_map.find('forwarding-class') is not None: i = 1 for forwarding_class in scheduler_map.iter('forwarding-class'): scheduler_map_details[ 'forwarding_class' + str(i)] = '{}_{}'.format( hostname.strip(), forwarding_class.find('name').text) scheduler_map_details[ 'scheduler' + str(i)] = '{}_{}'.format( hostname.strip(), forwarding_class.find('scheduler').text) i = i + 1 logger.debug(scheduler_map_details) for k in scheduler_map_details: if k[:16] in ('forwarding_class', ): try: db_do( cur.execute( 'update scheduler_maps set {} = %s where name = %s' .format(k, ), (scheduler_map_details[k], scheduler_map_details['name']))) except Exception as e: logger.warning('Error: {}'.format(e)) db_do(db.commit()) for k in scheduler_map_details: if k[:9] in ('scheduler', ): try: db_do( cur.execute( 'update scheduler_maps set {} = %s where name = %s' .format(k, ), (scheduler_map_details[k], scheduler_map_details['name']))) except Exception as e: logger.warning('Error: {}'.format(e)) db_do(db.commit()) if config.find('class-of-service/traffic-control-profiles') is not None: traffic_control_profiles = config.findall( 'class-of-service/traffic-control-profiles') for traffic_control_profile in traffic_control_profiles: if traffic_control_profile.find('name') is not None: tcp_details = { 'name': '{}_{}'.format(hostname.strip(), traffic_control_profile.find('name').text) } else: tcp_details = {'name': None} if traffic_control_profile.find('scheduler-map') is not None: tcp_details['scheduler_map'] = '{}_{}'.format( hostname.strip(), traffic_control_profile.find('scheduler-map').text) else: tcp_details['scheduler_map'] = None if traffic_control_profile.find('shaping-rate/rate') is not None: tcp_details['shaping_rate'] = traffic_control_profile.find( 'shaping-rate/rate').text else: tcp_details['shaping_rate'] = None logger.debug(tcp_details) try: db_do( cur.execute( 'insert into traffic_control_profiles (name, scheduler_map, shaping_rate) values (%s, %s, %s)', (tcp_details['name'], tcp_details['scheduler_map'], tcp_details['shaping_rate']))) except Exception as e: logger.warning('Error: {}'.format(e)) db_do(db.commit()) if config.find('class-of-service/interfaces/interface-set') is not None: cos_interface_sets = config.findall( 'class-of-service/interfaces/interface-set') for cos_interface_set in cos_interface_sets: if cos_interface_set.find('name') is not None: cos_interface_set_details = { 'name': '{}_{}'.format(hostname.strip(), cos_interface_set.find('name').text) } else: cos_interface_set_details = {'name': None} if cos_interface_set.find( 'output-traffic-control-profile/profile-name') is not None: cos_interface_set_details[ 'traffic_control_profile'] = '{}_{}'.format( hostname.strip(), cos_interface_set.find( 'output-traffic-control-profile/profile-name').text ) else: cos_interface_set_details[ 'output-traffic-control-profile/profile-name'] = None logger.debug(cos_interface_set_details) try: db_do( cur.execute( 'insert into cos_interface_sets (name, traffic_control_profile) values (%s, %s)', (cos_interface_set_details['name'], cos_interface_set_details['traffic_control_profile'] ))) except Exception as e: logger.warning('Error: {}'.format(e)) db_do(db.commit()) if config.findall('class-of-service/interfaces/interface') is not None: cos_interfaces = config.findall( 'class-of-service/interfaces/interface') for cos_interface in cos_interfaces: # create a variable for the main interface number interface = cos_interface.find('name').text cos_interface_details = { 'device_int_unit': '{}_{}'.format(hostname.strip(), interface) } if cos_interface.find('scheduler-map') is not None: cos_interface_details['scheduler_map'] = '{}_{}'.format( hostname.strip(), cos_interface.find('scheduler-map').text) else: cos_interface_details['scheduler_map'] = None if cos_interface.find( 'output-traffic-control-profile/profile-name') is not None: cos_interface_details[ 'traffic_control_profile'] = '{}_{}'.format( hostname.strip(), cos_interface.find( 'output-traffic-control-profile/profile-name').text ) else: cos_interface_details['traffic_control_profile'] = None if cos_interface.find('apply-groups') is not None: cos_interface_details['apply_group'] = cos_interface.find( 'apply-groups').text else: cos_interface_details['apply_group'] = None logger.debug(cos_interface_details) try: db_do( cur.execute( 'insert into cos_interfaces (device_int_unit, apply_group, scheduler_map, traffic_control_profile) values (%s, %s, %s, %s)', (cos_interface_details['device_int_unit'], cos_interface_details['apply_group'], cos_interface_details['scheduler_map'], cos_interface_details['traffic_control_profile']))) except Exception as e: logger.warning('Error: {}'.format(e)) db_do(db.commit()) for units in cos_interface.iter('unit'): cos_interface_details = { 'device_int_unit': '{}_{}.{}'.format(hostname.strip(), interface, units.find('name').text) } if units.find('scheduler-map') is not None: cos_interface_details['scheduler_map'] = '{}_{}'.format( hostname.strip(), units.find('scheduler-map').text) else: cos_interface_details['scheduler_map'] = None if units.find('output-traffic-control-profile/profile-name' ) is not None: cos_interface_details[ 'traffic_control_profile'] = '{}_{}'.format( hostname.strip(), units.find( 'output-traffic-control-profile/profile-name'). text) else: cos_interface_details['traffic_control_profile'] = None if units.find('apply-groups') is not None: cos_interface_details['apply_group'] = units.find( 'apply-groups').text else: cos_interface_details['apply_group'] = None if units.find( 'classifiers/ieee-802.1/classifier-name') is not None: cos_interface_details['802_classifier'] = units.find( 'classifiers/ieee-802.1/classifier-name').text else: cos_interface_details['802_classifier'] = None if units.find('classifiers/exp/classifier-name') is not None: cos_interface_details['exp_classifier'] = units.find( 'classifiers/exp/classifier-name').text else: cos_interface_details['exp_classifier'] = None if units.find('classifiers/dscp/name') is not None: cos_interface_details['dscp_classifier'] = units.find( 'classifiers/dscp/name').text else: cos_interface_details['dscp_classifier'] = None if units.find('rewrite-rules/ieee-802.1/rewrite-rule-name' ) is not None: cos_interface_details['802_rewrite'] = units.find( 'rewrite-rules/ieee-802.1/rewrite-rule-name').text else: cos_interface_details['802_rewrite'] = None if units.find('rewrite-rules/exp/name') is not None: cos_interface_details['exp_rewrite'] = units.find( 'rewrite-rules/exp/name').text else: cos_interface_details['exp_rewrite'] = None if units.find('rewrite-rules/dscp/name') is not None: cos_interface_details['dscp_rewrite'] = units.find( 'rewrite-rules/dscp/name').text else: cos_interface_details['dscp_rewrite'] = None logger.debug(cos_interface_details) try: db_do( cur.execute( 'insert into cos_interfaces (device_int_unit, apply_group, scheduler_map, traffic_control_profile, exp_classifier, 802_classifier, dscp_classifier, exp_rewrite, 802_rewrite, dscp_rewrite) values (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)', (cos_interface_details['device_int_unit'], cos_interface_details['apply_group'], cos_interface_details['scheduler_map'], cos_interface_details['traffic_control_profile'], cos_interface_details['exp_classifier'], cos_interface_details['802_classifier'], cos_interface_details['dscp_classifier'], cos_interface_details['exp_rewrite'], cos_interface_details['802_rewrite'], cos_interface_details['dscp_rewrite']))) except Exception as e: logger.warning('Error: {}'.format(e)) db_do(db.commit()) db_do(db.close())
def check_connected(device): return device.connected def gather_arp_table(device): return ArpTable(device).get() def gather_routes(device): return RouteTable(device).get() def print_output(device, rt_table, arp_table): print("Hostname:") print(device.facts["hostname"]) print("NETCONF port:") print(device.port) print("Username:") print(device.user) print(rt_table.keys()) print(arp_table.keys()) srx2_dev = Device(**srx2) srx2_dev.open() route_t = gather_routes(srx2_dev) arp_t = gather_arp_table(srx2_dev) print_output(srx2_dev, route_t, arp_t)
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")
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
class SRXDevice: def __init__(self, name, address, un, passw): self.yml_file = "routeStatus.yml" globals().update(loadyaml(self.yml_file)) self.dev = Device(host=address, user=un, passwd=passw) self.name = name self.version = '' self.lastState = False self.lastError = '' def connect(self): # print(self.name, 'wait for connections') try: self.dev.open() except ConnectRefusedError: # print('Error: Connection refused!') self.lastError = 'Error: Connection refused!' return False except ConnectTimeoutError: # print('Connection timeout error!') self.lastError = 'Connection timeout error!' return False except ConnectUnknownHostError: # print('Error: Connection attempt to unknown host') self.lastError = 'Error: Connection attempt to unknown host' return False except ConnectionError: # print('Connection error!') self.lastError = 'Connection error!' return False except ConnectAuthError: # print('Connection authentication error!') self.lastError = 'Connection authentication error!' return False else: # print(self.name, 'connected!') self.lastError = '' return True def fake_connect(self): print('Begin fake connect') time.sleep(3) print('End fake connect') def get_route(self): tbl = RouteTable(self.dev) tbl.get('192.168.0.0/24') for key in tbl: result = key.to # print(key.name, key.via, key.to) return result def clear_ospf(self): ss = StartShell(self.dev) ss.open() ss.run('cli -c "clear ospf neighbor area 0"') def get_version(self): ss = StartShell(self.dev) ss.open() self.version = ss.run('cli -c "show version"') def disconnect(self): # print('Close connection') self.dev.close() def get_status(self): return self.dev.connected
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
# c:\Python27\IP_FABRIC\audit>lldp_neighbor_status.py # --------------------------------------------------------------------------------------------------------------- from jnpr.junos import Device from jnpr.junos.op.lldp import LLDPNeighborTable import yaml from datetime import datetime my_list_of_devices = open('tables_and_views/devices.yml').read() my_list_of_switches = yaml.load(my_list_of_devices) f = open("lldp_neighbors.txt", "a") f.write("\n" + str(datetime.now()) + "\n") for host in my_list_of_switches: switch = Device(host=host, user='******', password='******') switch.open() print "\nLLDP neighbors of device " + host + " (hostname is " + switch.facts[ "hostname"] + "):" f.write("\nLLDP neighbors of device " + host + " (hostname is " + switch.facts["hostname"] + "):\n") lldp_neighbors = LLDPNeighborTable(switch) lldp_neighbors.get() for neighbor in lldp_neighbors: print "interface " + neighbor.local_int + " has this neighbor: " + neighbor.remote_sysname f.write("interface " + neighbor.local_int + " has this neighbor: " + neighbor.remote_sysname + "\n") f.close()
import os from getpass import getpass from jnpr.junos import Device from jnpr.junos.exception import LockError from jnpr.junos.utils.config import Config # Use getpass password = os.getenv("JNPR_PASSWORD") if password is None: password = getpass("Enter vMX password: "******"vmx2.lasthop.io", user="******", password=password) a_device.open() # create config object cfg = Config(a_device) # lock configuration # cfg.lock() # lock status print() try: cfg.lock() print("Lock acquired!") except LockError: print("Device is already locked.") # unlock config cfg.unlock()
class TestRoutingEngines(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.facts = {} self.mode = '' self.vc = False self.vct = False self.vcf = False @patch('jnpr.junos.Device.execute') def test_multi_re_vc(self, mock_execute): mock_execute.side_effect = self._mock_manager self.mode = 'multi' self.vc = True routing_engines(self.dev, self.facts) self.assertTrue(self.facts['vc_capable']) self.assertTrue(self.facts['2RE']) self.assertEqual(self.facts['RE0-RE1']['mastership_state'], 'backup') # This test is for an issue where a MX may return nothing for the vc rpc @patch('jnpr.junos.Device.execute') def test_vc_info_true(self, mock_execute): mock_execute.side_effect = self._mock_manager self.mode = 'multi' self.vc = True self.vct = True routing_engines(self.dev, self.facts) print self.facts self.assertFalse(self.facts['vc_capable']) self.assertTrue(self.facts['2RE']) self.assertEqual(self.facts['RE1']['mastership_state'], 'backup') @patch('jnpr.junos.Device.execute') def test_mixed_mode_vcf(self, mock_execute): mock_execute.side_effect = self._mock_manager self.mode = 'multi' self.vc = True self.vcf = True routing_engines(self.dev, self.facts) self.assertTrue(self.facts['vc_fabric']) self.assertEqual(self.facts['vc_mode'], 'Mixed') @patch('jnpr.junos.Device.execute') def test_multi_instance(self, mock_execute): mock_execute.side_effect = self._mock_manager self.mode = 'multi' routing_engines(self.dev, self.facts) self.assertTrue(self.facts['2RE']) @patch('jnpr.junos.Device.execute') def test_master(self, mock_execute): mock_execute.side_effect = self._mock_manager self.mode = 'master' routing_engines(self.dev, self.facts) self.assertEqual(self.facts['RE0']['mastership_state'], 'master') @patch('jnpr.junos.Device.execute') def test_routing_engine_exception_ret_none(self, mock_execute): mock_execute.side_effect = self._mock_manager self.dev.rpc.get_route_engine_information = MagicMock( side_effect=ValueError) self.assertEqual(routing_engines(self.dev, self.facts), None) 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: device_params = kwargs['device_params'] device_handler = make_device_handler(device_params) session = SSHSession(device_handler) return Manager(session, device_handler) if args: if self.vc is True and args[ 0].tag == 'get-virtual-chassis-information': if self.vct is True: return True elif self.vcf is True: return self._read_file( 'get-virtual-chassis-information_mmvcf.xml') else: return self._read_file( 'get-virtual-chassis-information.xml') return self._read_file(args[0].tag + '_' + self.mode + '.xml')
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