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:
parent
ca313b0de4
commit
83b3d0d39c
@ -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
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user