Support for benchmarking with existing users (part 1)

This patch covers next topics:

1) Changes db deploymnet model to store admin endpoint and list of
   non-admin users

2) Changes objects.deployment to have this admin and users instead of
   endpoints

3) Changes input format of ExistingCloud engine, to make it easy to
   pass users & admins

4) Changes engine.bind method to accept admin and list of users

5) Code cleanup related to removing list of endpoints and making
   admin/non-admin stuff

6) Fix CLI code related to deployment model change

7) Fix docs & samples

8) Fixing all related tests

In next patch we should drop default "users" context and use users
from deployment if they are passed.

Change-Id: Ifb469d80c61ee5f26f313db75c98a6d496bcdb92
This commit is contained in:
Boris Pavlovic 2014-08-26 06:36:26 +04:00
parent c3892e190f
commit 296558a05e
28 changed files with 447 additions and 338 deletions

View File

@ -62,8 +62,8 @@ function _create_deployment_config() {
cat >$1 <<EOF cat >$1 <<EOF
{ {
"type": "ExistingCloud", "type": "ExistingCloud",
"endpoint": { "auth_url": "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v$IDENTITY_API_VERSION",
"auth_url": "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v$IDENTITY_API_VERSION", "admin": {
"username": "admin", "username": "admin",
"password": "$ADMIN_PASSWORD", "password": "$ADMIN_PASSWORD",
"tenant_name": "benchmark" "tenant_name": "benchmark"

View File

@ -0,0 +1,14 @@
{
"type": "ExistingCloud",
"auth_url": "http://example.net:5000/v3/",
"region_name": "RegionOne",
"use_public_urls": true,
"admin_port": 35357,
"admin": {
"username": "admin",
"password": "myadminpass",
"user_domain_name": "admin",
"project_name": "admin",
"project_domain_name": "admin",
}
}

View File

@ -1,7 +1,10 @@
{ {
"type": "ExistingCloud", "type": "ExistingCloud",
"endpoint": { "auth_url": "http://example.net:5000/v2.0/",
"auth_url": "http://example.net:5000/v2.0/", "region_name": "RegionOne",
"use_public_urls": true,
"admin_port": 35357,
"admin": {
"username": "admin", "username": "admin",
"password": "myadminpass", "password": "myadminpass",
"tenant_name": "demo" "tenant_name": "demo"

View File

@ -82,8 +82,10 @@ class BenchmarkEngine(object):
... ...
benchmark_engine = BenchmarkEngine(config, task) benchmark_engine = BenchmarkEngine(config, task)
# Deploying the cloud... # Deploying the cloud...
# endpoint - is a dict with data on endpoint of deployed cloud # admin - is an objects.Endpoint that actually presents admin user
with benchmark_engine.bind(endpoints): # users - is a list of objects.Endpoint that actually presents list
of users.
with benchmark_engine.bind(admin=admin, users=users):
benchmark_engine.run() benchmark_engine.run()
""" """
@ -173,7 +175,8 @@ class BenchmarkEngine(object):
def _get_runner(self, config): def _get_runner(self, config):
runner = config.get("runner", {}) runner = config.get("runner", {})
runner.setdefault("type", consts.RunnerType.SERIAL) runner.setdefault("type", consts.RunnerType.SERIAL)
return base_runner.ScenarioRunner.get_runner(self.task, self.endpoints, return base_runner.ScenarioRunner.get_runner(self.task,
self.admin_endpoint,
runner) runner)
@rutils.log_task_wrapper(LOG.info, _("Benchmarking.")) @rutils.log_task_wrapper(LOG.info, _("Benchmarking."))
@ -203,15 +206,17 @@ class BenchmarkEngine(object):
self.task.update_status(consts.TaskStatus.FINISHED) self.task.update_status(consts.TaskStatus.FINISHED)
@rutils.log_task_wrapper(LOG.info, _("Check cloud.")) @rutils.log_task_wrapper(LOG.info, _("Check cloud."))
def bind(self, endpoints): def bind(self, admin=None, users=None):
self.endpoints = [endpoint.Endpoint(**endpoint_dict) """Bind benchmark engine to OpenStack cloud.
for endpoint_dict in endpoints]
# NOTE(msdubov): Passing predefined user endpoints hasn't been This method will set self.admin_endpoint with passed values,
# implemented yet, so the scenario runner always gets as well it will check that admin user is actually admin.
# a single admin endpoint here.
self.admin_endpoint = self.endpoints[0] :param admin: admin credentials
self.admin_endpoint.permission = consts.EndpointPermission.ADMIN :param users: List of users credentials
# Try to access cloud via keystone client :returns: self
"""
self.admin_endpoint = endpoint.Endpoint(**admin)
clients = osclients.Clients(self.admin_endpoint) clients = osclients.Clients(self.admin_endpoint)
clients.verified_keystone() clients.verified_keystone()
return self return self

View File

@ -154,13 +154,18 @@ class ScenarioRunner(object):
CONFIG_SCHEMA = {} CONFIG_SCHEMA = {}
def __init__(self, task, endpoints, config): def __init__(self, task, admin, config):
"""Runner constructor.
It sets task, admin and config to local variables. Also initialize
result_queue, where results will be put by _send_result method.
:param task: Instance of objects.Task
:param admin: Instance of objects.Endpoint
:param config: Dict with runner section from benchmark configuration
"""
self.task = task self.task = task
self.endpoints = endpoints self.admin_user = admin
# NOTE(msdubov): Passing predefined user endpoints hasn't been
# implemented yet, so the scenario runner always gets
# a single admin endpoint here.
self.admin_user = endpoints[0]
self.config = config self.config = config
self.result_queue = collections.deque() self.result_queue = collections.deque()
@ -172,9 +177,15 @@ class ScenarioRunner(object):
raise exceptions.NoSuchRunner(type=runner_type) raise exceptions.NoSuchRunner(type=runner_type)
@staticmethod @staticmethod
def get_runner(task, endpoint, config): def get_runner(task, admin, config):
"""Returns instance of a scenario runner for execution type.""" """Returns instance of a scenario runner for execution type.
return ScenarioRunner._get_cls(config["type"])(task, endpoint, config)
:param task: instance of objects.Task corresponding to current task
:param admin: endpoint instance with admin credentials.
:param config: contents of "runner" section from task configuration
for specific benchmark
"""
return ScenarioRunner._get_cls(config["type"])(task, admin, config)
@staticmethod @staticmethod
def validate(config): def validate(config):

View File

@ -70,8 +70,8 @@ class DeploymentCommands(object):
config = { config = {
"type": "ExistingCloud", "type": "ExistingCloud",
"endpoint": { "auth_url": os.environ['OS_AUTH_URL'],
"auth_url": os.environ['OS_AUTH_URL'], "admin": {
"username": os.environ['OS_USERNAME'], "username": os.environ['OS_USERNAME'],
"password": os.environ['OS_PASSWORD'], "password": os.environ['OS_PASSWORD'],
"tenant_name": os.environ['OS_TENANT_NAME'] "tenant_name": os.environ['OS_TENANT_NAME']
@ -79,7 +79,7 @@ class DeploymentCommands(object):
} }
region_name = os.environ.get('OS_REGION_NAME') region_name = os.environ.get('OS_REGION_NAME')
if region_name and region_name != 'None': if region_name and region_name != 'None':
config['endpoint']['region_name'] = region_name config['region_name'] = region_name
else: else:
if not filename: if not filename:
print("Either --filename or --fromenv is required") print("Either --filename or --fromenv is required")
@ -167,14 +167,19 @@ class DeploymentCommands(object):
help='UUID of a deployment.') help='UUID of a deployment.')
@envutils.with_default_deploy_id @envutils.with_default_deploy_id
def endpoint(self, deploy_id=None): def endpoint(self, deploy_id=None):
"""Print endpoint of the deployment. """Print all endpoints of the deployment.
:param deploy_id: a UUID of the deployment :param deploy_id: a UUID of the deployment
""" """
headers = ['auth_url', 'username', 'password', 'tenant_name', headers = ['auth_url', 'username', 'password', 'tenant_name',
'region_name', 'use_public_urls', 'admin_port'] 'region_name', 'use_public_urls', 'admin_port']
table_rows = [] table_rows = []
endpoints = db.deployment_get(deploy_id)['endpoints']
deployment = db.deployment_get(deploy_id)
users = deployment.get("users", [])
admin = deployment.get("admin")
endpoints = users + [admin] if admin else users
for ep in endpoints: for ep in endpoints:
data = [ep.get(m, '') for m in headers] data = [ep.get(m, '') for m in headers]
table_rows.append(utils.Struct(**dict(zip(headers, data)))) table_rows.append(utils.Struct(**dict(zip(headers, data))))
@ -193,8 +198,9 @@ class DeploymentCommands(object):
headers = ['services', 'type', 'status'] headers = ['services', 'type', 'status']
table_rows = [] table_rows = []
try: try:
endpoints = db.deployment_get(deploy_id)['endpoints'] admin = db.deployment_get(deploy_id)['admin']
for endpoint_dict in endpoints: # TODO(boris-42): make this work for users in future
for endpoint_dict in [admin]:
clients = osclients.Clients(endpoint.Endpoint(**endpoint_dict)) clients = osclients.Clients(endpoint.Endpoint(**endpoint_dict))
client = clients.verified_keystone() client = clients.verified_keystone()
print("keystone endpoints are valid and following " print("keystone endpoints are valid and following "

View File

@ -17,20 +17,26 @@
from __future__ import print_function from __future__ import print_function
import sys
from rally.cmd import cliutils from rally.cmd import cliutils
from rally.cmd import envutils from rally.cmd import envutils
from rally import db from rally import db
from rally import exceptions from rally import exceptions
from rally.objects import endpoint from rally.objects import endpoint
from rally.openstack.common import cliutils as common_cliutils from rally.openstack.common import cliutils as common_cliutils
from rally.openstack.common.gettextutils import _
from rally import osclients from rally import osclients
from rally import utils from rally import utils
class ShowCommands(object): class ShowCommands(object):
def _get_endpoints(self, deploy_id):
deployment = db.deployment_get(deploy_id)
admin = deployment.get("admin")
admin = [admin] if admin else []
return admin + deployment.get("users", [])
@cliutils.args('--deploy-id', dest='deploy_id', type=str, required=False, @cliutils.args('--deploy-id', dest='deploy_id', type=str, required=False,
help='the UUID of a deployment') help='the UUID of a deployment')
@envutils.with_default_deploy_id @envutils.with_default_deploy_id
@ -46,22 +52,23 @@ class ShowCommands(object):
formatters = dict(zip(float_cols, formatters = dict(zip(float_cols,
[cliutils.pretty_float_formatter(col) [cliutils.pretty_float_formatter(col)
for col in float_cols])) for col in float_cols]))
try: try:
endpoints = db.deployment_get(deploy_id)['endpoints'] for endpoint_dict in self._get_endpoints(deploy_id):
for endpoint_dict in endpoints:
clients = osclients.Clients(endpoint.Endpoint(**endpoint_dict)) clients = osclients.Clients(endpoint.Endpoint(**endpoint_dict))
glance_client = clients.glance() glance_client = clients.glance()
for image in glance_client.images.list(): for image in glance_client.images.list():
data = [image.id, image.name, image.size] data = [image.id, image.name, image.size]
table_rows.append(utils.Struct(**dict(zip(headers, data)))) table_rows.append(utils.Struct(**dict(zip(headers, data))))
except exceptions.InvalidArgumentsException: common_cliutils.print_list(table_rows,
print(_("Authentication Issues: %s") % sys.exc_info()[1]) fields=headers,
formatters=formatters,
mixed_case_fields=mixed_case_fields)
except exceptions.InvalidArgumentsException as e:
print(_("Authentication Issues: %s") % e)
return(1) return(1)
common_cliutils.print_list(table_rows,
fields=headers,
formatters=formatters,
mixed_case_fields=mixed_case_fields)
@cliutils.args('--deploy-id', dest='deploy_id', type=str, required=False, @cliutils.args('--deploy-id', dest='deploy_id', type=str, required=False,
help='the UUID of a deployment') help='the UUID of a deployment')
@ -79,8 +86,7 @@ class ShowCommands(object):
for col in float_cols])) for col in float_cols]))
table_rows = [] table_rows = []
try: try:
endpoints = db.deployment_get(deploy_id)['endpoints'] for endpoint_dict in self._get_endpoints(deploy_id):
for endpoint_dict in endpoints:
clients = osclients.Clients(endpoint.Endpoint(**endpoint_dict)) clients = osclients.Clients(endpoint.Endpoint(**endpoint_dict))
nova_client = clients.nova() nova_client = clients.nova()
for flavor in nova_client.flavors.list(): for flavor in nova_client.flavors.list():
@ -88,13 +94,14 @@ class ShowCommands(object):
flavor.ram, flavor.swap, flavor.disk] flavor.ram, flavor.swap, flavor.disk]
table_rows.append(utils.Struct(**dict(zip(headers, data)))) table_rows.append(utils.Struct(**dict(zip(headers, data))))
except exceptions.InvalidArgumentsException: common_cliutils.print_list(table_rows,
print(_("Authentication Issues: %s") % sys.exc_info()[1]) fields=headers,
formatters=formatters,
mixed_case_fields=mixed_case_fields)
except exceptions.InvalidArgumentsException as e:
print(_("Authentication Issues: %s") % e)
return(1) return(1)
common_cliutils.print_list(table_rows,
fields=headers,
formatters=formatters,
mixed_case_fields=mixed_case_fields)
@cliutils.args('--deploy-id', dest='deploy_id', type=str, required=False, @cliutils.args('--deploy-id', dest='deploy_id', type=str, required=False,
help='the UUID of a deployment') help='the UUID of a deployment')
@ -104,19 +111,19 @@ class ShowCommands(object):
mixed_case_fields = ['ID', 'Label', 'CIDR'] mixed_case_fields = ['ID', 'Label', 'CIDR']
table_rows = [] table_rows = []
try: try:
endpoints = db.deployment_get(deploy_id)['endpoints'] for endpoint_dict in self._get_endpoints(deploy_id):
for endpoint_dict in endpoints:
clients = osclients.Clients(endpoint.Endpoint(**endpoint_dict)) clients = osclients.Clients(endpoint.Endpoint(**endpoint_dict))
nova_client = clients.nova() nova_client = clients.nova()
for network in nova_client.networks.list(): for network in nova_client.networks.list():
data = [network.id, network.label, network.cidr] data = [network.id, network.label, network.cidr]
table_rows.append(utils.Struct(**dict(zip(headers, data)))) table_rows.append(utils.Struct(**dict(zip(headers, data))))
except exceptions.InvalidArgumentsException:
print(_("Authentication Issues: %s") % sys.exc_info()[1]) common_cliutils.print_list(table_rows,
fields=headers,
mixed_case_fields=mixed_case_fields)
except exceptions.InvalidArgumentsException as e:
print(_("Authentication Issues: %s") % e)
return(1) return(1)
common_cliutils.print_list(table_rows,
fields=headers,
mixed_case_fields=mixed_case_fields)
@cliutils.args('--deploy-id', dest='deploy_id', type=str, required=False, @cliutils.args('--deploy-id', dest='deploy_id', type=str, required=False,
help='the UUID of a deployment') help='the UUID of a deployment')
@ -126,8 +133,7 @@ class ShowCommands(object):
mixed_case_fields = ['ID', 'Name', 'Description'] mixed_case_fields = ['ID', 'Name', 'Description']
table_rows = [] table_rows = []
try: try:
endpoints = db.deployment_get(deploy_id)['endpoints'] for endpoint_dict in self._get_endpoints(deploy_id):
for endpoint_dict in endpoints:
clients = osclients.Clients(endpoint.Endpoint(**endpoint_dict)) clients = osclients.Clients(endpoint.Endpoint(**endpoint_dict))
nova_client = clients.nova() nova_client = clients.nova()
for secgroup in nova_client.security_groups.list(): for secgroup in nova_client.security_groups.list():
@ -135,12 +141,14 @@ class ShowCommands(object):
secgroup.description] secgroup.description]
table_rows.append(utils.Struct(**dict(zip(headers, table_rows.append(utils.Struct(**dict(zip(headers,
data)))) data))))
except exceptions.InvalidArgumentsException: common_cliutils.print_list(
print(_("Authentication Issues: %s") % sys.exc_info()[1]) table_rows,
fields=headers,
mixed_case_fields=mixed_case_fields)
except exceptions.InvalidArgumentsException as e:
print(_("Authentication Issues: %s") % e)
return(1) return(1)
common_cliutils.print_list(table_rows,
fields=headers,
mixed_case_fields=mixed_case_fields)
@cliutils.args('--deploy-id', dest='deploy_id', type=str, required=False, @cliutils.args('--deploy-id', dest='deploy_id', type=str, required=False,
help='the UUID of a deployment') help='the UUID of a deployment')
@ -150,16 +158,16 @@ class ShowCommands(object):
mixed_case_fields = ['Name', 'Fingerprint'] mixed_case_fields = ['Name', 'Fingerprint']
table_rows = [] table_rows = []
try: try:
endpoints = db.deployment_get(deploy_id)['endpoints'] for endpoint_dict in self._get_endpoints(deploy_id):
for endpoint_dict in endpoints:
clients = osclients.Clients(endpoint.Endpoint(**endpoint_dict)) clients = osclients.Clients(endpoint.Endpoint(**endpoint_dict))
nova_client = clients.nova() nova_client = clients.nova()
for keypair in nova_client.keypairs.list(): for keypair in nova_client.keypairs.list():
data = [keypair.name, keypair.fingerprint] data = [keypair.name, keypair.fingerprint]
table_rows.append(utils.Struct(**dict(zip(headers, data)))) table_rows.append(utils.Struct(**dict(zip(headers, data))))
except exceptions.InvalidArgumentsException: common_cliutils.print_list(table_rows,
print(_("Authentication Issues: %s") % sys.exc_info()[1]) fields=headers,
mixed_case_fields=mixed_case_fields)
except exceptions.InvalidArgumentsException as e:
print(_("Authentication Issues: %s") % e)
return(1) return(1)
common_cliutils.print_list(table_rows,
fields=headers,
mixed_case_fields=mixed_case_fields)

View File

@ -25,23 +25,18 @@ from rally import fileutils
class UseCommands(object): class UseCommands(object):
def _update_openrc_deployment_file(self, deploy_id, endpoints): def _update_openrc_deployment_file(self, deploy_id, endpoint):
openrc_path = os.path.expanduser('~/.rally/openrc-%s' % deploy_id) openrc_path = os.path.expanduser('~/.rally/openrc-%s' % deploy_id)
# NOTE(msdubov): In case of multiple endpoints write the first one. # NOTE(msdubov): In case of multiple endpoints write the first one.
with open(openrc_path, 'w+') as env_file: with open(openrc_path, 'w+') as env_file:
if endpoints[0].get('region_name'): env_file.write('export OS_AUTH_URL=%(auth_url)s\n'
env_file.write('export OS_AUTH_URL=%(auth_url)s\n' 'export OS_USERNAME=%(username)s\n'
'export OS_USERNAME=%(username)s\n' 'export OS_PASSWORD=%(password)s\n'
'export OS_PASSWORD=%(password)s\n' 'export OS_TENANT_NAME=%(tenant_name)s\n'
'export OS_TENANT_NAME=%(tenant_name)s\n' % endpoint)
'export OS_REGION_NAME=%(region_name)s\n' if endpoint.get('region_name'):
% endpoints[0]) env_file.write('export OS_REGION_NAME=%(region_name)s\n'
else: % endpoint)
env_file.write('export OS_AUTH_URL=%(auth_url)s\n'
'export OS_USERNAME=%(username)s\n'
'export OS_PASSWORD=%(password)s\n'
'export OS_TENANT_NAME=%(tenant_name)s\n'
% endpoints[0])
expanded_path = os.path.expanduser('~/.rally/openrc') expanded_path = os.path.expanduser('~/.rally/openrc')
if os.path.exists(expanded_path): if os.path.exists(expanded_path):
os.remove(expanded_path) os.remove(expanded_path)
@ -88,8 +83,8 @@ class UseCommands(object):
self._ensure_rally_configuration_dir_exists() self._ensure_rally_configuration_dir_exists()
self._update_attribute_in_global_file('RALLY_DEPLOYMENT', self._update_attribute_in_global_file('RALLY_DEPLOYMENT',
deploy_id) deploy_id)
self._update_openrc_deployment_file(deploy_id, self._update_openrc_deployment_file(
deploy['endpoints']) deploy_id, deploy.get('admin') or deploy.get('users')[0])
print ('~/.rally/openrc was updated\n\nHINTS:\n' print ('~/.rally/openrc was updated\n\nHINTS:\n'
'* To get your cloud resources, run:\n\t' '* To get your cloud resources, run:\n\t'
'rally show [flavors|images|keypairs|networks|secgroups]\n' 'rally show [flavors|images|keypairs|networks|secgroups]\n'

View File

@ -76,14 +76,11 @@ class Deployment(BASE, RallyBase):
nullable=False, nullable=False,
) )
# TODO(akscram): Actually a endpoint of a deployment can be # NOTE(boris-42): This is pickled rally.object.Endpoint object
# represented by a set of parameters are auth_url, admin = sa.Column(types.PickleType, nullable=True)
# user, password and project.
endpoints = sa.Column( # NOTE(boris-42): This is list of pickled rally.object.Endpoint objects
types.PickleType, users = sa.Column(types.PickleType, default=[], nullable=False)
default=[],
nullable=False,
)
status = sa.Column( status = sa.Column(
sa.Enum(*consts.DeployStatus), sa.Enum(*consts.DeployStatus),

View File

@ -116,7 +116,7 @@ class DevstackEngine(engine.EngineFactory):
self.localrc['ADMIN_PASSWORD'], self.localrc['ADMIN_PASSWORD'],
'admin', 'admin',
consts.EndpointPermission.ADMIN) consts.EndpointPermission.ADMIN)
return [admin_endpoint] return {"admin": admin_endpoint}
def cleanup(self): def cleanup(self):
for resource in self.deployment.get_resources(type='credentials'): for resource in self.deployment.get_resources(type='credentials'):

View File

@ -19,20 +19,20 @@ from rally import objects
class ExistingCloud(engine.EngineFactory): class ExistingCloud(engine.EngineFactory):
"""ExistingCloud doesn't deploy OpenStack it just use existing. """ExistingCloud doesn't deploy OpenStack it just use existing cloud.
To use ExistingCloud you should put in a config endpoint key, e.g: To use ExistingCloud you should put in a config endpoint key, e.g:
{ {
"type": "ExistingCloud", "type": "ExistingCloud",
"endpoint": { "auth_url": "http://localhost:5000/v2.0/",
"auth_url": "http://localhost:5000/v2.0/", "region_name": "RegionOne",
"use_public_urls": true,
"admin_port": 35357
"admin": {
"username": "admin", "username": "admin",
"password": "password", "password": "password",
"tenant_name": "demo", "tenant_name": "demo",
"region_name": "RegionOne",
"use_public_urls": True,
"admin_port": 35357
} }
} }
@ -40,83 +40,103 @@ class ExistingCloud(engine.EngineFactory):
{ {
"type": "ExistingCloud", "type": "ExistingCloud",
"endpoint": { "auth_url": "http://localhost:5000/v3/",
"auth_url": "http://localhost:5000/v3/", "region_name": "RegionOne",
"username": "engineer1", "use_public_urls": false,
"user_domain_name": "qa", "admin_port": 35357
"project_name": "qa_admin_project", "admin": {
"project_domain_name": "qa", "username": "admin",
"password": "password", "password": "admin",
"region_name": "RegionOne", "user_domain_name": "admin",
"use_public_urls": False, "project_name": "admin",
"admin_port": 35357, "project_domain_name": "admin",
} }
} }
""" """
CONFIG_SCHEMA = { CONFIG_SCHEMA = {
'type': 'object', "type": "object",
'properties': {
'type': {'type': 'string'}, "definitions": {
'endpoint': { "user": {
'type': 'object', "type": "object",
'properties': { "properties": {
'auth_url': {'type': 'string'}, "username": {"type": "string"},
'username': {'type': 'string'}, "password": {"type": "string"},
'password': {'type': 'string'},
'region_name': {'type': 'string'},
'use_public_urls': {'type': 'boolean'},
'admin_port': {
'type': 'integer',
'minimum': 2,
'maximum': 65535
},
}, },
'oneOf': [ "oneOf": [
{ {
# v2.0 authentication # v2.0 authentication
'properties': { "properties": {
'tenant_name': {'type': 'string'}, "tenant_name": {"type": "string"},
}, },
'required': ['auth_url', 'username', 'password', "required": ["username", "password", "tenant_name"],
'tenant_name'],
}, },
{ {
# Authentication in project scope # Authentication in project scope
'properties': { "properties": {
'user_domain_name': {'type': 'string'}, "user_domain_name": {"type": "string"},
'project_name': {'type': 'string'}, "project_name": {"type": "string"},
'project_domain_name': {'type': 'string'}, "project_domain_name": {"type": "string"},
}, },
'required': ['auth_url', 'username', 'password', "required": ["username", "password", "project_name"],
'project_name'], }
},
] ]
}, }
}, },
'required': ['type', 'endpoint'],
"properties": {
"type": {"type": "string"},
"auth_url": {"type": "string"},
"region_name": {"type": "string"},
"use_public_urls": {"type": "boolean"},
"admin_port": {
"type": "integer",
"minimum": 2,
"maximum": 65535
}
},
"anyOf": [
{
"properties": {
"admin": {"$ref": "#/definitions/user"}
},
"required": ["type", "auth_url", "admin"]
},
{
"users": {
"type": "array",
"items": {"$ref": "#/definitions/user"}
},
"required": ["type", "auth_url", "users"]
}
]
} }
def deploy(self): def _create_endpoint(self, common, user, permission):
endpoint_dict = self.deployment['config']['endpoint'] return objects.Endpoint(
project_name = endpoint_dict.get('project_name', common["auth_url"], user["username"], user["password"],
endpoint_dict.get('tenant_name')) tenant_name=user.get("project_name", user.get("tenant_name")),
permission=permission,
admin_endpoint = objects.Endpoint( region_name=common.get("region_name"),
endpoint_dict['auth_url'], endpoint_dict['username'], use_public_urls=common.get("use_public_urls", False),
endpoint_dict['password'], admin_port=common.get("admin_port", 35357),
tenant_name=project_name, domain_name=user.get("domain_name"),
permission=consts.EndpointPermission.ADMIN, user_domain_name=user.get("user_domain_name", "Default"),
region_name=endpoint_dict.get('region_name'), project_domain_name=user.get("project_domain_name", "Default")
use_public_urls=endpoint_dict.get('use_public_urls', False),
admin_port=endpoint_dict.get('admin_port', 35357),
domain_name=endpoint_dict.get('domain_name'),
user_domain_name=endpoint_dict.get('user_domain_name',
'Default'),
project_domain_name=endpoint_dict.get('project_domain_name',
'Default')
) )
return [admin_endpoint]
def deploy(self):
permissions = consts.EndpointPermission
users = [self._create_endpoint(self.config, user, permissions.USER)
for user in self.config.get("users", [])]
admin = self._create_endpoint(self.config,
self.config.get("admin"),
permissions.ADMIN)
return {"admin": admin, "users": users}
def cleanup(self): def cleanup(self):
pass pass

View File

@ -164,13 +164,13 @@ class FuelEngine(engine.EngineFactory):
ip = cluster.get_endpoint_ip() ip = cluster.get_endpoint_ip()
attrs = cluster.get_attributes()['editable']['access'] attrs = cluster.get_attributes()['editable']['access']
return [objects.Endpoint( admin_endpoint = objects.Endpoint(
'http://%s:5000/v2.0/' % ip, 'http://%s:5000/v2.0/' % ip,
attrs['user']['value'], attrs['user']['value'],
attrs['password']['value'], attrs['password']['value'],
attrs['tenant']['value'], attrs['tenant']['value'],
consts.EndpointPermission.ADMIN consts.EndpointPermission.ADMIN)
)] return {"admin": admin_endpoint}
def cleanup(self): def cleanup(self):
resources = self.deployment.get_resources(provider_name='FuelEngine', resources = self.deployment.get_resources(provider_name='FuelEngine',

View File

@ -148,7 +148,7 @@ class LxcEngine(engine.EngineFactory):
container.ssh.run('/bin/sh -e', stdin=open(start_script, 'rb')) container.ssh.run('/bin/sh -e', stdin=open(start_script, 'rb'))
if network: if network:
network += 1 network += 1
return objects.Endpoint('', '', '', '') return {"admin": objects.Endpoint('', '', '', '')}
def cleanup(self): def cleanup(self):
resources = self.deployment.get_resources() resources = self.deployment.get_resources()

View File

@ -40,39 +40,46 @@ class Deployment(object):
db.deployment_delete(uuid) db.deployment_delete(uuid)
def _update(self, values): def _update(self, values):
self.deployment = db.deployment_update(self.deployment['uuid'], values) self.deployment = db.deployment_update(self.deployment["uuid"], values)
def update_status(self, status): def update_status(self, status):
self._update({'status': status}) self._update({"status": status})
def update_name(self, name): def update_name(self, name):
self._update({'name': name}) self._update({"name": name})
def update_config(self, config): def update_config(self, config):
self._update({'config': config}) self._update({"config": config})
def update_endpoints(self, endpoints): def update_endpoints(self, endpoints):
self._update({'endpoints': [e.to_dict(include_permission=True) admin = endpoints.get("admin", {})
for e in endpoints]}) if admin:
admin = admin.to_dict(include_permission=True)
self._update({
"admin": admin,
"users": [e.to_dict(include_permission=True)
for e in endpoints.get("users", [])]
})
def set_started(self): def set_started(self):
self._update({'started_at': datetime.datetime.now(), self._update({"started_at": datetime.datetime.now(),
'status': consts.DeployStatus.DEPLOY_STARTED}) "status": consts.DeployStatus.DEPLOY_STARTED})
def set_completed(self): def set_completed(self):
self._update({'completed_at': datetime.datetime.now(), self._update({"completed_at": datetime.datetime.now(),
'status': consts.DeployStatus.DEPLOY_FINISHED}) "status": consts.DeployStatus.DEPLOY_FINISHED})
def add_resource(self, provider_name, type=None, info=None): def add_resource(self, provider_name, type=None, info=None):
return db.resource_create({ return db.resource_create({
'deployment_uuid': self.deployment['uuid'], "deployment_uuid": self.deployment["uuid"],
'provider_name': provider_name, "provider_name": provider_name,
'type': type, "type": type,
'info': info, "info": info,
}) })
def get_resources(self, provider_name=None, type=None): def get_resources(self, provider_name=None, type=None):
return db.resource_get_all(self.deployment['uuid'], return db.resource_get_all(self.deployment["uuid"],
provider_name=provider_name, type=type) provider_name=provider_name, type=type)
@staticmethod @staticmethod
@ -80,4 +87,4 @@ class Deployment(object):
db.resource_delete(resource_id) db.resource_delete(resource_id)
def delete(self): def delete(self):
db.deployment_delete(self.deployment['uuid']) db.deployment_delete(self.deployment["uuid"])

View File

@ -98,10 +98,11 @@ def start_task(deploy_uuid, config, task=None):
LOG.info("Benchmark Task %s on Deployment %s" % (task['uuid'], LOG.info("Benchmark Task %s on Deployment %s" % (task['uuid'],
deployment['uuid'])) deployment['uuid']))
benchmark_engine = engine.BenchmarkEngine(config, task) benchmark_engine = engine.BenchmarkEngine(config, task)
endpoint = deployment['endpoints'] admin = deployment["admin"]
users = deployment["users"]
try: try:
benchmark_engine.bind(endpoint) benchmark_engine.bind(admin=admin, users=users)
benchmark_engine.validate() benchmark_engine.validate()
benchmark_engine.run() benchmark_engine.run()
except exceptions.InvalidTaskException: except exceptions.InvalidTaskException:

View File

@ -49,7 +49,7 @@ CONF.register_opts(image_opts, 'image')
class TempestConf(object): class TempestConf(object):
def __init__(self, deploy_id): def __init__(self, deploy_id):
self.endpoint = db.deployment_get(deploy_id)['endpoints'][0] self.endpoint = db.deployment_get(deploy_id)['admin']
self.clients = osclients.Clients(endpoint.Endpoint(**self.endpoint)) self.clients = osclients.Clients(endpoint.Endpoint(**self.endpoint))
try: try:
self.keystoneclient = self.clients.verified_keystone() self.keystoneclient = self.clients.verified_keystone()
@ -102,7 +102,7 @@ class TempestConf(object):
def _get_url(self, servicename): def _get_url(self, servicename):
for service in self.keystoneclient.auth_ref['serviceCatalog']: for service in self.keystoneclient.auth_ref['serviceCatalog']:
if service['name'] == servicename: if service['name'] == servicename:
return service['endpoints'][0]['publicURL'] return service['admin']['publicURL']
def _set_default(self): def _set_default(self):
lock_path = os.path.join(self.data_path, lock_path = os.path.join(self.data_path,

View File

@ -197,13 +197,12 @@ class ScenarioRunnerTestCase(test.TestCase):
__execution_type__ = "new_runner" __execution_type__ = "new_runner"
task = mock.MagicMock() task = mock.MagicMock()
endpoints = [mock.MagicMock(), mock.MagicMock()] admin = mock.MagicMock()
config = {"type": "new_runner", "a": 123} config = {"type": "new_runner", "a": 123}
runner = base.ScenarioRunner.get_runner(task, endpoints, config) runner = base.ScenarioRunner.get_runner(task, admin, config)
self.assertEqual(runner.task, task) self.assertEqual(runner.task, task)
self.assertEqual(runner.endpoints, endpoints) self.assertEqual(runner.admin_user, admin)
self.assertEqual(runner.admin_user, endpoints[0])
self.assertEqual(runner.config, config) self.assertEqual(runner.config, config)
self.assertIsInstance(runner, NewRunner) self.assertIsInstance(runner, NewRunner)

View File

@ -242,7 +242,7 @@ class BenchmarkEngineTestCase(test.TestCase):
"b.args": [{"args": {"a": 1}}] "b.args": [{"args": {"a": 1}}]
} }
task = mock.MagicMock() task = mock.MagicMock()
eng = engine.BenchmarkEngine(config, task).bind([{}]) eng = engine.BenchmarkEngine(config, task).bind({})
eng.run() eng.run()
@mock.patch("rally.benchmark.engine.BenchmarkEngine.consume_results") @mock.patch("rally.benchmark.engine.BenchmarkEngine.consume_results")
@ -256,7 +256,7 @@ class BenchmarkEngineTestCase(test.TestCase):
"b.args": [{"runner": {"a": 1}}] "b.args": [{"runner": {"a": 1}}]
} }
task = mock.MagicMock() task = mock.MagicMock()
eng = engine.BenchmarkEngine(config, task).bind([{}]) eng = engine.BenchmarkEngine(config, task).bind({})
eng.run() eng.run()
@mock.patch("rally.benchmark.engine.BenchmarkEngine.consume_results") @mock.patch("rally.benchmark.engine.BenchmarkEngine.consume_results")
@ -270,7 +270,7 @@ class BenchmarkEngineTestCase(test.TestCase):
"b.args": [{"context": {"context_b": {"b": 2}}}] "b.args": [{"context": {"context_b": {"b": 2}}}]
} }
task = mock.MagicMock() task = mock.MagicMock()
eng = engine.BenchmarkEngine(config, task).bind([{}]) eng = engine.BenchmarkEngine(config, task).bind({})
eng.run() eng.run()
@mock.patch("rally.benchmark.engine.osclients") @mock.patch("rally.benchmark.engine.osclients")
@ -279,16 +279,16 @@ class BenchmarkEngineTestCase(test.TestCase):
mock_endpoint.return_value = mock.MagicMock() mock_endpoint.return_value = mock.MagicMock()
benchmark_engine = engine.BenchmarkEngine(mock.MagicMock(), benchmark_engine = engine.BenchmarkEngine(mock.MagicMock(),
mock.MagicMock()) mock.MagicMock())
endpoint = { admin = {
"auth_url": "http://valid.com", "auth_url": "http://valid.com",
"username": "user", "username": "user",
"password": "pwd", "password": "pwd",
"tenant_name": "tenant" "tenant_name": "tenant"
} }
binded_benchmark_engine = benchmark_engine.bind([endpoint]) binded_benchmark_engine = benchmark_engine.bind(admin)
self.assertEqual([mock_endpoint.return_value], self.assertEqual(mock_endpoint.return_value,
benchmark_engine.endpoints) benchmark_engine.admin_endpoint)
self.assertEqual(benchmark_engine, binded_benchmark_engine) self.assertEqual(benchmark_engine, binded_benchmark_engine)
expected_calls = [ expected_calls = [
mock.call.Clients(mock_endpoint.return_value), mock.call.Clients(mock_endpoint.return_value),

View File

@ -50,15 +50,15 @@ class DeploymentCommandsTestCase(test.TestCase):
mock_create.assert_called_once_with( mock_create.assert_called_once_with(
{ {
"type": "ExistingCloud", "type": "ExistingCloud",
"endpoint": { "auth_url": 'fake_auth_url',
"auth_url": 'fake_auth_url', "region_name": "fake_region_name",
"username": 'fake_username', "admin": {
"password": 'fake_password', "username": "fake_username",
"tenant_name": 'fake_tenant_name', "password": "fake_password",
"region_name": 'fake_region_name' "tenant_name": "fake_tenant_name"
} }
}, },
'from_env' "from_env"
) )
@mock.patch('rally.cmd.commands.deployment.DeploymentCommands.list') @mock.patch('rally.cmd.commands.deployment.DeploymentCommands.list')
@ -193,15 +193,26 @@ class DeploymentCommandsTestCase(test.TestCase):
@mock.patch('rally.cmd.commands.deployment.utils.Struct') @mock.patch('rally.cmd.commands.deployment.utils.Struct')
@mock.patch('rally.cmd.commands.deployment.db.deployment_get') @mock.patch('rally.cmd.commands.deployment.db.deployment_get')
def test_endpoint(self, mock_deployment, mock_struct, mock_print_list): def test_endpoint(self, mock_deployment, mock_struct, mock_print_list):
deploy_id = 'b1a6153e-a314-4cb3-b63b-cf08c1a416c3' deploy_id = "b1a6153e-a314-4cb3-b63b-cf08c1a416c3"
value = {'endpoints': [{}]} value = {
"admin": {
"auth_url": "url",
"username": "u",
"password": "p",
"tenant_name": "t",
"region_name": "r",
"use_public_urls": "upu",
"admin_port": "ap"
},
"users": []
}
mock_deployment.return_value = value mock_deployment.return_value = value
self.deployment.endpoint(deploy_id) self.deployment.endpoint(deploy_id)
mock_deployment.assert_called_once_with(deploy_id) mock_deployment.assert_called_once_with(deploy_id)
headers = ['auth_url', 'username', 'password', 'tenant_name', headers = ["auth_url", "username", "password", "tenant_name",
'region_name', 'use_public_urls', 'admin_port'] "region_name", "use_public_urls", "admin_port"]
fake_data = ['', '', '', '', '', '', ''] fake_data = ["url", "u", "p", "t", "r", "upu", "ap"]
mock_struct.assert_called_once_with(**dict(zip(headers, fake_data))) mock_struct.assert_called_once_with(**dict(zip(headers, fake_data)))
mock_print_list.assert_called_once_with([mock_struct()], headers) mock_print_list.assert_called_once_with([mock_struct()], headers)

View File

@ -45,7 +45,7 @@ class ShowCommandsTestCase(test.TestCase):
fake_image = self.fake_glance_client.images.cache.values()[0] fake_image = self.fake_glance_client.images.cache.values()[0]
fake_image.size = 1 fake_image.size = 1
mock_get_glance.return_value = self.fake_glance_client mock_get_glance.return_value = self.fake_glance_client
mock_deployment_get.return_value = {'endpoints': [self.fake_endpoint]} mock_deployment_get.return_value = {'admin': self.fake_endpoint}
self.show.images(self.fake_deploy_id) self.show.images(self.fake_deploy_id)
mock_deployment_get.assert_called_once_with(self.fake_deploy_id) mock_deployment_get.assert_called_once_with(self.fake_deploy_id)
mock_get_glance.assert_called_once_with() mock_get_glance.assert_called_once_with()
@ -74,7 +74,7 @@ class ShowCommandsTestCase(test.TestCase):
fake_flavor.id, fake_flavor.name, fake_flavor.vcpus = 1, 'm1.fake', 1 fake_flavor.id, fake_flavor.name, fake_flavor.vcpus = 1, 'm1.fake', 1
fake_flavor.ram, fake_flavor.swap, fake_flavor.disk = 1024, 128, 10 fake_flavor.ram, fake_flavor.swap, fake_flavor.disk = 1024, 128, 10
mock_get_nova.return_value = self.fake_nova_client mock_get_nova.return_value = self.fake_nova_client
mock_deployment_get.return_value = {'endpoints': [self.fake_endpoint]} mock_deployment_get.return_value = {'admin': self.fake_endpoint}
self.show.flavors(self.fake_deploy_id) self.show.flavors(self.fake_deploy_id)
mock_deployment_get.assert_called_once_with(self.fake_deploy_id) mock_deployment_get.assert_called_once_with(self.fake_deploy_id)
mock_get_nova.assert_called_once_with() mock_get_nova.assert_called_once_with()
@ -105,7 +105,7 @@ class ShowCommandsTestCase(test.TestCase):
fake_network.label = 'fakenet' fake_network.label = 'fakenet'
fake_network.cidr = '10.0.0.0/24' fake_network.cidr = '10.0.0.0/24'
mock_get_nova.return_value = self.fake_nova_client mock_get_nova.return_value = self.fake_nova_client
mock_deployment_get.return_value = {'endpoints': [self.fake_endpoint]} mock_deployment_get.return_value = {'admin': self.fake_endpoint}
self.show.networks(self.fake_deploy_id) self.show.networks(self.fake_deploy_id)
mock_deployment_get.assert_called_once_with(self.fake_deploy_id) mock_deployment_get.assert_called_once_with(self.fake_deploy_id)
mock_get_nova.assert_called_once_with() mock_get_nova.assert_called_once_with()
@ -129,7 +129,7 @@ class ShowCommandsTestCase(test.TestCase):
fake_secgroup = self.fake_nova_client.security_groups.cache.values()[0] fake_secgroup = self.fake_nova_client.security_groups.cache.values()[0]
fake_secgroup.id = 0 fake_secgroup.id = 0
mock_get_nova.return_value = self.fake_nova_client mock_get_nova.return_value = self.fake_nova_client
mock_deployment_get.return_value = {'endpoints': [self.fake_endpoint]} mock_deployment_get.return_value = {'admin': self.fake_endpoint}
self.show.secgroups(self.fake_deploy_id) self.show.secgroups(self.fake_deploy_id)
mock_deployment_get.assert_called_once_with(self.fake_deploy_id) mock_deployment_get.assert_called_once_with(self.fake_deploy_id)
mock_get_nova.assert_called_once_with() mock_get_nova.assert_called_once_with()
@ -154,7 +154,7 @@ class ShowCommandsTestCase(test.TestCase):
fake_keypair = self.fake_nova_client.keypairs.cache.values()[0] fake_keypair = self.fake_nova_client.keypairs.cache.values()[0]
fake_keypair.fingerprint = '84:87:58' fake_keypair.fingerprint = '84:87:58'
mock_get_nova.return_value = self.fake_nova_client mock_get_nova.return_value = self.fake_nova_client
mock_deployment_get.return_value = {'endpoints': [self.fake_endpoint]} mock_deployment_get.return_value = {'admin': self.fake_endpoint}
self.show.keypairs(self.fake_deploy_id) self.show.keypairs(self.fake_deploy_id)
mock_deployment_get.assert_called_once_with(self.fake_deploy_id) mock_deployment_get.assert_called_once_with(self.fake_deploy_id)
mock_get_nova.assert_called_once_with() mock_get_nova.assert_called_once_with()

View File

@ -40,7 +40,7 @@ class UseCommandsTestCase(test.TestCase):
@mock.patch(MOD + 'db') @mock.patch(MOD + 'db')
def test_deployment_use_by_name(self, m_db, m_ercde, m_uaigf, m_uodf): def test_deployment_use_by_name(self, m_db, m_ercde, m_uaigf, m_uodf):
fake_deployment = {'uuid': 'fake_uuid', fake_deployment = {'uuid': 'fake_uuid',
'endpoints': 'fake_endpoints'} 'admin': 'fake_endpoints'}
m_db.deployment_list.return_value = [fake_deployment] m_db.deployment_list.return_value = [fake_deployment]
m_db.deployment_get.return_value = fake_deployment m_db.deployment_get.return_value = fake_deployment
status = self.use.deployment(name='fake_name') status = self.use.deployment(name='fake_name')
@ -58,11 +58,15 @@ class UseCommandsTestCase(test.TestCase):
def test_deployment(self, mock_env, mock_path, mock_deployment, def test_deployment(self, mock_env, mock_path, mock_deployment,
mock_symlink, mock_remove): mock_symlink, mock_remove):
deploy_id = '593b683c-4b16-4b2b-a56b-e162bd60f10b' deploy_id = '593b683c-4b16-4b2b-a56b-e162bd60f10b'
endpoints = {'endpoints': [{'auth_url': 'fake_auth_url', endpoints = {
'username': 'fake_username', 'admin': {
'password': 'fake_password', 'auth_url': 'fake_auth_url',
'tenant_name': 'fake_tenant_name', 'username': 'fake_username',
'region_name': None}]} 'password': 'fake_password',
'tenant_name': 'fake_tenant_name',
'region_name': None
}
}
mock_deployment.return_value = endpoints mock_deployment.return_value = endpoints
with mock.patch('rally.cmd.commands.use.open', mock.mock_open(), with mock.patch('rally.cmd.commands.use.open', mock.mock_open(),
create=True) as mock_file: create=True) as mock_file:

View File

@ -85,7 +85,7 @@ class DevstackEngineTestCase(test.TestCase):
fake_provider.create_servers.return_value = [server] fake_provider.create_servers.return_value = [server]
with mock.patch.object(self.engine, 'deployment') as m_d: with mock.patch.object(self.engine, 'deployment') as m_d:
endpoints = self.engine.deploy() endpoints = self.engine.deploy()
self.assertEqual(['fake_endpoint'], endpoints) self.assertEqual({"admin": "fake_endpoint"}, endpoints)
m_endpoint.assert_called_once_with('http://host:5000/v2.0/', 'admin', m_endpoint.assert_called_once_with('http://host:5000/v2.0/', 'admin',
'secret', 'admin', 'admin') 'secret', 'admin', 'admin')
m_d.add_resource.assert_called_once_with( m_d.add_resource.assert_called_once_with(

View File

@ -24,44 +24,47 @@ from tests import test
class TestExistingCloud(test.TestCase): class TestExistingCloud(test.TestCase):
def setUp(self): def setUp(self):
self.deployment = {
'config': {
'type': 'ExistingCloud',
'endpoint': {
'auth_url': 'http://example.net:5000/v2.0/',
'username': 'admin',
'password': 'myadminpass',
'tenant_name': 'demo',
'region_name': 'RegionOne',
'use_public_urls': False,
'admin_port': 35357,
'domain_name': None,
'project_domain_name': 'Default',
'user_domain_name': 'Default',
},
},
}
super(TestExistingCloud, self).setUp() super(TestExistingCloud, self).setUp()
self.deployment = {
"config": {
"type": "ExistingCloud",
"auth_url": "http://example.net:5000/v2.0/",
"region_name": "RegionOne",
"use_public_urls": False,
"admin_port": 35357,
"admin": {
"username": "admin",
"password": "myadminpass",
"tenant_name": "demo",
"domain_name": None,
"project_domain_name": "Default",
"user_domain_name": "Default",
}
}
}
def test_init(self): def test_init(self):
existing.ExistingCloud(self.deployment) existing.ExistingCloud(self.deployment)
def test_init_invalid_config(self): def test_init_invalid_config(self):
self.deployment['config']['endpoint'] = 42 self.deployment["config"]["admin"] = 42
self.assertRaises(jsonschema.ValidationError, self.assertRaises(jsonschema.ValidationError,
existing.ExistingCloud, self.deployment) existing.ExistingCloud, self.deployment)
def test_deploy(self): def test_deploy(self):
engine = existing.ExistingCloud(self.deployment) engine = existing.ExistingCloud(self.deployment)
endpoints = engine.deploy() endpoints = engine.deploy()
admin_endpoint = self.deployment['config']['endpoint'].copy() admin_endpoint = self.deployment["config"].copy()
self.assertEqual(admin_endpoint, endpoints[0].to_dict()) admin_endpoint.pop("type")
admin_endpoint.update(admin_endpoint.pop("admin"))
self.assertEqual(admin_endpoint, endpoints["admin"].to_dict())
self.assertEqual([], endpoints["users"])
def test_cleanup(self): def test_cleanup(self):
existing.ExistingCloud(self.deployment).cleanup() existing.ExistingCloud(self.deployment).cleanup()
def test_is_in_factory(self): def test_is_in_factory(self):
name = self.deployment['config']['type'] name = self.deployment["config"]["type"]
engine = deploy.EngineFactory.get_engine(name, engine = deploy.EngineFactory.get_engine(name,
self.deployment) self.deployment)
self.assertIsInstance(engine, existing.ExistingCloud) self.assertIsInstance(engine, existing.ExistingCloud)

View File

@ -103,8 +103,8 @@ class FuelEngineTestCase(test.TestCase):
engine._get_release_id = mock.Mock() engine._get_release_id = mock.Mock()
endpoint = engine.deploy() endpoint = engine.deploy()
self.assertEqual(1, len(endpoint)) self.assertEqual(["admin"], endpoint.keys())
endpoint = endpoint[0] endpoint = endpoint["admin"]
self.assertEqual('user', endpoint.username) self.assertEqual('user', endpoint.username)
self.assertEqual('pw', endpoint.password) self.assertEqual('pw', endpoint.password)

View File

@ -113,7 +113,7 @@ class LxcEngineTestCase(test.TestCase):
with mock.patch.object(self.engine, 'deployment') as m_deployment: with mock.patch.object(self.engine, 'deployment') as m_deployment:
endpoint = self.engine.deploy() endpoint = self.engine.deploy()
self.assertIsInstance(endpoint, objects.Endpoint) self.assertIsInstance(endpoint["admin"], objects.Endpoint)
LxcHost_calls = [ LxcHost_calls = [
mock.call(fake_servers[0], {'network': '10.128.128.0/28', mock.call(fake_servers[0], {'network': '10.128.128.0/28',
'tunnel_to': ['1.1.1.1', '2.2.2.2']}), 'tunnel_to': ['1.1.1.1', '2.2.2.2']}),

View File

@ -119,12 +119,35 @@ class DeploymentTestCase(test.TestCase):
def test_update_endpoints(self, mock_update): def test_update_endpoints(self, mock_update):
mock_update.return_value = self.deployment mock_update.return_value = self.deployment
deploy = objects.Deployment(deployment=self.deployment) deploy = objects.Deployment(deployment=self.deployment)
endpoints = [objects.Endpoint("url", "user", "pwd", "tenant", endpoints = {
consts.EndpointPermission.ADMIN)] "admin": objects.Endpoint("url", "user", "pwd", "tenant",
consts.EndpointPermission.ADMIN),
"users": [
objects.Endpoint("url1", "user1", "pwd1", "tenant1",
consts.EndpointPermission.USER),
objects.Endpoint("url2", "user2", "pwd2", "tenant2",
consts.EndpointPermission.USER),
]
}
expected_users = [u.to_dict(include_permission=True)
for u in endpoints["users"]]
deploy.update_endpoints(endpoints) deploy.update_endpoints(endpoints)
mock_update.assert_called_once_with( mock_update.assert_called_once_with(
self.deployment["uuid"], self.deployment["uuid"],
{"endpoints": [endpoints[0].to_dict(include_permission=True)]}) {
"admin": endpoints["admin"].to_dict(include_permission=True),
"users": expected_users
})
@mock.patch('rally.objects.deploy.db.deployment_update')
def test_update_empty_endpoints(self, mock_update):
mock_update.return_value = self.deployment
deploy = objects.Deployment(deployment=self.deployment)
deploy.update_endpoints({})
mock_update.assert_called_once_with(self.deployment["uuid"],
{"admin": {}, "users": []})
@mock.patch('rally.objects.deploy.db.resource_create') @mock.patch('rally.objects.deploy.db.resource_create')
def test_add_resource(self, mock_create): def test_add_resource(self, mock_create):

View File

@ -27,36 +27,36 @@ from tests import test
FAKE_DEPLOY_CONFIG = { FAKE_DEPLOY_CONFIG = {
# TODO(akscram): A fake engine is more suitable for that. # TODO(akscram): A fake engine is more suitable for that.
'type': 'ExistingCloud', "type": "ExistingCloud",
'endpoint': { "auth_url": "http://example.net:5000/v2.0/",
'auth_url': 'http://example.net:5000/v2.0/', "admin": {
'username': 'admin', "username": "admin",
'password': 'myadminpass', "password": "myadminpass",
'tenant_name': 'demo', "tenant_name": "demo",
'region_name': 'RegionOne', "domain_name": None,
'use_public_urls': False, "project_domain_name": "Default",
'admin_port': 35357, "user_domain_name": "Default"
'domain_name': None,
'project_domain_name': 'Default',
'user_domain_name': 'Default',
}, },
"region_name": "RegionOne",
"use_public_urls": False,
"admin_port": 35357
} }
FAKE_TASK_CONFIG = { FAKE_TASK_CONFIG = {
'FakeScenario.fake': [ "FakeScenario.fake": [
{ {
'args': {}, "args": {},
'runner': { "runner": {
'type': 'constant', "type": "constant",
'timeout': 10000, "timeout": 10000,
'times': 3, "times": 3,
'concurrency': 2, "concurrency": 2,
}, },
'context': { "context": {
'users': { "users": {
'tenants': 5, "tenants": 5,
'users_per_tenant': 6, "users_per_tenant": 6,
} }
} }
} }
@ -79,26 +79,29 @@ class APITestCase(test.TestCase):
super(APITestCase, self).setUp() super(APITestCase, self).setUp()
self.deploy_config = FAKE_DEPLOY_CONFIG self.deploy_config = FAKE_DEPLOY_CONFIG
self.task_config = FAKE_TASK_CONFIG self.task_config = FAKE_TASK_CONFIG
self.deploy_uuid = '599bdf1d-fe77-461a-a810-d59b1490f4e3' self.deploy_uuid = "599bdf1d-fe77-461a-a810-d59b1490f4e3"
self.endpoints = [FAKE_DEPLOY_CONFIG['endpoint']] admin_endpoint = FAKE_DEPLOY_CONFIG.copy()
# TODO(msdubov): Remove this as soon as ExistingCloud requires admin_endpoint.pop("type")
# permission on input admin_endpoint.update(admin_endpoint.pop("admin"))
self.endpoints[0]["permission"] = consts.EndpointPermission.ADMIN admin_endpoint["permission"] = consts.EndpointPermission.ADMIN
self.task_uuid = 'b0d9cd6c-2c94-4417-a238-35c7019d0257' self.endpoints = {"admin": admin_endpoint, "users": []}
self.task_uuid = "b0d9cd6c-2c94-4417-a238-35c7019d0257"
self.task = { self.task = {
'uuid': self.task_uuid, "uuid": self.task_uuid,
} }
self.deployment = { self.deployment = {
'uuid': self.deploy_uuid, "uuid": self.deploy_uuid,
'name': 'fake_name', "name": "fake_name",
'config': self.deploy_config, "config": self.deploy_config,
'endpoints': self.endpoints, "admin": self.endpoints["admin"],
"users": []
} }
self.tempest = mock.Mock() self.tempest = mock.Mock()
@mock.patch('rally.objects.Task') @mock.patch("rally.objects.Task")
def test_create_task(self, mock_task): def test_create_task(self, mock_task):
deployment_uuid = 'b0d9cd6c-2c94-4417-a238-35c7019d0257' deployment_uuid = "b0d9cd6c-2c94-4417-a238-35c7019d0257"
tag = "a" tag = "a"
api.create_task(deployment_uuid, tag) api.create_task(deployment_uuid, tag)
mock_task.assert_called_once_with(deployment_uuid=deployment_uuid, mock_task.assert_called_once_with(deployment_uuid=deployment_uuid,
@ -110,12 +113,12 @@ class APITestCase(test.TestCase):
"._validate_config_syntax") "._validate_config_syntax")
@mock.patch("rally.benchmark.engine.BenchmarkEngine" @mock.patch("rally.benchmark.engine.BenchmarkEngine"
"._validate_config_scenarios_name") "._validate_config_scenarios_name")
@mock.patch('rally.benchmark.engine.osclients') @mock.patch("rally.benchmark.engine.osclients")
@mock.patch('rally.benchmark.engine.base_runner.ScenarioRunner.get_runner') @mock.patch("rally.benchmark.engine.base_runner.ScenarioRunner.get_runner")
@mock.patch('rally.objects.deploy.db.deployment_get') @mock.patch("rally.objects.deploy.db.deployment_get")
@mock.patch('rally.objects.task.db.task_result_create') @mock.patch("rally.objects.task.db.task_result_create")
@mock.patch('rally.objects.task.db.task_update') @mock.patch("rally.objects.task.db.task_update")
@mock.patch('rally.objects.task.db.task_create') @mock.patch("rally.objects.task.db.task_create")
def test_start_task(self, mock_task_create, mock_task_update, def test_start_task(self, mock_task_create, mock_task_update,
mock_task_result_create, mock_deploy_get, mock_task_result_create, mock_deploy_get,
mock_utils_runner, mock_osclients, mock_utils_runner, mock_osclients,
@ -126,48 +129,47 @@ class APITestCase(test.TestCase):
mock_deploy_get.return_value = self.deployment mock_deploy_get.return_value = self.deployment
mock_utils_runner.return_value = mock_runner = mock.Mock() mock_utils_runner.return_value = mock_runner = mock.Mock()
mock_runner.result_queue = collections.deque(['fake_result']) mock_runner.result_queue = collections.deque(["fake_result"])
mock_runner.run.return_value = 42 mock_runner.run.return_value = 42
mock_osclients.Clients.return_value = fakes.FakeClients() mock_osclients.Clients.return_value = fakes.FakeClients()
api.start_task(self.deploy_uuid, self.task_config) api.start_task(self.deploy_uuid, self.task_config)
mock_deploy_get.assert_called_once_with(self.deploy_uuid) mock_deploy_get.assert_called_once_with(self.deploy_uuid)
mock_task_create.assert_called_once_with({ mock_task_create.assert_called_once_with({
'deployment_uuid': self.deploy_uuid, "deployment_uuid": self.deploy_uuid,
}) })
mock_task_update.assert_has_calls([ mock_task_update.assert_has_calls([
mock.call(self.task_uuid, {'status': consts.TaskStatus.VERIFYING}), mock.call(self.task_uuid, {"status": consts.TaskStatus.VERIFYING}),
mock.call(self.task_uuid, {'status': consts.TaskStatus.RUNNING}), mock.call(self.task_uuid, {"status": consts.TaskStatus.RUNNING}),
mock.call(self.task_uuid, {'status': consts.TaskStatus.FINISHED}) mock.call(self.task_uuid, {"status": consts.TaskStatus.FINISHED})
]) ])
# NOTE(akscram): It looks really awful, but checks degradation. # NOTE(akscram): It looks really awful, but checks degradation.
mock_task_result_create.assert_called_once_with( mock_task_result_create.assert_called_once_with(
self.task_uuid, self.task_uuid,
{ {
'kw': { "kw": {
'args': {}, "args": {},
'runner': { "runner": {
'type': 'constant', "type": "constant",
'timeout': 10000, "timeout": 10000,
'times': 3, "times": 3,
'concurrency': 2, "concurrency": 2,
}, },
'context': { "context": {
'users': { "users": {
'tenants': 5, "tenants": 5,
'users_per_tenant': 6, "users_per_tenant": 6,
} }
} }
}, },
'name': 'FakeScenario.fake', "name": "FakeScenario.fake",
'pos': 0, "pos": 0,
}, },
{ {
'raw': ['fake_result'], "raw": ["fake_result"],
'scenario_duration': 42 "scenario_duration": 42
} }
) )
@ -175,35 +177,35 @@ class APITestCase(test.TestCase):
self.assertRaises(NotImplementedError, api.abort_task, self.assertRaises(NotImplementedError, api.abort_task,
self.task_uuid) self.task_uuid)
@mock.patch('rally.objects.task.db.task_delete') @mock.patch("rally.objects.task.db.task_delete")
def test_delete_task(self, mock_delete): def test_delete_task(self, mock_delete):
api.delete_task(self.task_uuid) api.delete_task(self.task_uuid)
mock_delete.assert_called_once_with( mock_delete.assert_called_once_with(
self.task_uuid, self.task_uuid,
status=consts.TaskStatus.FINISHED) status=consts.TaskStatus.FINISHED)
@mock.patch('rally.objects.task.db.task_delete') @mock.patch("rally.objects.task.db.task_delete")
def test_delete_task_force(self, mock_delete): def test_delete_task_force(self, mock_delete):
api.delete_task(self.task_uuid, force=True) api.delete_task(self.task_uuid, force=True)
mock_delete.assert_called_once_with(self.task_uuid, status=None) mock_delete.assert_called_once_with(self.task_uuid, status=None)
@mock.patch('rally.objects.deploy.db.deployment_update') @mock.patch("rally.objects.deploy.db.deployment_update")
@mock.patch('rally.objects.deploy.db.deployment_create') @mock.patch("rally.objects.deploy.db.deployment_create")
def test_create_deploy(self, mock_create, mock_update): def test_create_deploy(self, mock_create, mock_update):
mock_create.return_value = self.deployment mock_create.return_value = self.deployment
mock_update.return_value = self.deployment mock_update.return_value = self.deployment
api.create_deploy(self.deploy_config, 'fake_deploy') api.create_deploy(self.deploy_config, "fake_deploy")
mock_create.assert_called_once_with({ mock_create.assert_called_once_with({
'name': 'fake_deploy', "name": "fake_deploy",
'config': self.deploy_config, "config": self.deploy_config,
}) })
mock_update.assert_has_calls([ mock_update.assert_has_calls([
mock.call(self.deploy_uuid, {'endpoints': self.endpoints}) mock.call(self.deploy_uuid, self.endpoints)
]) ])
@mock.patch('rally.objects.deploy.db.deployment_delete') @mock.patch("rally.objects.deploy.db.deployment_delete")
@mock.patch('rally.objects.deploy.db.deployment_update') @mock.patch("rally.objects.deploy.db.deployment_update")
@mock.patch('rally.objects.deploy.db.deployment_get') @mock.patch("rally.objects.deploy.db.deployment_get")
def test_destroy_deploy(self, mock_get, mock_update, mock_delete): def test_destroy_deploy(self, mock_get, mock_update, mock_delete):
mock_get.return_value = self.deployment mock_get.return_value = self.deployment
mock_update.return_value = self.deployment mock_update.return_value = self.deployment
@ -211,37 +213,37 @@ class APITestCase(test.TestCase):
mock_get.assert_called_once_with(self.deploy_uuid) mock_get.assert_called_once_with(self.deploy_uuid)
mock_delete.assert_called_once_with(self.deploy_uuid) mock_delete.assert_called_once_with(self.deploy_uuid)
@mock.patch('rally.objects.deploy.db.deployment_update') @mock.patch("rally.objects.deploy.db.deployment_update")
@mock.patch('rally.objects.deploy.db.deployment_get') @mock.patch("rally.objects.deploy.db.deployment_get")
def test_recreate_deploy(self, mock_get, mock_update): def test_recreate_deploy(self, mock_get, mock_update):
mock_get.return_value = self.deployment mock_get.return_value = self.deployment
mock_update.return_value = self.deployment mock_update.return_value = self.deployment
api.recreate_deploy(self.deploy_uuid) api.recreate_deploy(self.deploy_uuid)
mock_get.assert_called_once_with(self.deploy_uuid) mock_get.assert_called_once_with(self.deploy_uuid)
mock_update.assert_has_calls([ mock_update.assert_has_calls([
mock.call(self.deploy_uuid, {'endpoints': self.endpoints}) mock.call(self.deploy_uuid, self.endpoints)
]) ])
@mock.patch('rally.orchestrator.api.objects.Verification') @mock.patch("rally.orchestrator.api.objects.Verification")
@mock.patch('rally.verification.verifiers.tempest.tempest.Tempest') @mock.patch("rally.verification.verifiers.tempest.tempest.Tempest")
def test_verify(self, mock_tempest, mock_verification): def test_verify(self, mock_tempest, mock_verification):
mock_tempest.return_value = self.tempest mock_tempest.return_value = self.tempest
self.tempest.is_installed.return_value = True self.tempest.is_installed.return_value = True
api.verify(self.deploy_uuid, 'smoke', None) api.verify(self.deploy_uuid, "smoke", None)
self.tempest.is_installed.assert_called_once_with() self.tempest.is_installed.assert_called_once_with()
self.tempest.verify.assert_called_once_with(set_name='smoke', self.tempest.verify.assert_called_once_with(set_name="smoke",
regex=None) regex=None)
@mock.patch('rally.orchestrator.api.objects.Verification') @mock.patch("rally.orchestrator.api.objects.Verification")
@mock.patch('rally.verification.verifiers.tempest.tempest.Tempest') @mock.patch("rally.verification.verifiers.tempest.tempest.Tempest")
def test_verify_tempest_not_installed(self, mock_tempest, def test_verify_tempest_not_installed(self, mock_tempest,
mock_verification): mock_verification):
mock_tempest.return_value = self.tempest mock_tempest.return_value = self.tempest
self.tempest.is_installed.return_value = False self.tempest.is_installed.return_value = False
api.verify(self.deploy_uuid, 'smoke', None) api.verify(self.deploy_uuid, "smoke", None)
self.tempest.is_installed.assert_called_once_with() self.tempest.is_installed.assert_called_once_with()
self.tempest.install.assert_called_once_with() self.tempest.install.assert_called_once_with()
self.tempest.verify.assert_called_once_with(set_name='smoke', self.tempest.verify.assert_called_once_with(set_name="smoke",
regex=None) regex=None)

View File

@ -39,7 +39,7 @@ class ConfigTestCase(test.TestCase):
"password": "test", "password": "test",
"auth_url": "http://test/v2.0", "auth_url": "http://test/v2.0",
"permission": "admin"} "permission": "admin"}
mock_get.return_value = {"endpoints": [self.endpoint]} mock_get.return_value = {"admin": self.endpoint}
self.deploy_id = "fake_deploy_id" self.deploy_id = "fake_deploy_id"
self.conf_generator = config.TempestConf(self.deploy_id) self.conf_generator = config.TempestConf(self.deploy_id)
@ -84,7 +84,7 @@ class ConfigTestCase(test.TestCase):
self.conf_generator.keystoneclient.auth_ref = { self.conf_generator.keystoneclient.auth_ref = {
"serviceCatalog": [{ "serviceCatalog": [{
"name": service, "name": service,
"endpoints": [{"publicURL": url}] "admin": {"publicURL": url}
}]} }]}
self.assertEqual(self.conf_generator._get_url(service), url) self.assertEqual(self.conf_generator._get_url(service), url)