Ejemplo n.º 1
0
    def connect(self, timeout=90):
        """
        Connect to the device via ACI SDK
        Arguments
        ---------
            timeout (int): Timeout value
        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:
                apic1:
                    connections:
                        cobra:
                            class: rest.connector.Acisdk
                            ip : "2.3.4.5"
                    credentials:
                        cobra:
                            username: admin
                            password: cisco123
        Code Example
        ------------
            >>> from pyats.topology import loader
            >>> testbed = loader.load('/users/xxx/xxx/testbed.yaml')
            >>> device = testbed.devices['apic1']
            >>> device.connect(alias='cobra', via='cobra')
        """

        if self.connected:
            return

        username, password = get_username_password(self)

        login_session = getattr(import_module('cobra.mit.session'),
                                'LoginSession')
        session = login_session(self.url, username, password, timeout=timeout)

        mo_directory = getattr(import_module('cobra.mit.access'),
                               'MoDirectory')
        self.mo_dir = mo_directory(session)

        log.info("Connecting to '{d}' with alias "
                 "'{a}'".format(d=self.device.name, a=self.alias))

        self.mo_dir.login()

        self._is_connected = True
        log.info("Connected successfully to '{d}'".format(d=self.device.name))
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    def connect(self, timeout=30):
        '''connect to the device via REST

        Arguments
        ---------

            timeout (int): Timeout value

        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

        # Building out Auth request.
        # 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', 443)
        self.verify = self.connection_info.get('verify', True)

        username, password = get_username_password(self)

        self.base_url = 'https://{host}:{port}'.format(host=host, port=port)

        auth_url = '{url}/dna/system/api/v1/auth/token'.format(
            url=self.base_url)
        resp = requests.post(auth_url,
                             headers=STD_HEADER,
                             auth=HTTPBasicAuth(username, password),
                             verify=self.verify)

        self.token = resp.json()[
            'Token']  # Retrieve the Token from the returned JSONhahhah

        self._is_connected = True
        log.info("Connected successfully to '{d}'".format(d=self.device.name))
Ejemplo n.º 4
0
    def connect(self, timeout=30, retries=3, retry_wait=10):
        """connect to the device via REST
        Arguments
        ---------
            timeout (int): Timeout value
            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:
                nd1:
                    os: nd
                    connections:
                        rest:
                            class: rest.connector.Rest
                            ip : "2.3.4.5"
                    credentials:
                        rest:
                            username: admin
                            password: cisco123

        Code Example
        ------------
            >>> from pyats.topology import loader
            >>> testbed = loader.load('/users/xxx/xxx/testbed.yaml')
            >>> device = testbed.devices['nd1']
            >>> device.connect(alias='rest', via='rest')
        """

        if self.connected:
            return

        if 'host' in self.connection_info:
            ip = self.connection_info['host']
        else:
            ip = self.connection_info['ip'].exploded
        if 'port' in self.connection_info:
            port = self.connection_info['port']
            self.url = 'https://{ip}:{port}/'.format(ip=ip, port=port)
        else:
            self.url = 'https://{ip}/'.format(ip=ip)
        login_url = '{f}login'.format(f=self.url)

        username, password = get_username_password(self)

        payload = {
            "userName": username,
            "userPasswd": password,
            "domain": "DefaultAuth"
        }

        headers = {'Content-Type': 'application/json'}

        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
                response = self.session.post(login_url,
                                             data=_data,
                                             timeout=timeout,
                                             verify=False,
                                             headers=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))
                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))

        self._is_connected = True
        log.info("Connected successfully to '{d}'".format(d=self.device.name))
Ejemplo n.º 5
0
    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
Ejemplo n.º 6
0
    def connect(self, timeout=30):
        '''connect to the device via REST

        Arguments
        ---------

            timeout (int): Timeout value

        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"
                            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

        ip = self.connection_info['ip'].exploded
        port = self.connection_info.get('port', 19399)
        self.url = 'http://{ip}:{port}'.format(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
        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))
Ejemplo n.º 7
0
    def connect(self,
                timeout=30,
                default_content_type='json',
                verbose=False):
        '''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
        ip = self.connection_info.ip.exploded
        port = self.connection_info.get('port', '443')
        self.base_url = 'https://{ip}:{port}'.format(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
Ejemplo n.º 8
0
    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
Ejemplo n.º 9
0
    def connect(self, timeout=30, default_content_type='json', verbose=False):
        '''connect to the device via REST

        Arguments
        ---------

            timeout (int): Timeout value
            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

        ip = self.connection_info.ip.exploded
        port = self.connection_info.get('port', '8080')
        self.base_url = 'http://{ip}:{port}'.format(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
Ejemplo n.º 10
0
    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
Ejemplo n.º 11
0
    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'
        }
Ejemplo n.º 12
0
    def connect(self, timeout=30):
        '''connect to the device via REST

        Arguments
        ---------

            timeout (int): Timeout value

        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:
                apic1:
                    connections:
                        rest:
                            class: rest.connector.Rest
                            ip : "2.3.4.5"
                            credentials:
                                rest:
                                    username: admin
                                    password: cisco123

        Code Example
        ------------

            >>> from pyats.topology import loader
            >>> testbed = loader.load('/users/xxx/xxx/testbed.yaml')
            >>> device = testbed.devices['apic1']
            >>> device.connect(alias='rest', via='rest')
        '''

        if self.connected:
            return

        if 'host' in self.connection_info:
            ip = self.connection_info['host']
        else:
            ip = self.connection_info['ip'].exploded
        if 'port' in self.connection_info:
            port = self.connection_info['port']
            self.url = 'https://{ip}:{port}/'.format(ip=ip, port=port)
        else:
            self.url = 'https://{ip}/'.format(ip=ip)
        login_url = '{f}api/aaaLogin.json'.format(f=self.url)

        username, password = get_username_password(self)

        payload = {
            "aaaUser": {
                "attributes": {
                    "name": username,
                    "pwd": password,
                }
            }
        }
        headers = {'Content-Type': 'text/plain'}

        log.info("Connecting to '{d}' with alias "
                 "'{a}'".format(d=self.device.name, a=self.alias))

        self.session = requests.Session()
        _data = json.dumps(payload)

        # Connect to the device via requests
        response = self.session.post(login_url,
                                     data=_data,
                                     timeout=timeout,
                                     verify=False,
                                     headers=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))
Ejemplo n.º 13
0
    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
Ejemplo n.º 14
0
    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))
Ejemplo n.º 15
0
    def connect(self, timeout=30):
        '''connect to the device via REST

        Arguments
        ---------

            timeout (int): Timeout value

        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"
                        netconf:
                            class: rest.connector.Rest
                            ip : "2.3.4.5"
                            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

        ip = self.connection_info['ip'].exploded

        if 'port' in self.connection_info:
            port = self.connection_info['port']
            self.url = 'http://{ip}:{port}'.format(ip=ip, port=port)
        else:
            self.url = 'http://{ip}'.format(ip=ip)

        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)

        # Connect to the device via requests
        response = self.session.post(login_url, data=_data, timeout=timeout)
        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))
Ejemplo n.º 16
0
    def connect(self, timeout=30):
        '''connect to the device via REST

        Arguments
        ---------

            timeout (int): Timeout value

        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

        ip = self.connection_info['ip'].exploded
        port = self.connection_info.get('port', 8443)
        self.verify = self.connection_info.get('verify', False)

        username, password = get_username_password(self)

        self.base_url = 'https://{ip}:{port}'.format(ip=ip, port=port)

        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'
        }
Ejemplo n.º 17
0
    def connect(self, auth_provider='tmos', verify=False, *args, **kwargs):

        if self.connected:
            return

        self.username, self.password = get_username_password(self)
        self.ip = self.connection_info["ip"].exploded
        self.port = self.connection_info.get("port", "443")
        self.base_url = "https://{ip}:{port}".format(ip=self.ip, port=self.port)
        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
Ejemplo n.º 18
0
    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))