Merge "Use keystoneauth plugins and session instead of keystoneclient"
This commit is contained in:
commit
19c89ca49f
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user