def connect(self, auth_provider='tmos', verify=False, port='443', protocol='https', retries=3, retry_wait=10, timeout=30, ttl=3600, *args, **kwargs): if self.connected: return # support sshtunnel if 'sshtunnel' in self.connection_info: try: from unicon.sshutils import sshtunnel except ImportError: raise ImportError("`unicon` is not installed for `sshtunnel`. " "Please install by `pip install unicon`.") try: tunnel_port = sshtunnel.auto_tunnel_add(self.device, self.via) if tunnel_port: self.ip = self.device.connections[ self.via].sshtunnel.tunnel_ip self.port = tunnel_port except AttributeError as e: raise AttributeError( "Cannot add ssh tunnel. Connection %s may not have ip/host or port.\n%s" % (self.via, e)) else: self.ip = self.connection_info['ip'].exploded self.port = self.connection_info.get('port', port) if 'protocol' in self.connection_info: protocol = self.connection_info['protocol'] self.base_url = '{protocol}://{ip}:{port}'.format(protocol=protocol, ip=self.ip, port=self.port) self.username, self.password = get_username_password(self) self.header = "Content-Type: application/json" self.verify = verify self._auth_provider = auth_provider self._ttl = ttl self._connect(timeout, retries, retry_wait) return self._is_connected, self.icr_session
def connect(self, timeout=10, port=443, protocol='https'): '''connect to the device via REST Arguments --------- timeout (int): Timeout value protocol (str): http or https. Default to https Raises ------ Exception --------- If the connection did not go well Note ---- There is no return from this method. If something goes wrong, an exception will be raised. YAML Example ------------ devices: dcnm: os: dcnm connections: vty: protocol : ssh ip : "2.3.4.5" protocol: https rest: class: rest.connector.Rest ip : "2.3.4.5" port: "443" protocol: https credentials: rest: username: admin password: cisco123 Code Example ------------ >>> from pyats.topology import loader >>> testbed = loader.load('/users/xxx/xxx/dcnm123.yaml') >>> device = testbed.devices['haPrimary'] >>> device.connect(alias='rest', via='rest') ''' # support sshtunnel if 'sshtunnel' in self.connection_info: try: from unicon.sshutils import sshtunnel except ImportError: raise ImportError( '`unicon` is not installed for `sshtunnel`. Please install by `pip install unicon`.' ) try: tunnel_port = sshtunnel.auto_tunnel_add(self.device, self.via) if tunnel_port: ip = self.device.connections[self.via].sshtunnel.tunnel_ip port = tunnel_port except AttributeError as e: raise AttributeError( "Cannot add ssh tunnel. Connection %s may not have ip/host or port.\n%s" % (self.via, e)) else: # prefer host instead of ip address directly try: host = self.connection_info['host'] except KeyError: host = self.connection_info['ip'].exploded port = self.connection_info.get('port', port) if 'protocol' in self.connection_info: protocol = self.connection_info['protocol'] self.url = '{protocol}://{host}:{port}'.format(protocol=protocol, host=host, port=port) self.verify = self.connection_info.get('verify', True) username, password = get_username_password(self) _data = json.dumps({'expirationTime': 999999}) login_url = '{url}/rest/logon'.format(url=self.url) log.info("Connecting to '{d}' with alias " "'{a}'".format(d=self.device.name, a=self.alias)) self.session = requests.Session() self.session.auth = HTTPBasicAuth(username, password) response = self.session.post(login_url, data=json.dumps( {'expirationTime': 999999}), headers=STD_HEADER, verify=self.verify) log.info(response) # Make sure it returned requests.codes.ok if response.status_code != requests.codes.ok: # Something bad happened raise RequestException("Connection to '{ip}' has returned the " "following code '{c}', instead of the " "expected status code '{ok}'" \ .format(ip=host, c=response.status_code, ok=requests.codes.ok)) self.token = response.json()[ 'Dcnm-Token'] # Retrieve the Token from the returned JSONhahhah self._is_connected = True log.info("Connected successfully to '{d}'".format(d=self.device.name)) return self.token
def connect(self, auth_provider='tmos', verify=False, port='443', protocol='https', *args, **kwargs): if self.connected: return # support sshtunnel if 'sshtunnel' in self.connection_info: try: from unicon.sshutils import sshtunnel except ImportError: raise ImportError( '`unicon` is not installed for `sshtunnel`. Please install by `pip install unicon`.' ) try: tunnel_port = sshtunnel.auto_tunnel_add(self.device, self.via) if tunnel_port: ip = self.device.connections[self.via].sshtunnel.tunnel_ip port = tunnel_port except AttributeError as e: raise AttributeError( "Cannot add ssh tunnel. Connection %s may not have ip/host or port.\n%s" % (self.via, e)) else: ip = self.connection_info['ip'].exploded port = self.connection_info.get('port', port) if 'protocol' in self.connection_info: protocol = self.connection_info['protocol'] self.base_url = '{protocol}://{ip}:{port}'.format(protocol=protocol, ip=ip, port=port) self.username, self.password = get_username_password(self) self.header = "Content-Type: application/json" self.verify = verify # URL to authenticate and receive the token url = "https://{0}:{1}/mgmt/shared/authn/login".format( self.ip, self.port) payload = { 'username': self.username, 'password': self.password, 'loginProviderName': auth_provider } iCRS = iControlRESTSession(self.username, self.password, verify=self.verify) log.info("Connecting to '{d}' with alias " "'{a}'".format(d=self.device.name, a=self.alias)) response = iCRS.post( url, json=payload, ) log.info(response.json()) if response.status_code not in [200]: if b'Configuration Utility restarting...' in response.content: time.sleep(30) # self.retries += 1 return self.connect() else: # self.retries = 0 return None, response.content self.token = response.json()['token']['token'] log.info( "The following toke is used to connect'{t}'".format(t=self.token)) # Self-link of the token timeout_url = "https://{0}:{1}/mgmt/shared/authz/tokens/{2}".format( self.ip, self.port, self.token) timeout_payload = {"timeout": "3600"} token_icr_session = iControlRESTSession(self.username, self.password, verify=self.verify, token_to_use=self.token) # Extending the timeout for the token received token_icr_session.patch(timeout_url, json=timeout_payload) log.info("'{t}' - Token timeout extended to '{time}'".format( t=self.token, time=timeout_payload)) params = dict(username=self.username, password=self.password, verify=self.verify, token_to_use=self.token) # creating an object to be used all new requests self.icr_session = iControlRESTSession(**params) self._is_connected = True log.info("Connected successfully to '{d}' using token: '{t}'".format( d=self.device.name, t=self.token)) return self._is_connected, self.icr_session
def connect(self, timeout=30, port='8080', protocol='http', default_content_type='json', verbose=False): '''connect to the device via REST Arguments --------- timeout (int): Timeout value port (str): Port number. Default to 8080 protocol (str): http or https. Default to http default_content_type: Default for content type, json or xml Raises ------ Exception --------- If the connection did not go well Note ---- There is no return from this method. If something goes wrong, an exception will be raised. ''' if self.connected: return log.debug("Content type: %s" % default_content_type) log.debug("Timeout: %s" % timeout) self.content_type = default_content_type # support sshtunnel if 'sshtunnel' in self.connection_info: try: from unicon.sshutils import sshtunnel except ImportError: raise ImportError( '`unicon` is not installed for `sshtunnel`. Please install by `pip install unicon`.' ) try: tunnel_port = sshtunnel.auto_tunnel_add(self.device, self.via) if tunnel_port: ip = self.device.connections[self.via].sshtunnel.tunnel_ip port = tunnel_port except AttributeError as e: raise AttributeError( "Cannot add ssh tunnel. Connection %s may not have ip/host or port.\n%s" % (self.via, e)) else: ip = self.connection_info['ip'].exploded port = self.connection_info.get('port', port) if 'protocol' in self.connection_info: protocol = self.connection_info['protocol'] self.base_url = '{protocol}://{ip}:{port}'.format(protocol=protocol, ip=ip, port=port) self.login_url = '{f}/api'.format(f=self.base_url) log.info("Connecting to '{d}' with alias " "'{a}'".format(d=self.device.name, a=self.alias)) username, password = get_username_password(self) self.session = requests.Session() self.session.auth = (username, password) # Connect to the device via requests response = self.session.get(self.login_url, timeout=timeout) output = response.text log.debug("Response: {c} {r}, headers: {h}".format( c=response.status_code, r=response.reason, h=response.headers)) if verbose: log.info("Response text:\n%s" % output) # Make sure it returned requests.codes.ok if response.status_code != requests.codes.ok: # Something bad happened raise RequestException("Connection to '{ip}:{port}' has returned the " "following code '{c}', instead of the " "expected status code '{ok}'"\ .format(ip=ip, port=port, c=response.status_code, ok=requests.codes.ok)) self._is_connected = True log.info("Connected successfully to '{d}'".format(d=self.device.name)) return response
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()
def connect(self, timeout=30, port="8443", protocol='https'): '''connect to the device via REST Arguments --------- timeout (int): Timeout value port (str): Port number. Default to 8443 protocol (str): http or https. Default to https Raises ------ Exception --------- If the connection did not go well Note ---- There is no return from this method. If something goes wrong, an exception will be raised. ''' if self.connected: return # support sshtunnel if 'sshtunnel' in self.connection_info: try: from unicon.sshutils import sshtunnel except ImportError: raise ImportError( '`unicon` is not installed for `sshtunnel`. Please install by `pip install unicon`.' ) try: tunnel_port = sshtunnel.auto_tunnel_add(self.device, self.via) if tunnel_port: ip = self.device.connections[self.via].sshtunnel.tunnel_ip port = tunnel_port except AttributeError as e: raise AttributeError( "Cannot add ssh tunnel. Connection %s may not have ip/host or port.\n%s" % (self.via, e)) else: ip = self.connection_info['ip'].exploded port = self.connection_info.get('port', port) if 'protocol' in self.connection_info: protocol = self.connection_info['protocol'] self.base_url = '{protocol}://{ip}:{port}'.format(protocol=protocol, ip=ip, port=port) self.verify = self.connection_info.get('verify', False) username, password = get_username_password(self) login_action = '/j_security_check' headers = {'Content-Type': 'application/x-www-form-urlencoded'} # Format data for loginForm login_data = {'j_username': username, 'j_password': password} # Url for posting login data login_url = self.base_url + login_action token_url = '{url}/dataservice/client/token'.format(url=self.base_url) self.session = requests.session() resp = self.session.post(login_url, data=login_data, headers=headers, verify=self.verify, timeout=timeout) if resp.status_code == 200: log.info("Login successfully to '{d}'".format(d=self.device.name)) else: raise RequestException( "Failed to login '{d}'".format(d=self.device.name)) login_token = self.session.get(url=token_url, verify=self.verify, timeout=timeout) if login_token.status_code == 200: self.token = login_token.content else: raise RequestException( "Failed to get token for '{d}'".format(d=self.device.name)) self._is_connected = True log.info("Connected successfully to '{d}'".format(d=self.device.name)) self.default_headers = { 'X-XSRF-TOKEN': self.token, 'Content-Type': 'application/json' }
def connect(self, timeout=30, default_content_type='json', verbose=False, port="443", protocol='https'): '''connect to the device via REST Arguments --------- timeout (int): Timeout value default_content_type: Default for content type, json or xml proxies: Specify the proxy to use for connection as seen below. {'http': 'http://proxy.esl.cisco.com:80/', 'ftp': 'http://proxy.esl.cisco.com:80/', 'https': 'http://proxy.esl.cisco.com:80/', 'no': '.cisco.com'} Raises ------ Exception --------- If the connection did not go well Note ---- Connecting via RESTCONF does not require contacting the device. This does nothing ''' if self.connected: return log.debug("Content type: %s" % default_content_type) log.debug("Timeout: %s" % timeout) self.content_type = default_content_type # support sshtunnel if 'sshtunnel' in self.connection_info: try: from unicon.sshutils import sshtunnel except ImportError: raise ImportError( '`unicon` is not installed for `sshtunnel`. Please install by `pip install unicon`.' ) try: tunnel_port = sshtunnel.auto_tunnel_add(self.device, self.via) if tunnel_port: ip = self.device.connections[self.via].sshtunnel.tunnel_ip port = tunnel_port except AttributeError as e: raise AttributeError( "Cannot add ssh tunnel. Connection %s may not have ip/host or port.\n%s" % (self.via, e)) else: ip = self.connection_info.ip.exploded port = self.connection_info.get('port', port) if 'protocol' in self.connection_info: protocol = self.connection_info['protocol'] self.base_url = '{protocol}://{ip}:{port}'.format(protocol=protocol, ip=ip, port=port) self.login_url = '{f}/'.format(f=self.base_url) log.info("Connecting to '{d}' with alias " "'{a}'".format(d=self.device.name, a=self.alias)) username, password = get_username_password(self) self.session = requests.Session() self.session.auth = (username, password) # Connect to the device via requests response = self.session.get(self.login_url, proxies=self.proxies, timeout=timeout, verify=False) output = response.text log.debug("Response: {c} {r}, headers: {h}".format( c=response.status_code, r=response.reason, h=response.headers)) if verbose: log.info("Response text:\n%s" % output) # Make sure it returned requests.codes.ok if response.status_code != requests.codes.ok: # Something bad happened raise RequestException( "Connection to '{ip}:{port}' has returned the " "following code '{c}', instead of the " "expected status code '{ok}'".format(ip=ip, port=port, c=response.status_code, ok=requests.codes.ok)) self._is_connected = True log.info("Connected successfully to '{d}'".format(d=self.device.name)) return response
def connect(self, timeout=30, port=443, protocol='https', retries=3, retry_wait=10): '''connect to the device via REST Arguments --------- timeout (int): Timeout value port (int): TCP port to use (default: 443) protocol (str): protocol to use (default: https) retries (int): Max retries on request exception (default: 3) retry_wait (int): Seconds to wait before retry (default: 10) Raises ------ Exception --------- If the connection did not go well Note ---- There is no return from this method. If something goes wrong, an exception will be raised. YAML Example ------------ devices: PE1: connections: a: protocol: telnet ip: "1.2.3.4" port: 2004 vty: protocol : telnet ip : "2.3.4.5" rest: class: rest.connector.Rest ip : "2.3.4.5" port: "443" protocol: https credentials: rest: 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='rest', via='rest') ''' if self.connected: return # support sshtunnel if 'sshtunnel' in self.connection_info: try: from unicon.sshutils import sshtunnel except ImportError: raise ImportError( '`unicon` is not installed for `sshtunnel`. Please install by `pip install unicon`.' ) try: tunnel_port = sshtunnel.auto_tunnel_add(self.device, self.via) if tunnel_port: ip = self.device.connections[self.via].sshtunnel.tunnel_ip port = tunnel_port except AttributeError as e: raise AttributeError( "Cannot add ssh tunnel. Connection %s may not have ip/host or port.\n%s" % (self.via, e)) else: ip = self.connection_info['ip'].exploded port = self.connection_info.get('port', port) if 'protocol' in self.connection_info: protocol = self.connection_info['protocol'] self.url = '{protocol}://{ip}:{port}'.format(protocol=protocol, ip=ip, port=port) login_url = '{f}/api/aaaLogin.json'.format(f=self.url) username, password = get_username_password(self) payload = { "aaaUser": { "attributes": { "name": username, "pwd": password, } } } log.info("Connecting to '{d}' with alias " "'{a}'".format(d=self.device.name, a=self.alias)) self.session = requests.Session() _data = json.dumps(payload) for _ in range(retries): try: # Connect to the device via requests if protocol == 'https': response = self.session.post(login_url, data=_data, timeout=timeout, verify=False) else: response = self.session.post(login_url, data=_data, timeout=timeout) break except Exception: log.warning('Request to {} failed. Waiting {} seconds before retrying\n'.format( self.device.name, retry_wait), exc_info=True) time.sleep(retry_wait) else: raise ConnectionError('Connection to {} failed'.format(self.device.name)) log.info(response) # Make sure it returned requests.codes.ok if response.status_code != requests.codes.ok: # Something bad happened raise RequestException("Connection to '{ip}' has returned the " "following code '{c}', instead of the " "expected status code '{ok}'" .format(ip=ip, c=response.status_code, ok=requests.codes.ok)) # Attach auth to session for future calls self.session.auth = HTTPBasicAuth(username, password) self._is_connected = True log.info("Connected successfully to '{d}'".format(d=self.device.name))
def connect(self, timeout=30, port="19399", protocol='http'): '''connect to the device via REST Arguments --------- timeout (int): Timeout value port (str): Port number. Default to 19399 protocol (str): http or https Raises ------ Exception --------- If the connection did not go well Note ---- There is no return from this method. If something goes wrong, an exception will be raised. YAML Example ------------ devices: virl: connections: rest: class: rest.connector.Rest ip : "192.168.1.1" port: "80" protocol : http credentials: default: username: admin password: cisco123 Code Example ------------ >>> from pyats.topology import loader >>> testbed = loader.load('/users/xxx/xxx/testbed.yaml') >>> device = testbed.devices['virl'] >>> device.connect(alias='rest', via='rest') ''' if self.connected: return # support sshtunnel if 'sshtunnel' in self.connection_info: try: from unicon.sshutils import sshtunnel except ImportError: raise ImportError( '`unicon` is not installed for `sshtunnel`. Please install by `pip install unicon`.' ) try: tunnel_port = sshtunnel.auto_tunnel_add(self.device, self.via) if tunnel_port: ip = self.device.connections[self.via].sshtunnel.tunnel_ip port = tunnel_port except AttributeError as e: raise AttributeError( "Cannot add ssh tunnel. Connection %s may not have ip/host or port.\n%s" % (self.via, e)) else: ip = self.connection_info['ip'].exploded port = self.connection_info.get('port', '19399') if 'protocol' in self.connection_info: protocol = self.connection_info['protocol'] self.url = '{protocol}://{ip}:{port}'.format(protocol=protocol, ip=ip, port=port) self.username, self.password = get_username_password(self) self.headers = {"Content-Type": "text/xml;charset=UTF-8"} log.info("Connecting to '{d}' with alias " "'{a}'".format(d=self.device.name, a=self.alias)) self.session = requests.Session() # Connect to the device via requests if protocol == 'https': response = self.session.get(self.url + '/roster/rest/test', auth=(self.username, self.password), timeout=timeout, headers=self.headers, verify=False) else: response = self.session.get(self.url + '/roster/rest/test', auth=(self.username, self.password), timeout=timeout, headers=self.headers) log.info(response) # Make sure it returned requests.codes.ok if response.status_code != requests.codes.ok: # Something bad happened raise RequestException("Connection to '{ip}' has returned the " "following code '{c}', instead of the " "expected status code '{ok}'"\ .format(ip=ip, c=response.status_code, ok=requests.codes.ok)) self._is_connected = True log.info("Connected successfully to '{d}'".format(d=self.device.name))