[api versions]Support to specify api versions in the spec of env
Spec example: Specify cinder client version { "openstack": { "auth_url": "http://example.net:5000/v2.0/", "region_name": "RegionOne", "endpoint_type": "public", "admin": { "username": "admin", "password": "myadminpass", "tenant_name": "demo" }, "https_insecure": false, "https_cacert": "" "api_info": { "cinder": { "version": "1", "service_type": "volume" } } } } Change-Id: I74578e3b1c4e7b662ba66955ef9fb62cd4eeb788
This commit is contained in:
parent
467cc05559
commit
0a73f8ae80
@ -27,6 +27,7 @@ Added
|
||||
``existing@openstack`` platform to represent client certificate bundle and
|
||||
key files. Also the support for appropriate system environment variables (
|
||||
``OS_CERT``, ``OS_KEY``) is added.
|
||||
* Support client api option while deploying platform.
|
||||
|
||||
Changed
|
||||
~~~~~~~
|
||||
|
@ -14,6 +14,7 @@
|
||||
# under the License.
|
||||
|
||||
import collections
|
||||
import copy
|
||||
import uuid
|
||||
|
||||
from rally.common import broker
|
||||
@ -106,8 +107,14 @@ class UserGenerator(context.Context):
|
||||
|
||||
creds = self.env["platforms"]["openstack"]
|
||||
if creds.get("admin"):
|
||||
admin_cred = copy.deepcopy(creds["admin"])
|
||||
api_info = copy.deepcopy(creds.get("api_info", {}))
|
||||
if "api_info" in admin_cred:
|
||||
api_info.update(creds["admin"]["api_info"])
|
||||
admin_cred["api_info"] = api_info
|
||||
context["admin"] = {
|
||||
"credential": credential.OpenStackCredential(**creds["admin"])}
|
||||
"credential": credential.OpenStackCredential(**admin_cred)
|
||||
}
|
||||
|
||||
if creds["users"] and not (set(self.config) - {"user_choice_method"}):
|
||||
self.existing_users = creds["users"]
|
||||
@ -218,7 +225,8 @@ class UserGenerator(context.Context):
|
||||
https_cacert=self.credential["https_cacert"],
|
||||
region_name=self.credential["region_name"],
|
||||
profiler_hmac_key=self.credential["profiler_hmac_key"],
|
||||
profiler_conn_str=self.credential["profiler_conn_str"])
|
||||
profiler_conn_str=self.credential["profiler_conn_str"],
|
||||
api_info=self.credential["api_info"])
|
||||
users.append({"id": user.id,
|
||||
"credential": user_credential,
|
||||
"tenant_id": tenant_id})
|
||||
@ -284,7 +292,13 @@ class UserGenerator(context.Context):
|
||||
|
||||
def use_existing_users(self):
|
||||
LOG.debug("Using existing users for OpenStack platform.")
|
||||
api_info = copy.deepcopy(self.env["platforms"]["openstack"].get(
|
||||
"api_info", {}))
|
||||
for user_credential in self.existing_users:
|
||||
user_credential = copy.deepcopy(user_credential)
|
||||
if "api_info" in user_credential:
|
||||
api_info.update(user_credential["api_info"])
|
||||
user_credential["api_info"] = api_info
|
||||
user_credential = credential.OpenStackCredential(**user_credential)
|
||||
user_clients = osclients.Clients(user_credential)
|
||||
user_id = user_clients.keystone.auth_ref.user_id
|
||||
|
@ -28,7 +28,8 @@ class OpenStackCredential(dict):
|
||||
domain_name=None, endpoint=None, user_domain_name=None,
|
||||
project_domain_name=None,
|
||||
https_insecure=False, https_cacert=None, https_cert=None,
|
||||
profiler_hmac_key=None, profiler_conn_str=None, **kwargs):
|
||||
profiler_hmac_key=None, profiler_conn_str=None,
|
||||
api_info=None, **kwargs):
|
||||
if kwargs:
|
||||
raise TypeError("%s" % kwargs)
|
||||
|
||||
@ -50,7 +51,8 @@ class OpenStackCredential(dict):
|
||||
("https_cacert", https_cacert),
|
||||
("https_cert", https_cert),
|
||||
("profiler_hmac_key", profiler_hmac_key),
|
||||
("profiler_conn_str", profiler_conn_str)
|
||||
("profiler_conn_str", profiler_conn_str),
|
||||
("api_info", api_info or {})
|
||||
])
|
||||
|
||||
self._clients_cache = {}
|
||||
|
@ -111,7 +111,8 @@ class OSClient(plugin.Plugin):
|
||||
self.credential = credential
|
||||
if not isinstance(self.credential, oscred.OpenStackCredential):
|
||||
self.credential = oscred.OpenStackCredential(**self.credential)
|
||||
self.api_info = api_info
|
||||
if api_info:
|
||||
self.credential.api_info.update(api_info)
|
||||
self.cache = cache_obj
|
||||
|
||||
def choose_version(self, version=None):
|
||||
@ -138,8 +139,8 @@ class OSClient(plugin.Plugin):
|
||||
# For those clients which doesn't accept string value(for example
|
||||
# zaqarclient), this method should be overridden.
|
||||
version = (version or
|
||||
self.api_info.get(self.get_name(), {}).get("version") or
|
||||
self._meta_get("default_version"))
|
||||
self.credential.api_info.get(self.get_name(), {}).get(
|
||||
"version") or self._meta_get("default_version"))
|
||||
if version is not None:
|
||||
version = str(version)
|
||||
return version
|
||||
@ -172,8 +173,8 @@ class OSClient(plugin.Plugin):
|
||||
service type from api_info(configured from a context) and default.
|
||||
"""
|
||||
return (service_type or
|
||||
self.api_info.get(self.get_name(), {}).get("service_type") or
|
||||
self._meta_get("default_service_type"))
|
||||
self.credential.api_info.get(self.get_name(), {}).get(
|
||||
"service_type") or self._meta_get("default_service_type"))
|
||||
|
||||
@classmethod
|
||||
def is_service_type_configurable(cls):
|
||||
@ -184,7 +185,7 @@ class OSClient(plugin.Plugin):
|
||||
|
||||
@property
|
||||
def keystone(self):
|
||||
return OSClient.get("keystone")(self.credential, self.api_info,
|
||||
return OSClient.get("keystone")(self.credential, None,
|
||||
self.cache)
|
||||
|
||||
def _get_endpoint(self, service_type=None):
|
||||
|
@ -33,6 +33,13 @@ class OpenStack(platform.Platform):
|
||||
|
||||
It may be used to test any existing OpenStack API compatible cloud.
|
||||
"""
|
||||
VERSION_SCHEMA = {
|
||||
"anyOf": [
|
||||
{"type": "string", "description": "a string-like version."},
|
||||
{"type": "number", "description": "a number-like version."}
|
||||
]
|
||||
}
|
||||
|
||||
CONFIG_SCHEMA = {
|
||||
"type": "object",
|
||||
"definitions": {
|
||||
@ -63,6 +70,21 @@ class OpenStack(platform.Platform):
|
||||
"additionalProperties": False
|
||||
}
|
||||
],
|
||||
},
|
||||
"api_info": {
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^[a-z]+$": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"version": VERSION_SCHEMA,
|
||||
"service_type": {"type": "string"}
|
||||
},
|
||||
"minProperties": 1,
|
||||
"additionalProperties": False
|
||||
}
|
||||
},
|
||||
"additionalProperties": False
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
@ -81,7 +103,8 @@ class OpenStack(platform.Platform):
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/definitions/user"},
|
||||
"minItems": 1
|
||||
}
|
||||
},
|
||||
"api_info": {"$ref": "#/definitions/api_info"}
|
||||
},
|
||||
"anyOf": [
|
||||
{
|
||||
@ -115,6 +138,7 @@ class OpenStack(platform.Platform):
|
||||
del new_data["endpoint"]
|
||||
admin = new_data.pop("admin", None)
|
||||
users = new_data.pop("users", [])
|
||||
api_info = new_data.pop("api_info", None)
|
||||
|
||||
if new_data.get("https_cert") and new_data.get("https_key"):
|
||||
new_data["https_cert"] = (new_data["https_cert"],
|
||||
@ -132,7 +156,10 @@ class OpenStack(platform.Platform):
|
||||
user.update(new_data)
|
||||
for k, v in defaults.items():
|
||||
user.setdefault(k, v)
|
||||
return {"admin": admin, "users": users}, {}
|
||||
platform_data = {"admin": admin, "users": users}
|
||||
if api_info:
|
||||
platform_data["api_info"] = api_info
|
||||
return platform_data, {}
|
||||
|
||||
def destroy(self):
|
||||
# NOTE(boris-42): No action need to be performed.
|
||||
|
@ -28,3 +28,9 @@ existing-with-predefined-users.json
|
||||
If you are using read-only backend in Keystone like LDAP, AD then
|
||||
you need this sample. If you don't specify "users" rally will use already
|
||||
existing users that you provide.
|
||||
|
||||
existing-api.json
|
||||
--------------------------------
|
||||
|
||||
If you expect to specify version of some clients, you could register existing
|
||||
Openstack cluster like this sample.
|
||||
|
20
samples/deployments/existing-api.json
Normal file
20
samples/deployments/existing-api.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"openstack": {
|
||||
"auth_url": "http://example.net:5000/v2.0/",
|
||||
"region_name": "RegionOne",
|
||||
"endpoint_type": "public",
|
||||
"admin": {
|
||||
"username": "admin",
|
||||
"password": "myadminpass",
|
||||
"tenant_name": "demo"
|
||||
},
|
||||
"https_insecure": false,
|
||||
"https_cacert": ""
|
||||
"api_info": {
|
||||
"specified_client_name": {
|
||||
"version": "version_number",
|
||||
"service_type": "service_type"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
39
tests/functional/extra/fake_dir/fake_plugin.py
Normal file
39
tests/functional/extra/fake_dir/fake_plugin.py
Normal file
@ -0,0 +1,39 @@
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from rally_openstack import osclients
|
||||
from rally_openstack import scenario
|
||||
|
||||
|
||||
@osclients.configure("fakedummy", default_version="1",
|
||||
default_service_type="dummy",
|
||||
supported_versions=["1", "2"])
|
||||
class FakeDummy(osclients.OSClient):
|
||||
def create_client(self, version=None, service_type=None):
|
||||
version = self.choose_version(version)
|
||||
service_type = self.choose_service_type(service_type)
|
||||
return {"version": version, "service_type": service_type}
|
||||
|
||||
|
||||
@scenario.configure(name="FakeDummy.openstack_api")
|
||||
class FakeDummyOpenstackAPI(scenario.OpenStackScenario):
|
||||
|
||||
def run(self):
|
||||
admin_client = self.admin_clients("fakedummy")
|
||||
self.assertEqual("dummyv2", admin_client["service_type"])
|
||||
self.assertEqual("2", admin_client["version"])
|
||||
|
||||
client = self.clients("fakedummy")
|
||||
self.assertEqual("dummyv2", client["service_type"])
|
||||
self.assertEqual("2", client["version"])
|
81
tests/functional/test_cli_task.py
Normal file
81
tests/functional/test_cli_task.py
Normal file
@ -0,0 +1,81 @@
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import json
|
||||
import unittest
|
||||
|
||||
from tests.functional import utils
|
||||
|
||||
|
||||
class TaskTestCase(unittest.TestCase):
|
||||
|
||||
def test_specify_version_by_deployment(self):
|
||||
rally = utils.Rally()
|
||||
deployment = json.loads(rally("deployment config"))
|
||||
deployment["openstack"]["api_info"] = {
|
||||
"fakedummy": {
|
||||
"version": "2",
|
||||
"service_type": "dummyv2"
|
||||
}
|
||||
}
|
||||
deployment = utils.JsonTempFile(deployment)
|
||||
rally("deployment create --name t_create_with_api_info "
|
||||
"--filename %s" % deployment.filename)
|
||||
self.assertIn("t_create_with_api_info", rally("deployment list"))
|
||||
|
||||
config = {
|
||||
"FakeDummy.openstack_api": [
|
||||
{
|
||||
"runner": {
|
||||
"type": "constant",
|
||||
"times": 1,
|
||||
"concurrency": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
config = utils.TaskConfig(config)
|
||||
plugins = "tests/functional/extra/fake_dir/fake_plugin.py"
|
||||
rally("--plugin-paths %s task start --task %s" % (
|
||||
plugins, config.filename))
|
||||
|
||||
def test_specify_version_by_deployment_with_existing_users(self):
|
||||
rally = utils.Rally()
|
||||
deployment = json.loads(rally("deployment config"))
|
||||
deployment["openstack"]["users"] = [deployment["openstack"]["admin"]]
|
||||
deployment["openstack"]["api_info"] = {
|
||||
"fakedummy": {
|
||||
"version": "2",
|
||||
"service_type": "dummyv2"
|
||||
}
|
||||
}
|
||||
deployment = utils.JsonTempFile(deployment)
|
||||
rally("deployment create --name t_create_with_api_info "
|
||||
"--filename %s" % deployment.filename)
|
||||
self.assertIn("t_create_with_api_info", rally("deployment list"))
|
||||
config = {
|
||||
"FakeDummy.openstack_api": [
|
||||
{
|
||||
"runner": {
|
||||
"type": "constant",
|
||||
"times": 1,
|
||||
"concurrency": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
config = utils.TaskConfig(config)
|
||||
plugins = "tests/functional/extra/fake_dir/fake_plugin.py"
|
||||
rally("--plugin-paths %s task start --task %s" % (
|
||||
plugins, config.filename))
|
@ -75,6 +75,25 @@ class ExistingPlatformTestCase(PlatformBaseTestCase):
|
||||
spec, spec["existing@openstack"])
|
||||
self.assertNotEqual([], result)
|
||||
|
||||
def test_validate_spec_schema_with_api_info(self):
|
||||
spec = {
|
||||
"existing@openstack": {
|
||||
"auth_url": "url",
|
||||
"admin": {
|
||||
"username": "admin",
|
||||
"password": "password123",
|
||||
"tenant_name": "admin"
|
||||
},
|
||||
"api_info": {
|
||||
"nova": {"version": 1},
|
||||
"cinder": {"version": 2, "service_type": "volumev2"}
|
||||
}
|
||||
}
|
||||
}
|
||||
result = platform.Platform.validate("existing@openstack", {},
|
||||
spec, spec["existing@openstack"])
|
||||
self.assertEqual([], result)
|
||||
|
||||
def test_create_users_only(self):
|
||||
|
||||
spec = {
|
||||
|
@ -43,7 +43,8 @@ class OpenStackCredentialTestCase(test.TestCase):
|
||||
"project_domain_name": None,
|
||||
"user_domain_name": None,
|
||||
"profiler_hmac_key": None,
|
||||
"profiler_conn_str": None},
|
||||
"profiler_conn_str": None,
|
||||
"api_info": {}},
|
||||
self.credential.to_dict())
|
||||
|
||||
@mock.patch("rally_openstack.osclients.Clients")
|
||||
|
Loading…
Reference in New Issue
Block a user