Accept keystone session in client
This already has auth configured, and allows us to re-use the session even with other clients. Currently this is not used by the CLI; however this is useful when instantiating the mistral client from a python script or from another service. Change-Id: I4fccb4117db11c966ac3f17ec6d2a53c657378e8
This commit is contained in:
		@@ -58,6 +58,7 @@ def log_request(func):
 | 
				
			|||||||
class HTTPClient(object):
 | 
					class HTTPClient(object):
 | 
				
			||||||
    def __init__(self, base_url, **kwargs):
 | 
					    def __init__(self, base_url, **kwargs):
 | 
				
			||||||
        self.base_url = base_url
 | 
					        self.base_url = base_url
 | 
				
			||||||
 | 
					        self.session = kwargs.pop('session', None)
 | 
				
			||||||
        self.auth_token = kwargs.get(AUTH_TOKEN)
 | 
					        self.auth_token = kwargs.get(AUTH_TOKEN)
 | 
				
			||||||
        self.project_id = kwargs.get(PROJECT_ID)
 | 
					        self.project_id = kwargs.get(PROJECT_ID)
 | 
				
			||||||
        self.user_id = kwargs.get(USER_ID)
 | 
					        self.user_id = kwargs.get(USER_ID)
 | 
				
			||||||
@@ -77,6 +78,11 @@ class HTTPClient(object):
 | 
				
			|||||||
            TARGET_PROJECT_DOMAIN_NAME
 | 
					            TARGET_PROJECT_DOMAIN_NAME
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if self.session:
 | 
				
			||||||
 | 
					            self.crud_provider = self.session
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            self.crud_provider = requests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if self.base_url.startswith('https'):
 | 
					        if self.base_url.startswith('https'):
 | 
				
			||||||
            if self.cacert and not os.path.exists(self.cacert):
 | 
					            if self.cacert and not os.path.exists(self.cacert):
 | 
				
			||||||
                raise ValueError('Unable to locate cacert file '
 | 
					                raise ValueError('Unable to locate cacert file '
 | 
				
			||||||
@@ -86,42 +92,47 @@ class HTTPClient(object):
 | 
				
			|||||||
                LOG.warning('Client is set to not verify even though '
 | 
					                LOG.warning('Client is set to not verify even though '
 | 
				
			||||||
                            'cacert is provided.')
 | 
					                            'cacert is provided.')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if self.insecure:
 | 
					            # These are already set by the session, so it's not needed
 | 
				
			||||||
                self.ssl_options['verify'] = False
 | 
					            if not self.session:
 | 
				
			||||||
            else:
 | 
					                if self.insecure:
 | 
				
			||||||
                if self.cacert:
 | 
					                    self.ssl_options['verify'] = False
 | 
				
			||||||
                    self.ssl_options['verify'] = self.cacert
 | 
					 | 
				
			||||||
                else:
 | 
					                else:
 | 
				
			||||||
                    self.ssl_options['verify'] = True
 | 
					                    if self.cacert:
 | 
				
			||||||
 | 
					                        self.ssl_options['verify'] = self.cacert
 | 
				
			||||||
 | 
					                    else:
 | 
				
			||||||
 | 
					                        self.ssl_options['verify'] = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            self.ssl_options['cert'] = (
 | 
					                self.ssl_options['cert'] = (
 | 
				
			||||||
                kwargs.get(CERT_FILE),
 | 
					                    kwargs.get(CERT_FILE),
 | 
				
			||||||
                kwargs.get(CERT_KEY)
 | 
					                    kwargs.get(CERT_KEY)
 | 
				
			||||||
            )
 | 
					                )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @log_request
 | 
					    @log_request
 | 
				
			||||||
    def get(self, url, headers=None):
 | 
					    def get(self, url, headers=None):
 | 
				
			||||||
        options = self._get_request_options('get', headers)
 | 
					        options = self._get_request_options('get', headers)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return requests.get(self.base_url + url, **options)
 | 
					        return self.crud_provider.get(self.base_url + url, **options)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @log_request
 | 
					    @log_request
 | 
				
			||||||
    def post(self, url, body, headers=None):
 | 
					    def post(self, url, body, headers=None):
 | 
				
			||||||
        options = self._get_request_options('post', headers)
 | 
					        options = self._get_request_options('post', headers)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return requests.post(self.base_url + url, body, **options)
 | 
					        return self.crud_provider.post(self.base_url + url,
 | 
				
			||||||
 | 
					                                       data=body, **options)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @log_request
 | 
					    @log_request
 | 
				
			||||||
    def put(self, url, body, headers=None):
 | 
					    def put(self, url, body, headers=None):
 | 
				
			||||||
        options = self._get_request_options('put', headers)
 | 
					        options = self._get_request_options('put', headers)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return requests.put(self.base_url + url, body, **options)
 | 
					        return self.crud_provider.put(self.base_url + url,
 | 
				
			||||||
 | 
					                                      data=body, **options)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @log_request
 | 
					    @log_request
 | 
				
			||||||
    def delete(self, url, headers=None):
 | 
					    def delete(self, url, headers=None):
 | 
				
			||||||
        options = self._get_request_options('delete', headers)
 | 
					        options = self._get_request_options('delete', headers)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return requests.delete(self.base_url + url, **options)
 | 
					        return self.crud_provider.delete(self.base_url + url,
 | 
				
			||||||
 | 
					                                         **options)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _get_request_options(self, method, headers):
 | 
					    def _get_request_options(self, method, headers):
 | 
				
			||||||
        headers = self._update_headers(headers)
 | 
					        headers = self._update_headers(headers)
 | 
				
			||||||
@@ -139,14 +150,15 @@ class HTTPClient(object):
 | 
				
			|||||||
        if not headers:
 | 
					        if not headers:
 | 
				
			||||||
            headers = {}
 | 
					            headers = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if self.auth_token:
 | 
					        if not self.session:
 | 
				
			||||||
            headers['x-auth-token'] = self.auth_token
 | 
					            if self.auth_token:
 | 
				
			||||||
 | 
					                headers['x-auth-token'] = self.auth_token
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if self.project_id:
 | 
					            if self.project_id:
 | 
				
			||||||
            headers['X-Project-Id'] = self.project_id
 | 
					                headers['X-Project-Id'] = self.project_id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if self.user_id:
 | 
					            if self.user_id:
 | 
				
			||||||
            headers['X-User-Id'] = self.user_id
 | 
					                headers['X-User-Id'] = self.user_id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if self.target_auth_token:
 | 
					        if self.target_auth_token:
 | 
				
			||||||
            headers['X-Target-Auth-Token'] = self.target_auth_token
 | 
					            headers['X-Target-Auth-Token'] = self.target_auth_token
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,6 +39,9 @@ _DEFAULT_MISTRAL_URL = "http://localhost:8989/v2"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class Client(object):
 | 
					class Client(object):
 | 
				
			||||||
    def __init__(self, auth_type='keystone', **kwargs):
 | 
					    def __init__(self, auth_type='keystone', **kwargs):
 | 
				
			||||||
 | 
					        # We get the session at this point, as some instances of session
 | 
				
			||||||
 | 
					        # objects might have mutexes that can't be deep-copied.
 | 
				
			||||||
 | 
					        session = kwargs.pop('session', None)
 | 
				
			||||||
        req = copy.deepcopy(kwargs)
 | 
					        req = copy.deepcopy(kwargs)
 | 
				
			||||||
        mistral_url = req.get('mistral_url')
 | 
					        mistral_url = req.get('mistral_url')
 | 
				
			||||||
        profile = req.get('profile')
 | 
					        profile = req.get('profile')
 | 
				
			||||||
@@ -47,7 +50,7 @@ class Client(object):
 | 
				
			|||||||
            raise RuntimeError('Mistral url should be a string.')
 | 
					            raise RuntimeError('Mistral url should be a string.')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        auth_handler = auth.get_auth_handler(auth_type)
 | 
					        auth_handler = auth.get_auth_handler(auth_type)
 | 
				
			||||||
        auth_response = auth_handler.authenticate(req) or {}
 | 
					        auth_response = auth_handler.authenticate(req, session=session) or {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        req.update(auth_response)
 | 
					        req.update(auth_response)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -59,7 +62,8 @@ class Client(object):
 | 
				
			|||||||
        if profile:
 | 
					        if profile:
 | 
				
			||||||
            osprofiler_profiler.init(profile)
 | 
					            osprofiler_profiler.init(profile)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        http_client = httpclient.HTTPClient(mistral_url, **req)
 | 
					        http_client = httpclient.HTTPClient(mistral_url, session=session,
 | 
				
			||||||
 | 
					                                            **req)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Create all resource managers.
 | 
					        # Create all resource managers.
 | 
				
			||||||
        self.workbooks = workbooks.WorkbookManager(http_client)
 | 
					        self.workbooks = workbooks.WorkbookManager(http_client)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,7 +24,7 @@ LOG = logging.getLogger(__name__)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class KeycloakAuthHandler(auth.AuthHandler):
 | 
					class KeycloakAuthHandler(auth.AuthHandler):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def authenticate(self, req):
 | 
					    def authenticate(self, req, session=None):
 | 
				
			||||||
        """Performs authentication using Keycloak OpenID Protocol.
 | 
					        """Performs authentication using Keycloak OpenID Protocol.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :param req: Request dict containing list of parameters required
 | 
					        :param req: Request dict containing list of parameters required
 | 
				
			||||||
@@ -46,6 +46,8 @@ class KeycloakAuthHandler(auth.AuthHandler):
 | 
				
			|||||||
            cacert: SSL certificate file (Optional).
 | 
					            cacert: SSL certificate file (Optional).
 | 
				
			||||||
            insecure: If True, SSL certificate is not verified (Optional).
 | 
					            insecure: If True, SSL certificate is not verified (Optional).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param session: Keystone session object. Not used by this plugin.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        if not isinstance(req, dict):
 | 
					        if not isinstance(req, dict):
 | 
				
			||||||
            raise TypeError('The input "req" is not typeof dict.')
 | 
					            raise TypeError('The input "req" is not typeof dict.')
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,7 +21,7 @@ import mistralclient.api.httpclient as api
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class KeystoneAuthHandler(auth.AuthHandler):
 | 
					class KeystoneAuthHandler(auth.AuthHandler):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def authenticate(self, req):
 | 
					    def authenticate(self, req, session=None):
 | 
				
			||||||
        """Performs authentication via Keystone.
 | 
					        """Performs authentication via Keystone.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :param req: Request dict containing list of parameters required
 | 
					        :param req: Request dict containing list of parameters required
 | 
				
			||||||
@@ -31,6 +31,7 @@ class KeystoneAuthHandler(auth.AuthHandler):
 | 
				
			|||||||
        if not isinstance(req, dict):
 | 
					        if not isinstance(req, dict):
 | 
				
			||||||
            raise TypeError('The input "req" is not typeof dict.')
 | 
					            raise TypeError('The input "req" is not typeof dict.')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        session = session
 | 
				
			||||||
        mistral_url = req.get('mistral_url')
 | 
					        mistral_url = req.get('mistral_url')
 | 
				
			||||||
        endpoint_type = req.get('endpoint_type', 'publicURL')
 | 
					        endpoint_type = req.get('endpoint_type', 'publicURL')
 | 
				
			||||||
        service_type = req.get('service_type', 'workflow2')
 | 
					        service_type = req.get('service_type', 'workflow2')
 | 
				
			||||||
@@ -76,7 +77,9 @@ class KeystoneAuthHandler(auth.AuthHandler):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        auth_response = {}
 | 
					        auth_response = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if auth_url:
 | 
					        if session:
 | 
				
			||||||
 | 
					            keystone = client.Client(session=session)
 | 
				
			||||||
 | 
					        elif auth_url:
 | 
				
			||||||
            keystone = client.Client(
 | 
					            keystone = client.Client(
 | 
				
			||||||
                username=username,
 | 
					                username=username,
 | 
				
			||||||
                user_id=user_id,
 | 
					                user_id=user_id,
 | 
				
			||||||
@@ -90,15 +93,14 @@ class KeystoneAuthHandler(auth.AuthHandler):
 | 
				
			|||||||
                user_domain_name=user_domain_name,
 | 
					                user_domain_name=user_domain_name,
 | 
				
			||||||
                project_domain_name=project_domain_name
 | 
					                project_domain_name=project_domain_name
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					 | 
				
			||||||
            keystone.authenticate()
 | 
					            keystone.authenticate()
 | 
				
			||||||
 | 
					 | 
				
			||||||
            auth_response.update({
 | 
					            auth_response.update({
 | 
				
			||||||
                api.AUTH_TOKEN: keystone.auth_token,
 | 
					                api.AUTH_TOKEN: keystone.auth_token,
 | 
				
			||||||
                api.PROJECT_ID: keystone.project_id,
 | 
					                api.PROJECT_ID: keystone.project_id,
 | 
				
			||||||
                api.USER_ID: keystone.user_id,
 | 
					                api.USER_ID: keystone.user_id,
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if session or auth_url:
 | 
				
			||||||
            if not mistral_url:
 | 
					            if not mistral_url:
 | 
				
			||||||
                try:
 | 
					                try:
 | 
				
			||||||
                    mistral_url = keystone.service_catalog.url_for(
 | 
					                    mistral_url = keystone.service_catalog.url_for(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -196,7 +196,7 @@ class HTTPClientTest(base.BaseTestCase):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        requests.post.assert_called_with(
 | 
					        requests.post.assert_called_with(
 | 
				
			||||||
            EXPECTED_URL,
 | 
					            EXPECTED_URL,
 | 
				
			||||||
            EXPECTED_BODY,
 | 
					            data=EXPECTED_BODY,
 | 
				
			||||||
            **expected_options
 | 
					            **expected_options
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -216,7 +216,7 @@ class HTTPClientTest(base.BaseTestCase):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        requests.put.assert_called_with(
 | 
					        requests.put.assert_called_with(
 | 
				
			||||||
            EXPECTED_URL,
 | 
					            EXPECTED_URL,
 | 
				
			||||||
            EXPECTED_BODY,
 | 
					            data=EXPECTED_BODY,
 | 
				
			||||||
            **expected_options
 | 
					            **expected_options
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -281,7 +281,7 @@ class HTTPClientTest(base.BaseTestCase):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        requests.post.assert_called_with(
 | 
					        requests.post.assert_called_with(
 | 
				
			||||||
            EXPECTED_URL,
 | 
					            EXPECTED_URL,
 | 
				
			||||||
            EXPECTED_BODY,
 | 
					            data=EXPECTED_BODY,
 | 
				
			||||||
            **EXPECTED_REQ_OPTIONS
 | 
					            **EXPECTED_REQ_OPTIONS
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -305,7 +305,7 @@ class HTTPClientTest(base.BaseTestCase):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        requests.put.assert_called_with(
 | 
					        requests.put.assert_called_with(
 | 
				
			||||||
            EXPECTED_URL,
 | 
					            EXPECTED_URL,
 | 
				
			||||||
            EXPECTED_BODY,
 | 
					            data=EXPECTED_BODY,
 | 
				
			||||||
            **EXPECTED_REQ_OPTIONS
 | 
					            **EXPECTED_REQ_OPTIONS
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user