Merge "[osclients] use keystone auth_ref directly"

This commit is contained in:
Jenkins 2016-09-01 11:57:00 +00:00 committed by Gerrit Code Review
commit cec6f3a4c5
8 changed files with 281 additions and 265 deletions

View File

@ -158,7 +158,7 @@ class ChecksumMismatch(RallyException):
class InvalidAdminException(InvalidArgumentsException):
msg_fmt = _("user %(username)s doesn't have 'admin' role")
msg_fmt = _("user '%(username)s' doesn't have 'admin' role")
class InvalidEndpointsException(InvalidArgumentsException):

View File

@ -142,59 +142,25 @@ class OSClient(plugin.Plugin):
raise exceptions.RallyException(_(
"Setting service type is not supported."))
def keystone(self, *args, **kwargs):
"""Make a call to keystone client."""
keystone = OSClient.get("keystone")(self.credential, self.api_info,
self.cache)
return keystone(*args, **kwargs)
@property
def keystone(self):
return OSClient.get("keystone")(self.credential, self.api_info,
self.cache)
def _get_session(self, auth_url=None, version=None):
from keystoneauth1 import discover
from keystoneauth1 import session
from keystoneclient.auth import identity
password_args = {
"auth_url": auth_url or self.credential.auth_url,
"username": self.credential.username,
"password": self.credential.password,
"tenant_name": self.credential.tenant_name
}
version = OSClient.get("keystone")(
self.credential, self.api_info, self.cache).choose_version(version)
if version is None:
# NOTE(rvasilets): If version not specified than we discover
# available version with the smallest number. To be able to
# discover versions we need session
temp_session = session.Session(
verify=(
self.credential.cacert or not self.credential.insecure),
timeout=CONF.openstack_client_http_timeout)
version = str(discover.Discover(
temp_session,
password_args["auth_url"]).version_data()[0]["version"][0])
if "v2.0" not in password_args["auth_url"] and (
version != "2"):
password_args.update({
"user_domain_name": self.credential.user_domain_name,
"domain_name": self.credential.domain_name,
"project_domain_name": self.credential.project_domain_name,
})
identity_plugin = identity.Password(**password_args)
sess = session.Session(
auth=identity_plugin, verify=(
self.credential.cacert or not self.credential.insecure),
timeout=CONF.openstack_client_http_timeout)
return sess, identity_plugin
import warnings
warnings.warn(
"Method `rally.osclient.OSClient._get_session` is deprecated since"
" Rally 0.6.0. Use "
"`rally.osclient.OSClient.keystone.get_session` instead.")
return self.keystone.get_session(version)
def _get_endpoint(self, service_type=None):
kc = self.keystone()
kw = {"service_type": self.choose_service_type(service_type),
"region_name": self.credential.region_name}
if self.credential.endpoint_type:
kw["endpoint_type"] = self.credential.endpoint_type
api_url = kc.service_catalog.url_for(**kw)
kw["interface"] = self.credential.endpoint_type
api_url = self.keystone.service_catalog.url_for(**kw)
return api_url
def _get_auth_info(self, user_key="username",
@ -250,10 +216,68 @@ class OSClient(plugin.Plugin):
@configure("keystone", supported_versions=("2", "3"))
class Keystone(OSClient):
def keystone(self, *args, **kwargs):
@property
def keystone(self):
raise exceptions.RallyException(_("Method 'keystone' is restricted "
"for keystoneclient. :)"))
@property
def service_catalog(self):
return self.auth_ref.service_catalog
@property
def auth_ref(self):
if "keystone_auth_ref" not in self.cache:
sess, plugin = self.get_session()
self.cache["keystone_auth_ref"] = plugin.get_access(sess)
return self.cache["keystone_auth_ref"]
def get_session(self, version=None):
key = "keystone_session_and_plugin_%s" % version
if key not in self.cache:
from keystoneauth1 import discover
from keystoneauth1 import identity
from keystoneauth1 import session
version = self.choose_version(version)
auth_url = self.credential.auth_url
if version is not None:
auth_url = self._remove_url_version()
password_args = {
"auth_url": auth_url,
"username": self.credential.username,
"password": self.credential.password,
"tenant_name": self.credential.tenant_name
}
if version is None:
# NOTE(rvasilets): If version not specified than we discover
# available version with the smallest number. To be able to
# discover versions we need session
temp_session = session.Session(
verify=(self.credential.cacert or
not self.credential.insecure),
timeout=CONF.openstack_client_http_timeout)
version = str(discover.Discover(
temp_session,
password_args["auth_url"]).version_data()[0]["version"][0])
if "v2.0" not in password_args["auth_url"] and (
version != "2"):
password_args.update({
"user_domain_name": self.credential.user_domain_name,
"domain_name": self.credential.domain_name,
"project_domain_name": self.credential.project_domain_name,
})
identity_plugin = identity.Password(**password_args)
sess = session.Session(
auth=identity_plugin, verify=(
self.credential.cacert or not self.credential.insecure),
timeout=CONF.openstack_client_http_timeout)
self.cache[key] = (sess, identity_plugin)
return self.cache[key]
def _remove_url_version(self):
"""Remove any version from the auth_url.
@ -282,36 +306,21 @@ class Keystone(OSClient):
# Use the version in the api_info if provided, otherwise fall
# back to the passed version (which may be None, in which case
# keystoneclient chooses).
version = self.choose_version(version)
auth_url = self.credential.auth_url
if version is not None:
auth_url = self._remove_url_version()
sess, plugin = self._get_session(auth_url=auth_url, version=version)
# NOTE(bigjools): When using sessions, keystoneclient no longer
# does any pre-auth and calling client.authenticate() with
# sessions is deprecated (it's still possible to call it but if
# endpoint is defined it'll crash). We're forcing that pre-auth
# here because the use of the service_catalog depends on doing
# this. Also note that while the API has got the
# endpoints.list() equivalent, there is no service_type in that
# list which is why we need to ensure service_catalog is still
# present.
auth_ref = plugin.get_access(sess)
sess = self.get_session(version=version)[0]
kw = {"version": version, "session": sess,
"timeout": CONF.openstack_client_http_timeout}
if keystoneclient.__version__[0] == "1":
# NOTE(andreykurilin): let's leave this hack for envs which uses
# old(<2.0.0) keystoneclient version. Upstream fix:
# https://github.com/openstack/python-keystoneclient/commit/d9031c252848d89270a543b67109a46f9c505c86
from keystoneclient import base
kw["auth_url"] = sess.get_endpoint(interface=base.AUTH_INTERFACE)
from keystoneauth1 import plugin
kw["auth_url"] = sess.get_endpoint(interface=plugin.AUTH_INTERFACE)
if self.credential.endpoint_type:
kw["endpoint_type"] = self.credential.endpoint_type
ks = client.Client(**kw)
ks.auth_ref = auth_ref
return ks
return client.Client(**kw)
@configure("nova", default_version="2", default_service_type="compute")
@ -331,9 +340,8 @@ class Nova(OSClient):
"""Return nova client."""
from novaclient import client as nova
kc = self.keystone()
client = nova.Client(self.choose_version(version),
auth_token=kc.auth_token,
auth_token=self.keystone.auth_ref.auth_token,
http_log_debug=logging.is_debug(),
timeout=CONF.openstack_client_http_timeout,
insecure=self.credential.insecure,
@ -349,9 +357,8 @@ class Neutron(OSClient):
"""Return neutron client."""
from neutronclient.neutron import client as neutron
kc = self.keystone()
client = neutron.Client(self.choose_version(version),
token=kc.auth_token,
token=self.keystone.auth_ref.auth_token,
endpoint_url=self._get_endpoint(service_type),
timeout=CONF.openstack_client_http_timeout,
insecure=self.credential.insecure,
@ -368,10 +375,9 @@ class Glance(OSClient):
"""Return glance client."""
import glanceclient as glance
kc = self.keystone()
client = glance.Client(self.choose_version(version),
endpoint=self._get_endpoint(service_type),
token=kc.auth_token,
token=self.keystone.auth_ref.auth_token,
timeout=CONF.openstack_client_http_timeout,
insecure=self.credential.insecure,
cacert=self.credential.cacert)
@ -385,10 +391,9 @@ class Heat(OSClient):
"""Return heat client."""
from heatclient import client as heat
kc = self.keystone()
client = heat.Client(self.choose_version(version),
endpoint=self._get_endpoint(service_type),
token=kc.auth_token,
token=self.keystone.auth_ref.auth_token,
timeout=CONF.openstack_client_http_timeout,
insecure=self.credential.insecure,
**self._get_auth_info(project_name_key=None,
@ -408,9 +413,8 @@ class Cinder(OSClient):
timeout=CONF.openstack_client_http_timeout,
insecure=self.credential.insecure,
**self._get_auth_info(password_key="api_key"))
kc = self.keystone()
client.client.management_url = self._get_endpoint(service_type)
client.client.auth_token = kc.auth_token
client.client.auth_token = self.keystone.auth_ref.auth_token
return client
@ -428,9 +432,8 @@ class Manila(OSClient):
insecure=self.credential.insecure,
**self._get_auth_info(password_key="api_key",
project_name_key="project_name"))
kc = self.keystone()
manila_client.client.management_url = self._get_endpoint(service_type)
manila_client.client.auth_token = kc.auth_token
manila_client.client.auth_token = self.keystone.auth_ref.auth_token
return manila_client
@ -441,16 +444,10 @@ class Ceilometer(OSClient):
"""Return ceilometer client."""
from ceilometerclient import client as ceilometer
kc = self.keystone()
auth_token = kc.auth_token
if not hasattr(auth_token, "__call__"):
# python-ceilometerclient requires auth_token to be a callable
auth_token = lambda: kc.auth_token
client = ceilometer.get_client(
self.choose_version(version),
os_endpoint=self._get_endpoint(service_type),
token=auth_token,
token=self.keystone.auth_ref.auth_token,
timeout=CONF.openstack_client_http_timeout,
insecure=self.credential.insecure,
**self._get_auth_info(project_name_key="tenant_name",
@ -469,7 +466,7 @@ class Gnocchi(OSClient):
from gnocchiclient import client as gnocchi
service_type = self.choose_service_type(service_type)
sess = self._get_session()[0]
sess = self.keystone.get_session()[0]
gclient = gnocchi.Client(version=self.choose_version(
version), session=sess, service_type=service_type)
return gclient
@ -483,9 +480,9 @@ class Ironic(OSClient):
"""Return Ironic client."""
from ironicclient import client as ironic
kc = self.keystone()
auth_token = self.keystone.auth_ref.auth_token
client = ironic.get_client(self.choose_version(version),
os_auth_token=kc.auth_token,
os_auth_token=auth_token,
ironic_url=self._get_endpoint(service_type),
timeout=CONF.openstack_client_http_timeout,
insecure=self.credential.insecure,
@ -534,12 +531,12 @@ class Zaqar(OSClient):
def create_client(self, version=None, service_type=None):
"""Return Zaqar client."""
from zaqarclient.queues import client as zaqar
kc = self.keystone()
tenant_id = self.keystone.auth_ref.get("token").get("tenant").get("id")
conf = {"auth_opts": {"backend": "keystone", "options": {
"os_username": self.credential.username,
"os_password": self.credential.password,
"os_project_name": self.credential.tenant_name,
"os_project_id": kc.auth_ref.get("token").get("tenant").get("id"),
"os_project_id": tenant_id,
"os_auth_url": self.credential.auth_url,
"insecure": self.credential.insecure,
}}}
@ -557,10 +554,9 @@ class Murano(OSClient):
"""Return Murano client."""
from muranoclient import client as murano
kc = self.keystone()
client = murano.Client(self.choose_version(version),
endpoint=self._get_endpoint(service_type),
token=kc.auth_token)
token=self.keystone.auth_ref.auth_token)
return client
@ -577,7 +573,7 @@ class Designate(OSClient):
api_url = self._get_endpoint(service_type)
api_url += "/v%s" % version
session = self._get_session()[0]
session = self.keystone.get_session()[0]
if version == "2":
return client.Client(version, session=session,
endpoint_override=api_url)
@ -606,11 +602,10 @@ class Mistral(OSClient):
"""Return Mistral client."""
from mistralclient.api import client as mistral
kc = self.keystone()
client = mistral.client(
mistral_url=self._get_endpoint(service_type),
service_type=self.choose_service_type(service_type),
auth_token=kc.auth_token)
auth_token=self.keystone.auth_ref.auth_token)
return client
@ -620,10 +615,10 @@ class Swift(OSClient):
"""Return swift client."""
from swiftclient import client as swift
kc = self.keystone()
auth_token = self.keystone.auth_ref.auth_token
client = swift.Connection(retries=1,
preauthurl=self._get_endpoint(service_type),
preauthtoken=kc.auth_token,
preauthtoken=auth_token,
insecure=self.credential.insecure,
cacert=self.credential.cacert,
user=self.credential.username,
@ -639,6 +634,7 @@ class EC2(OSClient):
import boto
kc = self.keystone()
if kc.version != "v2.0":
raise exceptions.RallyException(
_("Rally EC2 benchmark currently supports only"
@ -660,12 +656,10 @@ class Monasca(OSClient):
"""Return monasca client."""
from monascaclient import client as monasca
kc = self.keystone()
auth_token = kc.auth_token
client = monasca.Client(
self.choose_version(version),
self._get_endpoint(service_type),
token=auth_token,
token=self.keystone.auth_ref.auth_token,
timeout=CONF.openstack_client_http_timeout,
insecure=self.credential.insecure,
**self._get_auth_info(project_name_key="tenant_name"))
@ -682,7 +676,7 @@ class Cue(OSClient):
api_url = self._get_endpoint(service_type)
api_url += "v%s" % version
session = self._get_session(auth_url=api_url)[0]
session = self.keystone.get_session()[0]
endpoint_type = self.credential.endpoint_type
return cue.Client(session=session, interface=endpoint_type)
@ -710,7 +704,7 @@ class Magnum(OSClient):
from magnumclient import client as magnum
api_url = self._get_endpoint(service_type)
session = self._get_session()[0]
session = self.keystone.get_session()[0]
return magnum.Client(
session=session,
@ -724,13 +718,12 @@ class Watcher(OSClient):
def create_client(self, version=None, service_type=None):
"""Return watcher client."""
from watcherclient import client as watcher_client
kc = self.keystone()
watcher_api_url = self._get_endpoint(
self.choose_service_type(service_type))
client = watcher_client.Client(
self.choose_version(version),
watcher_api_url,
token=kc.auth_token,
token=self.keystone.auth_ref.auth_token,
timeout=CONF.openstack_client_http_timeout,
insecure=self.credential.insecure,
ca_file=self.credential.cacert,
@ -781,9 +774,8 @@ class Clients(object):
from keystoneclient import exceptions as keystone_exceptions
try:
# Ensure that user is admin
client = self.keystone()
if "admin" not in [role.lower() for role in
client.auth_ref.role_names]:
self.keystone.auth_ref.role_names]:
raise exceptions.InvalidAdminException(
username=self.credential.username)
except keystone_exceptions.Unauthorized:
@ -791,7 +783,7 @@ class Clients(object):
except keystone_exceptions.AuthorizationFailure:
raise exceptions.HostUnreachableException(
url=self.credential.auth_url)
return client
return self.keystone()
def services(self):
"""Return available services names and types.
@ -800,8 +792,7 @@ class Clients(object):
"""
if "services_data" not in self.cache:
services_data = {}
ks = self.keystone()
available_services = ks.service_catalog.get_endpoints()
available_services = self.keystone.service_catalog.get_endpoints()
for stype in available_services.keys():
if stype in consts.ServiceType:
services_data[stype] = consts.ServiceType[stype]

View File

@ -191,7 +191,7 @@ class OpenStackAPIVersions(context.Context):
self.context.get("admin", {}).get("credential"))
clients = osclients.Clients(random.choice(
self.context["users"])["credential"])
services = clients.keystone().service_catalog.get_endpoints()
services = clients.keystone.service_catalog.get_endpoints()
services_from_admin = None
for client_name, conf in six.iteritems(self.config):
if "service_type" in conf and conf["service_type"] not in services:

View File

@ -50,17 +50,15 @@ class ExistingUsers(users.UserContextMixin, context.Context):
for user in self.config:
user_credential = objects.Credential(**user)
user_kclient = osclients.Clients(user_credential).keystone()
user_clients = osclients.Clients(user_credential)
user_name = user_kclient.username
tenant_name = user_kclient.project_name
user_id = user_kclient.get_user_id(user_name)
tenant_id = user_kclient.get_project_id(tenant_name)
user_id = user_clients.keystone.auth_ref.user_id
tenant_id = user_clients.keystone.auth_ref.project_id
if tenant_id not in self.context["tenants"]:
self.context["tenants"][tenant_id] = {
"id": tenant_id,
"name": tenant_name
"name": user_credential.tenant_name
}
self.context["users"].append({

View File

@ -26,18 +26,30 @@ class ExistingUserTestCase(test.TestCase):
@mock.patch("%s.keystone.existing_users.objects.Credential" % CTX)
def test_setup(self, mock_credential, mock_clients):
user1 = mock.MagicMock(tenant_id="1", user_id="1",
project_name="proj", username="usr")
tenant_name="proj", username="usr")
user2 = mock.MagicMock(tenant_id="1", user_id="2",
project_name="proj", username="usr")
tenant_name="proj", username="usr")
user3 = mock.MagicMock(tenant_id="2", user_id="3",
project_name="proj", username="usr")
tenant_name="proj", username="usr")
user_list = [user1, user2, user3]
for u in user_list:
u.get_user_id.return_value = u.user_id
u.get_project_id.return_value = u.tenant_id
mock_clients.return_value.keystone.side_effect = user_list
class AuthRef(object):
USER_ID_COUNT = 0
PROJECT_ID_COUNT = 0
@property
def user_id(self):
self.USER_ID_COUNT += 1
return user_list[self.USER_ID_COUNT - 1].user_id
@property
def project_id(self):
self.PROJECT_ID_COUNT += 1
return user_list[self.PROJECT_ID_COUNT - 1].tenant_id
mock_clients.return_value.keystone.auth_ref = AuthRef()
mock_credential.side_effect = user_list
context = {
"task": mock.MagicMock(),
@ -53,15 +65,15 @@ class ExistingUserTestCase(test.TestCase):
self.assertEqual(
{
"id": user1.user_id,
"credential": mock_credential.return_value,
"credential": user1,
"tenant_id": user1.tenant_id
},
context["users"][0]
)
self.assertEqual(["1", "2"], sorted(context["tenants"].keys()))
self.assertEqual({"id": "1", "name": user1.project_name},
self.assertEqual({"id": "1", "name": user1.tenant_name},
context["tenants"]["1"])
self.assertEqual({"id": "2", "name": user3.project_name},
self.assertEqual({"id": "2", "name": user3.tenant_name},
context["tenants"]["2"])
def test_cleanup(self):

View File

@ -24,8 +24,10 @@ class OpenStackServicesTestCase(test.TestCase):
def setUp(self):
super(OpenStackServicesTestCase, self).setUp()
self.mock_clients = mock.patch("rally.osclients.Clients").start()
self.mock_kc = self.mock_clients.return_value.keystone.return_value
self.mock_kc.service_catalog.get_endpoints.return_value = []
osclient_kc = self.mock_clients.return_value.keystone
self.mock_kc = osclient_kc.return_value
self.service_catalog = osclient_kc.service_catalog
self.service_catalog.get_endpoints.return_value = []
self.mock_kc.services.list.return_value = []
def test_validate_correct_config(self):
@ -85,7 +87,7 @@ class OpenStackServicesTestCase(test.TestCase):
"users": [{"credential": mock.MagicMock()}]}
ctx = api_versions.OpenStackAPIVersions(context)
self.assertRaises(exceptions.ValidationError, ctx.setup)
self.mock_kc.service_catalog.get_endpoints.assert_called_once_with()
self.service_catalog.get_endpoints.assert_called_once_with()
self.mock_kc.services.list.assert_called_once_with()
def test_setup_with_wrong_service_name_and_without_admin(self):
@ -95,7 +97,7 @@ class OpenStackServicesTestCase(test.TestCase):
"users": [{"credential": mock.MagicMock()}]}
ctx = api_versions.OpenStackAPIVersions(context)
self.assertRaises(exceptions.BenchmarkSetupFailure, ctx.setup)
self.mock_kc.service_catalog.get_endpoints.assert_called_once_with()
self.service_catalog.get_endpoints.assert_called_once_with()
self.assertFalse(self.mock_kc.services.list.called)
def test_setup_with_wrong_service_type(self):
@ -105,7 +107,7 @@ class OpenStackServicesTestCase(test.TestCase):
"users": [{"credential": mock.MagicMock()}]}
ctx = api_versions.OpenStackAPIVersions(context)
self.assertRaises(exceptions.ValidationError, ctx.setup)
self.mock_kc.service_catalog.get_endpoints.assert_called_once_with()
self.service_catalog.get_endpoints.assert_called_once_with()
def test_setup_with_service_name(self):
self.mock_kc.services.list.return_value = [
@ -118,7 +120,7 @@ class OpenStackServicesTestCase(test.TestCase):
ctx = api_versions.OpenStackAPIVersions(context)
ctx.setup()
self.mock_kc.service_catalog.get_endpoints.assert_called_once_with()
self.service_catalog.get_endpoints.assert_called_once_with()
self.mock_kc.services.list.assert_called_once_with()
self.assertEqual(

View File

@ -377,8 +377,10 @@ class DeploymentAPITestCase(BaseDeploymentTestCase):
for key in self.deployment:
self.assertEqual(ret[key], self.deployment[key])
@mock.patch("rally.osclients.Clients.services")
@mock.patch("rally.osclients.Keystone.create_client")
def test_deployment_check(self, mock_keystone_create_client):
def test_deployment_check(self, mock_keystone_create_client,
mock_clients_services):
sample_credential = objects.Credential("http://192.168.1.1:5000/v2.0/",
"admin",
"adminpass").to_dict()
@ -386,6 +388,7 @@ class DeploymentAPITestCase(BaseDeploymentTestCase):
"users": [sample_credential]}
api.Deployment.check(deployment)
mock_keystone_create_client.assert_called_with()
mock_clients_services.assert_called_once_with()
def test_deployment_check_raise(self):
sample_credential = objects.Credential("http://192.168.1.1:5000/v2.0/",

View File

@ -37,23 +37,20 @@ class OSClientTestCaseUtils(object):
def set_up_keystone_mocks(self):
self.ksc_module = mock.MagicMock(__version__="2.0.0")
self.ksc_client = mock.MagicMock()
self.ksc_identity = mock.MagicMock()
self.ksc_identity_plugin = mock.MagicMock()
self.ksc_password = mock.MagicMock(
return_value=self.ksc_identity_plugin)
self.ksc_auth = mock.MagicMock()
self.ksa_identity_plugin = mock.MagicMock()
self.ksa_password = mock.MagicMock(
return_value=self.ksa_identity_plugin)
self.ksa_identity = mock.MagicMock(Password=self.ksa_password)
self.ksa_auth = mock.MagicMock()
self.ksa_session = mock.MagicMock()
self.patcher = mock.patch.dict("sys.modules",
{"keystoneclient": self.ksc_module,
"keystoneclient.auth": self.ksc_auth,
"keystoneauth1": self.ksa_auth})
self.patcher.start()
self.addCleanup(self.patcher.stop)
self.ksc_module.client = self.ksc_client
self.ksc_auth.identity = self.ksc_identity
self.ksc_auth.identity.Password = self.ksc_password
self.ksa_auth.identity = self.ksa_identity
self.ksa_auth.session = self.ksa_session
def make_auth_args(self):
@ -86,70 +83,43 @@ class OSClientTestCase(test.TestCase, OSClientTestCaseUtils):
self.assertEqual("foo",
fake_client.choose_service_type("foo"))
@ddt.data(
{"auth_url": "http://auth_url/v2.0"},
{"auth_url": "http://auth_url/v3"},
{"auth_url": "http://auth_url/"},
{"auth_url": None},
)
@ddt.unpack
def test__get_session(self, auth_url):
credential = objects.Credential("http://auth_url/v2.0", "user",
"pass", "tenant")
mock_keystoneauth1 = mock.MagicMock()
self.set_up_keystone_mocks()
osclient = osclients.OSClient(credential, {}, mock.MagicMock())
with mock.patch.dict(
"sys.modules", {
"keystoneauth1": mock_keystoneauth1}):
mock_keystoneauth1.discover.Discover.return_value = (
mock.Mock(version_data=mock.Mock(return_value=[
{"version": (1, 0)}]))
)
osclient._get_session(auth_url=auth_url)
if auth_url == "http://auth_url/v2.0":
self.ksc_password.assert_called_once_with(
auth_url=auth_url, password="pass",
tenant_name="tenant", username="user")
elif auth_url is None:
self.ksc_password.assert_called_once_with(
auth_url="http://auth_url/v2.0", password="pass",
tenant_name="tenant", username="user")
else:
self.ksc_password.assert_called_once_with(
auth_url=auth_url, password="pass",
tenant_name="tenant", username="user",
domain_name=None, project_domain_name=None,
user_domain_name=None)
mock_keystoneauth1.session.Session.assert_has_calls(
[mock.call(timeout=180.0, verify=True),
mock.call(auth=self.ksc_identity_plugin, timeout=180.0,
verify=True)])
@mock.patch("rally.osclients.Keystone.service_catalog")
@ddt.data(
{"endpoint_type": None, "service_type": None, "region_name": None},
{"endpoint_type": "et", "service_type": "st", "region_name": "rn"}
)
@ddt.unpack
def test__get_endpoint(self, endpoint_type, service_type, region_name):
def test__get_endpoint(self, mock_keystone_service_catalog, endpoint_type,
service_type, region_name):
credential = objects.Credential("http://auth_url/v2.0", "user", "pass",
endpoint_type=endpoint_type,
region_name=region_name)
mock_choose_service_type = mock.MagicMock()
osclient = osclients.OSClient(credential, {}, mock.MagicMock())
osclient.choose_service_type = mock_choose_service_type
with mock.patch.object(osclient, "keystone") as ks:
mock_url_for = ks.return_value.service_catalog.url_for
self.assertEqual(mock_url_for.return_value,
osclient._get_endpoint(service_type))
call_args = {
"service_type": mock_choose_service_type.return_value,
"region_name": region_name}
if endpoint_type:
call_args["endpoint_type"] = endpoint_type
mock_url_for.assert_called_once_with(**call_args)
mock_url_for = mock_keystone_service_catalog.url_for
self.assertEqual(mock_url_for.return_value,
osclient._get_endpoint(service_type))
call_args = {
"service_type": mock_choose_service_type.return_value,
"region_name": region_name}
if endpoint_type:
call_args["interface"] = endpoint_type
mock_url_for.assert_called_once_with(**call_args)
mock_choose_service_type.assert_called_once_with(service_type)
@mock.patch("rally.osclients.Keystone.get_session")
def test__get_session(self, mock_keystone_get_session):
osclient = osclients.OSClient(None, None, None)
auth_url = "auth_url"
version = "version"
import warnings
with mock.patch.object(warnings, "warn") as mock_warn:
self.assertEqual(mock_keystone_get_session.return_value,
osclient._get_session(auth_url, version))
self.assertTrue(mock_warn.called)
mock_keystone_get_session.assert_called_once_with(version)
class CachedTestCase(test.TestCase):
@ -178,6 +148,7 @@ class CachedTestCase(test.TestCase):
self.assertEqual({}, clients.cache)
@ddt.ddt
class TestCreateKeystoneClient(test.TestCase, OSClientTestCaseUtils):
def setUp(self):
@ -195,10 +166,8 @@ class TestCreateKeystoneClient(test.TestCase, OSClientTestCaseUtils):
# keystone guys.
self.set_up_keystone_mocks()
keystone = osclients.Keystone(self.credential, {}, mock.MagicMock())
keystone._get_session = mock.Mock(
return_value=(self.ksa_session, self.ksc_identity_plugin,))
self.ksc_identity_plugin.get_access = mock.Mock(
return_value="fake_auth_ref")
keystone.get_session = mock.Mock(
return_value=(self.ksa_session, self.ksa_identity_plugin,))
client = keystone.create_client(version=3)
kwargs_session = self.credential.to_dict()
@ -206,19 +175,10 @@ class TestCreateKeystoneClient(test.TestCase, OSClientTestCaseUtils):
"auth_url": "http://auth_url/",
"session": self.ksa_session,
"timeout": 180.0})
keystone._get_session.assert_called_once_with(
auth_url="http://auth_url/", version="3")
self.ksc_identity_plugin.get_access.assert_called_once_with(
self.ksa_session)
keystone.get_session.assert_called_once_with(version="3")
self.ksc_client.Client.assert_called_once_with(
session=self.ksa_session, timeout=180.0, version="3")
self.assertIs(client, self.ksc_client.Client())
self.assertEqual("fake_auth_ref", self.ksc_client.Client().auth_ref)
# The client needs to be pre-authed so that service_catalog
# works. This is because when using sessions, lazy auth is done
# in keystoneclient.
auth_ref = getattr(client, "auth_ref", None)
self.assertIsNot(auth_ref, None)
def test_create_client_removes_url_path_if_version_specified(self):
# If specifying a version on the client creation call, ensure
@ -228,8 +188,8 @@ class TestCreateKeystoneClient(test.TestCase, OSClientTestCaseUtils):
auth_kwargs, all_kwargs = self.make_auth_args()
keystone = osclients.Keystone(
self.credential, {}, mock.MagicMock())
keystone._get_session = mock.Mock(
return_value=(self.ksa_session, self.ksc_identity_plugin,))
keystone.get_session = mock.Mock(
return_value=(self.ksa_session, self.ksa_identity_plugin,))
client = keystone.create_client(version="3")
self.assertIs(client, self.ksc_client.Client())
@ -238,6 +198,57 @@ class TestCreateKeystoneClient(test.TestCase, OSClientTestCaseUtils):
{"session": self.ksa_session, "timeout": 180.0, "version": "3"},
called_with)
@ddt.data("http://auth_url/v2.0", "http://auth_url/v3",
"http://auth_url/", "auth_url")
def test_keystone_get_session(self, auth_url):
credential = objects.Credential(auth_url, "user",
"pass", "tenant")
self.set_up_keystone_mocks()
keystone = osclients.Keystone(credential, {}, {})
version_data = mock.Mock(return_value=[{"version": (1, 0)}])
self.ksa_auth.discover.Discover.return_value = (
mock.Mock(version_data=version_data))
self.assertEqual((self.ksa_session.Session.return_value,
self.ksa_identity_plugin),
keystone.get_session())
if auth_url.endswith("v2.0"):
self.ksa_password.assert_called_once_with(
auth_url=auth_url, password="pass",
tenant_name="tenant", username="user")
else:
self.ksa_password.assert_called_once_with(
auth_url=auth_url, password="pass",
tenant_name="tenant", username="user",
domain_name=None, project_domain_name=None,
user_domain_name=None)
self.ksa_session.Session.assert_has_calls(
[mock.call(timeout=180.0, verify=True),
mock.call(auth=self.ksa_identity_plugin, timeout=180.0,
verify=True)])
def test_keystone_property(self):
keystone = osclients.Keystone(None, None, None)
self.assertRaises(exceptions.RallyException, lambda: keystone.keystone)
@mock.patch("rally.osclients.Keystone.get_session")
def test_auth_ref(self, mock_keystone_get_session):
session = mock.MagicMock()
auth_plugin = mock.MagicMock()
mock_keystone_get_session.return_value = (session, auth_plugin)
cache = {}
keystone = osclients.Keystone(None, None, cache)
self.assertEqual(auth_plugin.get_access.return_value,
keystone.auth_ref)
self.assertEqual(auth_plugin.get_access.return_value,
cache["keystone_auth_ref"])
# check that auth_ref was cached.
keystone.auth_ref
mock_keystone_get_session.assert_called_once_with()
@ddt.ddt
class OSClientsTestCase(test.TestCase):
@ -249,18 +260,17 @@ class OSClientsTestCase(test.TestCase):
self.clients = osclients.Clients(self.credential, {})
self.fake_keystone = fakes.FakeKeystoneClient()
self.fake_keystone.auth_token = mock.MagicMock()
self.service_catalog = self.fake_keystone.service_catalog
self.service_catalog.url_for = mock.MagicMock()
keystone_patcher = mock.patch(
"rally.osclients.Keystone.create_client")
"rally.osclients.Keystone.create_client",
return_value=self.fake_keystone)
self.mock_create_keystone_client = keystone_patcher.start()
self.addCleanup(keystone_patcher.stop)
self.mock_create_keystone_client.return_value = self.fake_keystone
def tearDown(self):
super(OSClientsTestCase, self).tearDown()
self.auth_ref_patcher = mock.patch("rally.osclients.Keystone.auth_ref")
self.auth_ref = self.auth_ref_patcher.start()
self.service_catalog = self.auth_ref.service_catalog
self.service_catalog.url_for = mock.MagicMock()
def test_create_from_env(self):
with mock.patch.dict("os.environ",
@ -288,28 +298,29 @@ class OSClientsTestCase(test.TestCase):
self.mock_create_keystone_client.assert_called_once_with()
self.assertEqual(self.fake_keystone, self.clients.cache["keystone"])
@mock.patch("rally.osclients.Keystone.create_client")
def test_verified_keystone_user_not_admin(self,
mock_keystone_create_client):
# naming rule for mocks sucks
mock_keystone = mock_keystone_create_client
mock_keystone.return_value = fakes.FakeKeystoneClient()
mock_keystone.return_value.auth_ref.role_names = ["notadmin"]
def test_verified_keystone(self):
self.auth_ref.role_names = ["admin"]
self.assertEqual(self.mock_create_keystone_client.return_value,
self.clients.verified_keystone())
def test_verified_keystone_user_not_admin(self):
self.auth_ref.role_names = ["notadmin"]
self.assertRaises(exceptions.InvalidAdminException,
self.clients.verified_keystone)
@mock.patch("rally.osclients.Keystone.create_client")
def test_verified_keystone_unauthorized(self, mock_keystone_create_client):
mock_keystone_create_client.return_value = fakes.FakeKeystoneClient()
mock_keystone_create_client.side_effect = (
keystone_exceptions.Unauthorized)
@mock.patch("rally.osclients.Keystone.get_session")
def test_verified_keystone_unauthorized(self, mock_keystone_get_session):
self.auth_ref_patcher.stop()
mock_keystone_get_session.side_effect = (
keystone_exceptions.Unauthorized
)
self.assertRaises(exceptions.InvalidEndpointsException,
self.clients.verified_keystone)
@mock.patch("rally.osclients.Keystone.create_client")
def test_verified_keystone_unreachable(self, mock_keystone_create_client):
mock_keystone_create_client.return_value = fakes.FakeKeystoneClient()
mock_keystone_create_client.side_effect = (
@mock.patch("rally.osclients.Keystone.get_session")
def test_verified_keystone_unreachable(self, mock_keystone_get_session):
self.auth_ref_patcher.stop()
mock_keystone_get_session.side_effect = (
keystone_exceptions.AuthorizationFailure
)
self.assertRaises(exceptions.HostUnreachableException,
@ -328,7 +339,7 @@ class OSClientsTestCase(test.TestCase):
region_name=self.credential.region_name)
mock_nova.client.Client.assert_called_once_with(
"2",
auth_token=self.fake_keystone.auth_token,
auth_token=self.auth_ref.auth_token,
http_log_debug=False,
timeout=cfg.CONF.openstack_client_http_timeout,
insecure=False, cacert=None,
@ -350,7 +361,7 @@ class OSClientsTestCase(test.TestCase):
client = self.clients.neutron()
self.assertEqual(fake_neutron, client)
kw = {
"token": self.fake_keystone.auth_token,
"token": self.auth_ref.auth_token,
"endpoint_url": self.service_catalog.url_for.return_value,
"timeout": cfg.CONF.openstack_client_http_timeout,
"insecure": self.credential.insecure,
@ -375,7 +386,7 @@ class OSClientsTestCase(test.TestCase):
client = self.clients.glance()
self.assertEqual(fake_glance, client)
kw = {"endpoint": self.service_catalog.url_for.return_value,
"token": self.fake_keystone.auth_token,
"token": self.auth_ref.auth_token,
"timeout": cfg.CONF.openstack_client_http_timeout,
"insecure": False, "cacert": None}
self.service_catalog.url_for.assert_called_once_with(
@ -407,7 +418,7 @@ class OSClientsTestCase(test.TestCase):
self.assertEqual(fake_cinder.client.management_url,
self.service_catalog.url_for.return_value)
self.assertEqual(fake_cinder.client.auth_token,
self.fake_keystone.auth_token)
self.auth_ref.auth_token)
self.assertEqual(fake_cinder, self.clients.cache["cinder"])
def test_manila(self):
@ -434,7 +445,7 @@ class OSClientsTestCase(test.TestCase):
self.service_catalog.url_for.return_value)
self.assertEqual(
mock_manila.client.Client.return_value.client.auth_token,
self.fake_keystone.auth_token)
self.auth_ref.auth_token)
self.assertEqual(
mock_manila.client.Client.return_value,
self.clients.cache["manila"])
@ -453,7 +464,7 @@ class OSClientsTestCase(test.TestCase):
service_type="metering",
region_name=self.credential.region_name)
kw = {"os_endpoint": self.service_catalog.url_for.return_value,
"token": self.fake_keystone.auth_token,
"token": self.auth_ref.auth_token,
"timeout": cfg.CONF.openstack_client_http_timeout,
"insecure": False, "cacert": None,
"username": self.credential.username,
@ -501,7 +512,7 @@ class OSClientsTestCase(test.TestCase):
service_type="monitoring",
region_name=self.credential.region_name)
os_endpoint = self.service_catalog.url_for.return_value
kw = {"token": self.fake_keystone.auth_token,
kw = {"token": self.auth_ref.auth_token,
"timeout": cfg.CONF.openstack_client_http_timeout,
"insecure": False, "cacert": None,
"username": self.credential.username,
@ -528,7 +539,7 @@ class OSClientsTestCase(test.TestCase):
service_type="baremetal",
region_name=self.credential.region_name)
kw = {
"os_auth_token": self.fake_keystone.auth_token,
"os_auth_token": self.auth_ref.auth_token,
"ironic_url": self.service_catalog.url_for.return_value,
"timeout": cfg.CONF.openstack_client_http_timeout,
"insecure": self.credential.insecure,
@ -563,7 +574,7 @@ class OSClientsTestCase(test.TestCase):
mock_zaqar = mock.MagicMock()
mock_zaqar.client.Client = mock.MagicMock(return_value=fake_zaqar)
self.assertNotIn("zaqar", self.clients.cache)
p_id = self.fake_keystone.auth_ref.get("token").get("tenant").get("id")
p_id = self.auth_ref.get("token").get("tenant").get("id")
with mock.patch.dict("sys.modules", {"zaqarclient.queues":
mock_zaqar}):
client = self.clients.zaqar()
@ -624,7 +635,7 @@ class OSClientsTestCase(test.TestCase):
mock_mistral.client.client.assert_called_once_with(
mistral_url=fake_mistral_url,
service_type="workflowv2",
auth_token=self.fake_keystone.auth_token
auth_token=self.auth_ref.auth_token
)
self.assertEqual(fake_mistral, self.clients.cache["mistral"])
@ -641,7 +652,7 @@ class OSClientsTestCase(test.TestCase):
region_name=self.credential.region_name)
kw = {"retries": 1,
"preauthurl": self.service_catalog.url_for.return_value,
"preauthtoken": self.fake_keystone.auth_token,
"preauthtoken": self.auth_ref.auth_token,
"insecure": False,
"cacert": None,
"user": self.credential.username,
@ -674,14 +685,13 @@ class OSClientsTestCase(test.TestCase):
mock_boto.connect_ec2_endpoint.assert_called_once_with(**kw)
self.assertEqual(fake_ec2, self.clients.cache["ec2"])
@mock.patch("rally.osclients.Keystone.create_client")
def test_services(self, mock_keystone_create_client):
@mock.patch("rally.osclients.Keystone.service_catalog")
def test_services(self, mock_keystone_service_catalog):
available_services = {consts.ServiceType.IDENTITY: {},
consts.ServiceType.COMPUTE: {},
"some_service": {}}
mock_keystone_create_client.return_value = mock.Mock(
service_catalog=mock.Mock(
get_endpoints=lambda: available_services))
mock_get_endpoints = mock_keystone_service_catalog.get_endpoints
mock_get_endpoints.return_value = available_services
clients = osclients.Clients(self.credential)
self.assertEqual(
@ -703,11 +713,11 @@ class OSClientsTestCase(test.TestCase):
region_name=self.credential.region_name
)
kw = {"endpoint": self.service_catalog.url_for.return_value,
"token": self.fake_keystone.auth_token}
"token": self.auth_ref.auth_token}
mock_murano.client.Client.assert_called_once_with("1", **kw)
self.assertEqual(fake_murano, self.clients.cache["murano"])
@mock.patch("rally.osclients.Designate._get_session")
@mock.patch("rally.osclients.Keystone.get_session")
@ddt.data(
{},
{"version": "2"},
@ -715,13 +725,13 @@ class OSClientsTestCase(test.TestCase):
{"version": None}
)
@ddt.unpack
def test_designate(self, mock_designate__get_session, version=None):
def test_designate(self, mock_keystone_get_session, version=None):
fake_designate = fakes.FakeDesignateClient()
mock_designate = mock.Mock()
mock_designate.client.Client.return_value = fake_designate
mock_designate__get_session.return_value = ("fake_session",
"fake_auth_plugin")
mock_keystone_get_session.return_value = ("fake_session",
"fake_auth_plugin")
self.assertNotIn("designate", self.clients.cache)
with mock.patch.dict("sys.modules",
@ -742,7 +752,7 @@ class OSClientsTestCase(test.TestCase):
url = self.service_catalog.url_for.return_value
url.__iadd__.assert_called_once_with("/v%s" % default)
mock_designate__get_session.assert_called_once_with()
mock_keystone_get_session.assert_called_once_with()
if version == "2":
mock_designate.client.Client.assert_called_once_with(
@ -760,13 +770,13 @@ class OSClientsTestCase(test.TestCase):
key += "%s" % {"version": version}
self.assertEqual(fake_designate, self.clients.cache[key])
@mock.patch("rally.osclients.Cue._get_session")
def test_cue(self, mock_cue__get_session):
@mock.patch("rally.osclients.Keystone.get_session")
def test_cue(self, mock_keystone_get_session):
fake_cue = fakes.FakeCueClient()
mock_cue = mock.MagicMock()
mock_cue.client.Client = mock.MagicMock(return_value=fake_cue)
mock_cue__get_session.return_value = ("fake_session",
"fake_auth_plugin")
mock_keystone_get_session.return_value = ("fake_session",
"fake_auth_plugin")
self.assertNotIn("cue", self.clients.cache)
with mock.patch.dict("sys.modules", {"cueclient": mock_cue,
"cueclient.v1": mock_cue}):
@ -794,14 +804,14 @@ class OSClientsTestCase(test.TestCase):
mock_senlin.client.Client.return_value,
self.clients.cache["senlin"])
@mock.patch("rally.osclients.Magnum._get_session")
def test_magnum(self, mock_magnum__get_session):
@mock.patch("rally.osclients.Keystone.get_session")
def test_magnum(self, mock_keystone_get_session):
fake_magnum = fakes.FakeMagnumClient()
mock_magnum = mock.MagicMock()
mock_magnum.client.Client.return_value = fake_magnum
mock_magnum__get_session.return_value = (self.fake_keystone.session,
"fake_auth_plugin")
mock_keystone_get_session.return_value = (self.fake_keystone.session,
"fake_auth_plugin")
self.service_catalog.url_for.return_value = "http://fakeurl/"
self.assertNotIn("magnum", self.clients.cache)
@ -838,7 +848,7 @@ class OSClientsTestCase(test.TestCase):
mock_watcher.client.Client.assert_called_once_with(
"1",
self.service_catalog.url_for.return_value,
token=self.fake_keystone.auth_token,
token=self.auth_ref.auth_token,
ca_file=None,
insecure=False,
timeout=180.0,