Allow user specified endpoint_type in config

* Use user specified endpoint_type (public|internal|admin) for creating
  openstack clients in Rally

Change-Id: I4af74d21417045df966c7fbe1ee735b15a36ae5f
Closes-Bug: #1351567
This commit is contained in:
Rohan Kanade 2014-09-30 12:31:40 +02:00
parent a11b217114
commit b3bfe485bc
13 changed files with 70 additions and 38 deletions

View File

@ -2,7 +2,7 @@
"type": "ExistingCloud",
"auth_url": "http://example.net:5000/v3/",
"region_name": "RegionOne",
"use_public_urls": true,
"endpoint_type": "internal",
"admin_port": 35357,
"admin": {
"username": "admin",

View File

@ -2,7 +2,7 @@
"type": "ExistingCloud",
"auth_url": "http://example.net:5000/v2.0/",
"region_name": "RegionOne",
"use_public_urls": true,
"endpoint_type": "internal",
"admin_port": 35357,
"admin": {
"username": "admin",

View File

@ -62,7 +62,7 @@ This engine in fact does not deploy anything, but uses an existing OpenStack ins
"username": "admin",
"password": "password",
"tenant_name": "admin",
"use_public_urls": True
"endpoint_type": "internal"
}
}
@ -80,14 +80,14 @@ Or using keystone v3 API endpoint:
"project_domain_name": "qa,
"password": "password,
"region_name": "RegionOne,
"use_public_urls": False,
"endpoint_type": "internal",
"admin_port": 35357
}
}
..
*use_public_urls* option will be used later for switching access method to the cloud.
Because in some use-cases cloud may be accessible only by public endpoints.
*endpoint_type* option will be used later for selecting access method to the cloud.
Users can select from "public", "internal", "admin" access methods.

View File

@ -172,7 +172,7 @@ class DeploymentCommands(object):
:param deploy_id: a UUID of the deployment
"""
headers = ['auth_url', 'username', 'password', 'tenant_name',
'region_name', 'use_public_urls', 'admin_port']
'region_name', 'endpoint_type', 'admin_port']
table_rows = []
deployment = db.deployment_get(deploy_id)

View File

@ -68,6 +68,12 @@ class _EndpointPermission(utils.ImmutableMixin, utils.EnumMixin):
USER = "user"
class _EndpointType(utils.ImmutableMixin, utils.EnumMixin):
INTERNAL = "internal"
ADMIN = "admin"
PUBLIC = "public"
class _RunnerType(utils.ImmutableMixin, utils.EnumMixin):
SERIAL = "serial"
CONSTANT = "constant"
@ -148,3 +154,4 @@ EndpointPermission = _EndpointPermission()
RunnerType = _RunnerType()
ServiceType = _ServiceType()
Service = _Service()
EndpointType = _EndpointType()

View File

@ -27,7 +27,7 @@ class ExistingCloud(engine.EngineFactory):
"type": "ExistingCloud",
"auth_url": "http://localhost:5000/v2.0/",
"region_name": "RegionOne",
"use_public_urls": true,
"endpoint_type": "admin",
"admin_port": 35357,
"admin": {
"username": "admin",
@ -42,7 +42,7 @@ class ExistingCloud(engine.EngineFactory):
"type": "ExistingCloud",
"auth_url": "http://localhost:5000/v3/",
"region_name": "RegionOne",
"use_public_urls": false,
"endpoint_type": "admin",
"admin_port": 35357,
"admin": {
"username": "admin",
@ -89,7 +89,10 @@ class ExistingCloud(engine.EngineFactory):
"type": {"type": "string"},
"auth_url": {"type": "string"},
"region_name": {"type": "string"},
"use_public_urls": {"type": "boolean"},
"endpoint_type": {"type": "string",
"enum": [consts.EndpointType.ADMIN,
consts.EndpointType.INTERNAL,
consts.EndpointType.PUBLIC]},
"admin_port": {
"type": "integer",
"minimum": 2,
@ -119,7 +122,8 @@ class ExistingCloud(engine.EngineFactory):
tenant_name=user.get("project_name", user.get("tenant_name")),
permission=permission,
region_name=common.get("region_name"),
use_public_urls=common.get("use_public_urls", False),
endpoint_type=common.get("endpoint_type",
consts.EndpointType.INTERNAL),
admin_port=common.get("admin_port", 35357),
domain_name=user.get("domain_name"),
user_domain_name=user.get("user_domain_name", "Default"),

View File

@ -20,8 +20,9 @@ class Endpoint(object):
def __init__(self, auth_url, username, password, tenant_name=None,
permission=consts.EndpointPermission.USER,
region_name=None, use_public_urls=False, admin_port=35357,
domain_name=None, user_domain_name='Default',
region_name=None, endpoint_type=consts.EndpointType.INTERNAL,
admin_port=35357, domain_name=None,
user_domain_name='Default',
project_domain_name='Default'):
self.auth_url = auth_url
self.username = username
@ -29,7 +30,7 @@ class Endpoint(object):
self.tenant_name = tenant_name
self.permission = permission
self.region_name = region_name
self.use_public_urls = use_public_urls
self.endpoint_type = endpoint_type
self.admin_port = admin_port
self.domain_name = domain_name
self.user_domain_name = user_domain_name
@ -39,7 +40,7 @@ class Endpoint(object):
dct = {"auth_url": self.auth_url, "username": self.username,
"password": self.password, "tenant_name": self.tenant_name,
"region_name": self.region_name,
"use_public_urls": self.use_public_urls,
"endpoint_type": self.endpoint_type,
"admin_port": self.admin_port,
"domain_name": self.domain_name,
"user_domain_name": self.user_domain_name,

View File

@ -97,7 +97,7 @@ class Clients(object):
"insecure": CONF.https_insecure, "cacert": CONF.https_cacert
}
kw = dict(self.endpoint.to_dict().items() + new_kw.items())
if kw["use_public_urls"]:
if kw["endpoint_type"] == consts.EndpointType.PUBLIC:
mgmt_url = urlparse.urlparse(kw["auth_url"])
if mgmt_url.port != kw["admin_port"]:
kw["endpoint"] = "{0}://{1}:{2}{3}".format(
@ -136,7 +136,8 @@ class Clients(object):
"""Return nova client."""
kc = self.keystone()
compute_api_url = kc.service_catalog.url_for(
service_type='compute', endpoint_type='public',
service_type='compute',
endpoint_type=self.endpoint.endpoint_type,
region_name=self.endpoint.region_name)
client = nova.Client(version,
auth_token=kc.auth_token,
@ -152,7 +153,8 @@ class Clients(object):
"""Return neutron client."""
kc = self.keystone()
network_api_url = kc.service_catalog.url_for(
service_type='network', endpoint_type='public',
service_type='network',
endpoint_type=self.endpoint.endpoint_type,
region_name=self.endpoint.region_name)
client = neutron.Client(version,
token=kc.auth_token,
@ -167,7 +169,8 @@ class Clients(object):
"""Return glance client."""
kc = self.keystone()
image_api_url = kc.service_catalog.url_for(
service_type='image', endpoint_type='public',
service_type='image',
endpoint_type=self.endpoint.endpoint_type,
region_name=self.endpoint.region_name)
client = glance.Client(version,
endpoint=image_api_url,
@ -182,7 +185,8 @@ class Clients(object):
"""Return heat client."""
kc = self.keystone()
orchestration_api_url = kc.service_catalog.url_for(
service_type='orchestration', endpoint_type='public',
service_type='orchestration',
endpoint_type=self.endpoint.endpoint_type,
region_name=self.endpoint.region_name)
client = heat.Client(version,
endpoint=orchestration_api_url,
@ -202,7 +206,8 @@ class Clients(object):
cacert=CONF.https_cacert)
kc = self.keystone()
volume_api_url = kc.service_catalog.url_for(
service_type='volume', endpoint_type='public',
service_type='volume',
endpoint_type=self.endpoint.endpoint_type,
region_name=self.endpoint.region_name)
client.client.management_url = volume_api_url
client.client.auth_token = kc.auth_token
@ -213,7 +218,8 @@ class Clients(object):
"""Return ceilometer client."""
kc = self.keystone()
metering_api_url = kc.service_catalog.url_for(
service_type='metering', endpoint_type='public',
service_type='metering',
endpoint_type=self.endpoint.endpoint_type,
region_name=self.endpoint.region_name)
auth_token = kc.auth_token
if not hasattr(auth_token, '__call__'):
@ -233,7 +239,8 @@ class Clients(object):
"""Return Ironic client."""
kc = self.keystone()
baremetal_api_url = kc.service_catalog.url_for(
service_type='baremetal', endpoint_type='public',
service_type='baremetal',
endpoint_type=self.endpoint.endpoint_type,
region_name=self.endpoint.region_name)
client = ironic.get_client(version,
os_auth_token=kc.auth_token,
@ -259,7 +266,8 @@ class Clients(object):
"""Return Zaqar client."""
kc = self.keystone()
messaging_api_url = kc.service_catalog.url_for(
service_type='messaging', endpoint_type='public',
service_type='messaging',
endpoint_type=self.endpoint.endpoint_type,
region_name=self.endpoint.region_name)
conf = {'auth_opts': {'backend': 'keystone', 'options': {
'os_username': self.endpoint.username,
@ -278,7 +286,8 @@ class Clients(object):
"""Return designate client."""
kc = self.keystone()
dns_api_url = kc.service_catalog.url_for(
service_type='dns', endpoint_type='public',
service_type='dns',
endpoint_type=self.endpoint.endpoint_type,
region_name=self.endpoint.region_name)
client = designate.Client(
endpoint=dns_api_url,

View File

@ -18,6 +18,7 @@ import os
import mock
from rally.cmd.commands import deployment
from rally import consts
from rally import exceptions
from tests import test
@ -201,7 +202,7 @@ class DeploymentCommandsTestCase(test.TestCase):
"password": "p",
"tenant_name": "t",
"region_name": "r",
"use_public_urls": "upu",
"endpoint_type": consts.EndpointType.INTERNAL,
"admin_port": "ap"
},
"users": []
@ -211,8 +212,9 @@ class DeploymentCommandsTestCase(test.TestCase):
mock_deployment.assert_called_once_with(deploy_id)
headers = ["auth_url", "username", "password", "tenant_name",
"region_name", "use_public_urls", "admin_port"]
fake_data = ["url", "u", "p", "t", "r", "upu", "ap"]
"region_name", "endpoint_type", "admin_port"]
fake_data = ["url", "u", "p", "t", "r", consts.EndpointType.INTERNAL,
"ap"]
mock_struct.assert_called_once_with(**dict(zip(headers, fake_data)))
mock_print_list.assert_called_once_with([mock_struct()], headers)

View File

@ -17,6 +17,7 @@
import jsonschema
from rally import consts
from rally import deploy
from rally.deploy.engines import existing
from tests import test
@ -30,7 +31,7 @@ class TestExistingCloud(test.TestCase):
"type": "ExistingCloud",
"auth_url": "http://example.net:5000/v2.0/",
"region_name": "RegionOne",
"use_public_urls": False,
"endpoint_type": consts.EndpointType.INTERNAL,
"admin_port": 35357,
"admin": {
"username": "admin",

View File

@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
from rally import consts
from rally import objects
from tests import test
@ -25,7 +26,8 @@ class EndpointTestCase(test.TestCase):
{"auth_url": "url", "username": "user",
"password": "pwd", "tenant_name": "tenant",
"region_name": None, "permission": "admin",
"domain_name": None, "use_public_urls": False,
"domain_name": None,
"endpoint_type": consts.EndpointType.INTERNAL,
"project_domain_name": "Default",
"user_domain_name": "Default",
'admin_port': 35357})

View File

@ -37,7 +37,7 @@ FAKE_DEPLOY_CONFIG = {
"user_domain_name": "Default"
},
"region_name": "RegionOne",
"use_public_urls": False,
"endpoint_type": consts.EndpointType.INTERNAL,
"admin_port": 35357
}

View File

@ -85,7 +85,8 @@ class OSClientsTestCase(test.TestCase):
client = self.clients.nova()
self.assertEqual(client, fake_nova)
self.service_catalog.url_for.assert_called_once_with(
service_type='compute', endpoint_type='public',
service_type='compute',
endpoint_type=consts.EndpointType.INTERNAL,
region_name=self.endpoint.region_name)
mock_nova.Client.assert_called_once_with(
"2",
@ -112,7 +113,7 @@ class OSClientsTestCase(test.TestCase):
"ca_cert": cfg.CONF.https_cacert
}
self.service_catalog.url_for.assert_called_once_with(
service_type='network', endpoint_type='public',
service_type='network', endpoint_type=consts.EndpointType.INTERNAL,
region_name=self.endpoint.region_name)
mock_neutron.Client.assert_called_once_with("2.0", **kw)
self.assertEqual(self.clients.cache["neutron"], fake_neutron)
@ -129,7 +130,8 @@ class OSClientsTestCase(test.TestCase):
"timeout": cfg.CONF.openstack_client_http_timeout,
"insecure": False, "cacert": None}
self.service_catalog.url_for.assert_called_once_with(
service_type='image', endpoint_type='public',
service_type='image',
endpoint_type=consts.EndpointType.INTERNAL,
region_name=self.endpoint.region_name)
mock_glance.Client.assert_called_once_with("1", **kw)
self.assertEqual(self.clients.cache["glance"], fake_glance)
@ -143,7 +145,8 @@ class OSClientsTestCase(test.TestCase):
client = self.clients.cinder()
self.assertEqual(client, fake_cinder)
self.service_catalog.url_for.assert_called_once_with(
service_type='volume', endpoint_type='public',
service_type='volume',
endpoint_type=consts.EndpointType.INTERNAL,
region_name=self.endpoint.region_name)
mock_cinder.Client.assert_called_once_with(
"1", None, None, http_log_debug=False,
@ -164,7 +167,8 @@ class OSClientsTestCase(test.TestCase):
client = self.clients.ceilometer()
self.assertEqual(client, fake_ceilometer)
self.service_catalog.url_for.assert_called_once_with(
service_type='metering', endpoint_type='public',
service_type='metering',
endpoint_type=consts.EndpointType.INTERNAL,
region_name=self.endpoint.region_name)
kw = {"endpoint": self.service_catalog.url_for.return_value,
"token": self.fake_keystone.auth_token,
@ -182,7 +186,8 @@ class OSClientsTestCase(test.TestCase):
client = self.clients.ironic()
self.assertEqual(client, fake_ironic)
self.service_catalog.url_for.assert_called_once_with(
service_type='baremetal', endpoint_type='public',
service_type='baremetal',
endpoint_type=consts.EndpointType.INTERNAL,
region_name=self.endpoint.region_name)
kw = {
"os_auth_token": self.fake_keystone.auth_token,
@ -218,7 +223,8 @@ class OSClientsTestCase(test.TestCase):
client = self.clients.zaqar()
self.assertEqual(client, fake_zaqar)
self.service_catalog.url_for.assert_called_once_with(
service_type='messaging', endpoint_type='public',
service_type='messaging',
endpoint_type=consts.EndpointType.INTERNAL,
region_name=self.endpoint.region_name)
fake_zaqar_url = self.service_catalog.url_for.return_value
conf = {'auth_opts': {'backend': 'keystone', 'options': {