def get_running_config_section_dict( device, section=None, options=None ): """ Get section information from show run Args: device ('str'): Device str section ('str'): Section str Returns: Configuration dict """ if options and section: cmd = "show run {options} | section {section}".format( options=options, section=section ) elif options: cmd = "show run {options}".format(options=options) elif section: cmd = "show run | section {section}".format(section=section) else: cmd = "show run" try: output = device.execute(cmd) except SubCommandFailure: return None config_dict = get_config_dict(output) return config_dict
def get_interface_running_config(device, interface): """ Get interface configuration from show running-config interface {interface} Args: device ('obj'): Device object interface ('str'): interface name Return: Dictionary with running interface configuration Raises: None """ interface = Common.convert_intf_name(interface) try: output = device.execute( "show running-config interface {interface}".format( interface=interface ) ) except SubCommandFailure: return {} return get_config_dict(output)
def verify_interface_config_ospf_bfd(device, interface, max_time=60, check_interval=10, flag=True): """Verify interface ospf bfd config in - show run interface Args: device (`obj`): Device object interface (`str`): Interface name max_time (`int`): max time check_interval (`int`): check interval flag (`bool`): True if verify shutdown False if verify no shutdown Returns: result(`bool`): verify result """ timeout = Timeout(max_time, check_interval) while timeout.iterate(): out = device.execute("show run interface {}".format(interface)) cfg_dict = get_config_dict(out) key = "interface {}".format(interface) if key in cfg_dict and "ip ospf bfd" in cfg_dict[key]: result = True else: result = False if flag == result: return True timeout.sleep() return False
def get_config_from_file(device, disk, filename): """ Get configuration from a file in disk Args: device ('obj'): Device object disk ('str'): Disk name filename ('str'): File name Raises: SubCommandFailure Returns: Dictionary: Configuration """ try: config = device.execute( "more {disk}{filename}".format(disk=disk, filename=filename) ) except SubCommandFailure as e: log.error( "Could not retrieve configuration information from " "file {filename}".format(filename=filename) ) return None return get_config_dict(config)
def get_startup_config_dict(device, section=None, options=None): """ Get section information from show startup-config Args: device ('str'): Device str section ('str'): Section str Returns: Configuration dict """ if options and section: cmd = "show startup-config {options} | section {section}".format( options=options, section=section) elif options: cmd = "show startup-config {options}".format(options=options) elif section: cmd = "show startup-config | section {section}".format(section=section) else: cmd = "show startup-config" try: output = device.execute(cmd) except Exception as e: raise Exception("Could not execute command {cmd}\nError:{e}".format( cmd=cmd, e=str(e))) config_dict = get_config_dict(output) return config_dict
def verify_config_exists_in_routing_options(device, regex, max_time=60, check_interval=10): """ Verify maximum-path exists in configuration Args: device (`obj`): Device object regex (`str`): Config to search max_time (`int`): Max time, default: 60 check_interval (`int`): Check interval, default: 10 Returns: result (`bool`): Verified result Raises: N/A """ timeout = Timeout(max_time, check_interval) while timeout.iterate(): out = None try: out = device.execute('show configuration routing-options') except SubCommandFailure as e: timeout.sleep() continue if not out: return False config_dict = get_config_dict(out) config_found = Dq(config_dict).contains(regex, regex=True) if config_found: return True timeout.sleep() return False
def get_running_config_dict(device): """ Get show running-config output Args: device (`obj`): Device object option (`str`): option command Returns: config_dict (`dict`): dict of show run output """ cmd = "show configuration" try: out = device.execute(cmd) except SubCommandFailure as e: raise SubCommandFailure( "Could not get running-config information " "on device {device}".format(device=device.name)) config_dict = get_config_dict(out) return config_dict
def verify_interface_config_carrier_delay(device, interface, max_time=60, check_interval=10, flag=True): """Verify interface carrier_delay config in - show run interface Args: device (`obj`): Device object interface (`str`): Interface name max_time (`int`): max time check_interval (`int`): check interval flag (`bool`): True if verify has carrier delay False if verify no carrier delay Returns: result(`bool`): verify result """ timeout = Timeout(max_time, check_interval) while timeout.iterate(): out = device.execute("show run interface {}".format(interface)) cfg_dict = get_config_dict(out) key = "interface {}".format(interface) if key in cfg_dict: for line in cfg_dict[key].keys(): if "carrier-delay" in line: result = True break else: result = False else: result = False if flag == result: return True timeout.sleep() return False
def _perform_issu(self, steps, upgrade_image, timeout=300): """Perform the ND-ISSU on NXOS device: NXOS: 1. execute install all <> non-disruptive Raises: Unicon errors Exception Example: >>> _perform_issu(steps=steps, upgrade_image='someimage') """ # Init lookup = Lookup.from_device(self.device) filetransfer = FileUtils.from_device(self.device) statement_list = authentication_statement_list + \ [Statement(pattern=r'.*Do you want to continue with the installation\s*\(y/n\)\?\s*\[n\]', action='sendline(y)', loop_continue=True, continue_timer=False)] + \ [Statement(pattern=r'.*Do you want to overwrite\s*\(yes/no\)\?\s* \[no\]', action='sendline(yes)', loop_continue=True, continue_timer=False)] dialog = Dialog(statement_list) ctrlplane_downtime = self.parameters.get('ctrlplane_downtime') user_boot_mode = self.parameters.get('mode') issu_timeout = self.parameters.get('issu_timeout') cfg_transfer = self.parameters.get('cfg_transfer') cfg_timeout = self.parameters.get('cfg_timeout') with steps.start("Check boot mode on {}".format( self.device.hostname)) as step: invalid_cmd = False out = self.device.execute('show boot mode') # p1 matches line "Current mode is <native/lxc>." p1 = re.compile(r'^Current\smode\sis\s(?P<mode>\w+)\.$') # p2 matches line "% Invalid command at '^' marker." p2 = re.compile(r'.*?\'\^ \'\smarker\.') for line in out.splitlines(): line = line.strip() m = p1.match(line) if m: sys_boot_mode = m.groupdict()['mode'] break m = p2.match(line) if m: invalid_cmd = True break if sys_boot_mode.lower() != user_boot_mode.lower(): step.failed( "System boot mode {} does not match user expected boot mode {}" .format(sys_boot_mode, user_boot_mode)) elif invalid_cmd and user_boot_mode.lower() != 'lxc': step.failed( "System only supports lxc mode. Invalid user expected boot mode input {}" .format(user_boot_mode)) else: step.passed( "System boot mode {} matches user expected boot mode {}". format(sys_boot_mode, user_boot_mode)) with steps.start( "Take a running-config snapshot pre trigger on {}".format( self.device.hostname)): if cfg_transfer: self.device.execute('show run > {}_pre_issu_trig.cfg'.format( self.device.hostname), timeout=cfg_timeout, reply=dialog) to_url = '{protocol}://{address}/{path}'.format( protocol=self.device.filetransfer_attributes['protocol'], address=self.device. filetransfer_attributes['server_address'], path=runtime.directory) filetransfer.copyfile( source='bootflash:/{}_pre_issu_trig.cfg'.format( self.device.hostname), destination=to_url, device=self.device, vrf='management', timeout_seconds=600) try: with open( "{}/{}_pre_issu_trig.cfg".format( runtime.directory, self.device.hostname), "r") as pre_trig_file: pre_cfg_str = pre_trig_file.read() except IOError: step.failed( "file not found.Please check path/content of the file") pre_trig_config = get_config_dict(pre_cfg_str) else: pre_trig_config = self.device.api.get_running_config_dict() with steps.start("Perform copy run start on {}".format( self.device.hostname)): execute_copy_run_to_start(self.device) with steps.start( "Performing non disruptive issu on the device {}".format( self.device.hostname)): image_name = basename(upgrade_image) self.device.execute( 'install all nxos bootflash:{} non-disruptive'.format( image_name), timeout=issu_timeout, reply=dialog) with steps.start("Reconnect back to device {} after ISSU".format( self.device.hostname)): reconnect_timeout = Timeout(max_time=1200, interval=120) self._reconnect(steps=steps, timeout=reconnect_timeout) with steps.start("Verify image version on device {} after ISSU".format( self.device.hostname)): version_dict = lookup.parser.show_platform.\ ShowVersion(device=self.device).parse() # version check rs = R([ 'platform', 'software', 'system_image_file', 'bootflash:///{}'.format(image_name) ]) ret = find([version_dict], rs, filter_=False, all_keys=True) if not ret: raise Exception( "Image version mismatch after ISSU on device {}".format( self.device.hostname)) with steps.start( "Verify module status and config load status on device {} after ISSU" .format(self.device.hostname)): self.device.api.verify_module_status() config_timeout = Timeout(max_time=180, interval=30) while config_timeout.iterate(): try: parsed = self.device.parse( "show logging logfile | include 'System ready'") except SchemaEmptyParserError as e: log.info("command did not return any output\n{}".format( str(e))) config_timeout.sleep() continue if parsed is not None: log.info("{}".format(parsed.q.get_values('logs', -1))) break config_timeout.sleep() with steps.start("Check CP downtime after on {} after ISSU".format( self.device.hostname)) as step: if user_boot_mode.lower() == 'lxc': step.passed( "show install all time-stats detail unsupported on lxc mode and cp downtime is minimal" ) else: out = self.device.execute('show install all time-stats detail') output_error = False cp_downtime = None for line in out.splitlines(): line = line.rstrip() p1 = re.compile(r'^ERROR:.*$') m = p1.match(line) if m: output_error = True break p2 = re.compile( r'^Total\s+.*?:\s(?P<cp_downtime>\d+)\s+seconds$') m = p2.match(line) if m: cp_downtime = m.groupdict()['cp_downtime'] continue if output_error: step.failed( "The output shows reset-reason as disruptive. ND ISSU was not performed properly." ) elif cp_downtime is None: step.failed( "garbled output for show install all time-stats detail so cp_downtime was not calculated properly." ) elif int(cp_downtime) > int(ctrlplane_downtime): step.failed( "Control plane was down for {} seconds which is longer than user expected at {} seconds" .format(cp_downtime, ctrlplane_downtime)) else: step.passed( "Control plane was down for {} seconds which is within an user acceptable range of {} seconds" .format(cp_downtime, ctrlplane_downtime)) with steps.start( "Compare post-trigger config with pre trigger config snapshot on {}" .format(self.device.hostname)) as step: if cfg_transfer: self.device.execute('show run > {}_post_issu_trig.cfg'.format( self.device.hostname), timeout=cfg_timeout, reply=dialog) to_url = '{protocol}://{address}/{path}'.format( protocol=self.device.filetransfer_attributes['protocol'], address=self.device. filetransfer_attributes['server_address'], path=runtime.directory) filetransfer.copyfile( source='bootflash:/{}_post_issu_trig.cfg'.format( self.device.hostname), destination=to_url, device=self.device, vrf='management', timeout_seconds=600) try: with open( "{}/{}_post_issu_trig.cfg".format( runtime.directory, self.device.hostname), "r") as post_trig_file: post_cfg_str = post_trig_file.read() except IOError: step.failed( "file not found. Please check path/content of the file" ) post_trig_config = get_config_dict(post_cfg_str) else: post_trig_config = self.device.api.get_running_config_dict() output = compare_config_dicts(pre_trig_config, post_trig_config, [r'(boot|version)']) if output: step.failed( "Inconsistencies in running config post trigger:{}".format( output))