diff --git a/setup.py b/setup.py index d2defbc..02be5c0 100755 --- a/setup.py +++ b/setup.py @@ -162,6 +162,7 @@ def find_version(*paths): 'requests >= 1.15.1', 'dict2xml', 'f5-icontrol-rest', + 'ciscoisesdk' ], # any additional groups of dependencies. diff --git a/src/rest/connector/libs/apic/__init__.py b/src/rest/connector/libs/apic/__init__.py index 05cdc37..d5c9bf4 100644 --- a/src/rest/connector/libs/apic/__init__.py +++ b/src/rest/connector/libs/apic/__init__.py @@ -1,7 +1,7 @@ # Enable abstraction using this directory name as the abstraction token try: from genie import abstract - abstract.declare_token(__name__) + abstract.declare_token(os='apic') except Exception as e: import warnings warnings.warn('Could not declare abstraction token: ' + str(e)) diff --git a/src/rest/connector/libs/bigip/__init__.py b/src/rest/connector/libs/bigip/__init__.py index 05cdc37..ccae25e 100755 --- a/src/rest/connector/libs/bigip/__init__.py +++ b/src/rest/connector/libs/bigip/__init__.py @@ -1,7 +1,7 @@ # Enable abstraction using this directory name as the abstraction token try: from genie import abstract - abstract.declare_token(__name__) + abstract.declare_token(os='bigip') except Exception as e: import warnings warnings.warn('Could not declare abstraction token: ' + str(e)) diff --git a/src/rest/connector/libs/dcnm/__init__.py b/src/rest/connector/libs/dcnm/__init__.py index c48faa1..76f6ac2 100644 --- a/src/rest/connector/libs/dcnm/__init__.py +++ b/src/rest/connector/libs/dcnm/__init__.py @@ -2,7 +2,7 @@ # Enable abstraction using this directory name as the abstraction token try: from genie import abstract - abstract.declare_token(__name__) + abstract.declare_token(os='dcnm') except Exception as e: import warnings warnings.warn('Could not declare abstraction token: ' + str(e)) diff --git a/src/rest/connector/libs/dnac/__init__.py b/src/rest/connector/libs/dnac/__init__.py index 05cdc37..2462384 100644 --- a/src/rest/connector/libs/dnac/__init__.py +++ b/src/rest/connector/libs/dnac/__init__.py @@ -1,7 +1,7 @@ # Enable abstraction using this directory name as the abstraction token try: from genie import abstract - abstract.declare_token(__name__) + abstract.declare_token(os='dnac') except Exception as e: import warnings warnings.warn('Could not declare abstraction token: ' + str(e)) diff --git a/src/rest/connector/libs/elasticsearch/__init__.py b/src/rest/connector/libs/elasticsearch/__init__.py index 05cdc37..337ea0f 100644 --- a/src/rest/connector/libs/elasticsearch/__init__.py +++ b/src/rest/connector/libs/elasticsearch/__init__.py @@ -1,7 +1,7 @@ # Enable abstraction using this directory name as the abstraction token try: from genie import abstract - abstract.declare_token(__name__) + abstract.declare_token(os='elasticsearch') except Exception as e: import warnings warnings.warn('Could not declare abstraction token: ' + str(e)) diff --git a/src/rest/connector/libs/iosxe/__init__.py b/src/rest/connector/libs/iosxe/__init__.py index 05cdc37..c56e2cc 100644 --- a/src/rest/connector/libs/iosxe/__init__.py +++ b/src/rest/connector/libs/iosxe/__init__.py @@ -1,7 +1,7 @@ # Enable abstraction using this directory name as the abstraction token try: from genie import abstract - abstract.declare_token(__name__) + abstract.declare_token(os='iosxe') except Exception as e: import warnings warnings.warn('Could not declare abstraction token: ' + str(e)) diff --git a/src/rest/connector/libs/ise/__init__.py b/src/rest/connector/libs/ise/__init__.py new file mode 100644 index 0000000..9f414ae --- /dev/null +++ b/src/rest/connector/libs/ise/__init__.py @@ -0,0 +1,2 @@ +from genie import abstract +abstract.declare_token(os='ise') diff --git a/src/rest/connector/libs/ise/implementation.py b/src/rest/connector/libs/ise/implementation.py new file mode 100644 index 0000000..7c6019d --- /dev/null +++ b/src/rest/connector/libs/ise/implementation.py @@ -0,0 +1,135 @@ + +import logging +import urllib.request +from requests.exceptions import RequestException + +from pyats.connections import BaseConnection +from rest.connector.utils import get_username_password +from rest.connector.implementation import Implementation as RestImplementation + +from ciscoisesdk import IdentityServicesEngineAPI + +# create a logger for this module +log = logging.getLogger(__name__) + + +class Implementation(RestImplementation): + '''Rest Implementation for ISE + + Implementation of Rest connection to ISE servers + + YAML Example + ------------ + + devices: + ise: + os: ise + connections: + rest: + class: rest.connector.Rest + ip: 127.0.0.1 + port: "443" + protocol: https + credentials: + rest: + username: admin + password: admin + + Code Example + ------------ + + >>> from pyats.topology import loader + >>> testbed = loader.load('topology.yaml') + >>> device = testbed.devices['ise'] + >>> device.connect(alias='rest', via='rest') + >>> device.rest.connected + True + ''' + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + if 'proxies' not in kwargs: + self.proxies = urllib.request.getproxies() + + @BaseConnection.locked + def connect(self, + timeout=30, + verbose=False, + port="443", + protocol='https', + debug=False, + **kwargs): + '''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 + + ''' + if self.connected: + log.info(f'{self} already 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) + + username, password = get_username_password(self) + + breakpoint() + self.api = IdentityServicesEngineAPI( + username=username, password=password, + base_url=self.base_url, uses_api_gateway=True, + verify=False, debug=debug) + + self._is_connected = True + log.info("Connected successfully to '{d}'".format(d=self.device.name)) + + return self.api + + @BaseConnection.locked + def disconnect(self): + """ + Does not make sense to disconnect from a device. + """ + self._is_connected = False + return diff --git a/src/rest/connector/libs/nd/__init__.py b/src/rest/connector/libs/nd/__init__.py index 05cdc37..700da8b 100644 --- a/src/rest/connector/libs/nd/__init__.py +++ b/src/rest/connector/libs/nd/__init__.py @@ -1,7 +1,7 @@ # Enable abstraction using this directory name as the abstraction token try: from genie import abstract - abstract.declare_token(__name__) + abstract.declare_token(os='nd') except Exception as e: import warnings warnings.warn('Could not declare abstraction token: ' + str(e)) diff --git a/src/rest/connector/libs/nexusdashboard/__init__.py b/src/rest/connector/libs/nexusdashboard/__init__.py index 05cdc37..8d2331b 100644 --- a/src/rest/connector/libs/nexusdashboard/__init__.py +++ b/src/rest/connector/libs/nexusdashboard/__init__.py @@ -1,7 +1,7 @@ # Enable abstraction using this directory name as the abstraction token try: from genie import abstract - abstract.declare_token(__name__) + abstract.declare_token(os='nexusdashboard') except Exception as e: import warnings warnings.warn('Could not declare abstraction token: ' + str(e)) diff --git a/src/rest/connector/libs/nso/__init__.py b/src/rest/connector/libs/nso/__init__.py index 05cdc37..1011e39 100644 --- a/src/rest/connector/libs/nso/__init__.py +++ b/src/rest/connector/libs/nso/__init__.py @@ -1,7 +1,7 @@ # Enable abstraction using this directory name as the abstraction token try: from genie import abstract - abstract.declare_token(__name__) + abstract.declare_token(os='nso') except Exception as e: import warnings warnings.warn('Could not declare abstraction token: ' + str(e)) diff --git a/src/rest/connector/libs/nxos/__init__.py b/src/rest/connector/libs/nxos/__init__.py index 05cdc37..046fcc7 100644 --- a/src/rest/connector/libs/nxos/__init__.py +++ b/src/rest/connector/libs/nxos/__init__.py @@ -1,7 +1,7 @@ # Enable abstraction using this directory name as the abstraction token try: from genie import abstract - abstract.declare_token(__name__) + abstract.declare_token(os='nxos') except Exception as e: import warnings warnings.warn('Could not declare abstraction token: ' + str(e)) diff --git a/src/rest/connector/libs/nxos/aci/__init__.py b/src/rest/connector/libs/nxos/aci/__init__.py index 05cdc37..c5cb26e 100644 --- a/src/rest/connector/libs/nxos/aci/__init__.py +++ b/src/rest/connector/libs/nxos/aci/__init__.py @@ -1,7 +1,7 @@ # Enable abstraction using this directory name as the abstraction token try: from genie import abstract - abstract.declare_token(__name__) + abstract.declare_token(platform='aci') except Exception as e: import warnings warnings.warn('Could not declare abstraction token: ' + str(e)) diff --git a/src/rest/connector/libs/viptela/__init__.py b/src/rest/connector/libs/viptela/__init__.py index 05cdc37..76285be 100644 --- a/src/rest/connector/libs/viptela/__init__.py +++ b/src/rest/connector/libs/viptela/__init__.py @@ -1,7 +1,7 @@ # Enable abstraction using this directory name as the abstraction token try: from genie import abstract - abstract.declare_token(__name__) + abstract.declare_token(os='viptela') except Exception as e: import warnings warnings.warn('Could not declare abstraction token: ' + str(e)) diff --git a/src/rest/connector/libs/virl/__init__.py b/src/rest/connector/libs/virl/__init__.py index 05cdc37..4c621d4 100644 --- a/src/rest/connector/libs/virl/__init__.py +++ b/src/rest/connector/libs/virl/__init__.py @@ -1,7 +1,7 @@ # Enable abstraction using this directory name as the abstraction token try: from genie import abstract - abstract.declare_token(__name__) + abstract.declare_token(os='virl') except Exception as e: import warnings warnings.warn('Could not declare abstraction token: ' + str(e)) diff --git a/src/rest/connector/libs/vmware/__init__.py b/src/rest/connector/libs/vmware/__init__.py index 05cdc37..78d2d7a 100644 --- a/src/rest/connector/libs/vmware/__init__.py +++ b/src/rest/connector/libs/vmware/__init__.py @@ -1,7 +1,7 @@ # Enable abstraction using this directory name as the abstraction token try: from genie import abstract - abstract.declare_token(__name__) + abstract.declare_token(os='vmware') except Exception as e: import warnings warnings.warn('Could not declare abstraction token: ' + str(e)) diff --git a/src/rest/connector/libs/webex/__init__.py b/src/rest/connector/libs/webex/__init__.py index 05cdc37..38d2709 100644 --- a/src/rest/connector/libs/webex/__init__.py +++ b/src/rest/connector/libs/webex/__init__.py @@ -1,7 +1,7 @@ # Enable abstraction using this directory name as the abstraction token try: from genie import abstract - abstract.declare_token(__name__) + abstract.declare_token(os='webex') except Exception as e: import warnings warnings.warn('Could not declare abstraction token: ' + str(e)) diff --git a/src/rest/connector/libs/xpresso/__init__.py b/src/rest/connector/libs/xpresso/__init__.py index 05cdc37..19705d2 100644 --- a/src/rest/connector/libs/xpresso/__init__.py +++ b/src/rest/connector/libs/xpresso/__init__.py @@ -1,7 +1,7 @@ # Enable abstraction using this directory name as the abstraction token try: from genie import abstract - abstract.declare_token(__name__) + abstract.declare_token(os='xpresso') except Exception as e: import warnings warnings.warn('Could not declare abstraction token: ' + str(e))