def __init__(self, *args, **kwargs): ''' __init__ instantiates a single connection instance. ''' # set defaults kwargs.setdefault('timeout', 30) # instanciate BaseConnection # (could use super...) BaseConnection.__init__(self, *args, **kwargs) # shortwire Ncclient device handling portion # and create just the DeviceHandler device_handler = DefaultDeviceHandler() # create the session instance session = transport.SSHSession(device_handler) # load known_hosts file (if available) session.load_known_hosts() # instanciate ncclient Manager # (can't use super due to mro change) manager.Manager.__init__(self, session = session, device_handler = device_handler, timeout = self.timeout)
def connect(ns): password = ns.password if password is None: password = getpass.getpass() connect_args = dict(host=ns.host, port=ns.port, username=ns.username, password=password, key_filename=ns.privKeyFile, hostkey_verify=False, look_for_keys=False, allow_agent=False) device_handler = manager.make_device_handler(None) if not ns.tcp and not ns.raw: # use the public API only session = transport.SSHSession(device_handler) elif ns.tcp: session = nctransport.TCPSession(device_handler, ns.raw) else: session = nctransport.SSHSession(device_handler, ns.raw) if not ns.tcp and ("hostkey_verify" not in connect_args or connect_args["hostkey_verify"]): session.load_known_hosts() try: session.connect(**connect_args) except Exception: if session.transport: session.close() raise return manager.Manager(session, device_handler, **connect_args)
def test_rawrpc(self): from ncclient.operations.retrieve import GetReply h = DefaultDeviceHandler() self.rawrpc = yang.connector.netconf.RawRPC( session=transport.SSHSession(h), device_handler=h) self.rawrpc._event = MyEvent() self.rawrpc._session = MySSHSession() reply_raw = ''' <rpc-reply message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" > <data> <native xmlns="http://cisco.com/ns/yang/ned/ios"> <version>16.3</version> </native> </data> </rpc-reply> ''' self.rawrpc._reply = GetReply(reply_raw) r = ''' <rpc message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <get> <filter> <native xmlns="http://cisco.com/ns/yang/ned/ios"> <version> </version> </native> </filter> </get> </rpc> ''' generated_value = self.rawrpc._request(r).xml expected_value = ''' <rpc-reply message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" > <data> <native xmlns="http://cisco.com/ns/yang/ned/ios"> <version>16.3</version> </native> </data> </rpc-reply> ''' self.assertEqual(generated_value, expected_value)
def connect_ssh(*args, **kwds): """ Initialize a :class:`Manager` over the SSH transport. For documentation of arguments see :meth:`ncclient.transport.SSHSession.connect`. The underlying :class:`ncclient.transport.SSHSession` is created with :data:`CAPABILITIES`. It is first instructed to :meth:`~ncclient.transport.SSHSession.load_known_hosts` and then all the provided arguments are passed directly to its implementation of :meth:`~ncclient.transport.SSHSession.connect`. To invoke advanced vendor related operation add device_params = {'name':'<vendor_alias>'} in connection paramerers. For the time, 'junos' and 'nexus' are supported for Juniper and Cisco Nexus respectively. A custom device handler can be provided with device_params = {'handler':<handler class>} in connection paramerers. """ # Extract device parameter dict, if it was passed into this function. Need to # remove it from kwds, since the session.connect() doesn't like extra stuff in # there. if "device_params" in kwds: device_params = kwds["device_params"] del kwds["device_params"] else: device_params = None device_handler = make_device_handler(device_params) device_handler.add_additional_ssh_connect_params(kwds) global VENDOR_OPERATIONS VENDOR_OPERATIONS.update(device_handler.add_additional_operations()) session = transport.SSHSession(device_handler) if "hostkey_verify" not in kwds or kwds["hostkey_verify"]: session.load_known_hosts() try: session.connect(*args, **kwds) except Exception as ex: if session.transport: session.close() raise return Manager(session, device_handler, **kwds)
def connect_ssh(*args, **kwds): """ Initialize a :class:`Manager` over the SSH transport. For documentation of arguments see :meth:`ncclient.transport.SSHSession.connect`. The underlying :class:`ncclient.transport.SSHSession` is created with :data:`CAPABILITIES`. It is first instructed to :meth:`~ncclient.transport.SSHSession.load_known_hosts` and then all the provided arguments are passed directly to its implementation of :meth:`~ncclient.transport.SSHSession.connect`. To customize the :class:`Manager`, add a `manager_params` dictionary in connection parameters (e.g. `manager_params={'timeout': 60}` for a bigger RPC timeout parameter) To invoke advanced vendor related operation add `device_params={'name': '<vendor_alias>'}` in connection parameters. For the time, 'junos' and 'nexus' are supported for Juniper and Cisco Nexus respectively. A custom device handler can be provided with `device_params={'handler':<handler class>}` in connection parameters. """ # Extract device parameter and manager parameter dictionaries, if they were passed into this function. # Remove them from kwds (which should keep only session.connect() parameters). device_params = _extract_device_params(kwds) manager_params = _extract_manager_params(kwds) device_handler = make_device_handler(device_params) device_handler.add_additional_ssh_connect_params(kwds) global VENDOR_OPERATIONS VENDOR_OPERATIONS.update(device_handler.add_additional_operations()) session = transport.SSHSession(device_handler) if "hostkey_verify" not in kwds or kwds["hostkey_verify"]: session.load_known_hosts() try: session.connect(*args, **kwds) except Exception as ex: if session.transport: session.close() raise return Manager(session, device_handler, **manager_params)
def connect(*args, **kwargs): """ Initialize a :class:`ModelDevice` over the SSH transport. For documentation of arguments see :meth:`ncclient.transport.SSHSession.connect`. The underlying :class:`ncclient.transport.SSHSession` is created with :data:`CAPABILITIES`. It is first instructed to :meth:`~ncclient.transport.SSHSession.load_known_hosts` and then all the provided arguments are passed directly to its implementation of :meth:`~ncclient.transport.SSHSession.connect`. """ device_handler = DefaultDeviceHandler() session = transport.SSHSession(device_handler) if "hostkey_verify" not in kwargs or kwargs["hostkey_verify"]: session.load_known_hosts() try: session.connect(*args, **kwargs) except Exception as ex: if session.transport: session.close() raise return ModelDevice(session, device_handler, **kwargs)
def connect(self): '''connect High-level api: opens the NetConf connection and exchanges capabilities. Since topology YAML file is parsed by BaseConnection, the following parameters can be specified in your YAML file. Parameters ---------- host : `string` Hostname or IP address to connect to. port : `int`, optional By default port is 830, but some devices use the default SSH port of 22 so this may need to be specified. timeout : `int`, optional An optional keyed argument to set timeout value in seconds. By default this value is 30 seconds. username : `string` The username to use for SSH authentication. password : `string` The password used if using password authentication, or the passphrase to use for unlocking keys that require it. key_filename : `string` a filename where a the private key to be used can be found. allow_agent : `boolean` Enables querying SSH agent (if found) for keys. The default value is True. hostkey_verify : `boolean` Enables hostkey verification from ~/.ssh/known_hosts. The default value is False. look_for_keys : `boolean` Enables looking in the usual locations for ssh keys (e.g. ~/.ssh/id_*). The default value is True. ssh_config : `string` Enables parsing of an OpenSSH configuration file, if set to its path, e.g. ~/.ssh/config or to True. If the value is True, ncclient uses ~/.ssh/config. The default value is None. Raises ------ Exception If the YAML file does not have correct connections section, or establishing transport to ip:port is failed, ssh authentication is failed, or other transport failures. Note ---- There is no return from this method. If something goes wrong, an exception will be raised. YAML Example:: devices: asr22: type: 'ASR' tacacs: login_prompt: "login:"******"Password:"******"admin" passwords: tacacs: admin enable: admin line: admin connections: a: protocol: telnet ip: "1.2.3.4" port: 2004 vty: protocol : telnet ip : "2.3.4.5" netconf: class: yang.connector.Netconf ip : "2.3.4.5" port: 830 username: admin password: admin Code Example:: >>> from pyats.topology import loader >>> testbed = loader.load('/users/xxx/xxx/asr22.yaml') >>> device = testbed.devices['asr22'] >>> device.connect(alias='nc', via='netconf') >>> Expected Results:: >>> device.nc.connected True >>> for iter in device.nc.server_capabilities: ... print(iter) ... urn:ietf:params:xml:ns:yang:smiv2:RFC-1215?module=RFC-1215 urn:ietf:params:xml:ns:yang:smiv2:SNMPv2-TC?module=SNMPv2-TC ... >>> ''' if self.connected: return logger.debug(self.session) if not self.session.is_alive(): self._session = transport.SSHSession(self._device_handler) # default values defaults = { 'host': None, 'port': 830, 'timeout': 30, 'username': None, 'password': None, 'key_filename': None, 'allow_agent': False, 'hostkey_verify': False, 'look_for_keys': False, 'ssh_config': None, } defaults.update(self.connection_info) # remove items disregards = ['class', 'model', 'protocol', 'async_mode', 'raise_mode', 'credentials'] defaults = {k: v for k, v in defaults.items() if k not in disregards} # rename ip -> host, cast to str type if 'ip' in defaults: defaults['host'] = str(defaults.pop('ip')) # rename user -> username if 'user' in defaults: defaults['username'] = str(defaults.pop('user')) # check credentials if self.connection_info.get('credentials'): try: defaults['username'] = str(self.connection_info['credentials']['netconf']['username']) except Exception: pass try: defaults['password'] = to_plaintext(self.connection_info['credentials']['netconf']['password']) except Exception: pass # support sshtunnel if 'sshtunnel' in defaults: from unicon.sshutils import sshtunnel try: tunnel_port = sshtunnel.auto_tunnel_add(self.device, self.via) if tunnel_port: defaults['host'] = self.device.connections[self.via] \ .sshtunnel.tunnel_ip defaults['port'] = tunnel_port except AttributeError as err: raise AttributeError("Cannot add ssh tunnel. Connection %s may " "not have ip/host or port.\n%s" % (self.via, err)) del defaults['sshtunnel'] defaults = {k: getattr(self, k, v) for k, v in defaults.items()} try: self.session.connect(**defaults) logger.info(banner('NETCONF CONNECTED')) except Exception: if self.session.transport: self.session.close() raise @atexit.register def cleanup(): if self.session.transport: self.session.close()