def _tty_login(self): tty_args = dict() tty_args['user'] = self._auth_user tty_args['passwd'] = self._auth_password tty_args['timeout'] = float(self._timeout) tty_args['attempts'] = int(self._attempts) tty_args['baud'] = self._baud tty_args['huge_tree'] = self._huge_tree if self._mode and self._mode.upper() == 'TELNET': tty_args['host'] = self._hostname tty_args['port'] = self._port tty_args['console_has_banner'] = self.console_has_banner self.console = ('telnet', self._hostname, self.port) self._tty = Telnet(**tty_args) elif self.cs_user is not None: tty_args['cs_user'] = self.cs_user tty_args['cs_passwd'] = self.cs_passwd tty_args['host'] = self._hostname tty_args['port'] = self._port tty_args['console_has_banner'] = self.console_has_banner tty_args['ssh_private_key_file'] = self._ssh_private_key_file self.console = ('ssh', self._hostname, self.port) self._tty = SSH(**tty_args) elif self._mode.upper() == 'SERIAL': tty_args['port'] = self._port self.console = ('serial', self._port) self._tty = Serial(**tty_args) else: logger.error('Mode should be either telnet or serial') raise AttributeError('Mode to be telnet/serial') self._tty.login()
def _tty_login(self): tty_args = dict() tty_args["user"] = self._auth_user tty_args["passwd"] = self._auth_password tty_args["timeout"] = float(self._timeout) tty_args["attempts"] = int(self._attempts) tty_args["baud"] = self._baud tty_args["huge_tree"] = self._huge_tree if self._mode and self._mode.upper() == "TELNET": tty_args["host"] = self._hostname tty_args["port"] = self._port tty_args["console_has_banner"] = self.console_has_banner self.console = ("telnet", self._hostname, self.port) self._tty = Telnet(**tty_args) elif self.cs_user is not None: tty_args["cs_user"] = self.cs_user tty_args["cs_passwd"] = self.cs_passwd tty_args["host"] = self._hostname tty_args["port"] = self._port tty_args["console_has_banner"] = self.console_has_banner tty_args["ssh_private_key_file"] = self._ssh_private_key_file self.console = ("ssh", self._hostname, self.port) self._tty = SSH(**tty_args) elif self._mode.upper() == "SERIAL": tty_args["port"] = self._port self.console = ("serial", self._port) self._tty = Serial(**tty_args) else: logger.error("Mode should be either telnet or serial") raise AttributeError("Mode to be telnet/serial") self._tty.login()
def _tty_login(self): tty_args = {} tty_args['user'] = self._auth_user tty_args['passwd'] = self._auth_password tty_args['timeout'] = float(self._timeout) tty_args['attempts'] = int(self._attempts) if self._mode.upper() == 'TELNET': tty_args['host'] = self._hostname tty_args['port'] = self._port self.console = ('telnet', self._hostname, self.port) self._tty = Telnet(**tty_args) elif self._mode.upper() == 'SERIAL': tty_args['port'] = self._port tty_args['baud'] = self._baud self.console = ('serial', self._port) self._tty = Serial(**tty_args) else: logger.error('Mode should be either telnet or serial') raise AttributeError('Mode to be telnet/serial') self._tty.login()
def _tty_login(self): tty_args = dict() tty_args['user'] = self._auth_user tty_args['passwd'] = self._auth_password tty_args['timeout'] = float(self._timeout) tty_args['attempts'] = int(self._attempts) tty_args['baud'] = self._baud if self._mode.upper() == 'TELNET': tty_args['host'] = self._hostname tty_args['port'] = self._port self.console = ('telnet', self._hostname, self.port) self._tty = Telnet(**tty_args) elif self._mode.upper() == 'SERIAL': tty_args['port'] = self._port self.console = ('serial', self._port) self._tty = Serial(**tty_args) else: logger.error('Mode should be either telnet or serial') raise AttributeError('Mode to be telnet/serial') self._tty.login()
class Console(object): def __init__(self, **kvargs): """ NoobDevice object constructor. :param str host: **REQUIRED** host-name or ipaddress of target device :param str user: *OPTIONAL* login user-name, uses root if not provided :param str passwd: *OPTIONAL* in console connection for device at zeroized state password is not required :param int port: *OPTIONAL* port, default is telnet port `23` :param int baud: *OPTIONAL* baud, default baud rate is 9600 :param str mode: *OPTIONAL* mode, mode of connection (telnet/serial/ssh) default is telnet :param int timeout: *OPTIONAL* timeout, default is 0.5 :param int attempts: *OPTIONAL* attempts, default is 10 :param str ssh_config: *OPTIONAL* The path to the SSH configuration file. This can be used to load SSH information from a configuration file. By default ~/.ssh/config is queried it will be used by SCP class. So its assumed ssh is enabled by the time we use SCP functionality. :param bool gather_facts: *OPTIONAL* default is ``False``. If ``False`` then the facts are not gathered on call to :meth:`open` """ # ---------------------------------------- # setup instance connection/open variables # ---------------------------------------- self._tty = None self._facts = {} self.connected = False self._skip_logout = False self.results = dict(changed=False, failed=False, errmsg=None) # hostname is not required in serial mode connection self._hostname = kvargs.get('host') self._auth_user = kvargs.get('user', 'root') self._auth_password = kvargs.get( 'password', '') or kvargs.get( 'passwd', '') self._port = kvargs.get('port', '23') self._baud = kvargs.get('baud', '9600') self._mode = kvargs.get('mode', 'telnet') self._timeout = kvargs.get('timeout', '0.5') # self.timeout needed by PyEZ utils self.timeout = self._timeout self._attempts = kvargs.get('attempts', 10) self.gather_facts = kvargs.get('gather_facts', False) self.rpc = _RpcMetaExec(self) from jnpr.junos import Device if sys.version < '3': self.cli = lambda cmd, format='text', warning=True: \ Device.cli.im_func(self, cmd, format, warning) self._sshconf_path = lambda: Device._sshconf_lkup.im_func(self) self.facts_refresh = lambda exception_on_failure=False: \ Device.facts_refresh.im_func(self, exception_on_failure) else: self.cli = lambda cmd, format='text', warning=True: \ Device.cli(self, cmd, format, warning) self._sshconf_path = lambda: Device._sshconf_lkup(self) self.facts_refresh = lambda exception_on_failure=False: \ Device.facts_refresh(self, exception_on_failure) self._ssh_config = kvargs.get('ssh_config') # ------------------------------------------------------------------------ # property: hostname # ------------------------------------------------------------------------ @property def hostname(self): """ :returns: the host-name of the Junos device. """ return self._hostname # ------------------------------------------------------------------------ # property: user # ------------------------------------------------------------------------ @property def user(self): """ :returns: the login user (str) accessing the Junos device """ return self._auth_user # ------------------------------------------------------------------------ # property: password # ------------------------------------------------------------------------ @property def password(self): """ :returns: ``None`` - do not provide the password """ return None # read-only @password.setter def password(self, value): """ Change the authentication password value. This is handy in case the calling program needs to attempt different passwords. """ self._auth_password = value # ------------------------------------------------------------------------ # property: port # ------------------------------------------------------------------------ @property def port(self): """ :returns: the port (str) to connect to the Junos device """ return self._port # ------------------------------------------------------------------------ # property: facts # ------------------------------------------------------------------------ @property def facts(self): """ :returns: Device fact dictionary """ return self._facts @facts.setter def facts(self, value): """ read-only property """ raise RuntimeError("facts is read-only!") def open(self): """ open the connection to the device """ # --------------------------------------------------------------- # validate device hostname or IP address # --------------------------------------------------------------- if self._mode.upper() is 'TELNET' and self._hostname is None: self.results['failed'] = True self.results[ 'errmsg'] = 'ERROR: Device hostname/IP not specified !!!' return self.results # -------------------- # login to the CONSOLE # -------------------- try: self._tty_login() except RuntimeError as err: logger.error("ERROR: {0}:{1}\n".format('login', str(err))) logger.error( "\nComplete traceback message: {0}".format( traceback.format_exc())) raise RuntimeError except Exception as ex: logger.error("Exception occurred: {0} \n".format('login', str(ex))) raise ex self.connected = True if self.gather_facts is True: logger.info('facts: retrieving device facts...') self.facts_refresh() self.results['facts'] = self._facts return self def close(self, skip_logout=False): """ Closes the connection to the device. """ if skip_logout is False and self.connected is True: try: self._tty_logout() except Exception as err: logger.error("ERROR {0}:{1}\n".format('logout', str(err))) raise err self.connected = False elif self.connected is True: try: self._tty._tty_close() except Exception as err: logger.error("ERROR {0}:{1}\n".format('close', str(err))) logger.error( "\nComplete traceback message: {0}".format( traceback.format_exc())) raise err self.connected = False # execute rpc calls def execute(self, rpc_cmd, *args, **kwargs): return self._tty.nc.rpc(etree.tounicode(rpc_cmd)) # ------------------------------------------------------------------------- # LOGIN/LOGOUT # ------------------------------------------------------------------------- def _tty_login(self): tty_args = {} tty_args['user'] = self._auth_user tty_args['passwd'] = self._auth_password tty_args['timeout'] = float(self._timeout) tty_args['attempts'] = int(self._attempts) if self._mode.upper() == 'TELNET': tty_args['host'] = self._hostname tty_args['port'] = self._port self.console = ('telnet', self._hostname, self.port) self._tty = Telnet(**tty_args) elif self._mode.upper() == 'SERIAL': tty_args['port'] = self._port tty_args['baud'] = self._baud self.console = ('serial', self._port) self._tty = Serial(**tty_args) else: logger.error('Mode should be either telnet or serial') raise AttributeError('Mode to be telnet/serial') self._tty.login() def _tty_logout(self): self._tty.logout() def zeroize(self): """ perform device ZEROIZE actions """ logger.info("zeroize : ZEROIZE device, rebooting") self._tty.nc.zeroize() self._skip_logout = True self.results['changed'] = True # ----------------------------------------------------------------------- # Context Manager # ----------------------------------------------------------------------- def __enter__(self): self.open() return self def __exit__(self, exc_type, exc_val, exc_tb): if self.connected: self.close()
class Console(_Connection): def __init__(self, **kvargs): """ NoobDevice object constructor. :param str host: **REQUIRED** host-name or ipaddress of target device :param str user: *OPTIONAL* login user-name, uses root if not provided :param str passwd: *OPTIONAL* in console connection for device at zeroized state password is not required :param int port: *OPTIONAL* port, defaults to '23' for telnet mode and '/dev/ttyUSB0' for serial. :param int baud: *OPTIONAL* baud, default baud rate is 9600 :param str mode: *OPTIONAL* mode, mode of connection (telnet/serial) default is telnet :param int timeout: *OPTIONAL* timeout, default is 0.5 :param int attempts: *OPTIONAL* attempts, default is 10 :param str ssh_config: *OPTIONAL* The path to the SSH configuration file. This can be used to load SSH information from a configuration file. By default ~/.ssh/config is queried it will be used by SCP class. So its assumed ssh is enabled by the time we use SCP functionality. :param bool gather_facts: *OPTIONAL* Defaults to ``False``. If ``False`` and old-style fact gathering is in use then facts are not gathered on call to :meth:`open`. This argument is a no-op when new-style fact gathering is in use (the default.) :param str fact_style: *OPTIONAL* The style of fact gathering to use. Valid values are: 'new', 'old', or 'both'. The default is 'new'. The value 'both' is only present for debugging purposes. It will be removed in a future release. The value 'old' is only present to workaround bugs in new-style fact gathering. It will be removed in a future release. :param bool console_has_banner: *OPTIONAL* default is ``False``. If ``False`` then in case of a hung state, <close-session/> rpc is sent to the console. If ``True``, after sleep(5), a new-line is sent """ # ---------------------------------------- # setup instance connection/open variables # ---------------------------------------- self._tty = None self._ofacts = {} self.connected = False self._skip_logout = False self.results = dict(changed=False, failed=False, errmsg=None) # hostname is not required in serial mode connection self._hostname = kvargs.get('host') self._auth_user = kvargs.get('user', 'root') self._auth_password = kvargs.get( 'password', '') or kvargs.get( 'passwd', '') self._port = kvargs.get('port', '23') self._baud = kvargs.get('baud', '9600') self._mode = kvargs.get('mode', 'telnet') self._timeout = kvargs.get('timeout', '0.5') self._normalize = kvargs.get('normalize', False) self._norm_transform = lambda: JXML.normalize_xslt.encode('UTF-8') self.transform = self._norm_transform # self.timeout needed by PyEZ utils #self.timeout = self._timeout self._attempts = kvargs.get('attempts', 10) self._gather_facts = kvargs.get('gather_facts', False) self._fact_style = kvargs.get('fact_style', 'new') if self._fact_style != 'new': warnings.warn('fact-style %s will be removed in a future release.' % (self._fact_style), RuntimeWarning) self.console_has_banner = kvargs.get('console_has_banner', False) self.rpc = _RpcMetaExec(self) self._ssh_config = kvargs.get('ssh_config') self._manages = [] self.junos_dev_handler = JunosDeviceHandler(device_params= {'name': 'junos', 'local': False}) if self._fact_style == 'old': self.facts = self.ofacts else: self.facts = _FactCache(self) @property def timeout(self): """ :returns: current console connection timeout value (int) in seconds. """ return self._timeout @timeout.setter def timeout(self, value): """ Used to change the console connection timeout value (default=0.5 sec). :param int value: New timeout value in seconds """ self._timeout = value def open(self, *vargs, **kvargs): """ Opens a connection to the device using existing login/auth information. :param bool gather_facts: If set to ``True``/``False`` will override the device instance value for only this open process """ # --------------------------------------------------------------- # validate device hostname or IP address # --------------------------------------------------------------- if self._mode.upper() == 'TELNET' and self._hostname is None: self.results['failed'] = True self.results[ 'errmsg'] = 'ERROR: Device hostname/IP not specified !!!' return self.results # -------------------- # login to the CONSOLE # -------------------- try: self._tty_login() except RuntimeError as err: logger.error("ERROR: {0}:{1}\n".format('login', str(err))) logger.error( "\nComplete traceback message: {0}".format( traceback.format_exc())) raise err except Exception as ex: logger.error("Exception occurred: {0}:{1}\n".format('login', str(ex))) raise ex self.connected = True gather_facts = kvargs.get('gather_facts', self._gather_facts) if gather_facts is True: logger.info('facts: retrieving device facts...') self.facts_refresh() self.results['facts'] = self.facts return self def close(self, skip_logout=False): """ Closes the connection to the device. """ if skip_logout is False and self.connected is True: try: self._tty_logout() except Exception as err: logger.error("ERROR {0}:{1}\n".format('logout', str(err))) raise err self.connected = False elif self.connected is True: try: self._tty._tty_close() except Exception as err: logger.error("ERROR {0}:{1}\n".format('close', str(err))) logger.error( "\nComplete traceback message: {0}".format( traceback.format_exc())) raise err self.connected = False def _rpc_reply(self, rpc_cmd_e): encode = None if sys.version < '3' else 'unicode' rpc_cmd = etree.tostring(rpc_cmd_e, encoding=encode) if \ isinstance(rpc_cmd_e, etree._Element) else rpc_cmd_e reply = self._tty.nc.rpc(rpc_cmd) rpc_rsp_e = NCElement(reply, self.junos_dev_handler.transform_reply())._NCElement__doc return rpc_rsp_e # ------------------------------------------------------------------------- # LOGIN/LOGOUT # ------------------------------------------------------------------------- def _tty_login(self): tty_args = dict() tty_args['user'] = self._auth_user tty_args['passwd'] = self._auth_password tty_args['timeout'] = float(self._timeout) tty_args['attempts'] = int(self._attempts) tty_args['baud'] = self._baud if self._mode.upper() == 'TELNET': tty_args['host'] = self._hostname tty_args['port'] = self._port tty_args['console_has_banner'] = self.console_has_banner self.console = ('telnet', self._hostname, self.port) self._tty = Telnet(**tty_args) elif self._mode.upper() == 'SERIAL': tty_args['port'] = self._port self.console = ('serial', self._port) self._tty = Serial(**tty_args) else: logger.error('Mode should be either telnet or serial') raise AttributeError('Mode to be telnet/serial') self._tty.login() def _tty_logout(self): self._tty.logout() def zeroize(self): """ perform device ZEROIZE actions """ logger.info("zeroize : ZEROIZE device, rebooting") self._tty.nc.zeroize() self._skip_logout = True self.results['changed'] = True # ----------------------------------------------------------------------- # Context Manager # ----------------------------------------------------------------------- def __enter__(self): self._conn = self.open() return self def __exit__(self, exc_type, exc_val, exc_tb): if self.connected: self.close()
class Console(_Connection): def __init__(self, **kvargs): """ NoobDevice object constructor. :param str host: **REQUIRED** host-name or ipaddress of target device :param str user: *OPTIONAL* login user-name, uses root if not provided :param str passwd: *OPTIONAL* in console connection for device at zeroized state password is not required :param int port: *OPTIONAL* port, defaults to '23' for telnet mode and '/dev/ttyUSB0' for serial. :param int baud: *OPTIONAL* baud, default baud rate is 9600 :param str mode: *OPTIONAL* mode, mode of connection (telnet/serial) default is telnet :param int timeout: *OPTIONAL* timeout, default is 0.5 :param int attempts: *OPTIONAL* attempts, default is 10 :param str ssh_config: *OPTIONAL* The path to the SSH configuration file. This can be used to load SSH information from a configuration file. By default ~/.ssh/config is queried it will be used by SCP class. So its assumed ssh is enabled by the time we use SCP functionality. :param bool gather_facts: *OPTIONAL* Defaults to ``False``. If ``False`` and old-style fact gathering is in use then facts are not gathered on call to :meth:`open`. This argument is a no-op when new-style fact gathering is in use (the default.) :param str fact_style: *OPTIONAL* The style of fact gathering to use. Valid values are: 'new', 'old', or 'both'. The default is 'new'. The value 'both' is only present for debugging purposes. It will be removed in a future release. The value 'old' is only present to workaround bugs in new-style fact gathering. It will be removed in a future release. :param bool console_has_banner: *OPTIONAL* default is ``False``. If ``False`` then in case of a hung state, <close-session/> rpc is sent to the console. If ``True``, after sleep(5), a new-line is sent """ # ---------------------------------------- # setup instance connection/open variables # ---------------------------------------- self._tty = None self._ofacts = {} self.connected = False self._skip_logout = False self.results = dict(changed=False, failed=False, errmsg=None) # hostname is not required in serial mode connection self._hostname = kvargs.get('host') self._auth_user = kvargs.get('user', 'root') self._auth_password = kvargs.get('password', '') or kvargs.get( 'passwd', '') self._port = kvargs.get('port', '23') self._baud = kvargs.get('baud', '9600') self._mode = kvargs.get('mode', 'telnet') self._timeout = kvargs.get('timeout', '0.5') self._normalize = kvargs.get('normalize', False) self._norm_transform = lambda: JXML.normalize_xslt.encode('UTF-8') self.transform = self._norm_transform # self.timeout needed by PyEZ utils #self.timeout = self._timeout self._attempts = kvargs.get('attempts', 10) self._gather_facts = kvargs.get('gather_facts', False) self._fact_style = kvargs.get('fact_style', 'new') if self._fact_style != 'new': warnings.warn( 'fact-style %s will be removed in a future release.' % (self._fact_style), RuntimeWarning) self.console_has_banner = kvargs.get('console_has_banner', False) self.rpc = _RpcMetaExec(self) self._ssh_config = kvargs.get('ssh_config') self._manages = [] self.junos_dev_handler = JunosDeviceHandler(device_params={ 'name': 'junos', 'local': False }) if self._fact_style == 'old': self.facts = self.ofacts else: self.facts = _FactCache(self) @property def timeout(self): """ :returns: current console connection timeout value (int) in seconds. """ return self._timeout @timeout.setter def timeout(self, value): """ Used to change the console connection timeout value (default=0.5 sec). :param int value: New timeout value in seconds """ self._timeout = value def open(self, *vargs, **kvargs): """ Opens a connection to the device using existing login/auth information. :param bool gather_facts: If set to ``True``/``False`` will override the device instance value for only this open process """ # --------------------------------------------------------------- # validate device hostname or IP address # --------------------------------------------------------------- if self._mode.upper() == 'TELNET' and self._hostname is None: self.results['failed'] = True self.results[ 'errmsg'] = 'ERROR: Device hostname/IP not specified !!!' return self.results # -------------------- # login to the CONSOLE # -------------------- try: self._tty_login() except RuntimeError as err: logger.error("ERROR: {0}:{1}\n".format('login', str(err))) logger.error("\nComplete traceback message: {0}".format( traceback.format_exc())) raise err except Exception as ex: logger.error("Exception occurred: {0}:{1}\n".format( 'login', str(ex))) raise ex self.connected = True gather_facts = kvargs.get('gather_facts', self._gather_facts) if gather_facts is True: logger.info('facts: retrieving device facts...') self.facts_refresh() self.results['facts'] = self.facts return self def close(self, skip_logout=False): """ Closes the connection to the device. """ if skip_logout is False and self.connected is True: try: self._tty_logout() except Exception as err: logger.error("ERROR {0}:{1}\n".format('logout', str(err))) raise err self.connected = False elif self.connected is True: try: self._tty._tty_close() except Exception as err: logger.error("ERROR {0}:{1}\n".format('close', str(err))) logger.error("\nComplete traceback message: {0}".format( traceback.format_exc())) raise err self.connected = False def _rpc_reply(self, rpc_cmd_e): encode = None if sys.version < '3' else 'unicode' rpc_cmd = etree.tostring(rpc_cmd_e, encoding=encode) if \ isinstance(rpc_cmd_e, etree._Element) else rpc_cmd_e reply = self._tty.nc.rpc(rpc_cmd) rpc_rsp_e = NCElement( reply, self.junos_dev_handler.transform_reply())._NCElement__doc return rpc_rsp_e # ------------------------------------------------------------------------- # LOGIN/LOGOUT # ------------------------------------------------------------------------- def _tty_login(self): tty_args = dict() tty_args['user'] = self._auth_user tty_args['passwd'] = self._auth_password tty_args['timeout'] = float(self._timeout) tty_args['attempts'] = int(self._attempts) tty_args['baud'] = self._baud if self._mode.upper() == 'TELNET': tty_args['host'] = self._hostname tty_args['port'] = self._port tty_args['console_has_banner'] = self.console_has_banner self.console = ('telnet', self._hostname, self.port) self._tty = Telnet(**tty_args) elif self._mode.upper() == 'SERIAL': tty_args['port'] = self._port self.console = ('serial', self._port) self._tty = Serial(**tty_args) else: logger.error('Mode should be either telnet or serial') raise AttributeError('Mode to be telnet/serial') self._tty.login() def _tty_logout(self): self._tty.logout() def zeroize(self): """ perform device ZEROIZE actions """ logger.info("zeroize : ZEROIZE device, rebooting") self._tty.nc.zeroize() self._skip_logout = True self.results['changed'] = True # ----------------------------------------------------------------------- # Context Manager # ----------------------------------------------------------------------- def __enter__(self): self._conn = self.open() return self def __exit__(self, exc_type, exc_val, exc_tb): if self.connected: self.close()
class Console(_Connection): def __init__(self, **kvargs): """ NoobDevice object constructor. :param str host: **REQUIRED** host-name or ipaddress of target device :param str user: *OPTIONAL* login user-name, uses root if not provided :param str passwd: *OPTIONAL* in console connection for device at zeroized state password is not required :param int port: *OPTIONAL* port, defaults to '23' for telnet mode and '/dev/ttyUSB0' for serial. :param int baud: *OPTIONAL* baud, default baud rate is 9600 :param str mode: *OPTIONAL* mode, mode of connection (telnet/serial) default is telnet :param int timeout: *OPTIONAL* timeout, default is 0.5 :param int attempts: *OPTIONAL* attempts, default is 10 :param str ssh_config: *OPTIONAL* The path to the SSH configuration file. This can be used to load SSH information from a configuration file. By default ~/.ssh/config is queried it will be used by SCP class. So its assumed ssh is enabled by the time we use SCP functionality. :param bool gather_facts: *OPTIONAL* Defaults to ``False``. If ``False`` and old-style fact gathering is in use then facts are not gathered on call to :meth:`open`. This argument is a no-op when new-style fact gathering is in use (the default.) :param str fact_style: *OPTIONAL* The style of fact gathering to use. Valid values are: 'new', 'old', or 'both'. The default is 'new'. The value 'both' is only present for debugging purposes. It will be removed in a future release. The value 'old' is only present to workaround bugs in new-style fact gathering. It will be removed in a future release. :param bool console_has_banner: *OPTIONAL* default is ``False``. If ``False`` then in case of a hung state, <close-session/> rpc is sent to the console. If ``True``, after sleep(5), a new-line is sent """ # ---------------------------------------- # setup instance connection/open variables # ---------------------------------------- self._tty = None self._ofacts = {} self.connected = False self._skip_logout = False self.results = dict(changed=False, failed=False, errmsg=None) # hostname is not required in serial mode connection self._hostname = kvargs.get("host") self._auth_user = kvargs.get("user", "root") self._conf_auth_user = None self._conf_ssh_private_key_file = None self._auth_password = kvargs.get("password", "") or kvargs.get( "passwd", "") self.cs_user = kvargs.get("cs_user") self.cs_passwd = kvargs.get("cs_passwd") self._port = kvargs.get("port", "22" if self.cs_user else "23") self._mode = kvargs.get("mode", None if self.cs_user else "telnet") self._baud = kvargs.get("baud", "9600") if self._hostname: self._ssh_config = kvargs.get("ssh_config") self._sshconf_lkup() self._ssh_private_key_file = (kvargs.get("ssh_private_key_file") or self._conf_ssh_private_key_file) self._timeout = kvargs.get("timeout", "0.5") self._normalize = kvargs.get("normalize", False) self._attempts = kvargs.get("attempts", 10) self._gather_facts = kvargs.get("gather_facts", False) self._fact_style = kvargs.get("fact_style", "new") self._huge_tree = kvargs.get("huge_tree", False) if self._fact_style != "new": warnings.warn( "fact-style %s will be removed in " "a future release." % (self._fact_style), RuntimeWarning, ) self.console_has_banner = kvargs.get("console_has_banner", False) self.rpc = _RpcMetaExec(self) self._manages = [] self.junos_dev_handler = JunosDeviceHandler(device_params={ "name": "junos", "local": False }) self._conn = None self._j2ldr = _Jinja2ldr if self._fact_style == "old": self.facts = self.ofacts else: self.facts = _FactCache(self) @property def timeout(self): """ :returns: current console connection timeout value (int) in seconds. """ return self._timeout @timeout.setter def timeout(self, value): """ Used to change the console connection timeout value (default=0.5 sec). :param int value: New timeout value in seconds """ self._timeout = value @property def transform(self): """ :returns: the current RPC XML Transformation. """ return self.junos_dev_handler.transform_reply @transform.setter def transform(self, func): """ Used to change the RPC XML Transformation. :param lambda value: New transform lambda """ self.junos_dev_handler.transform_reply = func def open(self, *vargs, **kvargs): """ Opens a connection to the device using existing login/auth information. :param bool gather_facts: If set to ``True``/``False`` will override the device instance value for only this open process """ # --------------------------------------------------------------- # validate device hostname or IP address # --------------------------------------------------------------- if ((self._mode and self._mode.upper() == "TELNET") or self.cs_user is not None) and self._hostname is None: self.results["failed"] = True self.results[ "errmsg"] = "ERROR: Device hostname/IP not specified !!!" return self.results # --------------------------------------------------------------- # validate console server and password. Password-less connection # is not supported # --------------------------------------------------------------- if self.cs_user is not None and self.cs_passwd is None: self.results["failed"] = True self.results["errmsg"] = ( "ERROR: Console SSH, Password-less connection is " "not supported !!!") logger.error(self.results["errmsg"]) return self.results # -------------------- # login to the CONSOLE # -------------------- try: self._tty_login() except RuntimeError as err: logger.error("ERROR: {}:{}\n".format("login", str(err))) logger.error("\nComplete traceback message: {}".format( traceback.format_exc())) raise err except Exception as ex: logger.error("Exception occurred: {}:{}\n".format( "login", str(ex))) raise ex self.connected = True self._nc_transform = self.transform self._norm_transform = lambda: JXML.normalize_xslt.encode("UTF-8") # normalize argument to open() overrides normalize argument value # to __init__(). Save value to self._normalize where it is used by # normalizeDecorator() self._normalize = kvargs.get("normalize", self._normalize) if self._normalize is True: self.transform = self._norm_transform gather_facts = kvargs.get("gather_facts", self._gather_facts) if gather_facts is True: logger.info("facts: retrieving device facts...") self.facts_refresh() self.results["facts"] = self.facts self._conn = self._tty return self def close(self, skip_logout=False): """ Closes the connection to the device. """ if skip_logout is False and self.connected is True: try: self._tty_logout() except socket.error as err: # if err contains "Connection reset by peer" connection to the # device got closed if "Connection reset by peer" not in str(err): raise err except EOFError as err: if "telnet connection closed" not in str(err): raise err except Exception as err: logger.error("ERROR {}:{}\n".format("logout", str(err))) raise err self.connected = False elif self.connected is True: try: self._tty._tty_close() except Exception as err: logger.error("ERROR {}:{}\n".format("close", str(err))) logger.error("\nComplete traceback message: {}".format( traceback.format_exc())) raise err self.connected = False @ignoreWarnDecorator def _rpc_reply(self, rpc_cmd_e, *args, **kwargs): encode = None if sys.version < "3" else "unicode" rpc_cmd = (etree.tostring(rpc_cmd_e, encoding=encode) if isinstance( rpc_cmd_e, etree._Element) else rpc_cmd_e) reply = self._tty.nc.rpc(rpc_cmd) rpc_rsp_e = NCElement(reply, self.junos_dev_handler.transform_reply(), self._huge_tree)._NCElement__doc return rpc_rsp_e # ------------------------------------------------------------------------- # LOGIN/LOGOUT # ------------------------------------------------------------------------- def _tty_login(self): tty_args = dict() tty_args["user"] = self._auth_user tty_args["passwd"] = self._auth_password tty_args["timeout"] = float(self._timeout) tty_args["attempts"] = int(self._attempts) tty_args["baud"] = self._baud tty_args["huge_tree"] = self._huge_tree if self._mode and self._mode.upper() == "TELNET": tty_args["host"] = self._hostname tty_args["port"] = self._port tty_args["console_has_banner"] = self.console_has_banner self.console = ("telnet", self._hostname, self.port) self._tty = Telnet(**tty_args) elif self.cs_user is not None: tty_args["cs_user"] = self.cs_user tty_args["cs_passwd"] = self.cs_passwd tty_args["host"] = self._hostname tty_args["port"] = self._port tty_args["console_has_banner"] = self.console_has_banner tty_args["ssh_private_key_file"] = self._ssh_private_key_file self.console = ("ssh", self._hostname, self.port) self._tty = SSH(**tty_args) elif self._mode.upper() == "SERIAL": tty_args["port"] = self._port self.console = ("serial", self._port) self._tty = Serial(**tty_args) else: logger.error("Mode should be either telnet or serial") raise AttributeError("Mode to be telnet/serial") self._tty.login() def _tty_logout(self): self._tty.logout() def zeroize(self): """ perform device ZEROIZE actions """ logger.info("zeroize : ZEROIZE device, rebooting") self._tty.nc.zeroize() self._skip_logout = True self.results["changed"] = True # ----------------------------------------------------------------------- # Context Manager # ----------------------------------------------------------------------- def __enter__(self): self.open() return self def __exit__(self, exc_type, exc_val, exc_tb): if self.connected: self.close()
class Console(object): def __init__(self, **kvargs): """ NoobDevice object constructor. :param str host: **REQUIRED** host-name or ipaddress of target device :param str user: *OPTIONAL* login user-name, uses root if not provided :param str passwd: *OPTIONAL* in console connection for device at zeroized state password is not required :param int port: *OPTIONAL* port, default is telnet port `23` :param int baud: *OPTIONAL* baud, default baud rate is 9600 :param str mode: *OPTIONAL* mode, mode of connection (telnet/serial/ssh) default is telnet :param int timeout: *OPTIONAL* timeout, default is 0.5 :param int attempts: *OPTIONAL* attempts, default is 10 :param str ssh_config: *OPTIONAL* The path to the SSH configuration file. This can be used to load SSH information from a configuration file. By default ~/.ssh/config is queried it will be used by SCP class. So its assumed ssh is enabled by the time we use SCP functionality. :param bool gather_facts: *OPTIONAL* default is ``False``. If ``False`` then the facts are not gathered on call to :meth:`open` """ # ---------------------------------------- # setup instance connection/open variables # ---------------------------------------- self._tty = None self._facts = {} self.connected = False self._skip_logout = False self.results = dict(changed=False, failed=False, errmsg=None) # hostname is not required in serial mode connection self._hostname = kvargs.get('host') self._auth_user = kvargs.get('user', 'root') self._auth_password = kvargs.get('password', '') or kvargs.get( 'passwd', '') self._port = kvargs.get('port', '23') self._baud = kvargs.get('baud', '9600') self._mode = kvargs.get('mode', 'telnet') self._timeout = kvargs.get('timeout', '0.5') self._attempts = kvargs.get('attempts', 10) self.gather_facts = kvargs.get('gather_facts', False) self.rpc = _RpcMetaExec(self) from jnpr.junos import Device if sys.version < '3': self.cli = lambda cmd, format='text', warning=True: \ Device.cli.im_func(self, cmd, format, warning) self._sshconf_path = lambda: Device._sshconf_lkup.im_func(self) self.facts_refresh = lambda exception_on_failure=False: \ Device.facts_refresh.im_func(self, exception_on_failure) else: self.cli = lambda cmd, format='text', warning=True: \ Device.cli(self, cmd, format, warning) self._sshconf_path = lambda: Device._sshconf_lkup(self) self.facts_refresh = lambda exception_on_failure=False: \ Device.facts_refresh(self, exception_on_failure) self._ssh_config = kvargs.get('ssh_config') # ------------------------------------------------------------------------ # property: hostname # ------------------------------------------------------------------------ @property def hostname(self): """ :returns: the host-name of the Junos device. """ return self._hostname # ------------------------------------------------------------------------ # property: user # ------------------------------------------------------------------------ @property def user(self): """ :returns: the login user (str) accessing the Junos device """ return self._auth_user # ------------------------------------------------------------------------ # property: password # ------------------------------------------------------------------------ @property def password(self): """ :returns: ``None`` - do not provide the password """ return None # read-only @password.setter def password(self, value): """ Change the authentication password value. This is handy in case the calling program needs to attempt different passwords. """ self._auth_password = value # ------------------------------------------------------------------------ # property: port # ------------------------------------------------------------------------ @property def port(self): """ :returns: the port (str) to connect to the Junos device """ return self._port # ------------------------------------------------------------------------ # property: facts # ------------------------------------------------------------------------ @property def facts(self): """ :returns: Device fact dictionary """ return self._facts @facts.setter def facts(self, value): """ read-only property """ raise RuntimeError("facts is read-only!") def open(self): """ open the connection to the device """ # --------------------------------------------------------------- # validate device hostname or IP address # --------------------------------------------------------------- if self._mode.upper() is 'TELNET' and self._hostname is None: self.results['failed'] = True self.results[ 'errmsg'] = 'ERROR: Device hostname/IP not specified !!!' return self.results # -------------------- # login to the CONSOLE # -------------------- try: self._tty_login() except RuntimeError as err: logger.error("ERROR: {0}:{1}\n".format('login', str(err))) logger.error("\nComplete traceback message: {0}".format( traceback.format_exc())) raise RuntimeError except Exception as ex: logger.error("Exception occurred: {0} \n".format('login', str(ex))) raise ex self.connected = True if self.gather_facts is True: logger.debug('facts: retrieving device facts...') self.facts_refresh() self.results['facts'] = self._facts return self # def facts_refresh(self, exception_on_failure=False): # """ # Reload the facts from the Junos device into :attr:`facts` property. # # :param bool exception_on_failure: To raise exception or warning when # facts gathering errors out. # # """ # logger.debug('facts: retrieving device facts...') # for gather in FACT_LIST: # try: # gather(self, self._facts) # except: # if exception_on_failure: # raise # warnings.warn('Facts gathering is incomplete. ' # 'To know the reason call ' # '"dev.facts_refresh(exception_on_failure=True)"', # RuntimeWarning) # self.results['facts'] = self._facts # return # self.results['facts'] = self._facts def close(self, skip_logout=False): """ Closes the connection to the device. """ if skip_logout is False and self.connected is True: try: self._tty_logout() except Exception as err: logger.error("ERROR {0}:{1}\n".format('logout', str(err))) raise err self.connected = False elif self.connected is True: try: self._tty._tty_close() except Exception as err: logger.error("ERROR {0}:{1}\n".format('close', str(err))) logger.error("\nComplete traceback message: {0}".format( traceback.format_exc())) raise err self.connected = False # execute rpc calls def execute(self, rpc_cmd): return self._tty.nc.rpc(etree.tounicode(rpc_cmd)) # ------------------------------------------------------------------------- # LOGIN/LOGOUT # ------------------------------------------------------------------------- def _tty_login(self): tty_args = {} tty_args['user'] = self._auth_user tty_args['passwd'] = self._auth_password tty_args['timeout'] = float(self._timeout) tty_args['attempts'] = int(self._attempts) if self._mode.upper() == 'TELNET': tty_args['host'] = self._hostname tty_args['port'] = self._port self.console = ('telnet', self._hostname, self.port) self._tty = Telnet(**tty_args) elif self._mode.upper() == 'SERIAL': tty_args['port'] = self._port tty_args['baud'] = self._baud self.console = ('serial', self._port) self._tty = Serial(**tty_args) else: logger.error('Mode should be either telnet or serial') raise AttributeError('Mode to be telnet/serial') self._tty.login() def _tty_logout(self): self._tty.logout() def zeroize(self): """ perform device ZEROIZE actions """ logger.debug("zeroize : ZEROIZE device, rebooting") self._tty.nc.zeroize() self._skip_logout = True self.results['changed'] = True # ----------------------------------------------------------------------- # Context Manager # ----------------------------------------------------------------------- def __enter__(self): self.open() return self def __exit__(self, exc_type, exc_val, exc_tb): if self.connected: self.close()
class Console(_Connection): def __init__(self, **kvargs): """ NoobDevice object constructor. :param str host: **REQUIRED** host-name or ipaddress of target device :param str user: *OPTIONAL* login user-name, uses root if not provided :param str passwd: *OPTIONAL* in console connection for device at zeroized state password is not required :param int port: *OPTIONAL* port, defaults to '23' for telnet mode and '/dev/ttyUSB0' for serial. :param int baud: *OPTIONAL* baud, default baud rate is 9600 :param str mode: *OPTIONAL* mode, mode of connection (telnet/serial) default is telnet :param int timeout: *OPTIONAL* timeout, default is 0.5 :param int attempts: *OPTIONAL* attempts, default is 10 :param str ssh_config: *OPTIONAL* The path to the SSH configuration file. This can be used to load SSH information from a configuration file. By default ~/.ssh/config is queried it will be used by SCP class. So its assumed ssh is enabled by the time we use SCP functionality. :param bool gather_facts: *OPTIONAL* default is ``False``. If ``False`` then the facts are not gathered on call to :meth:`open` """ # ---------------------------------------- # setup instance connection/open variables # ---------------------------------------- self._tty = None self._facts = {} self.connected = False self._skip_logout = False self.results = dict(changed=False, failed=False, errmsg=None) # hostname is not required in serial mode connection self._hostname = kvargs.get('host') self._auth_user = kvargs.get('user', 'root') self._auth_password = kvargs.get( 'password', '') or kvargs.get( 'passwd', '') self._port = kvargs.get('port', '23') self._baud = kvargs.get('baud', '9600') self._mode = kvargs.get('mode', 'telnet') self._timeout = kvargs.get('timeout', '0.5') # self.timeout needed by PyEZ utils #self.timeout = self._timeout self._attempts = kvargs.get('attempts', 10) self.gather_facts = kvargs.get('gather_facts', False) self.rpc = _RpcMetaExec(self) self._ssh_config = kvargs.get('ssh_config') self._manages = [] @property def timeout(self): """ :returns: current console connection timeout value (int) in seconds. """ return self._timeout @timeout.setter def timeout(self, value): """ Used to change the console connection timeout value (default=0.5 sec). :param int value: New timeout value in seconds """ self._timeout = value def open(self): """ open the connection to the device """ # --------------------------------------------------------------- # validate device hostname or IP address # --------------------------------------------------------------- if self._mode.upper() is 'TELNET' and self._hostname is None: self.results['failed'] = True self.results[ 'errmsg'] = 'ERROR: Device hostname/IP not specified !!!' return self.results # -------------------- # login to the CONSOLE # -------------------- try: self._tty_login() except RuntimeError as err: logger.error("ERROR: {0}:{1}\n".format('login', str(err))) logger.error( "\nComplete traceback message: {0}".format( traceback.format_exc())) raise err except Exception as ex: logger.error("Exception occurred: {0}:{1}\n".format('login', str(ex))) raise ex self.connected = True if self.gather_facts is True: logger.info('facts: retrieving device facts...') self.facts_refresh() self.results['facts'] = self._facts return self def close(self, skip_logout=False): """ Closes the connection to the device. """ if skip_logout is False and self.connected is True: try: self._tty_logout() except Exception as err: logger.error("ERROR {0}:{1}\n".format('logout', str(err))) raise err self.connected = False elif self.connected is True: try: self._tty._tty_close() except Exception as err: logger.error("ERROR {0}:{1}\n".format('close', str(err))) logger.error( "\nComplete traceback message: {0}".format( traceback.format_exc())) raise err self.connected = False # execute rpc calls @timeoutDecorator def execute(self, rpc_cmd, *args, **kwargs): return self._tty.nc.rpc(etree.tounicode(rpc_cmd)) # ------------------------------------------------------------------------- # LOGIN/LOGOUT # ------------------------------------------------------------------------- def _tty_login(self): tty_args = {} tty_args['user'] = self._auth_user tty_args['passwd'] = self._auth_password tty_args['timeout'] = float(self._timeout) tty_args['attempts'] = int(self._attempts) if self._mode.upper() == 'TELNET': tty_args['host'] = self._hostname tty_args['port'] = self._port self.console = ('telnet', self._hostname, self.port) self._tty = Telnet(**tty_args) elif self._mode.upper() == 'SERIAL': tty_args['port'] = self._port tty_args['baud'] = self._baud self.console = ('serial', self._port) self._tty = Serial(**tty_args) else: logger.error('Mode should be either telnet or serial') raise AttributeError('Mode to be telnet/serial') self._tty.login() def _tty_logout(self): self._tty.logout() def zeroize(self): """ perform device ZEROIZE actions """ logger.info("zeroize : ZEROIZE device, rebooting") self._tty.nc.zeroize() self._skip_logout = True self.results['changed'] = True # ----------------------------------------------------------------------- # Context Manager # ----------------------------------------------------------------------- def __enter__(self): self._conn = self.open() return self def __exit__(self, exc_type, exc_val, exc_tb): if self.connected: self.close()
class Console(_Connection): def __init__(self, **kvargs): """ NoobDevice object constructor. :param str host: **REQUIRED** host-name or ipaddress of target device :param str user: *OPTIONAL* login user-name, uses root if not provided :param str passwd: *OPTIONAL* in console connection for device at zeroized state password is not required :param int port: *OPTIONAL* port, defaults to '23' for telnet mode and '/dev/ttyUSB0' for serial. :param int baud: *OPTIONAL* baud, default baud rate is 9600 :param str mode: *OPTIONAL* mode, mode of connection (telnet/serial) default is telnet :param int timeout: *OPTIONAL* timeout, default is 0.5 :param int attempts: *OPTIONAL* attempts, default is 10 :param str ssh_config: *OPTIONAL* The path to the SSH configuration file. This can be used to load SSH information from a configuration file. By default ~/.ssh/config is queried it will be used by SCP class. So its assumed ssh is enabled by the time we use SCP functionality. :param bool gather_facts: *OPTIONAL* default is ``False``. If ``False`` then the facts are not gathered on call to :meth:`open` """ # ---------------------------------------- # setup instance connection/open variables # ---------------------------------------- self._tty = None self._facts = {} self.connected = False self._skip_logout = False self.results = dict(changed=False, failed=False, errmsg=None) # hostname is not required in serial mode connection self._hostname = kvargs.get('host') self._auth_user = kvargs.get('user', 'root') self._auth_password = kvargs.get('password', '') or kvargs.get( 'passwd', '') self._port = kvargs.get('port', '23') self._baud = kvargs.get('baud', '9600') self._mode = kvargs.get('mode', 'telnet') self._timeout = kvargs.get('timeout', '0.5') # self.timeout needed by PyEZ utils #self.timeout = self._timeout self._attempts = kvargs.get('attempts', 10) self.gather_facts = kvargs.get('gather_facts', False) self.rpc = _RpcMetaExec(self) self._ssh_config = kvargs.get('ssh_config') self._manages = [] @property def timeout(self): """ :returns: current console connection timeout value (int) in seconds. """ return self._timeout @timeout.setter def timeout(self, value): """ Used to change the console connection timeout value (default=0.5 sec). :param int value: New timeout value in seconds """ self._timeout = value def open(self): """ open the connection to the device """ # --------------------------------------------------------------- # validate device hostname or IP address # --------------------------------------------------------------- if self._mode.upper() == 'TELNET' and self._hostname is None: self.results['failed'] = True self.results[ 'errmsg'] = 'ERROR: Device hostname/IP not specified !!!' return self.results # -------------------- # login to the CONSOLE # -------------------- try: self._tty_login() except RuntimeError as err: logger.error("ERROR: {0}:{1}\n".format('login', str(err))) logger.error("\nComplete traceback message: {0}".format( traceback.format_exc())) raise err except Exception as ex: logger.error("Exception occurred: {0}:{1}\n".format( 'login', str(ex))) raise ex self.connected = True if self.gather_facts is True: logger.info('facts: retrieving device facts...') self.facts_refresh() self.results['facts'] = self._facts return self def close(self, skip_logout=False): """ Closes the connection to the device. """ if skip_logout is False and self.connected is True: try: self._tty_logout() except Exception as err: logger.error("ERROR {0}:{1}\n".format('logout', str(err))) raise err self.connected = False elif self.connected is True: try: self._tty._tty_close() except Exception as err: logger.error("ERROR {0}:{1}\n".format('close', str(err))) logger.error("\nComplete traceback message: {0}".format( traceback.format_exc())) raise err self.connected = False # execute rpc calls @timeoutDecorator def execute(self, rpc_cmd, *args, **kwargs): encode = None if sys.version < '3' else 'unicode' rpc_cmd = etree.tostring(rpc_cmd, encoding=encode) if \ isinstance(rpc_cmd, etree._Element) else rpc_cmd return self._tty.nc.rpc(rpc_cmd) # ------------------------------------------------------------------------- # LOGIN/LOGOUT # ------------------------------------------------------------------------- def _tty_login(self): tty_args = {} tty_args['user'] = self._auth_user tty_args['passwd'] = self._auth_password tty_args['timeout'] = float(self._timeout) tty_args['attempts'] = int(self._attempts) tty_args['baud'] = self._baud if self._mode.upper() == 'TELNET': tty_args['host'] = self._hostname tty_args['port'] = self._port self.console = ('telnet', self._hostname, self.port) self._tty = Telnet(**tty_args) elif self._mode.upper() == 'SERIAL': tty_args['port'] = self._port self.console = ('serial', self._port) self._tty = Serial(**tty_args) else: logger.error('Mode should be either telnet or serial') raise AttributeError('Mode to be telnet/serial') self._tty.login() def _tty_logout(self): self._tty.logout() def zeroize(self): """ perform device ZEROIZE actions """ logger.info("zeroize : ZEROIZE device, rebooting") self._tty.nc.zeroize() self._skip_logout = True self.results['changed'] = True # ----------------------------------------------------------------------- # Context Manager # ----------------------------------------------------------------------- def __enter__(self): self._conn = self.open() return self def __exit__(self, exc_type, exc_val, exc_tb): if self.connected: self.close()