def get_configured_networks(vrf=None, interactive=True): """Get static routes from router configuration Args: vrf (str): VRF name interactive (bool): interactive mode (or automated), used for logging method Returns: dict with 2 lists of network prefixes (ipv4, ipv6). """ v4cfg_nets = [] v6cfg_nets = [] vrf_insert = "vrf {}".format(vrf) if vrf else "" exec_result = execute("sh run | section ip route {}".format(vrf_insert)) routes = exec_result.split("\n") for r in routes: netw = match_ipv4_route(r, vrf=vrf) if netw: v4cfg_nets.append(netw) exec_result = execute("sh run | section ipv6 route {}".format(vrf_insert)) routes = exec_result.split("\n") for r in routes: netw = match_ipv6_route(r, vrf=vrf) if netw: v6cfg_nets.append(netw) return {"ipv4": v4cfg_nets, "ipv6": v6cfg_nets}
def main(): execute('send log Application subscriber_listener.py started') logging.basicConfig( filename='application_run.log', level=logging.DEBUG, format= '%(asctime)s.%(msecs)03d %(levelname)s %(module)s - %(funcName)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S') global IOS_XE_HOST_IP, DEVICE_HOSTNAME, DEVICE_LOCATION # retrieve the ios xe device management ip address, Gi0/0 IOS_XE_HOST_IP = execute('sh run int gi1 | in ip address').split(' ')[3] # retrieve the device hostname using RESTCONF DEVICE_HOSTNAME = netconf_restconf.get_restconf_hostname( IOS_XE_HOST_IP, IOS_XE_USER, IOS_XE_PASS) print(str('\nThe device hostname: ' + DEVICE_HOSTNAME)) """ The following commands are if Cisco DNA Center is available # get DNA C AUth JWT token dnac_token = dnac_apis.get_dnac_jwt_token(DNAC_AUTH) DEVICE_LOCATION = dnac_apis.get_device_location(DEVICE_HOSTNAME, dnac_token) print(str("\nDevice Location: " + DEVICE_LOCATION)) """ # init the PubNub channel pubnub = pubnub_init(DEVICE_HOSTNAME) pubnub.add_listener(MySubscribeCallback()) pubnub.subscribe().channels(CHANNEL).execute()
def heartbeat_call(self, event): # Send a packet to every WiFiTrilat server. for host in [s[1:s.find('/WiFi')] for s in self.client.discover()]: #sr(IP(dst=host)/ICMP(), iface=self.interface) cli.execute(command='ping -c 4 %s' % host, wait=False, shellexec=True)
def configure_IBNS2(): # Copy and merge IBNS 2.0 template into running-config configure('file prompt quiet') execute('copy http://192.168.1.100/IBNS2.cfg running-config') print '\n\n\n\n****************************************\n' print 'IBNS 2.0 template applied...' print '\n****************************************\n\n'
def message(self, pubnub, message): output_message = '' new_message = message.message print("\nNew message received: ") utils.pprint(new_message) device = new_message['device'] if device == DEVICE_HOSTNAME or device == "all": command_type = new_message['command_type'] incident = new_message['incident'] # execute the configuration type of commands if command_type == 'config': try: # parse the config commands or command command = new_message['commands'] command_list = command.split('!') comment = 'Configuration commands received: ' + command # print to Python console, log to host device, and update ServiceNow print(comment) execute('send log WhatsOp: ' + comment) service_now_apis.update_incident(incident, comment, SNOW_DEV) # submit the command using Python CLI, update incident with result output = configure(command_list) output_message = (str(output).replace('),', '),\n')).replace('[', ' ').replace(']', ' ') print(output_message) service_now_apis.update_incident(incident, output_message, SNOW_DEV) status_message = 'Configuration command Successful' except: status_message = "Configuration Command Executed" print(output_message) # execute the exec type of commands if command_type == 'exec': try: # parse the exec command command = new_message['commands'] comment = str('Exec command received: ' + command) # print to Python console, log to host device, and update ServiceNow print(comment) execute('send log WhatsOp: ' + comment) service_now_apis.update_incident(incident, comment, SNOW_DEV) # send the command to device using Python CLI output_message = execute(str(command)) service_now_apis.update_incident(incident, output_message, SNOW_DEV) # pretty print the command output to console out_list = output_message.split('\n') for items in out_list: if items is not "": print(items) status_message = 'Successful' except: status_message = 'Unsuccessful' print(str('\nCommand result: ' + status_message))
def stop_capture(job_id, filename): cli.execute("monitor capture PKT_CAP stop") cmd = "monitor capture PKT_CAP export flash:%s" % filename cli.execute(cmd) configuration = 'no ip access-list extended PKT_CAP' # delete capture ACL so next capture has a fresh filter cli.configure(configuration) print('job_id %d stopped' % job_id)
def execute_command(command, print_output): cmd_output = cli.execute(command) while len(cmd_output) == 0: print "CMD FAILED, retrying" cmd_output = cli.execute(command) print_cmd_output(command, cmd_output, print_output) return cmd_output
def log(severity, message): """ Sends string representation of message to stdout and IOS logging """ ztp['logbuf'] += '\n' + str(message) print('\n%s' % str(message)) sys.stdout.flush( ) # force writing everything in the buffer to the terminal if SYSLOG: for line in str(message).splitlines(): cli.execute('send log %d "%s"' % (severity, line))
def blue_beacon(sw_nums): """ Turns on blue beacon of given switch number list, if supported """ for num in sw_nums: # up to and including 16.8.x try: cli.cli('configure terminal ; hw-module beacon on switch %d' % num) except (cli.errors.cli_syntax_error, cli.errors.cli_exec_error): pass # from 16.9.x onwards try: cli.execute('hw-module beacon slot %d on' % num) except cli.CLISyntaxError: pass log(6, 'Switch %d beacon LED turned on' % num)
def Main(): es = Elasticsearch('http://' + ELASTIC_CREDS + '@' + ELASTIC_HOST + ':9200/') SGTcounters = cli.execute('show cts role-based counters') daclCounters = showCtsCounters2Table(SGTcounters) idx = int(time.time()) for record in daclCounters: res = es.index(index=ELASTIC_INDEX, doc_type='counters', id=idx, body=record) idx += 1 rs = cli.execute('clear cts role-based counters')
def final_cli(command): """ Returns True if given command string is executed succesfully """ success = False if command is not None: success = True for cmd in command.splitlines(): # look for python expressions within {{...}} match = re.search('{{(.*?)}}', cmd) if match: try: result = eval(match.group(1)) # evaluate expression except Exception as e: log(3, 'Final command failure: %s' % e) success = False continue else: if result is None: continue # replace expression with result cmd = cmd.replace(match.group(0), str(result)) try: output = cli.execute(cmd) # execute command except cli.CLISyntaxError as e: log(3, 'Final command failure: %s' % e) success = False else: # append command output to cli item of global dict ztp fmt = '{}{:-^60.54}\n\n{}\n\n' ztp['cli'] = fmt.format(ztp.get('cli', ''), cmd, output) return success
def upload(**kwargs): """ Adds given named arguments to dict and sends data to log API """ ztp.update(kwargs) if LOGAPI: try: with open('/bootflash/temp.json', 'w') as outfile: json.dump(ztp, outfile) except (IOError, ValueError) as e: log(3, e) return for retry in range(3): log(6, 'Storing %s...' % LOGAPI) result = cli.execute('copy temp.json %s' % LOGAPI) # log error message in case of failure match = re.search('^(%Error .*)', result, re.MULTILINE) if match: log(3, match.group(1)) else: break try: os.remove('/bootflash/temp.json') except OSError as e: log(3, e)
def get_hostname(): from cli import execute command = 'show version' show_version = execute(command) exp = re.compile(r'([\w\d]+)\suptime is\s') hostname = exp.findall(show_version) return hostname[0]
def check_qos_enabled(interface): result = cli.execute( "show policy-map interface {} output".format(interface)) if len(result) == 0: return False else: return True
def span_port_occupancy(span_port): ''' INPUT Input on the function will come from CLI execution using the SPAN Port ID OUTPUT Return the queue real time occupancy per queue for the SPAN port in units. the return is a list. ''' output = cli.execute('show platform hardware fed active qos queue stats interface {0} | section include [0-9][ ]+[0-9]+.*'.format(span_port)) queues_only = 0 All_queues_occupancy = {} for queue_buffer in output.splitlines(): p = re.compile(r'^([0-9]+)[ ]+([0-9]+).*') m = p.match(queue_buffer) if m: Queue_ID = m.group(1) occupancy = int(m.group(2)) All_queues_occupancy.update({Queue_ID : occupancy}) queues_only = queues_only + 1 if queues_only == 9: break return All_queues_occupancy
def span_port_totalbuffer_units(span_port): ''' INPUT Input on the function will come from CLI execution using the SPAN Port ID OUTPUT Return per queue total number of units give to queue. the return is a list ''' output = cli.execute('show platform hardware fed active qos queue config interface {0} | begin DTS'.format(span_port)) queues_only = 0 All_queues_buffers = {} for queue_buffer in output.splitlines(): p = re.compile(r'^[ ]([0-9]+)[ ]+[0-9]+[ ]+[0-9]+[ ]+[0-9]+[ ]+[0-9]+[ ]+([0-9]+).*') m = p.match(queue_buffer) if m: Queue_ID = m.group(1) Buffers = int(m.group(2)) All_queues_buffers.update(\{Queue_ID : Buffers\}) queues_only = queues_only + 1 if queues_only == 11: break return All_queues_buffers
def start_capture(proto, src, dst): configuration = acl_command(proto, src, dst) cli.configure(configuration) cli.execute( "monitor capture PKT_CAP access-list PKT_CAP buffer circular size 100") cmd = "monitor capture PKT_CAP interface %s both" % args.interface cli.execute(cmd) cli.execute("monitor capture PKT_CAP clear") cli.execute("monitor capture PKT_CAP start")
def shutdown(save=False, abnormal=False): """ Cleansup and saves config if needed and terminates script """ if save: log(6, 'Saving configuration upon script termination') # store script state to LOGAPI if specified upload(status='Failed' if abnormal else 'Finished') if SYSLOG: cli.configure('''no logging host %s no logging discriminator ztp''' % SYSLOG) if save: cli.execute('copy running-config startup-config') # terminate script with exit status sys.exit(int(abnormal))
def testTimeoutErrorContainsOutput(self): try: response = cli.execute(TIMEOUT_COMMAND) self.fail( "Command did not timeout, cannot check the timeout error.") except cli.CLITimeoutError as e: self.assertIsInstance(e.output, basestring) self.assertGreater(len(e.output), 0)
def start_capture(job_id, iface, proto, src, dst): configuration = acl_command(proto, src, dst) cli.configure(configuration) cli.execute( "monitor capture PKT_CAP access-list PKT_CAP buffer circular size 100") cmd = "monitor capture PKT_CAP interface %s both" % iface cli.execute(cmd) cli.execute("monitor capture PKT_CAP clear") print('job_id %d starting' % job_id) cli.execute("monitor capture PKT_CAP start")
def hostname(): showver = cli.execute("show version") for line in showver.split('\n'): tokens = line.split() if len(tokens) > 2: if tokens[1] == 'uptime': return (tokens[0]) break return ('switch')
def save_config(): # save running configuration, use local time to create new config file name command_output = execute('show run') timestr = time.strftime('%Y%m%d-%H%M%S') config_filename = '/bootflash/CONFIG_FILES/' + timestr + '_shrun' fileop1 = open(config_filename, 'w') fileop1.write(command_output) fileop1.close() fileop2 = open('/bootflash/CONFIG_FILES/current_config_name', 'w') fileop2.write(config_filename) fileop2.close() execute('copy run start') # save the running config to startup return config_filename
def is_iosxe_package(url): """ Returns True if the given file is an IOS XE package """ info = cli.execute('show file information %s' % url) # log error message if any and terminate script in case of failure match = re.match('^(%Error .*)', info) if match: log(3, match.group(1)) shutdown(save=False, abnormal=True) return bool(re.search('IFS|NOVA|IOSXE_PACKAGE', info))
def install(target, is_chassis): """ Returns True if install script is configured or False otherwise """ # remove leading zeros from required version numbers and compare if (target.version is None or target.install is None or ztp['version'] == re.sub(r'\b0+(\d)', r'\1', target.version.strip())): return False install_url = urljoin(target.base_url, target.install) # terminate script in case of invalid file log(6, 'Checking %s' % install_url) if not is_iosxe_package(install_url): log(3, '%s is not valid image file' % install_url) shutdown(save=False, abnormal=True) # change boot mode if device is in bundle mode if 'bundle' in ztp['version']: fs = 'bootflash:' if is_chassis else 'flash:' log(6, 'Changing the Boot Mode') cli.configure('''no boot system boot system {}packages.conf'''.format(fs)) cli.execute('write memory') cli.execute('write erase') # install command needs confirmation on changed boot config confirm_bm = '''pattern "\[y\/n\]|#" action 5.3 cli command "y"''' else: confirm_bm = '' # Configure EEM applet for interactive command execution cli.configure('''event manager applet upgrade event none maxrun 900 action 1.0 cli command "enable" action 2.0 syslog msg "Removing inactive images..." action 3.0 cli command "install remove inactive" pattern "\[y\/n\]|#" action 3.1 cli command "y" action 4.0 syslog msg "Downloading and installing image..." action 5.0 cli command "install add file %s activate commit" pattern "\[y\/n\/q\]|#" action 5.1 cli command "n" pattern "\[y\/n\]|#" action 5.2 cli command "y" %s action 6.0 syslog msg "Reloading stack..." action 7.0 reload''' % (install_url, confirm_bm)) return True
def get_onprem_ips(): if 'cli' not in sys.modules: # Testing without IOS on_prem_ips = [u'10.100.100.20'] #, u'10.100.100.5'] log.info('Using test IPs {} for testing as this does not run on IOS'.format(on_prem_ips)) # on_prem_ips = [u'10.100.100.20', u'10.100.100.30', u'10.100.100.31', u'10.100.100.32', u'10.100.100.33'] ## will use REST for LIPS on IOSXR but for now testing it out... else: ios_lisp_show_output = execute('show ip lisp database eid-table default | inc {}'.format(site_name)) log.info('IOS output of show = {}'.format(ios_lisp_show_output)) on_prem_ips = [ip.split('/')[0] for ip in ios_lisp_show_output.split('\n')] log.info('Running on IOS. Picking up IPs {} in local database'.format(on_prem_ips)) return on_prem_ips
def save_config(usernameTFTP, passwordTFTP, ipTFTP, path, filename): print "\n\n *** Printing show cmd with 'execute' function *** \n\n" output = cli.execute("copy startup-config ftp://" + usernameTFTP + ":" + passwordTFTP + "@" + ipTFTP + path + filename + ".cfg") print(output) post_message_markdown( "# Kitty save config \n" "Configuration has been saved successfully! Configuration has been saved using **ftp**.\n" "> " + usernameTFTP + "@" + ipTFTP + path + filename + ".cfg", roomID_SoftwareProject, bearer_Bot)
def get_version(): """ Returns a string with the IOS version """ version = cli.execute('show version') # extract version string match = re.search('Version ([A-Za-z0-9.:()]+)', version) # remove leading zeros from numbers ver_str = re.sub(r'\b0+(\d)', r'\1', match.group(1)) if match else 'unknown' # extract boot string match = re.search('System image file is "(.*)"', version) # check if the device started in bundle mode ver_str += ' bundle' if match and is_iosxe_package(match.group(1)) else '' return ver_str
def get_usernames(): """ Devuelve una lista con los usuarios configurados en el dispositivo :return: list of usernames """ from cli import execute exp = re.compile(r'username\s([^\ ]+)\s.*secret [0-9]\s[^\ ]+?') show_command = execute("show running-config") while True: # Block intended to solve bug in cli module try: exp.search(show_command).group(0) break except: print('Ups show_command vacio, intentando de nuevo...') show_command = execute("show running-config") usuarios = exp.findall(show_command) if 'ec2-user' in usuarios: usuarios.remove('ec2-user') if 'conatel' in usuarios: usuarios.remove('conatel') return usuarios
def renumber_stack(stack, serials): """ Returns True if stack is renumbered or False otherwise """ if stack is None: return False # get current switch number and priorities as list of tuples switch = cli.execute('show switch') match = re.findall('(\d)\s+\S+\s+\S+\s+(\d+)', switch) # renumber switches renumber = False for old_num in serials: # lookup new switch number new_num = next((n for n in stack if serials[old_num] == stack[n]), None) if new_num and old_num != int(new_num): renumber = True # renumber switch and log error message in case of failure try: cli.execute('switch {} renumber {}'.format(old_num, new_num)) log(6, 'Renumbered switch {} to {}'.format(old_num, new_num)) except cli.CLISyntaxError as e: log(3, e) shutdown(save=False, abnormal=True) # terminate script if new_num: # calculate new switch priority new_prio = 16 - int(new_num) # lookup current switch priority old_prio = next((p for n, p in match if int(n) == old_num), 1) if int(old_prio) != new_prio: # check if top switch is not active if switch.find('*{}'.format(sorted(serials.keys())[0])) == -1: renumber = True # set switch priority and log error message in case of failure try: cli.execute('switch %s priority %d' % (old_num, new_prio)) log(6, 'Switch %s priority set to %d' % (old_num, new_prio)) except cli.CLISyntaxError as e: log(3, e) shutdown(save=False, abnormal=True) # terminate script if renumber: for num in serials.keys(): # to prevent recovery from backup nvram try: cli.execute('delete flash-%s:nvram_config*' % num) except cli.CLISyntaxError as e: pass return renumber
def autoupgrade(): """ Returns True if autoupgrade script is configured or False otherwise """ switch = cli.execute('show switch') # look for a switch in version mismatch state if switch.find('V-Mismatch') > -1: # Workaround to execute interactive marked commands from guestshell cli.configure('''event manager applet upgrade event none maxrun 600 action 1.0 cli command "enable" action 2.0 cli command "request platform software package install autoupgrade" action 3.0 syslog msg "Reloading stack..." action 4.0 reload''') return True else: return False