Merge "Allows identity endpoint to be specified as URI"
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index d12da44..8429cd0 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -10,18 +10,8 @@
# Ignore SSL certificate validation failures? Use when in testing
# environments that have self-signed SSL certs.
disable_ssl_certificate_validation = False
-# Set to True if your test environment's Keystone authentication service should
-# be accessed over HTTPS
-use_ssl = False
-# This is the main host address of the authentication service API
-host = 127.0.0.1
-# Port that the authentication service API is running on
-port = 5000
-# Version of the authentication service API (a string)
-api_version = v2.0
-# Path to the authentication service tokens resource (do not modify unless you
-# have a custom authentication API and are not using Keystone)
-path = tokens
+# URL for where to find the OpenStack Identity API endpoint (Keystone)
+uri = http://127.0.0.1:5000/v2.0/
# Should typically be left as keystone unless you have a non-Keystone
# authentication API service
strategy = keystone
diff --git a/stress/tools/nova_destroy_all.py b/stress/tools/nova_destroy_all.py
index 21cac11..0070e72 100755
--- a/stress/tools/nova_destroy_all.py
+++ b/stress/tools/nova_destroy_all.py
@@ -24,7 +24,7 @@
compute = tempest.config.TempestConfig().compute
nt = client.Client(compute.username, compute.password,
- compute.tenant_name, identity.auth_url)
+ compute.tenant_name, identity.uri)
flavor_list = nt.flavors.list()
server_list = nt.servers.list()
diff --git a/stress/tools/nova_status.py b/stress/tools/nova_status.py
index d413d7a..f9bc707 100755
--- a/stress/tools/nova_status.py
+++ b/stress/tools/nova_status.py
@@ -23,10 +23,10 @@
identity = tempest.config.TempestConfig().identity
compute = tempest.config.TempestConfig().compute
print compute.username, compute.password,\
- compute.tenant_name, identity.auth_url
+ compute.tenant_name, identity.uri
nt = client.Client(compute.username, compute.password,
- compute.tenant_name, identity.auth_url)
+ compute.tenant_name, identity.uri)
flavor_list = nt.flavors.list()
server_list = nt.servers.list()
diff --git a/tempest/clients.py b/tempest/clients.py
index 245f852..ac163b6 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -166,7 +166,7 @@
"tenant_name: %(tenant_name)s") % locals()
raise exceptions.InvalidConfiguration(msg)
- self.auth_url = self.config.identity.auth_url
+ self.auth_url = self.config.identity.uri
if self.config.identity.strategy == 'keystone':
client_args = (self.config, self.username, self.password,
diff --git a/tempest/common/rest_client.py b/tempest/common/rest_client.py
index 7beef3f..4213b10 100644
--- a/tempest/common/rest_client.py
+++ b/tempest/common/rest_client.py
@@ -116,6 +116,10 @@
Provides authentication via Keystone
"""
+ # Normalize URI to ensure /tokens is in it.
+ if 'tokens' not in auth_url:
+ auth_url = auth_url.rstrip('/') + '/tokens'
+
creds = {
'auth': {
'passwordCredentials': {
diff --git a/tempest/config.py b/tempest/config.py
index 45e8bc4..70b1c79 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -34,21 +34,25 @@
cfg.BoolOpt('disable_ssl_certificate_validation',
default=False,
help="Set to True if using self-signed SSL certificates."),
+ cfg.StrOpt('uri',
+ default=None,
+ help="Full URI of the OpenStack Identity API (Keystone)"),
cfg.StrOpt('host',
default="127.0.0.1",
- help="Host IP for making Identity API requests."),
+ help="(DEPRECATED, use uri) Host IP for making Identity "
+ "API requests."),
cfg.IntOpt('port',
default=8773,
- help="Port for the Identity service."),
+ help="(DEPRECATED, use uri) Port for the Identity service."),
cfg.StrOpt('api_version',
default="v1.1",
- help="Version of the Identity API"),
+ help="(DEPRECATED, use uri) Version of the Identity API"),
cfg.StrOpt('path',
default='/',
- help="Path of API request"),
+ help="(IGNORED) Path of API request"),
cfg.BoolOpt('use_ssl',
default=False,
- help="Specifies if we are using https."),
+ help="(DEPRECATED, use uri) Specifies if we are using https."),
cfg.StrOpt('strategy',
default='keystone',
help="Which auth method does the environment use? "
@@ -64,16 +68,15 @@
for opt in IdentityGroup:
conf.register_opt(opt, group='identity')
+ # Fall back to piecemeal identity URI for legacy support
authurl = data_utils.build_url(conf.identity.host,
str(conf.identity.port),
conf.identity.api_version,
- conf.identity.path,
+ path='', # Ignore path...
use_ssl=conf.identity.use_ssl)
- auth_url = cfg.StrOpt('auth_url',
- default=authurl,
- help="The Identity URL (derived)")
- conf.register_opt(auth_url, group="identity")
+ if not conf.identity.uri:
+ conf.identity.uri = authurl
identity_admin_group = cfg.OptGroup(name='identity-admin',
diff --git a/tempest/manager.py b/tempest/manager.py
index cfe8a5c..8e7cbd1 100644
--- a/tempest/manager.py
+++ b/tempest/manager.py
@@ -126,8 +126,7 @@
"tenant_name: %(tenant_name)s") % locals()
raise exceptions.InvalidConfiguration(msg)
- # Novaclient adds a /tokens/ part to the auth URL automatically
- auth_url = self.config.identity.auth_url.rstrip('tokens')
+ auth_url = self.config.identity.uri
dscv = self.config.identity.disable_ssl_certificate_validation
client_args = (username, password, tenant_name, auth_url)
@@ -166,7 +165,7 @@
"tenant_name: %(tenant_name)s") % locals()
raise exceptions.InvalidConfiguration(msg)
- auth_url = self.config.identity.auth_url.rstrip('tokens')
+ auth_url = self.config.identity.uri
dscv = self.config.identity.disable_ssl_certificate_validation
return keystoneclient.v2_0.client.Client(username=username,
@@ -192,7 +191,7 @@
"tenant_name: %(tenant_name)s") % locals()
raise exceptions.InvalidConfiguration(msg)
- auth_url = self.config.identity.auth_url.rstrip('tokens')
+ auth_url = self.config.identity.uri
dscv = self.config.identity.disable_ssl_certificate_validation
return quantumclient.v2_0.client.Client(username=username,
@@ -233,7 +232,11 @@
"tenant_name: %(tenant_name)s") % locals()
raise exceptions.InvalidConfiguration(msg)
- auth_url = self.config.identity.auth_url
+ auth_url = self.config.identity.uri
+
+ # Ensure /tokens is in the URL for Keystone...
+ if 'tokens' not in auth_url:
+ auth_url = auth_url.rstrip('/') + '/tokens'
if self.config.identity.strategy == 'keystone':
client_args = (self.config, username, password, auth_url,
diff --git a/tempest/services/boto/__init__.py b/tempest/services/boto/__init__.py
index 1365435..83bf1f9 100644
--- a/tempest/services/boto/__init__.py
+++ b/tempest/services/boto/__init__.py
@@ -38,10 +38,6 @@
self.connection_timeout = str(config.boto.http_socket_timeout)
self.num_retries = str(config.boto.num_retries)
self.build_timeout = config.boto.build_timeout
- # We do not need the "path": "/token" part
- if auth_url:
- auth_url = re.sub("(.*)" + re.escape(config.identity.path) + "$",
- "\\1", auth_url)
self.ks_cred = {"username": username,
"password": password,
"auth_url": auth_url,
diff --git a/tempest/services/identity/json/admin_client.py b/tempest/services/identity/json/admin_client.py
index a0da4ca..7b1cb4b 100644
--- a/tempest/services/identity/json/admin_client.py
+++ b/tempest/services/identity/json/admin_client.py
@@ -206,7 +206,14 @@
class TokenClientJSON(RestClient):
def __init__(self, config):
- self.auth_url = config.identity.auth_url
+ auth_url = config.identity.uri
+
+ # TODO(jaypipes) Why is this all repeated code in here?
+ # Normalize URI to ensure /tokens is in it.
+ if 'tokens' not in auth_url:
+ auth_url = auth_url.rstrip('/') + '/tokens'
+
+ self.auth_url = auth_url
self.config = config
def auth(self, user, password, tenant):
diff --git a/tempest/services/identity/xml/admin_client.py b/tempest/services/identity/xml/admin_client.py
index 46a1255..1c71d87 100644
--- a/tempest/services/identity/xml/admin_client.py
+++ b/tempest/services/identity/xml/admin_client.py
@@ -242,7 +242,14 @@
class TokenClientXML(RestClientXML):
def __init__(self, config):
- self.auth_url = config.identity.auth_url
+ auth_url = config.identity.uri
+
+ # TODO(jaypipes) Why is this all repeated code in here?
+ # Normalize URI to ensure /tokens is in it.
+ if 'tokens' not in auth_url:
+ auth_url = auth_url.rstrip('/') + '/tokens'
+
+ self.auth_url = auth_url
self.config = config
def auth(self, user, password, tenant):
diff --git a/tempest/services/image/service.py b/tempest/services/image/service.py
index 3ffdd10..cf4ff4d 100644
--- a/tempest/services/image/service.py
+++ b/tempest/services/image/service.py
@@ -42,8 +42,7 @@
import keystoneclient.v2_0.client
dscv = self.config.identity.disable_ssl_certificate_validation
-
- auth_url = self.config.identity.auth_url.rstrip('tokens')
+ auth_url = self.config.identity.uri
keystone = keystoneclient.v2_0.client.Client(
username=config.images.username,
password=config.images.password,
diff --git a/tempest/tests/compute/admin/test_quotas.py b/tempest/tests/compute/admin/test_quotas.py
index 452de80..eaf245a 100644
--- a/tempest/tests/compute/admin/test_quotas.py
+++ b/tempest/tests/compute/admin/test_quotas.py
@@ -30,7 +30,7 @@
adm_user = cls.config.compute_admin.username
adm_pass = cls.config.compute_admin.password
adm_tenant = cls.config.compute_admin.tenant_name
- auth_url = cls.config.identity.auth_url
+ auth_url = cls.config.identity.uri
cls.adm_client = adm_quotas.AdminQuotasClient(cls.config, adm_user,
adm_pass, auth_url,
diff --git a/tempest/tests/compute/base.py b/tempest/tests/compute/base.py
index 8044d01..c44a2f1 100644
--- a/tempest/tests/compute/base.py
+++ b/tempest/tests/compute/base.py
@@ -89,7 +89,7 @@
cls.config,
cls.config.identity_admin.username,
cls.config.identity_admin.password,
- cls.config.identity.auth_url
+ cls.config.identity.uri
)
@classmethod
diff --git a/tempest/tests/volume/admin/base.py b/tempest/tests/volume/admin/base.py
index 81c7c78..d35efbc 100644
--- a/tempest/tests/volume/admin/base.py
+++ b/tempest/tests/volume/admin/base.py
@@ -35,7 +35,7 @@
cls.adm_user = cls.config.compute_admin.username
cls.adm_pass = cls.config.compute_admin.password
cls.adm_tenant = cls.config.compute_admin.tenant_name
- cls.auth_url = cls.config.identity.auth_url
+ cls.auth_url = cls.config.identity.uri
if not cls.adm_user and cls.adm_pass and cls.adm_tenant:
msg = ("Missing Volume Admin API credentials "
diff --git a/tempest/tests/volume/admin/test_volume_types.py b/tempest/tests/volume/admin/test_volume_types.py
index 65c975a..a907a79 100644
--- a/tempest/tests/volume/admin/test_volume_types.py
+++ b/tempest/tests/volume/admin/test_volume_types.py
@@ -28,7 +28,7 @@
adm_user = cls.config.compute_admin.username
adm_pass = cls.config.compute_admin.password
adm_tenant = cls.config.compute_admin.tenant_name
- auth_url = cls.config.identity.auth_url
+ auth_url = cls.config.identity.uri
cls.client = volume_types_client.VolumeTypesClientJSON(cls.config,
adm_user,
diff --git a/tempest/tests/volume/admin/test_volume_types_extra_specs.py b/tempest/tests/volume/admin/test_volume_types_extra_specs.py
index 9734c42..c5a1fa9 100644
--- a/tempest/tests/volume/admin/test_volume_types_extra_specs.py
+++ b/tempest/tests/volume/admin/test_volume_types_extra_specs.py
@@ -29,7 +29,7 @@
adm_user = cls.config.compute_admin.username
adm_pass = cls.config.compute_admin.password
adm_tenant = cls.config.compute_admin.tenant_name
- auth_url = cls.config.identity.auth_url
+ auth_url = cls.config.identity.uri
cls.client = volume_types_client.VolumeTypesClientJSON(cls.config,
adm_user,
diff --git a/tools/tempest_coverage.py b/tools/tempest_coverage.py
index 73dcfbc..6e7ac04 100755
--- a/tools/tempest_coverage.py
+++ b/tools/tempest_coverage.py
@@ -139,7 +139,7 @@
def main(argv):
CLI = parse_opts(argv)
client_args = (CONF, CONF.compute_admin.username,
- CONF.compute_admin.password, CONF.identity.auth_url,
+ CONF.compute_admin.password, CONF.identity.uri,
CONF.compute_admin.tenant_name)
coverage_client = CoverageClientJSON(*client_args)