def unshut_interface(device, interface): """ Unshut interface Args: device (`obj`): Device object interface (`str`): Interface name Returns: None Raises: SubCommandFailure """ if not device.is_connected(): connect_device(device=device) try: device.configure( [ "interface {interface}".format(interface=interface), "no shutdown", ] ) except SubCommandFailure as e: raise SubCommandFailure( "Could not unshut interface {interface} on device {dev}. Error:\n{error}".format( interface=interface, dev=device.name, error=e ) )
def _reconnect(self, steps, timeout, sleep_disconnect=30): """Disconnect and reconnect to router within given timeout. Args: Mandatory: steps (`obj`) : Step object to represent each step taken. timeout (`obj`) : max_time (int): Maximum wait time for the trigger, in second. Default: 180 interval (int): Wait time between iterations when looping is needed, in second. Default: 15 Optional: sleep_disconnect (`int`) : Break between issue the command and the HA action really take place, in second. Default: 30 Returns: AETEST Step Result Raises: None Example: >>> _reconnect(steps=ats.aetest.Steps(), timeout=genie.utils.timeout.Timeout( max_time=180, interval=15)) """ with steps.start('Disconnecting device {}'.format(self.device.name), continue_=True) as step: disconnect_device(self.device) time.sleep(sleep_disconnect) with steps.start('Reconnecting to device {}'.format(self.device.name), continue_=True) as step: temp = TempResult(container=step) while timeout.iterate(): try: connect_device(self.device) except Exception as e: temp.failed('Could not reconnect to the device', from_exception=e) # incase console is existed but cannot enable the device. # conf mode is not active when standby RP is coming up try: disconnect_device(self.device) except: pass timeout.sleep() continue temp.passed('Reconnected to the device') break temp.result()
def _reconnect(self, steps, timeout): '''Reconnect to the device if needed''' if self.process in self.reconnect: ha = self.abstract.sdk.libs.abstracted_libs.ha.HA( device=self.device) with steps.start( 'The device is reloading when restarting this process', continue_=True) as step: disconnect_device(self.device) time.sleep(30) temp = TempResult(container=step) while timeout.iterate(): try: connect_device(self.device) except Exception as e: temp.failed('Could not reconnect to the device', from_exception=e) timeout.sleep() continue temp.passed('Reconnected to the device') break temp.result() # check show module with steps.start('Check module status after reconnection', continue_=True) as step: temp = TempResult(container=step) while timeout.iterate(): try: ha.check_module() except AttributeError as e: temp.failed( 'Could not find mandatory information from show module', from_exception=e) continue except AssertionError as e: temp.failed('Modules are not ready', from_exception=e) timeout.sleep() continue temp.passed('Modules are ready') break temp.result()
def write_erase_reload_device( device, via_console, reload_timeout, static_route, static_route_netmask, static_route_nexthop, priv, vty_start, vty_end, mgmt_interface, mgmt_netmask, config_sleep, vrf, via_mgmt, post_reconnect_time, username=None, password=None, reload_creds=None, reload_hostname='Router', ): """Execute 'write erase' on device, reload and apply basic configuration. Args: device(`obj`): Device object via_console(`str`): Via to use to reach the device console. reload_timeout(`int`): Maximum time to wait for reload to complete reload_creds(`str or list`): Creds to apply if reloading device asks static_route_ip (`str`): IP address for static route configuration config_sleep (`int`): Time to wait after applying mgmt IP configuration vrf (`str`): VRF to use for management IP operations via_mgmt(`str`): Via to use to reach the device mgt IP. post_reconnect_time(`int`): Maximum time to wait after reload before configuring Returns: None """ device.write_erase_reload_device_without_reconfig( device=device, via_console=via_console, vrf=vrf, reload_timeout=reload_timeout, username=username, password=password, reload_creds=reload_creds, reload_hostname=reload_hostname, ) os = device.os hostname = device.name ip = str(device.connections[via_console]["ip"]) port = str(device.connections[via_console]["port"]) username, password = device.api.get_username_password(device=device, username=username, password=password, creds=reload_creds) # Wait before reconnecting log.info("\n\nWaiting '{}' seconds after reload ...".format( post_reconnect_time)) time.sleep(post_reconnect_time) new_device = Connection( credentials=dict(default=dict(username=username, password=password)), os=os, hostname=reload_hostname, start=["telnet {ip} {port}".format(ip=ip, port=port)], prompt_recovery=True, ) # Configure hostname log.info("\n\nConfigure hostname on device '{}'".format(hostname)) try: new_device.connect() new_device.configure("hostname {}".format(hostname)) new_device.disconnect() except StateMachineError: new_device.disconnect() log.info( "Successfully configured hostname on device '{}'".format(hostname)) except Exception as e: raise Exception( "Error while trying to configure hostname on device '{}'".format( hostname)) from e # Configure mgmt IP configuration mgmt_ip = str(device.connections[via_mgmt]["ip"]) log.info( "\n\nConfigure mgmt IP configuration on device '{}'".format(hostname)) new_device2 = Connection( username=username, password=password, os=os, hostname="{}".format(hostname), prompt_recovery=True, start=["telnet {ip} {port}".format(ip=ip, port=port)], ) # Build config string cfg_str = ( "ip route vrf {vrf} {static_route} {static_route_netmask} {static_route_nexthop}\n" "username {username} priv {priv} password {password}\n" "line vty {vty_start} {vty_end}\n" "login local\n" "interface {mgmt_interface}\n" " vrf forwarding {vrf}\n" " ip address {mgmt_ip} {mgmt_netmask}\n" " no shutdown\n" " negotiation auto".format( vrf=vrf, static_route=static_route, username=username, static_route_netmask=static_route_netmask, password=password, static_route_nexthop=static_route_nexthop, priv=priv, vty_start=vty_start, vty_end=vty_end, mgmt_ip=mgmt_ip, mgmt_netmask=mgmt_netmask, mgmt_interface=mgmt_interface, )) try: # Connect and configure new_device2.connect() new_device2.configure(cfg_str) except Exception as e: # Disconnect new_device2.disconnect() log.error(e) raise Exception( "Unable to configure mgmt IP configuration on '{}'".format( hostname)) from e else: new_device2.disconnect() log.info("Sucessfully configured mgmt IP configuration on '{}'".format( hostname)) # Waiting for configuration apply to take effect before reconnecting to device log.info("\n\nWaiting for '{}' seconds for applied configuration to " "take effect...".format(config_sleep)) time.sleep(config_sleep) # Reconnect to device using vty log.info( "\n\nReconnect to device '{}' using management IP".format(hostname)) try: connect_device(device=device) except Exception as e: raise Exception( "'write erase' and 'reload' did not complete successfully") from e else: log.info("Successfully erased all device configurations with " "'write erase' and 'reload' on device '{}'".format(hostname))
def write_erase_reload_device( device, via_console, via_mgmt, vrf, reload_timeout, static_route, static_route_netmask, priv, static_route_nexthop, vty_start, vty_end, mgmt_interface, mgmt_netmask, config_sleep, post_reconnect_time, ): """Execute 'write erase' on device Args: device(`obj`): Device object reload_timeout(`int`): Maximum time to wait for reload to complete static_route_ip (`str`): IP address for static route configuration config_sleep (`int`): Time to wait after applying mgmt IP configuration Returns: None """ # Set 'write erase' dialog wr_dialog = Dialog( [ Statement( pattern=r"Erasing the nvram filesystem will " "remove all configuration files! " "Continue? \[confirm\].*", action="sendline()", loop_continue=True, continue_timer=False, ) ] ) # Execute 'write erase' command log.info("\n\nExecuting 'write erase' on device '{}'".format(device.name)) try: device.execute("write erase", reply=wr_dialog) except Exception as e: raise Exception( "Error while executing 'write erase' on device '{}'".format( device.name ) ) else: log.info( "Successfully executed 'write erase' command on device '{}'".format( device.name ) ) # Collect device base information before reload os = device.os hostname = device.name username = device.tacacs["username"] password = device.passwords["enable"] ip = str(device.connections[via_console]["ip"]) port = str(device.connections[via_console]["port"]) mgmt_ip = str(device.connections[via_mgmt]["ip"]) # Set 'reload' dialog r_dialog = Dialog( [ Statement( pattern=r".*System configuration has been modified.*", action="sendline(no)", loop_continue=True, continue_timer=False, ), Statement( pattern=r".*Do you want to proceed?\[confirm\].*", action="sendline()", loop_continue=True, continue_timer=False, ), Statement( pattern=r".*Proceed with reload? *\[confirm\].*", action="sendline()", loop_continue=True, continue_timer=False, ), Statement( pattern=r".*Would you like to enter the initial configuration.*", action="sendline(no)", loop_continue=True, continue_timer=False, ), ] ) # Execute 'reload' command log.info("\n\nExecuting 'reload' on device '{}'".format(device.name)) try: device.reload(prompt_recovery=True, dialog=r_dialog) except SubCommandFailure: # Disconnect and destroy the connection log.info( "Sucessfully executed 'reload' command on device {}".format( device.name ) ) log.info( "Disconnecting and destroying handle to device {}".format( device.name ) ) device.destroy() except: raise Exception( "Error while reloading device '{}'".format(device.name) ) # Wait until reload has completed and device can be reachable log.info( "\n\nWaiting '{}' seconds for device to reboot after reload...".format( reload_timeout ) ) time.sleep(reload_timeout) # Reconnect to device log.info( "\n\nReconnecting to device '{}' after reload...".format(hostname) ) new_device = Connection( username=username, password=password, os=os, hostname="Router", start=["telnet {ip} {port}".format(ip=ip, port=port)], prompt_recovery=True, ) try: new_device.connect() except (ConnectionError, TimeoutError) as e: # Connection or Timeout Error but 'no' has been sent # simply destroy handle at this point new_device.disconnect() log.info( "Reconnected to device '{}' after 'write erase' and reload'".format( hostname ) ) except: raise Exception( "Error reconnecting to device '{}' after 'write erase'" " and reload".format(hostname) ) else: new_device.disconnect() log.info( "Successully reconnected to device '{}' after 'write erase' " "and reload'".format(hostname) ) # Wait before reconnecting to configure hostname log.info( "\n\nWaiting '{}' seconds before configuring hostname on device...".format( post_reconnect_time ) ) time.sleep(post_reconnect_time) # Configure hostname log.info("\n\nConfigure hostname on device '{}'".format(hostname)) try: new_device.connect() new_device.configure("hostname {}".format(hostname)) except StateMachineError: new_device.disconnect() log.info( "Successfully configured hostname on device '{}'".format(hostname) ) except: raise Exception( "Error while trying to configure hostname on device '{}'".format( hostname ) ) # Configure mgmt IP configuration log.info( "\n\nConfigure mgmt IP configuration on device '{}'".format(hostname) ) new_device2 = Connection( username=username, password=password, os=os, hostname="{}".format(hostname), prompt_recovery=True, start=["telnet {ip} {port}".format(ip=ip, port=port)], ) # Build config string cfg_str = ( "ip route vrf {vrf} {static_route} {static_route_netmask} {static_route_nexthop}\n" "username {username} priv {priv} password {password}\n" "line vty {vty_start} {vty_end}\n" "login local\n" "interface {mgmt_interface}\n" " vrf forwarding {vrf}\n" " ip address {mgmt_ip} {mgmt_netmask}\n" " no shutdown\n" " negotiation auto".format( vrf=vrf, static_route=static_route, username=username, static_route_netmask=static_route_netmask, password=password, static_route_nexthop=static_route_nexthop, priv=priv, vty_start=vty_start, vty_end=vty_end, mgmt_ip=mgmt_ip, mgmt_netmask=mgmt_netmask, mgmt_interface=mgmt_interface, ) ) try: # Connect and configure new_device2.connect() new_device2.configure(cfg_str) except Exception as e: # Disconnect new_device2.disconnect() log.error(e) raise Exception( "Unable to configure mgmt IP configuration on '{}'".format( hostname ) ) else: new_device2.disconnect() log.info( "Sucessfully configured mgmt IP configuration on '{}'".format( hostname ) ) # Waiting for configuration apply to take effect before reconnecting to device log.info( "\n\nWaiting for '{}' seconds for applied configuration to " "take effect...".format(config_sleep) ) time.sleep(config_sleep) # Reconnect to device using vty log.info( "\n\nReconnect to device '{}' using management IP".format(hostname) ) try: connect_device(device=device) except: raise Exception( "'write erase' and 'reload' did not complete successfully" ) else: log.info( "Successfully erased all device configurations with " "'write erase' and 'reload' on device '{}'".format(hostname) )
def execute_install_package(device, image_dir, image, save_system_config=True, timeout=660, _install=True): """ Installs package Args: device ("obj"): Device object image_dir ("str"): Directory image is located in image ("str"): Image name save_system_config ("bool"): If config changed do we save it? timeout ("int"): maximum time for install _install ("bool"): True to install, False to uninstall. Not meant to be changed manually. Raises: Exception Returns: True if install succeeded else False """ dialog = Dialog([ Statement(pattern=r".*Press Quit\(q\) to exit, you may save " r"configuration and re-enter the command\. " r"\[y\/n\/q\]", action='sendline(y)' if save_system_config else 'sendline(n)', loop_continue=True, continue_timer=False), Statement(pattern=r".*This operation may require a reload of the " r"system\. Do you want to proceed\? \[y\/n\]", action='sendline(y)', loop_continue=True, continue_timer=False), Statement(pattern=r"^.*RETURN to get started", action='sendline()', loop_continue=False, continue_timer=False) ]) if _install: cmd = """install add file {dir}{image} install activate file {dir}{image}""".format( dir=image_dir, image=image ) else: cmd = "install deactivate file {dir}{image}".format( dir=image_dir, image=image ) try: device.execute(cmd, reply=dialog, timeout=timeout) except StateMachineError: # this will be raised after 'Return to get started' is seen device.destroy() timeout = Timeout(90, 30) while timeout.iterate(): try: connect_device(device) except Exception: timeout.sleep() continue break else: raise Exception("Couldnt reconnect to the device") if _install: cmd = "install commit" else: cmd = """install commit install remove file {dir}{image}""".format( dir=image_dir, image=image ) device.execute(cmd) try: out = device.parse("show install summary") except SchemaEmptyParserError: out = {} for location in out.get("location"): for pkg in out['location'][location]['pkg_state']: pkg = out['location'][location]['pkg_state'][pkg] if (_install and image in pkg['filename_version'] and 'C' == pkg['state']): # the image should exist; it was just installed return True elif (not _install and image in pkg['filename_version']): # the image should not exist; it was just uninstalled. return False return False if _install else True