def write_descr(ip, username, password, enable_secret, localint, descr): ssh_connection = ConnectHandler( device_type = 'cisco_ios', ip = ip, username = username, password = password, secret = enable_secret ) ssh_connection.enable() rt = ssh_connection.find_prompt() + "\n" rt = ssh_connection.send_command("conf t", delay_factor=0) rt = ssh_connection.send_command("int "+localint, delay_factor=0) rt = ssh_connection.send_command("description "+descr, delay_factor=0) ssh_connection.disconnect()
class ConnectivityTest: def login(self): self.cisco_switch = ConnectHandler( device_type='cisco_nxos', ip=HOSTNAME, username=USERNAME, password=PASSWORD, verbose=False) def setUp(self): self.failure = False self.login() self.cisco_switch.send_command('checkpoint ' + CHECKPOINT_NAME) def test_snippets(self): for snippet_file in os.listdir(SNIPPET_DIR): self.cisco_switch.send_config_from_file(os.path.join(SNIPPET_DIR, snippet_file)) ping_result = self.cisco_switch.send_command('ping 192.168.56.2') print "==========================" print snippet_file print "--------------------------" print ping_result if not ping_is_successful(ping_result): self.failure = True def tearDown(self): self.cisco_switch.send_command('rollback running-config checkpoint ' + CHECKPOINT_NAME) self.cisco_switch.send_command('no checkpoint ' + CHECKPOINT_NAME) self.cisco_switch.disconnect()
def get_cdp_neighbor_details(ip, username, password, enable_secret): """ get the CDP neighbor detail from the device using SSH :param ip: IP address of the device :param username: username used for the authentication :param password: password used for the authentication :param enable_secret: enable secret :return: """ # establish a connection to the device ssh_connection = ConnectHandler( device_type='cisco_ios', ip=ip, username=username, password=password, secret=enable_secret ) # enter enable mode ssh_connection.enable() # prepend the command prompt to the result (used to identify the local device) result = ssh_connection.find_prompt() + "\n" # execute the show cdp neighbor detail command # we increase the delay_factor for this command, because it take some time if many devices are seen by CDP result += ssh_connection.send_command("show cdp neighbor detail", delay_factor=2) # close SSH connection ssh_connection.disconnect() return result
def main(): router = { 'device_type': 'cisco_ios', 'ip': '10.9.0.67', 'username': '******', 'password': '******' } # Connect to device device_conn = ConnectHandler(**router) # Show logging buffered print "Pre Change Logging Check:" print device_conn.send_command("show run | in logging") # To change the logging buffered value config_commands = ['logging buffered 25000', 'do wr mem'] output = device_conn.send_config_set(config_commands) print output # Show logging buffered print "Post Change Logging Check:" print device_conn.send_command("show run | in logging") # Close connection device_conn.disconnect()
def clean_unused_files(self): # Initiate SSH Connection to device device = {'device_type': 'cisco_ios', 'ip': self.ip_address, 'username': self.username, 'password': self.password} ssh_conn = ConnectHandler(**device) # Loop through the inactive images of the device and attempt to delete. for image in self.inactive_images: # Perform a dir to determine if the image exists, to avoid an "image not found" command error. dir_output = ssh_conn.send_command('dir') if image in dir_output and image != self.compliant_image: try: # Force delete the inactive image from flash. i.e. 'del /force flash:/image.bin'. Allows for different file systems (flash:, slot0:, etc) ssh_conn.send_command('del /force {}/{}'.format(self.filesystem, image)) print "Deleted image file %s from %s" % (image, self.hostname) self.inactive_images.remove(image) except Exception as e: print "Error - %s" % e else: # If file no longer exists (perhaps deleted manually), update the inactive_images list. print "Image %s not found or filename matches the compliant image for model %s, skipping...." % (image,self.model) self.inactive_images.remove(image) ssh_conn.disconnect()
def main(): """ This will run an command via serial on an cisco ios switch and so serial cable must be attached to the device """ serialhandle = { "device_type": "cisco_ios_serial", "port": "USB Serial", # can be COM<number> or any line you can get from # serial.tools.list_ports.comports() "username": "******", "password": "******", "secret": "<secret>", "serial_settings": { # this are the default values "baudrate": 9600, "bytesize": serial.EIGHTBITS, "parity": serial.PARITY_NONE, "stopbits": serial.STOPBITS_ONE, }, } net_connect = ConnectHandler(**serialhandle) net_connect.enable() output = net_connect.send_command("show run") net_connect.disconnect() print(output)
def main(): router1 = { 'device_type': 'cisco_ios', 'ip': '10.9.0.67', 'username': '******', 'password': '******' } router2 = { 'device_type': 'cisco_ios', 'ip': '10.63.176.57', 'username': '******', 'password': '******' } routers = [router1, router2] for router in routers: # Connect to device device_conn = ConnectHandler(**router) # Print arp table print device_conn.send_command("show arp") print "\n\n" # Close connection device_conn.disconnect()
def setup_module(module): module.EXPECTED_RESPONSES = { 'enable_prompt' : 'n7k1#', 'base_prompt' : 'n7k1', 'interface_ip' : '10.3.3.245', 'config_mode' : '(config)' } show_ver_command = 'show version' module.basic_command = 'show ip int brief' net_connect = ConnectHandler(**cisco_nxos) module.show_version = net_connect.send_command(show_ver_command) module.show_ip = net_connect.send_command(module.basic_command) net_connect.enable() module.enable_prompt = net_connect.find_prompt() module.config_mode = net_connect.config_mode() config_commands = ['logging monitor 3', 'logging monitor 7', 'no logging console'] net_connect.send_config_set(config_commands) module.exit_config_mode = net_connect.exit_config_mode() module.config_commands_output = net_connect.send_command("show run | inc 'logging monitor'") net_connect.disconnect()
def main(): router1 = { 'device_type': 'cisco_ios', 'ip': '10.9.0.67', 'username': '******', 'password': '******' } router2 = { 'device_type': 'cisco_ios', 'ip': '10.63.176.57', 'username': '******', 'password': '******' } routers = [router1, router2] for router in routers: # Connect to device device_conn = ConnectHandler(**router) # Change config from file device_conn.send_config_from_file(config_file='config_commands.txt') # Validate changes print ">>> " + device_conn.find_prompt() + " <<<" #output = device_conn.send_command("show run | in logging", delay_factor=.5) output = device_conn.send_command_expect("show run | in logging") print output + "\n\n" # Close connection device_conn.disconnect()
def setup_module(module): module.EXPECTED_RESPONSES = { 'base_prompt' : 'openstack-rb5', 'config_mode' : '(config)', } net_connect = ConnectHandler(**brocade_vdx) # Enter enable mode module.prompt_initial = net_connect.find_prompt() net_connect.enable() module.enable_prompt = net_connect.find_prompt() # Send a set of config commands module.config_mode = net_connect.config_mode() config_commands = ['logging raslog console WARNING', 'interface vlan 20', 'banner motd test_message'] net_connect.send_config_set(config_commands) # Exit config mode module.exit_config_mode = net_connect.exit_config_mode() # Verify config changes module.config_commands_output = net_connect.send_command('show vlan brief') net_connect.disconnect()
def main(): ''' This will run an command via serial on an cisco ios switch and so serial cable must be attached to the device ''' serialhandle = { 'device_type':'cisco_ios_serial', 'port': 'USB Serial', # can be COM<number> or any line you can get from # serial.tools.list_ports.comports() 'username':'******', 'password':'******', 'secret':'<secret>', 'serial_settings':{ # this are the default values 'baudrate': 9600, 'bytesize': serial.EIGHTBITS, 'parity': serial.PARITY_NONE, 'stopbits': serial.STOPBITS_ONE } } net_connect = ConnectHandler(**serialhandle) net_connect.enable() output = net_connect.send_command('show run') net_connect.disconnect() print(output)
def setup_module(module): module.EXPECTED_RESPONSES = { 'enable_prompt' : 'xe-test-rtr#', 'base_prompt' : 'xe-test-rtr', 'interface_ip' : '172.30.0.167', 'config_mode' : '(config)', } show_ver_command = 'show version' module.basic_command = 'show ip int brief' net_connect = ConnectHandler(**cisco_xe) module.show_version = net_connect.send_command(show_ver_command) module.show_ip = net_connect.send_command(module.basic_command) net_connect.enable() module.enable_prompt = net_connect.find_prompt() module.config_mode = net_connect.config_mode() config_commands = ['logging buffered 20000', 'logging buffered 20010', 'no logging console'] net_connect.send_config_set(config_commands) module.exit_config_mode = net_connect.exit_config_mode() module.config_commands_output = net_connect.send_command('show run | inc logging buffer') net_connect.disconnect()
def main(): inputfile, config_commands = get_cmd_line() print("Switch configuration updater. Please provide login information.\n") # Get username and password information. username = input("Username: "******"Password: "******"Enable Secret: ") print("{}{:<20}{:<40}{:<20}".format( "\n", "IP Address", "Name", "Results"), end="") for switchip in inputfile: ciscosw = { "device_type": "cisco_ios", "ip": switchip.strip(), "username": username.strip(), "password": password.strip(), "secret": enasecret.strip(), } print() print("{:<20}".format(switchip.strip()), end="", flush=True) try: # Connect to switch and enter enable mode. net_connect = ConnectHandler(**ciscosw) except Exception: print("** Failed to connect.", end="", flush=True) continue prompt = net_connect.find_prompt() # Print out the prompt/hostname of the device print("{:<40}".format(prompt), end="", flush=True) try: # Ensure we are in enable mode and can make changes. if "#" not in prompt[-1]: net_connect.enable() print("#", end="", flush=True) except Exception: print("Unable to enter enable mode.", end="", flush=True) continue else: for cmd in config_commands: # Make requested configuration changes. try: if cmd in ("w", "wr"): output = net_connect.save_config() print("w", end="", flush=True) else: output = net_connect.send_config_set(cmd) if "Invalid input" in output: # Unsupported command in this IOS version. print("Invalid input: ", cmd, end="", flush=True) print("*", end="", flush=True) except Exception: # Command failed! Stop processing further commands. print("!") break net_connect.disconnect()
def cisco_xr(host): from netmiko import ConnectHandler from prettytable import PrettyTable from modules import ReadableRate import re interface, neighbor = "","" rx,tx = "","" table = PrettyTable(['Interface','In','Out','Neighbor','Metric','Total_Traffic']) net_connect = ConnectHandler(**host) no_prompt = net_connect.send_command("terminal exec prompt no-timestamp") isis_int = net_connect.send_command("show isis neighbor | include Up") isis_int = isis_int.splitlines() while '' in isis_int: isis_int.pop(isis_int.index('')) for line in isis_int: total_traffic = 0 # Extract neighbor and interface for item in line.split(): if re.search("[0-9]+/[0-9]+/[0-9]+/[0-9+]", item) != None: interface = item elif re.search("^BE", item) != None: interface = 'Bundle-Ether' + item[2:len(item)] neighbor = line.split()[0] neighbor = neighbor.replace('-re0','') # Don't care about Junipers with apply- neighbor = neighbor.replace('-re1','') # groups to append active RE to hostname # Get interface traffic show_int = net_connect.send_command("show interface " + interface.split('.')[0] + ' | include "put rate"') show_int = show_int.splitlines() for l in show_int: counter = 0 for thing in l.split(): if re.search("bits",thing) == None: counter+=1 else: counter -=1 if "nput" in l: rx = ReadableRate(int(l.split()[counter])) total_traffic = total_traffic + int(l.split()[counter]) counter +=1 elif "utput" in l: tx = ReadableRate(int(l.split()[counter])) total_traffic = total_traffic + int(l.split()[counter]) counter +=1 # Get isis metric show_isis = net_connect.send_command("show isis interface " + interface + " | include Metric") show_isis = show_isis.splitlines() for lines in show_isis: for word in lines .split(): if re.search("[0-9]+/[0-9]+", word) != None: metric = word table.add_row([interface,rx.rate,tx.rate,neighbor,metric,(total_traffic*-1)]) net_connect.disconnect() print(table.get_string(sortby='Total_Traffic'))
def connect_silent(*ios_commands,ip_address,dev=0): # connect_silent is able to log into and run enable mode commands as well but it connects on a best effort basis. # It might connect to enable mode if the enable secret is correct but it might just connect to user exec if it's not. # If you want verification about being able to connect to enable mode, use connect_enable_silent. # connect_silent is recommended for user exec commands. global output try: with open ("credentials.txt") as line: line = json.load(line) try_credentials = 0 for k,v in line.items(): router=(k,v) try_credentials += 1 try: if globals.pref_cred != {} and try_credentials == 1: if dev != 0: print("[[DEV:] Trying Prefered credentials]") ssh = ConnectHandler(**globals.pref_cred, device_type="cisco_ios", ip=ip_address) else: if dev != 0: print("[[DEV:] Trying Privileged User EXEC credentials '", k, "']", sep="") ssh = ConnectHandler(**router[1], device_type="cisco_ios", ip=ip_address) except netmiko.ssh_exception.NetMikoAuthenticationException: if dev != 0: print ("[[DEV:] Incorrect credentials]") continue except netmiko.ssh_exception.NetMikoTimeoutException: if dev != 0: print("[[DEV:] SSH not enabled (User EXEC timed out)]") raise SSHnotEnabled("SSH not enabled on target device (" + ip_address + ")") from None except Exception: if dev != 0: print("[[DEV:] Unknown error in ssh.connect_silent]") raise UnknownError ("Unknown error in ssh.connect_silent") else: for ios_command in ios_commands: if dev != 0: print("[[DEV:] Running command '", ios_command, "']", sep="") output = ios_command + "\n" + ssh.send_command(ios_command) if dev != 0 and "at '^' marker" in output: print("[[DEV:] '", ios_command, "' incorrect syntax or requires Privileged EXEC mode]", sep="") if "at '^' marker" not in output: ssh.disconnect() break if "at '^' marker" in output: raise IosSyntaxError ("incorrect syntax or requires Privileged EXEC mode") if globals.pref_cred == {} or globals.pref_cred != {} and try_credentials > 1: if dev != 0: print("[[DEV:] Saving '", k, "' as prefered credentials]", sep="") globals.pref_cred = v return output except json.decoder.JSONDecodeError: if dev != 0: print("[[DEV:] credentials file not in JSON format]") raise JsonIncorrectFormat ("Credentials file not in JSON format")
def execute(host): from netmiko import ConnectHandler from prettytable import PrettyTable from modules import ReadableRate from modules import table_header import re interface, neighbor = "","" rx,tx = "","" table = PrettyTable(['Interface','In','Out','Neighbor','Metric','Total_Traffic']) net_connect = ConnectHandler(**host) isis_int = net_connect.send_command("show isis adjacency | match Up") isis_int = isis_int.splitlines() while '' in isis_int: isis_int.pop(isis_int.index('')) while '{master}' in isis_int: isis_int.pop(isis_int.index('{master}')) for line in isis_int: total_traffic = 0 # Extract neighbor and interface for item in line.split(): if re.search("..\-[0-9]+/[0-9]+/[0-9+]", item) != None or re.search("^ae", item) != None: interface = item elif len(item) > 4: if re.search("..\:..\:..\:..",item) == None: neighbor = item neighbor = neighbor.replace('-re0','') # Don't care about Junipers with apply- neighbor = neighbor.replace('-re1','') # groups to append active RE to hostname # Get interface traffic show_int = net_connect.send_command("show interface " + interface.split('.')[0] + ' | match "put rate"') for lines in show_int.splitlines(): for i, word in enumerate(lines.split()): if 'bps' in word: traf = int(lines.split()[i-1]) total_traffic = total_traffic + traf if 'nput' in lines: rx = ReadableRate(traf) elif "utput" in lines: tx = ReadableRate(traf) # Get isis metric show_isis = net_connect.send_command("show isis interface | match " + interface) show_isis = show_isis.splitlines() while '' in show_isis: show_isis.pop(show_isis.index('')) for lines in show_isis: for word in lines .split(): if re.search("[0-9]+/[0-9]+", word) != None: metric = word table.add_row([interface,rx.rate,tx.rate,neighbor,metric,(total_traffic*-1)]) # (multiplying total_traffic by -1 to reverse table sort order) net_connect.disconnect() table_header(host['ip']) print(table.get_string(sortby='Total_Traffic'))
def connect_ssh(target_ip, username, password, DEBUG, output): if DEBUG: verbose = True else: verbose = False dns_list = list() for i in target_ip: try: # Define variables for function x, z, v = 0, 1, 2 vlan_list = list() output += ("*" * 4 + " START device: %s " + "-" * 35 + ">" * 4 + "\n") % i ssh_con = ConnectHandler(device_type='hp_procurve', ip=i, username=username, password=password, verbose=verbose) # Find hostname will be used for first part of VLAN IP dns name output += "\nFind prompt: \n" output_cmd = ssh_con.find_prompt() hostname = output_cmd if DEBUG: print hostname output += output_cmd # Get VLAN information from switch output_cmd = ssh_con.send_command('show vlan custom id name ipaddr') vlan_output = output_cmd.split(' ') output += output_cmd # Clean output information vlan_output = filter(None, vlan_output) # Filter VLAN ID's for y in vlan_output[18:-1]: if y != '\n': vlan_list.append(y) if DEBUG: print vlan_list lp = len(vlan_list) / 3 while lp != 0: vlan_name = hostname[:-1] + '-' + 'VL' + vlan_list[x] + '-' + vlan_list[z] dns_list.append(vlan_name) dns_list.append(vlan_list[v]) x += 3 z += 3 v += 3 lp -= 1 if DEBUG: print dns_list ssh_con.disconnect() except: print "Problem connecting with ip: %s" % (i) continue return output, dns_list
def execute(host): from netmiko import ConnectHandler from prettytable import PrettyTable from modules import ReadableRate from modules import table_header import re interface, neighbor = "","" rx,tx = "","" table = PrettyTable(['Interface','In','Out','Neighbor','Metric','Total_Traffic']) net_connect = ConnectHandler(**host) isis_int = net_connect.send_command("show isis neighbor | i L2") isis_int = isis_int.splitlines() while '' in isis_int: isis_int.pop(isis_int.index('')) for line in isis_int: total_traffic = 0 # Extract neighbor and interface for item in line.split(): if re.search("^[Fa|Gi|Te|Hu|Po|Vl]", item) != None: interface = item neighbor = line.split()[0] neighbor = neighbor.replace('-re0','') # Don't care about Junipers with apply- neighbor = neighbor.replace('-re1','') # groups to append active RE to hostname # Get interface traffic show_int = net_connect.send_command("show interface " + interface.split('.')[0] + " | include put rate") for lines in show_int.splitlines(): for i, word in enumerate(lines.split()): if 'bits' in word: traf = int(lines.split()[i-1]) total_traffic = total_traffic + traf if 'nput' in lines: rx = ReadableRate(traf) elif "utput" in lines: tx = ReadableRate(traf) # Get isis metric show_isis = net_connect.send_command("show clns interface " + interface + " | include Metric") show_isis = show_isis.splitlines() while '' in show_isis: show_isis.pop(show_isis.index('')) for lines in show_isis: counter = 0 for word in lines.split(): if re.search("Metric", word) != None: metric = lines.split()[counter+1] metric = metric.split(',')[0] counter +=1 table.add_row([interface,rx.rate,tx.rate,neighbor,metric,(total_traffic*-1)]) # (multiplying total_traffic by -1 to reverse table sort order) net_connect.disconnect() table_header(host['ip']) print(table.get_string(sortby='Total_Traffic'))
def call(method, *args, **kwargs): ''' Calls an arbitrary netmiko method. ''' kwargs = clean_kwargs(**kwargs) if not netmiko_device['always_alive']: connection = ConnectHandler(**netmiko_device['args']) ret = getattr(connection, method)(*args, **kwargs) connection.disconnect() return ret return getattr(netmiko_device['connection'], method)(*args, **kwargs)
def execute(host): from netmiko import ConnectHandler from prettytable import PrettyTable from modules import ReadableRate from modules import table_header import re interface, neighbor = "", "" rx, tx = "", "" table = PrettyTable(['Interface', 'In', 'Out', 'Neighbor', 'Metric', 'Total_Traffic']) net_connect = ConnectHandler(**host) isis_int = net_connect.send_command("terminal exec prompt no-timestamp") isis_int = net_connect.send_command("show isis neighbor | include Up") isis_int = isis_int.splitlines() while '' in isis_int: isis_int.pop(isis_int.index('')) for line in isis_int: total_traffic = 0 # Extract neighbor and interface for item in line.split(): if re.search("[0-9]+/[0-9]+/[0-9]+/[0-9+]", item) is not None: interface = item elif re.search("^BE", item) is not None: interface = 'Bundle-Ether' + item[2:len(item)] neighbor = line.split()[0] neighbor = neighbor.replace('-re0', '') # Don't care about Junipers with apply- neighbor = neighbor.replace('-re1', '') # groups to append active RE to hostname # Get interface traffic show_int = net_connect.send_command("show interface " + interface.split('.')[0] + ' | include "put rate"') for lines in show_int.splitlines(): for i, word in enumerate(lines.split()): if 'bits' in word: traf = int(lines.split()[i - 1]) total_traffic = total_traffic + traf if 'nput' in lines: rx = ReadableRate(traf) elif "utput" in lines: tx = ReadableRate(traf) # Get isis metric show_isis = net_connect.send_command("show isis interface " + interface + " | include Metric") show_isis = show_isis.splitlines() for lines in show_isis: for word in lines .split(): if re.search("[0-9]+/[0-9]+", word) is not None: metric = word table.add_row([interface, rx.rate, tx.rate, neighbor, metric, (total_traffic)]) net_connect.disconnect() table_header(host['ip']) print(table.get_string(sortby='Total_Traffic', reversesort=True))
def get_cdp_neighbors(ip, username, password, enable_secret): ssh_connection = ConnectHandler( device_type = 'cisco_ios', ip = ip, username = username, password = password, secret = enable_secret ) ssh_connection.enable() result = ssh_connection.find_prompt() + "\n" result = ssh_connection.send_command("show cdp neighbors", delay_factor=0) with open(os.getcwd()+'/temps/'+ip, 'w') as outfile: outfile.write(result) ssh_connection.disconnect()
def main(): """ In a file define a network device in YAML (compatible with Netmiko) Read that file in and connect to the network device using Netmiko Display show arp from that device """ filename = "my_device.yml" devices = read_yml_file(filename) for a_device in devices: device_name = a_device.pop('device_name') print "\n\nConnecting to: {}".format(device_name) net_conn = ConnectHandler(**a_device) print net_conn.send_command("show arp") net_conn.disconnect() print
def connect_to_device(devicein,destpath): try: net_connect = ConnectHandler(device_type=devicein.dtype, ip=devicein.ipaddr, username=baseuser, password=basepass, verbose=True) if devicein.dtype == "hp_comware": output = net_connect.send_command(devicein.cmdin) elif devicein.dtype == "cisco_ios": output = net_connect.send_command_expect(devicein.cmdin) net_connect.disconnect() filetowrite = devicein.cfgfiles[0] outfile = open(filetowrite, 'a') outfile.write(output) shutil.copy(filetowrite, destpath) os.remove(filetowrite) except Exception as e: writeerror(devicein.ipaddr, e)
def show_version(a_device): ''' Execute show version command using Netmiko ''' creds = a_device.credentials remote_conn = ConnectHandler(device_type=a_device.device_type, ip=a_device.ip_address, username=creds.username, password=creds.password, port=a_device.port, secret='') print print '#' * 80 print remote_conn.send_command_expect("show version") print '#' * 80 print remote_conn.disconnect()
def hostname_silent(ip_address,dev=0): try: with open ("credentials.txt") as line: line_1 = json.load(line) try_credentials = 0 for k,v in line_1.items(): router=(k,v) try_credentials += 1 try: if globals.pref_cred != {} and try_credentials == 1: if dev != 0: print("[[DEV:] Trying Prefered credentials]") ssh = ConnectHandler(**globals.pref_cred, device_type="cisco_ios", ip=ip_address) else: if dev != 0: print("[[DEV:] Trying Privileged EXEC credentials '", k, "']", sep="") ssh = ConnectHandler(**router[1],device_type="cisco_ios",ip=ip_address) except netmiko.ssh_exception.NetMikoAuthenticationException: if dev != 0: print("[[DEV:] Incorrect credentials]") continue except netmiko.ssh_exception.NetMikoTimeoutException: if dev != 0: print("[[DEV:] SSH not enabled (User EXEC timed out)]") raise SSHnotEnabled("SSH not enabled on target device (" + ip_address + ")") from None except Exception: if dev != 0: print("[[DEV:] Unknown error in ssh.hostname_silent]") raise UnknownError("Unknown error in ssh.hostname_silent") else: output = ssh.find_prompt() if ('#') in output: (output_split,junk) = output.split('#') else: (output_split, junk) = output.split('>') ssh.disconnect() if globals.pref_cred == {} or globals.pref_cred != {} and try_credentials > 1: if dev != 0: print("[[DEV:] Saving '", k, "' as prefered credentials]", sep="") globals.pref_cred = v return output_split except json.decoder.JSONDecodeError: if dev != 0: print("[[DEV:] credentials file not in JSON format]") raise JsonIncorrectFormat("Credentials file not in JSON format")
class router: def help(self, req, resp): h = ''' 路由器管理 ops router show -i 10.3.128.1 -c "show run" 执行查看命令 ops router config -i 10.3.128.1 -c "logging buffered 20000,logging buffered 20010,no logging console" 执行配置命令 多条用,分开 ''' return h def _connect(self, ip): if not ip: return None router_config.update({'ip': ip}) self.connect = ConnectHandler(**router_config) def __exit__(self, exc_type, exc_val, exc_tb): self.connect.disconnect() def show(self, req, resp): '''查看状态或配置''' ip = req.get_param(name='i') cmd = req.get_param(name='c') if ip is None: return '-i(ip) need' if cmd is None: return '-c(cmd) need' self._connect(ip) return self.connect.send_command(cmd) def config(self, req, resp): '''修改配置''' ip = req.get_param(name='i') cmd = req.get_param(name='c') if ip is None: return '-i(ip) need' if cmd is None: return '-c(cmd) need' self._connect(ip) cmds = cmd.split(',') return self.connect.send_config_set(cmds)
class NetworkDevice(object): """ Class container for all attributes and methods related to a Network Device """ def __init__(self, device_name, user_name, user_password, enable_password, device_type='cisco_ios'): self.DeviceName = device_name self.UserName = user_name self.UPassword = user_password self.EnablePassword = enable_password self.Interfaces = {} self.Vlans = {} self.VRF = {} self.MacAddress = {} """ testing using Netmiko as seems stable """ from netmiko import ConnectHandler self.Cisco_Device = { 'device_type': device_type, 'ip': self.DeviceName, 'username': self.UserName, 'password': self.UPassword, 'secret': self.EnablePassword, } self.Device_Connection = ConnectHandler(**self.Cisco_Device) def send_command(self, command): output = self.Device_Connection.send_command(command) return output def disconnect(self): self.Device_Connection.disconnect() def ios_version(self): return def clear_txt_configuration(self): return def mac_address(self): return
def hp_connect_to_device(dtype,dip,prefixlist,v4routelist,v6routelist): net_connect = ConnectHandler(device_type=dtype, ip=dip, username=myusername, password=mypassword) try: net_connect.send_command("sys\n") for pfxlst in prefixlist: net_connect.send_command(pfxlst) net_connect.send_command('bgp 65000') net_connect.send_command('address-family ipv4 unicast') for routes in v4routelist: pfxip = routes.split('/')[0] pfxlen = routes.split('/')[1] net_connect.send_command('aggregate %s %s detail-suppressed' % (pfxip, pfxlen)) net_connect.send_command('address-family ipv6 unicast') for routes in v6routelist: pfxip = routes.split('/')[0] pfxlen = routes.split('/')[1] net_connect.send_command('aggregate %s %s detail-suppressed' % (pfxip, pfxlen)) net_connect.send_command('save f') net_connect.disconnect() except: print "Failed to connect to device"
def main(): '''Use Netmiko to change logging buffer size (logging buffered <size>) and to disable console logging (no logging console) from a file on pynet-rtr1 and pynet-rtr2 routers.''' password = getpass() pynet1 = { 'device_type': 'cisco_ios', 'ip': '184.105.247.70', 'username': '******', 'password': password, 'port': 22, } pynet2 = { 'device_type': 'cisco_ios', 'ip': '184.105.247.71', 'username': '******', 'password': password, 'port': 22, } routers = [pynet1, pynet2] for rtr in routers: # Connect to router router_conn = ConnectHandler(**rtr) # Change config from file router_conn.send_config_from_file(config_file='config_commands.txt') # Validate changes print 10 * '*', router_conn.find_prompt(), 10 * '*' outp = router_conn.send_command("show run | inc logging") ## In the above line you can use send_command_expect instead print outp, '\n' # Close connection router_conn.disconnect()
def setup_module(module): module.EXPECTED_RESPONSES = { 'base_prompt' : 'vsr1000', 'router_prompt' : '<vsr1000>', 'interface_ip' : '192.168.112.11', 'config_mode' : '[vsr1000]', } show_ver_command = 'display version' multiple_line_command = 'display logbuffer' module.basic_command = 'display ip interface brief' net_connect = ConnectHandler(**hp_comware) module.show_version = net_connect.send_command(show_ver_command) module.multiple_line_output = net_connect.send_command(multiple_line_command, delay_factor=2) module.show_ip = net_connect.send_command(module.basic_command) module.base_prompt = net_connect.base_prompt # Enter config mode module.config_mode = net_connect.config_mode() # Exit config mode module.exit_config_mode = net_connect.exit_config_mode() # Send a set of config commands config_commands = ['vlan 3000', 'name 3000-test'] net_connect.send_config_set(config_commands) # Verify config changes module.config_commands_output = net_connect.send_command('display vlan 3000') # Undo config changes net_connect.send_command('undo vlan 3000') net_connect.disconnect()
def ssh_conn(device, show_command): net_connect = ConnectHandler(**device) return net_connect.send_command(show_command) net_connect.disconnect()
"session_log": './session_logs/session_log_nxos1.txt', } host_nxos2 = { "host": 'nxos2.lasthop.io', "username": '******', "password": getpass(), "device_type": 'cisco_ios', #"fast_cli": True, "session_log": './session_logs/session_log_nxos2.txt', } host_connect = ConnectHandler(**host_nxos1) configure_vlans = [ 'vlan 100', 'vlan 101', 'vlan 102', ] #datetime_now = datetime.now() #print('Current DATE and TIME ---------------->: ' + str(datetime_now) + '\n') #output = host_connect.send_config_set(configure_name_server) output = host_connect.send_config_from_file( config_file='pyscripts/week_02/vlans.txt') print(output) print('\n') host_connect.disconnect()
nomearquivo=router['hostname'] + '_bgp.conf' with open(nomearquivo,'r') as fh: for line in fh: line2=line.strip('\n') comandosdeconf.append(line2) print("------------------------------------------------------------") print("Enviandos os seguintes comandos para %s" % router['hostname']) print(comandosdeconf) #Enviar os comandos de configuracao if router['so'] == 'cisco_ios' : router_connect.enable() router_connect.send_config_set(comandosdeconf) if router['so'] == 'cisco_ios' : router_connect.send_command('wr') #Saio do modo enable router_connect.exit_enable_mode() else: # Se o roteador eh Juniper mando um commit e saiu do configure router_connect.commit(and_quit=True) #Fecho a conexao e zero a lista de comandos comandosdeconf=[] router_connect.disconnect()
'secret': secret, # optional, defaults to '' 'verbose': False, # optional, defaults to False } wlc_connect = ConnectHandler(**wlc) client = sys.argv[1] print "Client,RSSI,SNR,channel,AP" try: while True: command = 'show client detail ' + client client_detail = wlc_connect.send_command(command).split("\n") for client_detail_line in client_detail: if "Radio Signal Strength Indicator" in client_detail_line: rssi = client_detail_line.split()[4] if "AP Name" in client_detail_line: ap_name = client_detail_line.split()[2] if "Channel." in client_detail_line: channel = client_detail_line.split()[1] if "Signal to Noise Ratio" in client_detail_line: snr = client_detail_line.split()[4] print client + "," + rssi + "," + snr + "," + channel + "," + ap_name time.sleep(2) except KeyboardInterrupt: pass wlc_connect.disconnect()
"fast_cli": True } nxos2 = { "host": "nxos2", 'username': '******', 'password': getpass(), 'device_type': 'cisco_nxos', 'session_log': 'nxos2_5.txt', 'fast_cli': True } device = [nxos1, nxos2] t0 = datetime.now() for d in device: t1 = datetime.now() ssh_con = ConnectHandler(**d) ssh_con.send_config_from_file('ex5_commands.txt') ssh_con.save_config() ssh_con.disconnect() t2 = datetime.now() t3 = t2 - t1 print("\nINICIO: ", t1) print('\nFIN: ', t2) print('\nDuracion ejecucion comando: ', t3) tf = datetime.now() print('\nDuracion configuracion equipos: ', tf - t0)
class CEDriver(NetworkDriver): """Napalm driver for HUAWEI CloudEngine.""" def __init__(self, hostname, username, password, timeout=60, optional_args=None): """Constructor.""" self.device = None self.hostname = hostname self.username = username self.password = password self.timeout = timeout # Get optional arguments if optional_args is None: optional_args = {} # Netmiko possible arguments netmiko_argument_map = { 'port': None, 'verbose': False, 'timeout': self.timeout, 'global_delay_factor': 1, 'use_keys': False, 'key_file': None, 'ssh_strict': False, 'system_host_keys': False, 'alt_host_keys': False, 'alt_key_file': '', 'ssh_config_file': None, 'allow_agent': False, 'keepalive': 30 } # Build dict of any optional Netmiko args self.netmiko_optional_args = { k: optional_args.get(k, v) for k, v in netmiko_argument_map.items() } self.transport = optional_args.get('transport', 'ssh') self.port = optional_args.get('port', 22) self.changed = False self.loaded = False self.backup_file = '' self.replace = False self.merge_candidate = '' self.replace_file = '' self.profile = ["ce"] def open(self): """Open a connection to the device.""" try: if self.transport == 'ssh': device_type = 'huawei' else: raise ConnectionException("Unknown transport: {}".format(self.transport)) self.device = ConnectHandler(device_type=device_type, host=self.hostname, username=self.username, password=self.password, **self.netmiko_optional_args) # self.device.enable() except NetMikoTimeoutException: raise ConnectionException('Cannot connect to {}'.format(self.hostname)) def close(self): """Close the connection to the device.""" if self.changed and self.backup_file is not "": self._delete_file(self.backup_file) self.device.disconnect() self.device = None def is_alive(self): """Return a flag with the state of the SSH connection.""" null = chr(0) try: if self.device is None: return {'is_alive': False} else: # Try sending ASCII null byte to maintain the connection alive self.device.send_command(null) except (socket.error, EOFError): # If unable to send, we can tell for sure that the connection is unusable, # hence return False. return {'is_alive': False} return { 'is_alive': self.device.remote_conn.transport.is_active() } def compare_config(self): """Compare candidate config with running.""" if self.loaded: if not self.replace: return self._get_merge_diff() # return self.merge_candidate diff = self._get_diff(self.replace_file.split('/')[-1]) return diff return '' def discard_config(self): """Discard changes.""" if self.loaded: self.merge_candidate = '' # clear the buffer if self.loaded and self.replace: self._delete_file(self.replace_file) self.loaded = False def get_facts(self): """Return a set of facts from the devices.""" # default values. vendor = u'Huawei' uptime = -1 serial_number, fqdn, os_version, hostname, model = (u'Unknown', u'Unknown', u'Unknown', u'Unknown', u'Unknown') # obtain output from device show_ver = self.device.send_command('display version') show_serial = self.device.send_command('display sn') show_serial2 = self.device.send_command('display device manufacture-info') show_hostname = self.device.send_command('display current-configuration | inc sysname') show_int_status = self.device.send_command('display interface brief') # serial_number/IOS version/uptime/model for line in show_ver.splitlines(): if 'VRP (R) software' in line: search_result = re.search(r"\((?P<serial_number>CE\S+)\s+(?P<os_version>V\S+)\)", line) if search_result is not None: #serial_number = search_result.group('serial_number') os_version = search_result.group('os_version') if 'HUAWEI' in line and 'uptime is' in line: search_result = re.search(r"CE\S+", line) if search_result is not None: model = search_result.group(0) uptime = self._parse_uptime(line) break for line in show_serial.splitlines(): if model in line: search_result = re.search(rf"{model}\s+(?P<serial_number>[0-9]+\S+)\s+", line) if search_result is not None: serial_number = search_result.group('serial_number') if serial_number is "Unknown": for line in show_serial2.splitlines(): if model in line: search_result = re.search(rf"{model}\s+(?P<serial_number>[0-9]+\S+)\s+", line) if search_result is not None: serial_number = search_result.group('serial_number') if 'sysname ' in show_hostname: _, hostname = show_hostname.split("sysname ") hostname = hostname.strip() # interface_list filter interface_list = [] if 'Interface' in show_int_status: _, interface_part = show_int_status.split("Interface") re_intf = r"(?P<interface>\S+)\s+(?P<physical_state>down|up|offline|\*down)\s+" \ r"(?P<protocal_state>down|up|\*down)" search_result = re.findall(re_intf, interface_part, flags=re.M) for interface_info in search_result: interface_list.append(interface_info[0]) return { 'uptime': int(uptime), 'vendor': vendor, 'os_version': py23_compat.text_type(os_version), 'serial_number': py23_compat.text_type(serial_number), 'model': py23_compat.text_type(model), 'hostname': py23_compat.text_type(hostname), 'fqdn': fqdn, # ? fqdn(fully qualified domain name) 'interface_list': interface_list } def cli(self, commands): """Execute raw CLI commands and returns their output.""" cli_output = {} if type(commands) is not list: raise TypeError('Please enter a valid list of commands!') for command in commands: output = self.device.send_command(command) cli_output[py23_compat.text_type(command)] = output return cli_output def commit_config(self): """Commit configuration.""" if self.loaded: try: self.backup_file = 'config_' + datetime.now().strftime("%Y%m%d_%H%M") + '.cfg' if self._check_file_exists(self.backup_file): self._delete_file(self.backup_file) self._save_config(self.backup_file) if self.replace: self._load_config(self.replace_file.split('/')[-1]) else: self._commit_merge() self.merge_candidate = '' # clear the merge buffer self.changed = True self.loaded = False self._save_config() except Exception as e: raise CommitError(str(e)) else: raise CommitError('No config loaded.') def load_merge_candidate(self, filename=None, config=None): """Open the candidate config and merge.""" if not filename and not config: raise MergeConfigException('filename or config param must be provided.') self.merge_candidate += '\n' # insert one extra line if filename is not None: with open(filename, "r") as f: self.merge_candidate += f.read() else: self.merge_candidate += config self.replace = False self.loaded = True def load_replace_candidate(self, filename=None, config=None): """Open the candidate config and replace.""" if not filename and not config: raise ReplaceConfigException('filename or config param must be provided.') self._replace_candidate(filename, config) self.replace = True self.loaded = True def get_interfaces(self): """ Get interface details (last_flapped is not implemented). Sample Output: { "Vlanif3000": { "is_enabled": false, "description": "Route Port,The Maximum Transmit Unit is 1500", "last_flapped": -1.0, "is_up": false, "mac_address": "0C:45:BA:7D:83:E6", "speed": -1 }, "Vlanif100": { "is_enabled": false, "description": "Route Port,The Maximum Transmit Unit is 1500", "last_flapped": -1.0, "is_up": false, "mac_address": "0C:45:BA:7D:83:E4", "speed": -1 } } """ interfaces = {} output = self.device.send_command('display interface') if not output: return {} separator = r"(^(?!Line protocol).*current state.*$)" re_intf_name_state = r"^(?!Line protocol)(?P<intf_name>\S+).+current state\W+(?P<intf_state>.+)$" re_protocol = r"Line protocol current state\W+(?P<protocol>.+)$" re_mac = r"Hardware address is\W+(?P<mac_address>\S+)" re_speed = r"^Speed\W+(?P<speed>\d+|\w+)" re_description = r"^Description\W+(?P<description>.*)$" new_interfaces = self._separate_section(separator, output) for interface in new_interfaces: interface = interface.strip() match_intf = re.search(re_intf_name_state, interface, flags=re.M) match_proto = re.search(re_protocol, interface, flags=re.M) if match_intf is None or match_proto is None: msg = "Unexpected interface format: {}".format(interface) raise ValueError(msg) intf_name = match_intf.group('intf_name') intf_state = match_intf.group('intf_state') is_enabled = bool('up' in intf_state.lower()) protocol = match_proto.group('protocol') is_up = bool('up' in protocol.lower()) match_mac = re.search(re_mac, interface, flags=re.M) if match_mac: mac_address = match_mac.group('mac_address') mac_address = napalm.base.helpers.mac(mac_address) else: mac_address = "" speed = -1 match_speed = re.search(re_speed, interface, flags=re.M) if match_speed: speed = match_speed.group('speed') if speed.isdigit(): speed = int(speed) description = '' match = re.search(re_description, interface, flags=re.M) if match: description = match.group('description') interfaces.update({ intf_name: { 'description': description, 'is_enabled': is_enabled, 'is_up': is_up, 'last_flapped': -1.0, 'mac_address': mac_address, 'speed': speed} }) return interfaces def get_interfaces_ip(self): """ Get interface IP details. Returns a dictionary of dictionaries. Sample output: { "LoopBack0": { "ipv4": { "192.168.0.9": { "prefix_length": 32 } } }, "Vlanif2000": { "ipv4": { "192.168.200.3": { "prefix_length": 24 }, "192.168.200.6": { "prefix_length": 24 }, "192.168.200.8": { "prefix_length": 24 } }, "ipv6": { "FC00::1": { "prefix_length": 64 } } } } """ interfaces_ip = {} output_v4 = self.device.send_command('display ip interface') output_v6 = self.device.send_command('display ipv6 interface') v4_interfaces = {} separator = r"(^(?!Line protocol).*current state.*$)" new_v4_interfaces = self._separate_section(separator, output_v4) for interface in new_v4_interfaces: re_intf_name_state = r"^(?!Line protocol)(?P<intf_name>\S+).+current state\W+(?P<intf_state>.+)$" re_intf_ip = r"Internet Address is\s+(?P<ip_address>\d+.\d+.\d+.\d+)\/(?P<prefix_length>\d+)" match_intf = re.search(re_intf_name_state, interface, flags=re.M) if match_intf is None: msg = "Unexpected interface format: {}".format(interface) raise ValueError(msg) intf_name = match_intf.group('intf_name') # v4_interfaces[intf_name] = {} match_ip = re.findall(re_intf_ip, interface, flags=re.M) for ip_info in match_ip: val = {'prefix_length': int(ip_info[1])} # v4_interfaces[intf_name][ip_info[0]] = val v4_interfaces.setdefault(intf_name, {})[ip_info[0]] = val v6_interfaces = {} separator = r"(^(?!IPv6 protocol).*current state.*$)" new_v6_interfaces = self._separate_section(separator, output_v6) for interface in new_v6_interfaces: re_intf_name_state = r"^(?!IPv6 protocol)(?P<intf_name>\S+).+current state\W+(?P<intf_state>.+)$" re_intf_ip = r"(?P<ip_address>\S+), subnet is.+\/(?P<prefix_length>\d+)" match_intf = re.search(re_intf_name_state, interface, flags=re.M) if match_intf is None: msg = "Unexpected interface format: {}".format(interface) raise ValueError(msg) intf_name = match_intf.group('intf_name') match_ip = re.findall(re_intf_ip, interface, flags=re.M) for ip_info in match_ip: val = {'prefix_length': int(ip_info[1])} v6_interfaces.setdefault(intf_name, {})[ip_info[0]] = val # Join data from intermediate dictionaries. for interface, data in v4_interfaces.items(): interfaces_ip.setdefault(interface, {'ipv4': {}})['ipv4'] = data for interface, data in v6_interfaces.items(): interfaces_ip.setdefault(interface, {'ipv6': {}})['ipv6'] = data return interfaces_ip def get_interfaces_counters(self): """Return interfaces counters.""" def process_counts(tup): for item in tup: if item != "": return int(item) return 0 interfaces = {} # command "display interface counters" lacks of some keys output = self.device.send_command('display interface') if not output: return {} separator = r"(^(?!Line protocol).*current state.*$)" re_intf_name_state = r"^(?!Line protocol)(?P<intf_name>\S+).+current state\W+(?P<intf_state>.+)$" re_unicast = r"Unicast:\s+(\d+)|(\d+)\s+unicast" re_multicast = r"Multicast:\s+(\d+)|(\d+)\s+multicast" re_broadcast = r"Broadcast:\s+(\d+)|(\d+)\s+broadcast" re_dicards = r"Discard:\s+(\d+)|(\d+)\s+discard" re_rx_octets = r"Input.+\s+(\d+)\sbytes|Input:.+,(\d+)\sbytes" re_tx_octets = r"Output.+\s+(\d+)\sbytes|Output:.+,(\d+)\sbytes" re_errors = r"Total Error:\s+(\d+)|(\d+)\s+errors" new_interfaces = self._separate_section(separator, output) for interface in new_interfaces: interface = interface.strip() match_intf = re.search(re_intf_name_state, interface, flags=re.M) if match_intf is None: msg = "Unexpected interface format: {}".format(interface) raise ValueError(msg) intf_name = match_intf.group('intf_name') intf_counter = { 'tx_errors': 0, 'rx_errors': 0, 'tx_discards': 0, 'rx_discards': 0, 'tx_octets': 0, 'rx_octets': 0, 'tx_unicast_packets': 0, 'rx_unicast_packets': 0, 'tx_multicast_packets': 0, 'rx_multicast_packets': 0, 'tx_broadcast_packets': 0, 'rx_broadcast_packets': 0 } match = re.findall(re_errors, interface, flags=re.M) if match: intf_counter['rx_errors'] = process_counts(match[0]) if len(match) == 2: intf_counter['tx_errors'] = process_counts(match[1]) match = re.findall(re_dicards, interface, flags=re.M) if len(match) == 2: intf_counter['rx_discards'] = process_counts(match[0]) intf_counter['tx_discards'] = process_counts(match[1]) match = re.findall(re_unicast, interface, flags=re.M) if len(match) == 2: intf_counter['rx_unicast_packets'] = process_counts(match[0]) intf_counter['tx_unicast_packets'] = process_counts(match[1]) match = re.findall(re_multicast, interface, flags=re.M) if len(match) == 2: intf_counter['rx_multicast_packets'] = process_counts(match[0]) intf_counter['tx_multicast_packets'] = process_counts(match[1]) match = re.findall(re_broadcast, interface, flags=re.M) if len(match) == 2: intf_counter['rx_broadcast_packets'] = process_counts(match[0]) intf_counter['tx_broadcast_packets'] = process_counts(match[1]) match = re.findall(re_rx_octets, interface, flags=re.M) if match: intf_counter['rx_octets'] = process_counts(match[0]) match = re.findall(re_tx_octets, interface, flags=re.M) if match: intf_counter['tx_octets'] = process_counts(match[0]) interfaces.update({ intf_name: intf_counter }) return interfaces def get_environment(self): """ Return environment details. Sample output: { "cpu": { "0": { "%usage": 18.0 } }, "fans": { "FAN1": { "status": true } }, "memory": { "available_ram": 3884224, "used_ram": 784552 }, "power": { "PWR1": { "capacity": 600.0, "output": 92.0, "status": true } }, "temperature": { "CPU": { "is_alert": false, "is_critical": false, "temperature": 45.0 } } } """ environment = {} fan_cmd = 'display device fan' power_cmd = 'display device power' temp_cmd = 'display device temperature all' cpu_cmd = 'display cpu' mem_cmd = 'display memory' output = self.device.send_command(fan_cmd) environment.setdefault('fans', {}) match = re.findall(r"(?P<id>FAN\S+).+(?P<status>Normal|Abnormal)", output, re.M) # if match: for fan in match: status = True if fan[1] == "Normal" else False environment['fans'].setdefault(fan[0], {})['status'] = status output = self.device.send_command(power_cmd) environment.setdefault('power', {}) re_power = r"(?P<id>PWR\S+).+(?P<status>Supply|NotSupply|Sleep)\s+\S+\s+\S+\s+" \ r"(?P<output>\d+)\s+(?P<capacity>\d+)" match = re.findall(re_power, output, re.M) for power in match: status = True if power[1] == "Supply" else False environment['power'].setdefault(power[0], {})['status'] = status environment['power'][power[0]]['output'] = float(power[2]) environment['power'][power[0]]['capacity'] = float(power[3]) output = self.device.send_command(temp_cmd) environment.setdefault('temperature', {}) re_temp = r"(?P<name>\S+)\s+(?P<status>NORMAL|MAJOR|FATAL|ABNORMAL)\s+\S+\s+\S+\s+(?P<temperature>\d+)" match = re.findall(re_temp, output, re.M) for temp in match: environment['temperature'].setdefault(temp[0], {}) name = temp[0] is_alert = True if temp[1] == "MAJOR" else False is_critical = True if temp[1] == "FATAL" else False environment['temperature'][name]['temperature'] = float(temp[2]) environment['temperature'][name]['is_alert'] = is_alert environment['temperature'][name]['is_critical'] = is_critical output = self.device.send_command(cpu_cmd) environment.setdefault('cpu', {}) match = re.findall(r"cpu(?P<id>\d+)\s+(?P<usage>\d+)%", output, re.M) for cpu in match: usage = float(cpu[1]) environment['cpu'].setdefault(cpu[0], {})['%usage'] = usage output = self.device.send_command(mem_cmd) environment.setdefault('memory', {'available_ram': 0, 'used_ram': 0}) match = re.search(r"System Total Memory:\s+(?P<available_ram>\d+)", output, re.M) if match is not None: environment['memory']['available_ram'] = int(match.group("available_ram")) match = re.search(r"Total Memory Used:\s+(?P<used_ram>\d+)", output, re.M) if match is not None: environment['memory']['used_ram'] = int(match.group("used_ram")) return environment def get_arp_table(self): """ Get arp table information. Return a list of dictionaries having the following set of keys: * interface (string) * mac (string) * ip (string) * age (float) (not support) Sample output: [ { 'interface' : 'MgmtEth0/RSP0/CPU0/0', 'mac' : '5c:5e:ab:da:3c:f0', 'ip' : '172.17.17.1', 'age' : -1 }, { 'interface': 'MgmtEth0/RSP0/CPU0/0', 'mac' : '66:0e:94:96:e0:ff', 'ip' : '172.17.17.2', 'age' : -1 } ] """ arp_table = [] output = self.device.send_command('display arp') re_arp = r"(?P<ip_address>\d+\.\d+\.\d+\.\d+)\s+(?P<mac>\S+)\s+(?P<exp>\d+|)\s+" \ r"(?P<type>I|D|S|O)\s+(?P<interface>\S+)" match = re.findall(re_arp, output, flags=re.M) for arp in match: # if arp[2].isdigit(): # exp = float(arp[2]) * 60 # else: # exp = 0 entry = { 'interface': arp[4], 'mac': napalm.base.helpers.mac(arp[1]), 'ip': arp[0], 'age': -1.0, } arp_table.append(entry) return arp_table def get_config(self, retrieve='all'): """ Get config from device. Returns the running configuration as dictionary. The candidate and startup are always empty string for now, since CE does not support candidate configuration. """ config = { 'startup': '', 'running': '', 'candidate': '' } if retrieve.lower() in ('running', 'all'): command = 'display current-configuration' config['running'] = py23_compat.text_type(self.device.send_command(command)) if retrieve.lower() in ('startup', 'all'): # command = 'display saved-configuration last' # config['startup'] = py23_compat.text_type(self.device.send_command(command)) pass return config def get_lldp_neighbors(self): """ Return LLDP neighbors details. Sample output: { "10GE4/0/1": [ { "hostname": "HUAWEI", "port": "10GE4/0/25" }, { "hostname": "HUAWEI2", "port": "10GE4/0/26" } ] } """ results = {} command = 'display lldp neighbor brief' output = self.device.send_command(command) re_lldp = r"(?P<local>\S+)\s+\d+\s+(?P<port>\S+)\s+(?P<hostname>\S+)" match = re.findall(re_lldp, output, re.M) for neighbor in match: local_iface = neighbor[0] if local_iface not in results: results[local_iface] = [] neighbor_dict = dict() neighbor_dict['port'] = py23_compat.text_type(neighbor[1]) neighbor_dict['hostname'] = py23_compat.text_type(neighbor[2]) results[local_iface].append(neighbor_dict) return results def get_lldp_neighbors_details(self): """ Return LLDP neighbors details. Sample output: Local Interface Exptime(s) Neighbor Interface Neighbor Device ------------------------------------------------------------------------------- 10GE1/0/1 117 GigabitEthernet4/0/9 bitb_G20U41_usg6680_om_1 10GE1/0/2 92 10GE1/0/1 bitb_G22U39_ce5850_manage_2 10GE1/0/3 117 10GE1/0/48 bitb_G19U42_CE6851_bmccore_1 10GE1/0/4 94 10GE1/0/15 tb-bier00d08u36nwswdwdm-1 GE1/0/2 118 GigabitEthernet0/0/0 bitb_G19U23_usg6670_vpn_1 GE1/0/3 117 GigabitEthernet0/0/0 bitb_G19U27_usg6680_nat_1 GE1/0/4 102 GigabitEthernet0/0/0 bitb_G19U31_usg6680_pod1_1 GE1/0/5 113 GigabitEthernet0/0/0 bitb_G19U35_usg6680_dmz_1 GE1/0/6 99 GigabitEthernet0/0/0 bitb_G19U39_usg6680_mgr_1 GE1/0/10 116 GigabitEthernet0/0/0 bitb_G20U29_usg6680_uds_1 GE1/0/11 92 GigabitEthernet0/0/0 bitb_G20U33_usg6680_uds_2 GE1/0/12 94 GigabitEthernet0/0/0 bitb_G20U37_usg6680_pod1_2 GE1/0/13 116 GigabitEthernet0/0/0 bitb_G20U41_usg6680_om_ """ results = {} command = 'display lldp neighbor brief' output = self.device.send_command(command) re_lldp = r"(?P<local>\S+)\s+\d+\s+(?P<port>\S+)\s+(?P<hostname>\S+)" match = re.findall(re_lldp, output, re.M) for neighbor in match: local_iface = neighbor[0] if local_iface not in results: results[local_iface] = [] neighbor_dict = dict() neighbor_dict['remote_port'] = py23_compat.text_type(neighbor[1]) neighbor_dict['remote_system_name'] = py23_compat.text_type(neighbor[2]) results[local_iface].append(neighbor_dict) return results def get_mac_address_table(self): """ Return the MAC address table. Sample output: [ { "active": true, "interface": "10GE1/0/1", "last_move": -1.0, "mac": "00:00:00:00:00:33", "moves": -1, "static": false, "vlan": 100 }, { "active": false, "interface": "10GE1/0/2", "last_move": -1.0, "mac": "00:00:00:00:00:01", "moves": -1, "static": true, "vlan": 200 } ] """ mac_address_table = [] command = 'display mac-address' output = self.device.send_command(command) re_mac = r"(?P<mac>\S+)\s+(?P<vlan>\d+|-)\S+\s+(?P<interface>\S+)\s+(?P<type>\w+)\s+(?P<age>\d+|-)" match = re.findall(re_mac, output, re.M) for mac_info in match: mac_dict = { 'mac': napalm.base.helpers.mac(mac_info[0]), 'interface': py23_compat.text_type(mac_info[2]), 'vlan': int(mac_info[1]), 'static': True if mac_info[3] == "static" else False, 'active': True if mac_info[3] == "dynamic" else False, 'moves': -1, 'last_move': -1.0 } mac_address_table.append(mac_dict) return mac_address_table def get_users(self): """ Return the configuration of the users. Sample output: { "admin": { "level": 3, "password": "", "sshkeys": [] } } """ result = {} command = 'display aaa local-user' output = self.device.send_command(command) re_user = r"(?P<username>\S+)\s+(Active|Block)(\s+\S+){3}\s+(\d+|--)" match = re.findall(re_user, output, re.M) try: for user in match: # level = -1 can not pass unit test level = 0 if user[3] == '--' else int(user[3]) result.setdefault(user[0], {})['level'] = level result[user[0]]['password'] = '' result[user[0]]['sshkeys'] = [] except Exception: msg = "Unexpected output data:\n{}".format(output) raise ValueError(msg) # Password is encrypted and cannot be read # command = 'display current-configuration | inc user' # output = self.device.send_command(command) return result def rollback(self): """Rollback to previous commit.""" if self.changed: self._load_config(self.backup_file) self.changed = False self._save_config() def ping(self, destination, source=c.PING_SOURCE, ttl=c.PING_TTL, timeout=c.PING_TIMEOUT, size=c.PING_SIZE, count=c.PING_COUNT, vrf=c.PING_VRF): """Execute ping on the device.""" ping_dict = {} command = 'ping' # Timeout in milliseconds to wait for each reply, the default is 2000 command += ' -t {}'.format(timeout*1000) # Specify the number of data bytes to be sent command += ' -s {}'.format(size) # Specify the number of echo requests to be sent command += ' -c {}'.format(count) if source != '': command += ' -a {}'.format(source) command += ' {}'.format(destination) output = self.device.send_command(command) if 'Error' in output: ping_dict['error'] = output elif 'PING' in output: ping_dict['success'] = { 'probes_sent': 0, 'packet_loss': 0, 'rtt_min': 0.0, 'rtt_max': 0.0, 'rtt_avg': 0.0, 'rtt_stddev': 0.0, 'results': [] } match_sent = re.search(r"(\d+).+transmitted", output, re.M) match_received = re.search(r"(\d+).+received", output, re.M) try: probes_sent = int(match_sent.group(1)) probes_received = int(match_received.group(1)) ping_dict['success']['probes_sent'] = probes_sent ping_dict['success']['packet_loss'] = probes_sent - probes_received except Exception: msg = "Unexpected output data:\n{}".format(output) raise ValueError(msg) match = re.search(r"min/avg/max = (\d+)/(\d+)/(\d+)", output, re.M) if match: ping_dict['success'].update({ 'rtt_min': float(match.group(1)), 'rtt_avg': float(match.group(2)), 'rtt_max': float(match.group(3)), }) results_array = [] match = re.findall(r"Reply from.+time=(\d+)", output, re.M) for i in match: results_array.append({'ip_address': py23_compat.text_type(destination), 'rtt': float(i)}) ping_dict['success'].update({'results': results_array}) return ping_dict def __get_snmp_information(self): snmp_information = {} # command = 'display snmp-agent sys-info' # output = self.device.send_command(command) snmp_information = { 'contact': py23_compat.text_type(''), 'location': py23_compat.text_type(''), 'community': {}, 'chassis_id': py23_compat.text_type('') } return snmp_information def __get_lldp_neighbors_detail(self, interface=''): """ Return a detailed view of the LLDP neighbors as a dictionary. Sample output: { 'TenGigE0/0/0/8': [ { 'parent_interface': u'Bundle-Ether8', 'remote_chassis_id': u'8c60.4f69.e96c', 'remote_system_name': u'switch', 'remote_port': u'Eth2/2/1', 'remote_port_description': u'Ethernet2/2/1', 'remote_system_description': u'''huawei os''', 'remote_system_capab': u'B, R', 'remote_system_enable_capab': u'B' } ] } """ lldp_neighbors = {} return lldp_neighbors def __get_ntp_peers(self): """ Return the NTP peers configuration as dictionary. Sample output: { '192.168.0.1': {}, '17.72.148.53': {}, '37.187.56.220': {}, '162.158.20.18': {} } """ ntp_server = {} # command = "display ntp session" # output = self.device.send_command(command) return ntp_server def __get_ntp_servers(self): """ Return the NTP servers configuration as dictionary. Sample output: { '192.168.0.1': {}, '17.72.148.53': {}, '37.187.56.220': {}, '162.158.20.18': {} } """ ntp_server = {} # command = "display ntp trace" # output = self.device.send_command(command) return ntp_server def __get_ntp_stats(self): ntp_stats = [] # command = "display ntp status" # output = self.device.send_command(command) return ntp_stats @staticmethod def _separate_section(separator, content): if content == "": return [] # Break output into per-interface sections interface_lines = re.split(separator, content, flags=re.M) if len(interface_lines) == 1: msg = "Unexpected output data:\n{}".format(interface_lines) raise ValueError(msg) # Get rid of the blank data at the beginning interface_lines.pop(0) # Must be pairs of data (the separator and section corresponding to it) if len(interface_lines) % 2 != 0: msg = "Unexpected output data:\n{}".format(interface_lines) raise ValueError(msg) # Combine the separator and section into one string intf_iter = iter(interface_lines) try: new_interfaces = [line + next(intf_iter, '') for line in intf_iter] except TypeError: raise ValueError() return new_interfaces def _delete_file(self, filename): command = 'delete /unreserved /quiet {0}'.format(filename) self.device.send_command(command) def _save_config(self, filename=''): """Save the current running config to the given file.""" command = 'save {}'.format(filename) save_log = self.device.send_command(command, max_loops=10, expect_string=r'Y/N') # Search pattern will not be detected when set a new hostname, so don't use auto_find_prompt=False save_log += self.device.send_command('y', expect_string=r'<.+>') search_result = re.search("successfully", save_log, re.M) if search_result is None: msg = "Failed to save config. Command output:{}".format(save_log) raise CommandErrorException(msg) def _load_config(self, config_file): command = 'rollback configuration to file {0}'.format(config_file) rollback_result = self.device.send_command(command, expect_string=r'Y/N') rollback_result += self.device.send_command('y', expect_string=r'[<\[].+[>\]]') search_result = re.search("clear the information", rollback_result, re.M) if search_result is not None: rollback_result += self.device.send_command('y', expect_string=r'<.+>') search_result = re.search("succeeded|finished", rollback_result, re.M) if search_result is None: msg = "Failed to load config. Command output:{}".format(rollback_result) raise CommandErrorException(msg) def _replace_candidate(self, filename, config): if not filename: filename = self._create_tmp_file(config) else: if not os.path.isfile(filename): raise ReplaceConfigException("File {} not found".format(filename)) self.replace_file = filename if not self._enough_space(self.replace_file): msg = 'Could not transfer file. Not enough space on device.' raise ReplaceConfigException(msg) need_transfer = True if self._check_file_exists(self.replace_file): if self._check_md5(self.replace_file): need_transfer = False if need_transfer: dest = os.path.basename(self.replace_file) # full_remote_path = 'flash:/{}'.format(dest) with paramiko.SSHClient() as ssh: ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(hostname=self.hostname, username=self.username, password=self.password, port=self.port, look_for_keys=False) try: with paramiko.SFTPClient.from_transport(ssh.get_transport()) as sftp_client: sftp_client.put(self.replace_file, dest) # with SCPClient(ssh.get_transport()) as scp_client: # scp_client.put(self.replace_file, dest) except Exception as e: msg = 'Could not transfer file. There was an error during transfer:' + str(e) raise ReplaceConfigException(msg) self.config_replace = True if config and os.path.isfile(self.replace_file): os.remove(self.replace_file) def _verify_remote_file_exists(self, dst, file_system='flash:'): command = 'dir {0}/{1}'.format(file_system, dst) output = self.device.send_command(command) if 'No file found' in output: raise ReplaceConfigException('Could not transfer file.') def _check_file_exists(self, cfg_file): command = 'dir {}'.format(cfg_file) output = self.device.send_command(command) if 'No file found' in output: return False return True def _check_md5(self, dst): dst_hash = self._get_remote_md5(dst) src_hash = self._get_local_md5(dst) if src_hash == dst_hash: return True return False @staticmethod def _get_local_md5(dst, blocksize=2**20): md5 = hashlib.md5() local_file = open(dst, 'rb') buf = local_file.read(blocksize) while buf: md5.update(buf) buf = local_file.read(blocksize) local_file.close() return md5.hexdigest() def _get_remote_md5(self, dst): command = 'display system file-md5 {0}'.format(dst) output = self.device.send_command(command) filename = os.path.basename(dst) match = re.search(filename + r'\s+(?P<md5>\w+)', output, re.M) if match is None: msg = "Unexpected format: {}".format(output) raise ValueError(msg) return match.group('md5') def _commit_merge(self): commands = [command for command in self.merge_candidate.splitlines() if command] output = '' try: output += self.device.send_command('system-view', expect_string=r'\[.+\]') for command in commands: output += self.device.send_command(command, expect_string=r'\[.+\]') if self.device.check_config_mode(): check_error = re.search("error", output, re.IGNORECASE) if check_error is not None: return_log = self.device.send_command('return', expect_string=r'[<\[].+[>\]]') if 'Uncommitted configurations' in return_log: # Discard uncommitted configuration return_log += self.device.send_command('n', expect_string=r'<.+>') output += return_log raise MergeConfigException('Error while applying config!') output += self.device.send_command('commit', expect_string=r'\[.+\]') output += self.device.send_command('return', expect_string=r'<.+>') else: raise MergeConfigException('Not in configuration mode.') except Exception as e: msg = str(e) + '\nconfiguration output: ' + output raise MergeConfigException(msg) def _get_merge_diff(self): diff = [] running_config = self.get_config(retrieve='running')['running'] running_lines = running_config.splitlines() for line in self.merge_candidate.splitlines(): if line not in running_lines and line: if line[0].strip() != '!': diff.append(line) return '\n'.join(diff) def _get_diff(self, filename=None): """Get a diff between running config and a proposed file.""" if filename is None: return self.device.send_command('display configuration changes') return self.device.send_command('display configuration changes running file ' + filename) def _enough_space(self, filename): flash_size = self._get_flash_size() file_size = os.path.getsize(filename) if file_size > flash_size: return False return True def _get_flash_size(self): command = 'dir {}'.format('flash:') output = self.device.send_command(command) match = re.search(r'\(\d.*KB free\)', output, re.M) if match is None: msg = "Failed to get free space of flash (not match). Log: {}".format(output) raise ValueError(msg) kbytes_free = 0 num_list = map(int, re.findall(r'\d+', match.group())) for index, val in enumerate(reversed(num_list)): kbytes_free += val * (1000 ** index) bytes_free = kbytes_free * 1024 return bytes_free @staticmethod def _parse_uptime(uptime_str): """Return the uptime in seconds as an integer.""" (years, weeks, days, hours, minutes, seconds) = (0, 0, 0, 0, 0, 0) years_regx = re.search(r"(?P<year>\d+)\syear", uptime_str) if years_regx is not None: years = int(years_regx.group(1)) weeks_regx = re.search(r"(?P<week>\d+)\sweek", uptime_str) if weeks_regx is not None: weeks = int(weeks_regx.group(1)) days_regx = re.search(r"(?P<day>\d+)\sday", uptime_str) if days_regx is not None: days = int(days_regx.group(1)) hours_regx = re.search(r"(?P<hour>\d+)\shour", uptime_str) if hours_regx is not None: hours = int(hours_regx.group(1)) minutes_regx = re.search(r"(?P<minute>\d+)\sminute", uptime_str) if minutes_regx is not None: minutes = int(minutes_regx.group(1)) seconds_regx = re.search(r"(?P<second>\d+)\ssecond", uptime_str) if seconds_regx is not None: seconds = int(seconds_regx.group(1)) uptime_sec = (years * YEAR_SECONDS) + (weeks * WEEK_SECONDS) + (days * DAY_SECONDS) + \ (hours * 3600) + (minutes * 60) + seconds return uptime_sec @staticmethod def _create_tmp_file(config): tmp_dir = tempfile.gettempdir() rand_fname = py23_compat.text_type(uuid.uuid4()) filename = os.path.join(tmp_dir, rand_fname) with open(filename, 'wt') as fobj: fobj.write(config) return filename
"nxos_subnet": 24, "nxos_local_as": as_num, "nxos_remote_as": as_num } nxos2_temp_dict = { "nxos_int": "Ethernet1/2", "nxos_ip": "10.1.250.2", "nxos_subnet": 24, "nxos_local_as": as_num, "nxos_remote_as": as_num } nxos1_temp_dict["nxos_peer_ip"] = nxos2_temp_dict["nxos_ip"] nxos2_temp_dict["nxos_peer_ip"] = nxos1_temp_dict["nxos_ip"] nxos1_t = env.get_template("Ex2b.j2") nxos1_op = nxos1_t.render(nxos1_temp_dict) nxos1_op_lines = [line.strip() for line in nxos1_op.splitlines()] nxos1_connect = ConnectHandler(**nxos1_dict) nxos1_cmd_op = nxos1_connect.send_config_set(nxos1_op_lines) nxos1_connect.disconnect() print(nxos1_cmd_op) nxos2_t = env.get_template("Ex2b.j2") nxos2_op = nxos2_t.render(nxos2_temp_dict) nxos2_op_lines = [line.strip() for line in nxos2_op.splitlines()] nxos2_connect = ConnectHandler(**nxos2_dict) nxos2_cmd_op = nxos2_connect.send_config_set(nxos2_op_lines) nxos2_connect.disconnect() print(nxos2_cmd_op)
logfile = open( "/home/GTSesMon/PycharmProjects/SIPGatewayLog/siplog_14412", "w") net_connect = ConnectHandler(**cisco_router) prompt_text = net_connect.find_prompt() print(prompt_text) if prompt_text != '': net_connect.enable() if gateway_info[gt_counter][1] == 'CALL': output = net_connect.send_command( 'sh call history voice brief | i :') elif gateway_info[gt_counter][1] == 'VIDEO': output = net_connect.send_command( 'sh call history video brief | i :') logfile.write(output) net_connect.disconnect() logfile.close() #CALL-SIP/CALL-PRI #VIDEO-SIP/VIDEO-PRI #IP RANGE #OPEN TEMPLATE if gateway_info[gt_counter][1] == 'CALL': template = open("parserSIP.textfsm") elif gateway_info[gt_counter][1] == 'VIDEO': template = open("parserVideo.textfsm") re_table = textfsm.TextFSM(template) fsm_results = re_table.ParseText(output) gateway_id_list = [[gateway_info[gt_counter][0]]] * len(fsm_results) gateway_type_list = [[gateway_info[gt_counter][1]]] * len(fsm_results) appended_fsm_results = [ x + y + z
def connect_ssh(target_ip, username, password, DEBUG, output): if DEBUG: verbose = True else: verbose = False dns_list = list() for i in target_ip: try: # Define variables for function x, z, v = 0, 1, 2 vlan_list = list() output += ("*" * 4 + " START device: %s " + "-" * 35 + ">" * 4 + "\n") % i ssh_con = ConnectHandler(device_type='hp_procurve', ip=i, username=username, password=password, verbose=verbose) # Find hostname will be used for first part of VLAN IP dns name output += "\nFind prompt: \n" output_cmd = ssh_con.find_prompt() hostname = output_cmd if DEBUG: print hostname output += output_cmd # Get VLAN information from switch output_cmd = ssh_con.send_command( 'show vlan custom id name ipaddr') vlan_output = output_cmd.split(' ') output += output_cmd # Clean output information vlan_output = filter(None, vlan_output) # Filter VLAN ID's for y in vlan_output[18:-1]: if y != '\n': vlan_list.append(y) if DEBUG: print vlan_list lp = len(vlan_list) / 3 while lp != 0: vlan_name = hostname[:-1] + '-' + 'VL' + vlan_list[ x] + '-' + vlan_list[z] dns_list.append(vlan_name) dns_list.append(vlan_list[v]) x += 3 z += 3 v += 3 lp -= 1 if DEBUG: print dns_list ssh_con.disconnect() except: print "Problem connecting with ip: %s" % (i) continue return output, dns_list