Merge "Use keystoneauth plugins and session instead of keystoneclient"

This commit is contained in:
Jenkins 2017-08-10 14:59:31 +00:00 committed by Gerrit Code Review
commit 19c89ca49f
12 changed files with 253 additions and 166 deletions

@ -31,6 +31,8 @@ source openrc alt_demo alt_demo
export OS_ALT_USERNAME=${OS_USERNAME}
export OS_ALT_TENANT_NAME=${OS_TENANT_NAME}
export OS_ALT_USER_DOMAIN_NAME=${OS_USER_DOMAIN_NAME}
export OS_ALT_PROJECT_DOMAIN__NAME=${OS_PROJECT_DOMAIN_NAME}
export OS_ALT_PASSWORD=${OS_PASSWORD}
# Get admin credentials.
@ -46,10 +48,14 @@ uri = $OS_AUTH_URL
user = $OS_USERNAME
tenant = $OS_TENANT_NAME
pass = $OS_PASSWORD
user_domain = $OS_USER_DOMAIN_NAME
project_domain = $OS_PROJECT_DOMAIN_NAME
[demo]
user = $OS_ALT_USERNAME
tenant = $OS_ALT_TENANT_NAME
pass = $OS_ALT_PASSWORD
user_domain = $OS_ALT_USER_DOMAIN_NAME
project_domain = $OS_ALT_PROJECT_DOMAIN_NAME
EOF
cd $MISTRALCLIENT_DIR

@ -15,6 +15,8 @@
import copy
import json
from keystoneauth1 import exceptions
class Resource(object):
resource_name = 'Something'
@ -89,7 +91,10 @@ class ResourceManager(object):
if dump_json:
data = json.dumps(data)
resp = self.http_client.post(url, data)
try:
resp = self.http_client.post(url, data)
except exceptions.HttpError as ex:
self._raise_api_exception(ex.response)
if resp.status_code != 201:
self._raise_api_exception(resp)
@ -100,7 +105,10 @@ class ResourceManager(object):
if dump_json:
data = json.dumps(data)
resp = self.http_client.put(url, data)
try:
resp = self.http_client.put(url, data)
except exceptions.HttpError as ex:
self._raise_api_exception(ex.response)
if resp.status_code != 200:
self._raise_api_exception(resp)
@ -108,7 +116,10 @@ class ResourceManager(object):
return self.resource_class(self, extract_json(resp, response_key))
def _list(self, url, response_key=None):
resp = self.http_client.get(url)
try:
resp = self.http_client.get(url)
except exceptions.HttpError as ex:
self._raise_api_exception(ex.response)
if resp.status_code != 200:
self._raise_api_exception(resp)
@ -117,7 +128,10 @@ class ResourceManager(object):
for resource_data in extract_json(resp, response_key)]
def _get(self, url, response_key=None):
resp = self.http_client.get(url)
try:
resp = self.http_client.get(url)
except exceptions.HttpError as ex:
self._raise_api_exception(ex.response)
if resp.status_code == 200:
return self.resource_class(self, extract_json(resp, response_key))
@ -125,7 +139,10 @@ class ResourceManager(object):
self._raise_api_exception(resp)
def _delete(self, url):
resp = self.http_client.delete(url)
try:
resp = self.http_client.delete(url)
except exceptions.HttpError as ex:
self._raise_api_exception(ex.response)
if resp.status_code != 204:
self._raise_api_exception(resp)

@ -15,15 +15,16 @@
import base64
import copy
import logging
import os
from oslo_utils import importutils
import requests
import logging
import requests
AUTH_TOKEN = 'auth_token'
SESSION = 'session'
CACERT = 'cacert'
CERT_FILE = 'cert'
CERT_KEY = 'key'
@ -33,6 +34,7 @@ USER_ID = 'user_id'
REGION_NAME = 'region_name'
TARGET_AUTH_TOKEN = 'target_auth_token'
TARGET_SESSION = 'target_session'
TARGET_AUTH_URI = 'target_auth_url'
TARGET_PROJECT_ID = 'target_project_id'
TARGET_USER_ID = 'target_user_id'
@ -59,7 +61,9 @@ def log_request(func):
class HTTPClient(object):
def __init__(self, base_url, **kwargs):
self.base_url = base_url
self.session = kwargs.pop('session', None)
self.session = kwargs.get('session')
if not self.session:
self.session = requests.Session()
self.auth_token = kwargs.get(AUTH_TOKEN)
self.project_id = kwargs.get(PROJECT_ID)
self.user_id = kwargs.get(USER_ID)
@ -68,6 +72,7 @@ class HTTPClient(object):
self.region_name = kwargs.get(REGION_NAME)
self.ssl_options = {}
self.target_session = kwargs.get(TARGET_SESSION)
self.target_auth_token = kwargs.get(TARGET_AUTH_TOKEN)
self.target_auth_uri = kwargs.get(TARGET_AUTH_URI)
self.target_user_id = kwargs.get(TARGET_USER_ID)
@ -80,11 +85,6 @@ class HTTPClient(object):
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.cacert and not os.path.exists(self.cacert):
raise ValueError('Unable to locate cacert file '
@ -94,47 +94,42 @@ class HTTPClient(object):
LOG.warning('Client is set to not verify even though '
'cacert is provided.')
# These are already set by the session, so it's not needed
if not self.session:
if self.insecure:
self.ssl_options['verify'] = False
if self.insecure:
self.ssl_options['verify'] = False
else:
if self.cacert:
self.ssl_options['verify'] = self.cacert
else:
if self.cacert:
self.ssl_options['verify'] = self.cacert
else:
self.ssl_options['verify'] = True
self.ssl_options['verify'] = True
self.ssl_options['cert'] = (
kwargs.get(CERT_FILE),
kwargs.get(CERT_KEY)
)
self.ssl_options['cert'] = (
kwargs.get(CERT_FILE),
kwargs.get(CERT_KEY)
)
@log_request
def get(self, url, headers=None):
options = self._get_request_options('get', headers)
return self.crud_provider.get(self.base_url + url, **options)
return self.session.get(self.base_url + url, **options)
@log_request
def post(self, url, body, headers=None):
options = self._get_request_options('post', headers)
return self.crud_provider.post(self.base_url + url,
data=body, **options)
return self.session.post(self.base_url + url, data=body, **options)
@log_request
def put(self, url, body, headers=None):
options = self._get_request_options('put', headers)
return self.crud_provider.put(self.base_url + url,
data=body, **options)
return self.session.put(self.base_url + url, data=body, **options)
@log_request
def delete(self, url, headers=None):
options = self._get_request_options('delete', headers)
return self.crud_provider.delete(self.base_url + url,
**options)
return self.session.delete(self.base_url + url, **options)
def _get_request_options(self, method, headers):
headers = self._update_headers(headers)
@ -152,9 +147,9 @@ class HTTPClient(object):
if not headers:
headers = {}
if not self.session:
if isinstance(self.session, requests.Session):
if self.auth_token:
headers['x-auth-token'] = self.auth_token
headers['X-Auth-Token'] = self.auth_token
if self.project_id:
headers['X-Project-Id'] = self.project_id

@ -54,6 +54,10 @@ class Client(object):
auth_handler = auth.get_auth_handler(auth_type)
auth_response = auth_handler.authenticate(req, session=session) or {}
# If the session was None and we're using keystone auth, it will be
# created by the auth_handler.
session = auth_response.pop('session', None)
req.update(auth_response)
mistral_url = auth_response.get('mistral_url') or mistral_url

@ -12,14 +12,19 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from keystoneclient import client
from mistralclient import auth
import logging
import keystoneauth1.identity.generic as auth_plugin
from keystoneauth1 import session as ks_session
import mistralclient.api.httpclient as api
from mistralclient import auth as mistral_auth
from oslo_serialization import jsonutils
import mistralclient.api.httpclient as api
LOG = logging.getLogger(__name__)
class KeystoneAuthHandler(auth.AuthHandler):
class KeystoneAuthHandler(mistral_auth.AuthHandler):
def authenticate(self, req, session=None):
"""Performs authentication via Keystone.
@ -44,8 +49,8 @@ class KeystoneAuthHandler(auth.AuthHandler):
project_name = req.get('project_name')
project_id = req.get('project_id')
region_name = req.get('region_name')
user_domain_name = req.get('user_domain_name', 'Default')
project_domain_name = req.get('project_domain_name', 'Default')
user_domain_name = req.get('user_domain_name')
project_domain_name = req.get('project_domain_name')
cacert = req.get('cacert')
insecure = req.get('insecure', False)
@ -56,12 +61,8 @@ class KeystoneAuthHandler(auth.AuthHandler):
target_auth_token = req.get('target_auth_token')
target_project_name = req.get('target_project_name')
target_project_id = req.get('target_project_id')
target_region_name = req.get('target_region_name')
target_user_domain_name = req.get('target_user_domain_name', 'Default')
target_project_domain_name = req.get(
'target_project_domain_name',
'Default'
)
target_user_domain_name = req.get('target_user_domain_name')
target_project_domain_name = req.get('target_project_domain_name')
target_cacert = req.get('target_cacert')
target_insecure = req.get('target_insecure')
@ -77,33 +78,42 @@ class KeystoneAuthHandler(auth.AuthHandler):
auth_response = {}
if session:
keystone = client.Client(session=session)
elif auth_url:
keystone = client.Client(
username=username,
user_id=user_id,
password=api_key,
token=auth_token,
tenant_id=project_id,
tenant_name=project_name,
auth_url=auth_url,
cacert=cacert,
insecure=insecure,
user_domain_name=user_domain_name,
project_domain_name=project_domain_name
)
keystone.authenticate()
auth_response.update({
api.AUTH_TOKEN: keystone.auth_token,
api.PROJECT_ID: keystone.project_id,
api.USER_ID: keystone.user_id,
})
if not session:
auth = None
if auth_token:
auth = auth_plugin.Token(
auth_url=auth_url,
token=auth_token,
project_id=project_id,
project_name=project_name,
project_domain_name=project_domain_name,
cacert=cacert,
insecure=insecure)
elif api_key and (username or user_id):
auth = auth_plugin.Password(
auth_url=auth_url,
username=username,
user_id=user_id,
password=api_key,
user_domain_name=user_domain_name,
project_id=project_id,
project_name=project_name,
project_domain_name=project_domain_name)
if session or auth_url:
else:
# NOTE(jaosorior): We don't crash here cause it's needed for
# bash-completion to work. However, we do issue a warning to
# the user so if the request doesn't work. It's because of
# this.
LOG.warning("You must either provide a valid token or "
"a password (api_key) and a user.")
if auth:
session = ks_session.Session(auth=auth)
if session:
if not mistral_url:
try:
mistral_url = keystone.service_catalog.url_for(
mistral_url = session.get_endpoint(
service_type=service_type,
endpoint_type=endpoint_type,
region_name=region_name
@ -112,35 +122,48 @@ class KeystoneAuthHandler(auth.AuthHandler):
mistral_url = None
auth_response['mistral_url'] = mistral_url
auth_response['session'] = session
if target_auth_url:
target_keystone = client.Client(
username=target_username,
user_id=target_user_id,
password=target_api_key,
token=target_auth_token,
tenant_id=target_project_id,
tenant_name=target_project_name,
project_id=target_project_id,
project_name=target_project_name,
auth_url=target_auth_url,
cacert=target_cacert,
insecure=target_insecure,
region_name=target_region_name,
user_domain_name=target_user_domain_name,
project_domain_name=target_project_domain_name
)
if target_auth_token:
target_auth = auth_plugin.Token(
auth_url=target_auth_url,
token=target_auth_token,
project_id=target_project_id,
project_name=target_project_name,
project_domain_name=target_project_domain_name,
cacert=target_cacert,
insecure=target_insecure)
elif target_api_key and (target_username or target_user_id):
target_auth = auth_plugin.Password(
auth_url=target_auth_url,
username=target_username,
user_id=target_user_id,
password=target_api_key,
user_domain_name=target_user_domain_name,
project_id=target_project_id,
project_name=target_project_name,
project_domain_name=target_project_domain_name,
)
else:
raise RuntimeError("You must either provide a valid token or "
"a password (target_api_key) and a user.")
target_keystone.authenticate()
target_session = ks_session.Session(auth=target_auth)
target_auth_headers = target_session.get_auth_headers() or {}
# NOTE: (sharatss) The target_auth_token is required here so that
# it can be passed as a separate header later.
target_auth_token = target_auth_headers.get('X-Auth-Token')
auth_response.update({
api.TARGET_AUTH_TOKEN: target_keystone.auth_token,
api.TARGET_PROJECT_ID: target_keystone.project_id,
api.TARGET_USER_ID: target_keystone.user_id,
api.TARGET_AUTH_TOKEN: target_auth_token,
api.TARGET_PROJECT_ID: target_session.get_project_id(),
api.TARGET_USER_ID: target_session.get_user_id(),
api.TARGET_AUTH_URI: target_auth_url,
api.TARGET_SERVICE_CATALOG: jsonutils.dumps(
target_keystone.auth_ref
)
target_auth.get_access(
target_session)._data['access'])
})
return auth_response

@ -285,8 +285,7 @@ class MistralShell(app.App):
'--os-tenant-name',
action='store',
dest='tenant_name',
default=env('OS_TENANT_NAME', 'OS_PROJECT_NAME',
default='Default'),
default=env('OS_TENANT_NAME', 'OS_PROJECT_NAME'),
help='Authentication tenant name (Env: OS_TENANT_NAME'
' or OS_PROJECT_NAME)'
)
@ -295,8 +294,7 @@ class MistralShell(app.App):
'--os-project-name',
action='store',
dest='project_name',
default=env('OS_TENANT_NAME', 'OS_PROJECT_NAME',
default='Default'),
default=env('OS_TENANT_NAME', 'OS_PROJECT_NAME'),
help='Authentication project name (Env: OS_TENANT_NAME'
' or OS_PROJECT_NAME), will use tenant_name if both'
' tenant_name and project_name are set'
@ -314,7 +312,7 @@ class MistralShell(app.App):
'--os-project-domain-name',
action='store',
dest='project_domain_name',
default=env('OS_PROJECT_DOMAIN_NAME', default='Default'),
default=env('OS_PROJECT_DOMAIN_NAME'),
help='Authentication project domain name'
' (Env: OS_PROJECT_DOMAIN_NAME)'
)
@ -323,7 +321,7 @@ class MistralShell(app.App):
'--os-user-domain-name',
action='store',
dest='user_domain_name',
default=env('OS_USER_DOMAIN_NAME', default='Default'),
default=env('OS_USER_DOMAIN_NAME'),
help='Authentication user domain name'
' (Env: OS_USER_DOMAIN_NAME)'
)
@ -435,7 +433,7 @@ class MistralShell(app.App):
'--os-target-tenant-name',
action='store',
dest='target_tenant_name',
default=env('OS_TARGET_TENANT_NAME', 'Default'),
default=env('OS_TARGET_TENANT_NAME'),
help='Authentication tenant name for target cloud'
' (Env: OS_TARGET_TENANT_NAME)'
)

@ -39,10 +39,14 @@ def credentials(group='admin'):
username = os.environ.get('OS_USERNAME')
password = os.environ.get('OS_PASSWORD')
tenant_name = os.environ.get('OS_TENANT_NAME')
user_domain = os.environ.get('OS_USER_DOMAIN_NAME')
project_domain = os.environ.get('OS_PROJECT_DOMAIN_NAME')
else:
username = os.environ.get('OS_ALT_USERNAME')
password = os.environ.get('OS_ALT_PASSWORD')
tenant_name = os.environ.get('OS_ALT_TENANT_NAME')
user_domain = os.environ.get('OS_ALT_USER_DOMAIN_NAME')
project_domain = os.environ.get('OS_ALT_PROJECT_DOMAIN_NAME')
auth_url = os.environ.get('OS_AUTH_URL')
@ -52,6 +56,8 @@ def credentials(group='admin'):
password = password or config.get(group, 'pass')
tenant_name = tenant_name or config.get(group, 'tenant')
auth_url = auth_url or config.get('auth', 'uri')
user_domain = user_domain or config.get(group, 'user_domain')
project_domain = project_domain or config.get(group, 'project_domain')
# TODO(ddeja): Default value of OS_AUTH_URL is to provide url to v3 API.
# Since tempest openstack client doesn't properly handle it, we switch
@ -77,6 +83,7 @@ class MistralCLIAuth(base.ClientTestBase):
username=creds['username'],
password=creds['password'],
tenant_name=creds['tenant_name'],
project_name=creds['tenant_name'],
uri=creds['auth_url'],
cli_dir=CLI_DIR
)
@ -130,6 +137,7 @@ class MistralCLIAltAuth(base.ClientTestBase):
clients = base.CLIClient(
username=creds['username'],
password=creds['password'],
project_name=creds['tenant_name'],
tenant_name=creds['tenant_name'],
uri=creds['auth_url'],
cli_dir=CLI_DIR

@ -192,7 +192,8 @@ class WorkflowSharingCLITests(base_v2.MistralClientTestBase):
self.assertEqual('pending', status)
cmd_param = '%s workflow --status %s' % (self.wf[0]["ID"], new_status)
cmd_param = '%s workflow --status %s --member-id %s' % (
self.wf[0]["ID"], new_status, self.get_project_id("demo"))
member = self.mistral_alt_user("member-update", params=cmd_param)
status = self.get_field_value(member, 'Status')

@ -35,26 +35,26 @@ PROFILER_HMAC_KEY = 'SECRET_HMAC_KEY'
class BaseClientTests(base.BaseTestCase):
@staticmethod
def setup_keystone_mock(keystone_client_mock):
keystone_client_instance = keystone_client_mock.return_value
def setup_keystone_mock(session_mock):
keystone_client_instance = session_mock.return_value
keystone_client_instance.auth_token = uuidutils.generate_uuid()
keystone_client_instance.project_id = uuidutils.generate_uuid()
keystone_client_instance.user_id = uuidutils.generate_uuid()
keystone_client_instance.auth_ref = str(json.dumps({}))
return keystone_client_instance
@mock.patch('keystoneclient.client.Client')
def test_mistral_url_from_catalog_v2(self, keystone_client_mock):
keystone_client_instance = self.setup_keystone_mock(
keystone_client_mock
)
@mock.patch('keystoneauth1.session.Session')
def test_mistral_url_from_catalog_v2(self, session_mock):
session = mock.Mock()
session_mock.side_effect = [session]
url_for = mock.Mock(return_value='http://mistral_host:8989/v2')
keystone_client_instance.service_catalog.url_for = url_for
get_endpoint = mock.Mock(return_value='http://mistral_host:8989/v2')
session.get_endpoint = get_endpoint
mistralclient = client.client(
username='mistral',
project_name='mistral',
api_key='password',
auth_url=AUTH_HTTP_URL_v2_0,
service_type='workflowv2'
)
@ -64,19 +64,20 @@ class BaseClientTests(base.BaseTestCase):
mistralclient.actions.http_client.base_url
)
@mock.patch('keystoneclient.client.Client')
def test_mistral_url_from_catalog(self, keystone_client_mock):
keystone_client_instance = self.setup_keystone_mock(
keystone_client_mock
)
@mock.patch('keystoneauth1.session.Session')
def test_mistral_url_from_catalog(self, session_mock):
session = mock.Mock()
session_mock.side_effect = [session]
url_for = mock.Mock(return_value='http://mistral_host:8989/v2')
keystone_client_instance.service_catalog.url_for = url_for
get_endpoint = mock.Mock(return_value='http://mistral_host:8989/v2')
session.get_endpoint = get_endpoint
mistralclient = client.client(
username='mistral',
project_name='mistral',
api_key='password',
user_domain_name='Default',
project_domain_name='Default',
auth_url=AUTH_HTTP_URL_v3,
service_type='workflowv2'
)
@ -86,82 +87,97 @@ class BaseClientTests(base.BaseTestCase):
mistralclient.actions.http_client.base_url
)
@mock.patch('keystoneclient.client.Client')
@mock.patch('keystoneauth1.session.Session')
@mock.patch('mistralclient.api.httpclient.HTTPClient')
def test_mistral_url_default(self, http_client_mock, keystone_client_mock):
keystone_client_instance = self.setup_keystone_mock(
keystone_client_mock
)
def test_mistral_url_default(self, http_client_mock, session_mock):
session = mock.Mock()
session_mock.side_effect = [session]
url_for = mock.Mock(side_effect=Exception)
keystone_client_instance.service_catalog.url_for = url_for
get_endpoint = mock.Mock(side_effect=Exception)
session.get_endpoint = get_endpoint
client.client(
username='mistral',
project_name='mistral',
api_key='password',
user_domain_name='Default',
project_domain_name='Default',
auth_url=AUTH_HTTP_URL_v3
)
self.assertTrue(http_client_mock.called)
mistral_url_for_http = http_client_mock.call_args[0][0]
kwargs = http_client_mock.call_args[1]
self.assertEqual(MISTRAL_HTTP_URL, mistral_url_for_http)
self.assertEqual(
keystone_client_instance.auth_token, kwargs['auth_token']
)
self.assertEqual(
keystone_client_instance.project_id, kwargs['project_id']
)
self.assertEqual(
keystone_client_instance.user_id, kwargs['user_id']
)
@mock.patch('keystoneclient.client.Client')
@mock.patch('keystoneauth1.identity.generic.Password')
@mock.patch('keystoneauth1.session.Session')
@mock.patch('mistralclient.api.httpclient.HTTPClient')
def test_target_parameters_processed(
self,
http_client_mock,
keystone_client_mock
session_mock,
password_mock
):
keystone_client_instance = self.setup_keystone_mock(
keystone_client_mock
)
url_for = mock.Mock(return_value='http://mistral_host:8989/v2')
keystone_client_instance.service_catalog.url_for = url_for
session = mock.MagicMock()
target_session = mock.MagicMock()
session_mock.side_effect = [session, target_session]
auth = mock.MagicMock()
password_mock.side_effect = [auth, auth]
get_endpoint = mock.Mock(return_value='http://mistral_host:8989/v2')
session.get_endpoint = get_endpoint
target_session.get_project_id = mock.Mock(return_value='projectid')
target_session.get_user_id = mock.Mock(return_value='userid')
target_session.get_auth_headers = mock.Mock(return_value={
'X-Auth-Token': 'authtoken'
})
mock_access = mock.MagicMock()
mock_catalog = mock.MagicMock()
mock_catalog.catalog = {}
mock_access.service_catalog = mock_catalog
auth.get_access = mock.Mock(return_value=mock_access)
client.client(
username='user',
api_key='password',
user_domain_name='Default',
project_domain_name='Default',
target_username='tmistral',
target_project_name='tmistralp',
target_auth_url=AUTH_HTTP_URL_v3,
target_api_key='tpassword',
target_user_domain_name='Default',
target_project_domain_name='Default',
target_region_name='tregion'
)
self.assertTrue(http_client_mock.called)
mistral_url_for_http = http_client_mock.call_args[0][0]
kwargs = http_client_mock.call_args[1]
self.assertEqual(MISTRAL_HTTP_URL, mistral_url_for_http)
self.assertEqual('http://mistral_host:8989/v2', mistral_url_for_http)
expected_values = {
'target_project_id': keystone_client_instance.project_id,
'target_auth_token': keystone_client_instance.auth_token,
'target_user_id': keystone_client_instance.user_id,
'target_project_id': 'projectid',
'target_auth_token': 'authtoken',
'target_user_id': 'userid',
'target_auth_url': AUTH_HTTP_URL_v3,
'target_project_name': 'tmistralp',
'target_username': 'tmistral',
'target_region_name': 'tregion',
'target_service_catalog': '"{}"'
'target_service_catalog': "{}"
}
for key in expected_values:
self.assertEqual(expected_values[key], kwargs[key])
@mock.patch('keystoneclient.client.Client')
@mock.patch('keystoneauth1.session.Session')
@mock.patch('mistralclient.api.httpclient.HTTPClient')
def test_mistral_url_https_insecure(self, http_client_mock,
keystone_client_mock):
def test_mistral_url_https_insecure(self, http_client_mock, session_mock):
keystone_client_instance = self.setup_keystone_mock( # noqa
keystone_client_mock
session_mock
)
expected_args = (
@ -172,6 +188,9 @@ class BaseClientTests(base.BaseTestCase):
mistral_url=MISTRAL_HTTPS_URL,
username='mistral',
project_name='mistral',
api_key='password',
user_domain_name='Default',
project_domain_name='Default',
auth_url=AUTH_HTTP_URL_v3,
cacert=None,
insecure=True
@ -181,14 +200,13 @@ class BaseClientTests(base.BaseTestCase):
self.assertEqual(http_client_mock.call_args[0], expected_args)
self.assertEqual(http_client_mock.call_args[1]['insecure'], True)
@mock.patch('keystoneclient.client.Client')
@mock.patch('keystoneauth1.session.Session')
@mock.patch('mistralclient.api.httpclient.HTTPClient')
def test_mistral_url_https_secure(self, http_client_mock,
keystone_client_mock):
def test_mistral_url_https_secure(self, http_client_mock, session_mock):
fd, cert_path = tempfile.mkstemp(suffix='.pem')
keystone_client_instance = self.setup_keystone_mock( # noqa
keystone_client_mock
session_mock
)
expected_args = (
@ -200,6 +218,9 @@ class BaseClientTests(base.BaseTestCase):
mistral_url=MISTRAL_HTTPS_URL,
username='mistral',
project_name='mistral',
api_key='password',
user_domain_name='Default',
project_domain_name='Default',
auth_url=AUTH_HTTP_URL_v3,
cacert=cert_path,
insecure=False
@ -212,10 +233,10 @@ class BaseClientTests(base.BaseTestCase):
self.assertEqual(http_client_mock.call_args[0], expected_args)
self.assertEqual(http_client_mock.call_args[1]['cacert'], cert_path)
@mock.patch('keystoneclient.client.Client')
def test_mistral_url_https_bad_cacert(self, keystone_client_mock):
@mock.patch('keystoneauth1.session.Session')
def test_mistral_url_https_bad_cacert(self, session_mock):
keystone_client_instance = self.setup_keystone_mock( # noqa
keystone_client_mock
session_mock
)
self.assertRaises(
@ -224,19 +245,22 @@ class BaseClientTests(base.BaseTestCase):
mistral_url=MISTRAL_HTTPS_URL,
username='mistral',
project_name='mistral',
api_key='password',
user_domain_name='Default',
project_domain_name='Default',
auth_url=AUTH_HTTP_URL_v3,
cacert='/path/to/foobar',
insecure=False
)
@mock.patch('logging.Logger.warning')
@mock.patch('keystoneclient.client.Client')
def test_mistral_url_https_bad_insecure(self, keystone_client_mock,
@mock.patch('keystoneauth1.session.Session')
def test_mistral_url_https_bad_insecure(self, session_mock,
log_warning_mock):
fd, path = tempfile.mkstemp(suffix='.pem')
keystone_client_instance = self.setup_keystone_mock(
keystone_client_mock
session_mock
)
try:
@ -244,6 +268,9 @@ class BaseClientTests(base.BaseTestCase):
mistral_url=MISTRAL_HTTPS_URL,
user_id=keystone_client_instance.user_id,
project_id=keystone_client_instance.project_id,
api_key='password',
user_domain_name='Default',
project_domain_name='Default',
auth_url=AUTH_HTTP_URL_v3,
cacert=path,
insecure=True
@ -254,17 +281,19 @@ class BaseClientTests(base.BaseTestCase):
self.assertTrue(log_warning_mock.called)
@mock.patch('keystoneclient.client.Client')
@mock.patch('keystoneauth1.session.Session')
@mock.patch('mistralclient.api.httpclient.HTTPClient')
def test_mistral_profile_enabled(self, http_client_mock,
keystone_client_mock):
def test_mistral_profile_enabled(self, http_client_mock, session_mock):
keystone_client_instance = self.setup_keystone_mock( # noqa
keystone_client_mock
session_mock
)
client.client(
username='mistral',
project_name='mistral',
api_key='password',
user_domain_name='Default',
project_domain_name='Default',
auth_url=AUTH_HTTP_URL_v3,
profile=PROFILER_HMAC_KEY
)

@ -38,7 +38,7 @@ PROFILER_HMAC_KEY = 'SECRET_HMAC_KEY'
PROFILER_TRACE_ID = uuidutils.generate_uuid()
EXPECTED_AUTH_HEADERS = {
'x-auth-token': AUTH_TOKEN,
'X-Auth-Token': AUTH_TOKEN,
'X-Project-Id': PROJECT_ID,
'X-User-Id': USER_ID,
'X-Region-Name': REGION_NAME

@ -0,0 +1,6 @@
---
other:
- The dependency to python-keystoneclient was removed. Relying solely on
keystoneauth1.
- The user has to set the "OS_USER_DOMAIN_NAME" and "OS_PROJECT_DOMAIN_NAME"
explicitly if keystone v3 version is being used.

@ -6,7 +6,7 @@ osc-lib>=1.7.0 # Apache-2.0
oslo.utils>=3.20.0 # Apache-2.0
oslo.i18n!=3.15.2,>=2.1.0 # Apache-2.0
pbr!=2.1.0,>=2.0.0 # Apache-2.0
python-keystoneclient>=3.8.0 # Apache-2.0
keystoneauth1>=3.1.0 # Apache-2.0
PyYAML>=3.10.0 # MIT
requests>=2.14.2 # Apache-2.0
six>=1.9.0 # MIT