Пример #1
0
    def test_load_from_environ(self):
        # No environ set
        import os
        with self.assertRaises(ConfigLoadError):
            load_from_environ()

        os.environ['SMC_ADDRESS'] = 'http://1.1.1.1'
        with self.assertRaises(ConfigLoadError):
            load_from_environ()

        os.environ['SMC_API_KEY'] = 'abc123'
        data = load_from_environ()
        self.assertEqual(data['api_key'], 'abc123')
        self.assertEqual(data['url'], 'http://1.1.1.1:8082')

        # HTTPS
        os.environ['SMC_ADDRESS'] = 'https://2.1.1.1'
        data = load_from_environ()
        self.assertEqual(data['url'], 'https://2.1.1.1:8082')
        self.assertFalse(data['verify'])  # No cert provided

        # HTTPS with client cert
        os.environ['SMC_ADDRESS'] = 'https://2.1.1.1'
        os.environ['SMC_CLIENT_CERT'] = 'mycert'
        data = load_from_environ()
        self.assertEqual(data['verify'], 'mycert')  # No cert provided

        # Unique port
        os.environ['SMC_ADDRESS'] = 'https://2.1.1.1:8888'
        data = load_from_environ()
        self.assertEqual(data['url'], 'https://2.1.1.1:8888')

        # Timeout and API Version
        os.environ['SMC_TIMEOUT'] = '30'
        os.environ['SMC_API_VERSION'] = '6.2'
        os.environ['SMC_DOMAIN'] = 'mydomain'
        data = load_from_environ()
        self.assertEqual(data['timeout'], 30)
        self.assertEqual(data['domain'], 'mydomain')

        for var in [
                'SMC_TIMEOUT', 'SMC_API_VERSION', 'SMC_DOMAIN', 'SMC_ADDRESS',
                'SMC_API_KEY'
        ]:
            del os.environ[var]
Пример #2
0
    def login(self,
              url=None,
              api_key=None,
              login=None,
              pwd=None,
              api_version=None,
              timeout=None,
              verify=True,
              alt_filepath=None,
              domain=None,
              **kwargs):
        """
        Login to SMC API and retrieve a valid session.
        Session will be re-used when multiple queries are required.

        An example login and logout session::

            from smc import session
            session.login(url='http://1.1.1.1:8082', api_key='SomeSMCG3ener@t3dPwd')
            .....do stuff.....
            session.logout()

        :param str url: ip of SMC management server
        :param str api_key: API key created for api client in SMC
        :param str login: Administrator user in SMC that has privilege to SMC API.
        :param str pwd: Password for user login.
        :param api_version (optional): specify api version
        :param int timeout: (optional): specify a timeout for initial connect; (default 10)
        :param str|boolean verify: verify SSL connections using cert (default: verify=True)
            You can pass verify the path to a CA_BUNDLE file or directory with certificates
            of trusted CAs
        :param str alt_filepath: If using .smcrc, alternate file+path
        :param str domain: domain to log in to. If domains are not configured, this
            field will be ignored and api client logged in to 'Shared Domain'.
        :raises ConfigLoadError: loading cfg from ~.smcrc fails

        For SSL connections, you can disable validation of the SMC SSL certificate by setting
        verify=False, however this is not a recommended practice.

        If you want to use the SSL certificate generated and used by the SMC API server
        for validation, set verify='path_to_my_dot_pem'. It is also recommended that your
        certificate has subjectAltName defined per RFC 2818
        
        If SSL warnings are thrown in debug output, see:
        https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings

        Logout should be called to remove the session immediately from the
        SMC server.
        
        .. note:: As of SMC 6.4 it is possible to give a standard Administrative user access
            to the SMC API. It is still possible to use an API Client by providing the api_key
            in the login call.
        """
        if not url or (not api_key and not (login and pwd)):
            # First try load from file
            try:
                cfg = load_from_file(alt_filepath) if alt_filepath\
                    is not None else load_from_file()
                logger.debug('Read config data from file: %s', cfg)
            except ConfigLoadError:
                # Last ditch effort, try to load from environment
                cfg = load_from_environ()
                logger.debug('Read config data from environ: %s', cfg)

            url = cfg.get('url')
            api_key = cfg.get('api_key')
            api_version = cfg.get('api_version')
            verify = cfg.get('verify')
            timeout = cfg.get('timeout')
            domain = cfg.get('domain')
            kwargs = cfg.get('kwargs')

        if timeout:
            self._timeout = timeout

        self._api_version = get_api_version(url, api_version, timeout, verify)

        base = get_api_base(url, self.api_version, verify=verify)

        self._resource.add(get_entry_points(base, timeout, verify))

        s = requests.session()  # empty session

        json = {'domain': domain}

        if api_key:
            json.update(authenticationkey=api_key)

        if kwargs:
            json.update(**kwargs)
            self._extra_args.update(**kwargs)

        params = dict(login=login, pwd=pwd) if login and pwd else None

        req = dict(
            url=self.entry_points.get('login') if api_key else \
                '{}/{}/lms_login'.format(url, self._api_version),
            json=json,
            params=params,
            headers={'content-type': 'application/json'},
            verify=verify)

        r = s.post(**req)
        logger.info('Using SMC API version: %s', self.api_version)

        if r.status_code == 200:
            self._session = s  # session creation was successful
            self._session.verify = verify  # make verify setting persistent
            self._url = url
            self.credential.set_credentials(api_key, login, pwd)

            if domain:
                self._domain = domain

            self._sessions[self.domain] = self.session
            if self.connection is None:
                self._connection = smc.api.web.SMCAPIConnection(self)

            logger.debug(
                'Login succeeded and session retrieved: %s, domain: %s',
                self.session_id, self.domain)

            # Reload entry points
            self.entry_points.clear()
            self._resource.add(reload_entry_points(self))

        else:
            raise SMCConnectionError(
                'Login failed, HTTP status code: %s and reason: %s' %
                (r.status_code, r.reason))

        if not self._MODS_LOADED:
            logger.debug('Registering class mappings.')
            # Load the modules to register needed classes
            for pkg in ('smc.policy', 'smc.elements', 'smc.routing', 'smc.vpn',
                        'smc.administration', 'smc.core',
                        'smc.administration.user_auth'):
                import_submodules(pkg, recursive=False)

            self._MODS_LOADED = True
Пример #3
0
    def login(self, url=None, api_key=None, login=None, pwd=None, api_version=None,
              timeout=None, verify=True, alt_filepath=None, domain=None, **kwargs):
        """
        Login to SMC API and retrieve a valid session.
        Session will be re-used when multiple queries are required.

        An example login and logout session::

            from smc import session
            session.login(url='http://1.1.1.1:8082', api_key='SomeSMCG3ener@t3dPwd')
            .....do stuff.....
            session.logout()

        :param str url: ip of SMC management server
        :param str api_key: API key created for api client in SMC
        :param str login: Administrator user in SMC that has privilege to SMC API.
        :param str pwd: Password for user login.
        :param api_version (optional): specify api version
        :param int timeout: (optional): specify a timeout for initial connect; (default 10)
        :param str|boolean verify: verify SSL connections using cert (default: verify=True)
            You can pass verify the path to a CA_BUNDLE file or directory with certificates
            of trusted CAs
        :param str alt_filepath: If using .smcrc, alternate file+path
        :param str domain: domain to log in to. If domains are not configured, this
            field will be ignored and api client logged in to 'Shared Domain'.
        :param bool retry_on_busy: pass as kwarg with boolean if you want to add retries
            if the SMC returns HTTP 503 error during operation. You can also optionally customize
            this behavior and call :meth:`.set_retry_on_busy`
        :raises ConfigLoadError: loading cfg from ~.smcrc fails

        For SSL connections, you can disable validation of the SMC SSL certificate by setting
        verify=False, however this is not a recommended practice.

        If you want to use the SSL certificate generated and used by the SMC API server
        for validation, set verify='path_to_my_dot_pem'. It is also recommended that your
        certificate has subjectAltName defined per RFC 2818
        
        If SSL warnings are thrown in debug output, see:
        https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings

        Logout should be called to remove the session immediately from the
        SMC server.
        
        .. note:: As of SMC 6.4 it is possible to give a standard Administrative user access
            to the SMC API. It is still possible to use an API Client by providing the api_key
            in the login call.
        """
        if not url or (not api_key and not (login and pwd)):
            # First try load from file
            try:
                cfg = load_from_file(alt_filepath) if alt_filepath\
                    is not None else load_from_file()
                logger.debug('Read config data from file: %s', cfg)
            except ConfigLoadError:
                # Last ditch effort, try to load from environment
                cfg = load_from_environ()
                logger.debug('Read config data from environ: %s', cfg)
                
            url = cfg.get('url')
            api_key = cfg.get('api_key')
            api_version = cfg.get('api_version')
            verify = cfg.get('verify')
            timeout = cfg.get('timeout')
            domain = cfg.get('domain')
            kwargs = cfg.get('kwargs', {})
        
        self._timeout = timeout or self._timeout
        self._domain = domain or self._domain
        self._url = url
        
        # Determine and set the API version we will use.
        self._api_version = get_api_version(url, api_version, timeout, verify)
        
        # Set the auth provider which will determine what type of login this is
        self.credential = Credential(api_key, login, pwd)
        
        # Retries configured generically
        retry_on_busy = kwargs.pop('retry_on_busy', False)
        
        request = self._build_auth_request(verify=verify, **kwargs)
        
        # This will raise if session login fails...
        self._session = self._get_session(request)
        self.session.verify = verify
        
        logger.debug('Login succeeded and session retrieved: %s, domain: %s',
            self.session_id, self.domain)
        
        if retry_on_busy:
            self.set_retry_on_busy()
        
        self._sessions[self.domain] = self.session
        if self.connection is None:
            self._connection = smc.api.web.SMCAPIConnection(self)
             
        # Load entry points
        load_entry_points(self)

        if not self._MODS_LOADED:
            logger.debug('Registering class mappings.')
            # Load the modules to register needed classes
            for pkg in ('smc.policy', 'smc.elements', 'smc.routing',
                        'smc.vpn', 'smc.administration', 'smc.core',
                        'smc.administration.user_auth'):
                import_submodules(pkg, recursive=False)

            self._MODS_LOADED = True