%PDF- %PDF-
Direktori : /usr/lib/python2.7/site-packages/salt/proxy/ |
Current File : //usr/lib/python2.7/site-packages/salt/proxy/junos.py |
# -*- coding: utf-8 -*- ''' Interface with a Junos device via proxy-minion. To connect to a junos device \ via junos proxy, specify the host information in the pillar in '/srv/pillar/details.sls' .. code-block:: yaml proxy: proxytype: junos host: <ip or dns name of host> username: <username> port: 830 password: <secret> In '/srv/pillar/top.sls' map the device details with the proxy name. .. code-block:: yaml base: 'vmx': - details After storing the device information in the pillar, configure the proxy \ in '/etc/salt/proxy' .. code-block:: yaml master: <ip or hostname of salt-master> Run the salt proxy via the following command: .. code-block:: bash salt-proxy --proxyid=vmx ''' from __future__ import absolute_import, print_function, unicode_literals import logging # Import 3rd-party libs try: HAS_JUNOS = True import jnpr.junos import jnpr.junos.utils import jnpr.junos.utils.config import jnpr.junos.utils.sw from jnpr.junos.exception import RpcTimeoutError, ConnectClosedError,\ RpcError, ConnectError, ProbeError, ConnectAuthError,\ ConnectRefusedError, ConnectTimeoutError from ncclient.operations.errors import TimeoutExpiredError except ImportError: HAS_JUNOS = False __proxyenabled__ = ['junos'] thisproxy = {} log = logging.getLogger(__name__) # Define the module's virtual name __virtualname__ = 'junos' def __virtual__(): ''' Only return if all the modules are available ''' if not HAS_JUNOS: return False, 'Missing dependency: The junos proxy minion requires the \'jnpr\' Python module.' return __virtualname__ def init(opts): ''' Open the connection to the Junos device, login, and bind to the Resource class ''' opts['multiprocessing'] = False log.debug('Opening connection to junos') args = {"host": opts['proxy']['host']} optional_args = ['user', 'username', 'password', 'passwd', 'port', 'gather_facts', 'mode', 'baud', 'attempts', 'auto_probe', 'ssh_private_key_file', 'ssh_config', 'normalize' ] if 'username' in opts['proxy'].keys(): opts['proxy']['user'] = opts['proxy'].pop('username') proxy_keys = opts['proxy'].keys() for arg in optional_args: if arg in proxy_keys: args[arg] = opts['proxy'][arg] thisproxy['conn'] = jnpr.junos.Device(**args) try: thisproxy['conn'].open() except (ProbeError, ConnectAuthError, ConnectRefusedError, ConnectTimeoutError, ConnectError) as ex: log.error("{} : not able to initiate connection to the device".format(str(ex))) thisproxy['initialized'] = False return if 'timeout' in proxy_keys: timeout = int(opts['proxy']['timeout']) try: thisproxy['conn'].timeout = timeout except Exception as ex: log.error('Not able to set timeout due to: %s', str(ex)) else: log.debug('RPC timeout set to %d seconds', timeout) try: thisproxy['conn'].bind(cu=jnpr.junos.utils.config.Config) except Exception as ex: log.error('Bind failed with Config class due to: {}'.format(str(ex))) try: thisproxy['conn'].bind(sw=jnpr.junos.utils.sw.SW) except Exception as ex: log.error('Bind failed with SW class due to: {}'.format(str(ex))) thisproxy['initialized'] = True def initialized(): return thisproxy.get('initialized', False) def conn(): return thisproxy['conn'] def alive(opts): ''' Validate and return the connection status with the remote device. .. versionadded:: 2018.3.0 ''' dev = conn() thisproxy['conn'].connected = ping() if not dev.connected: __salt__['event.fire_master']({}, 'junos/proxy/{}/stop'.format( opts['proxy']['host'])) return dev.connected def ping(): ''' Ping? Pong! ''' dev = conn() # Check that the underlying netconf connection still exists. if dev._conn is None: return False # call rpc only if ncclient queue is empty. If not empty that means other # rpc call is going on. if hasattr(dev._conn, '_session'): if dev._conn._session._transport.is_active(): # there is no on going rpc call. buffer tell can be 1 as it stores # remaining char after "]]>]]>" which can be a new line char if dev._conn._session._buffer.tell() <= 1 and \ dev._conn._session._q.empty(): return _rpc_file_list(dev) else: log.debug('skipped ping() call as proxy already getting data') return True else: # ssh connection is lost return False else: # other connection modes, like telnet return _rpc_file_list(dev) def _rpc_file_list(dev): try: dev.rpc.file_list(path='/dev/null', dev_timeout=5) return True except (RpcTimeoutError, ConnectClosedError): try: dev.close() return False except (RpcError, ConnectError, TimeoutExpiredError): return False except AttributeError as ex: if "'NoneType' object has no attribute 'timeout'" in ex: return False def proxytype(): ''' Returns the name of this proxy ''' return 'junos' def get_serialized_facts(): facts = dict(thisproxy['conn'].facts) if 'version_info' in facts: facts['version_info'] = \ dict(facts['version_info']) # For backward compatibility. 'junos_info' is present # only of in newer versions of facts. if 'junos_info' in facts: for re in facts['junos_info']: facts['junos_info'][re]['object'] = \ dict(facts['junos_info'][re]['object']) return facts def shutdown(opts): ''' This is called when the proxy-minion is exiting to make sure the connection to the device is closed cleanly. ''' log.debug('Proxy module %s shutting down!!', opts['id']) try: thisproxy['conn'].close() except Exception: pass