Make return data of Deployment API serializable

Add method '.to_dict()' which allows converts returned result to
JSON format

Change-Id: Id005d6e224ae9351ad9786b7c2903616acc00ad8
This commit is contained in:
astaroverov 2017-03-07 16:30:53 +03:00
parent 44047515ab
commit df2c1807a3
11 changed files with 130 additions and 64 deletions

View File

@ -46,7 +46,7 @@ LOG = logging.getLogger(__name__)
class _Deployment(object):
@classmethod
def create(cls, config, name):
def _create(cls, config, name):
"""Create a deployment.
:param config: a dict with deployment configuration
@ -76,6 +76,10 @@ class _Deployment(object):
deployment.update_credentials(credentials)
return deployment
@classmethod
def create(cls, config, name):
return cls._create(config, name).to_dict()
@classmethod
def destroy(cls, deployment):
"""Destroy the deployment.
@ -133,7 +137,7 @@ class _Deployment(object):
deployment.update_credentials(credentials)
@classmethod
def get(cls, deployment):
def _get(cls, deployment):
"""Get the deployment.
:param deployment: UUID or name of the deployment
@ -141,6 +145,10 @@ class _Deployment(object):
"""
return objects.Deployment.get(deployment)
@classmethod
def get(cls, deployment):
return cls._get(deployment).to_dict()
@classmethod
def service_list(cls, deployment):
"""Get the services list.
@ -164,10 +172,11 @@ class _Deployment(object):
def check(cls, deployment):
"""Check keystone authentication and list all available services.
:param deployment: UUID of deployment
:returns: Service list
"""
# TODO(astudenov): make this method platform independent
creds = deployment.get_credentials_for("openstack")
creds = cls._get(deployment).get_credentials_for("openstack")
creds["admin"].verify_connection()
for user in creds["users"]:
user.verify_connection()

View File

@ -111,7 +111,7 @@ class DeploymentCommands(object):
self.list(api, deployment_list=[deployment])
if do_use:
self.use(api, deployment["uuid"])
self.use(api, deployment)
@cliutils.args("--filename", type=str, required=False, metavar="<path>",
help="Path to the configuration file of the deployment.")
@ -206,13 +206,13 @@ class DeploymentCommands(object):
table_rows = []
deployment = api.deployment.get(deployment)
creds = deployment.get_credentials_for("openstack")
creds = deployment["credentials"]["openstack"][0]
users = creds["users"]
admin = creds["admin"]
credentials = users + [admin] if admin else users
for ep in credentials:
data = ["***" if m == "password" else getattr(ep, m, "")
data = ["***" if m == "password" else ep.get(m, "")
for m in headers]
table_rows.append(utils.Struct(**dict(zip(headers, data))))
cliutils.print_list(table_rows, headers)
@ -230,17 +230,12 @@ class DeploymentCommands(object):
# TODO(astudenov): make this method platform independent
headers = ["services", "type", "status"]
table_rows = []
try:
deployment = api.deployment.get(deployment)
except exceptions.DeploymentNotFound:
print(_("Deployment %s is not found.") % deployment)
return(1)
deployment = api.deployment.get(deployment)
try:
services = api.deployment.check(deployment)
services = api.deployment.check(deployment["uuid"])
except keystone_exceptions.ConnectionRefused:
admin = deployment.get_credentials_for("openstack")["admin"]
admin = deployment["credentials"]["openstack"][0]["admin"]
print(_("Unable to connect %s.") % admin.auth_url)
return(1)
@ -310,16 +305,16 @@ class DeploymentCommands(object):
"""
# TODO(astudenov): make this method platform independent
try:
deployment = api.deployment.get(deployment)
if not isinstance(deployment, dict):
deployment = api.deployment.get(deployment)
print("Using deployment: %s" % deployment["uuid"])
fileutils.update_globals_file("RALLY_DEPLOYMENT",
deployment["uuid"])
creds = deployment.get_credentials_for("openstack")
credential = creds["admin"] or creds["users"][0]
creds = deployment["credentials"]["openstack"][0]
self._update_openrc_deployment_file(
deployment["uuid"], credential.to_dict())
deployment["uuid"], creds["admin"] or creds["users"][0])
print("~/.rally/openrc was updated\n\nHINTS:\n"
"\n* To use standard OpenStack clients, set up your env by "
"running:\n\tsource ~/.rally/openrc\n"

View File

@ -52,6 +52,7 @@ CREDENTIALS_SCHEMA = {
class Deployment(object):
"""Represents a deployment object."""
TIME_FORMAT = consts.TimeFormat.ISO8601
def __init__(self, deployment=None, **attributes):
if deployment:
@ -68,6 +69,15 @@ class Deployment(object):
return self.get_credentials_for("openstack")[key]
return self.deployment[key]
def to_dict(self):
result = {}
formatters = ["created_at", "completed_at", "started_at", "updated_at"]
for field, value in self.deployment.items():
if field in formatters:
value = value.strftime(self.TIME_FORMAT)
result[field] = value
return result
@staticmethod
def get(deploy):
return Deployment(db.deployment_get(deploy))

View File

@ -19,7 +19,7 @@ from rally import consts
class Verification(object):
"""Represents a verification object."""
TIME_FORMAT = consts.TimeFormat.TIME_FORMAT_ISO8601
TIME_FORMAT = consts.TimeFormat.ISO8601
def __init__(self, verification):
"""Init a verification object.

View File

@ -21,7 +21,7 @@ from rally.verification import manager
class Verifier(object):
"""Represents a verifier object."""
TIME_FORMAT = consts.TimeFormat.TIME_FORMAT_ISO8601
TIME_FORMAT = consts.TimeFormat.ISO8601
def __init__(self, verifier):
"""Init a verifier object.

View File

@ -216,7 +216,7 @@ class _VerificationStatus(utils.ImmutableMixin, utils.EnumMixin):
class _TimeFormat(utils.ImmutableMixin, utils.EnumMixin):
"""International time formats"""
TIME_FORMAT_ISO8601 = "%Y-%m-%dT%H:%M:%S%z"
ISO8601 = "%Y-%m-%dT%H:%M:%S%z"
TaskStatus = _TaskStatus()

View File

@ -26,7 +26,7 @@ from rally.verification import reporter
SKIP_RE = re.compile("Skipped until Bug: ?(?P<bug_number>\d+) is resolved.")
LP_BUG_LINK = "https://launchpad.net/bugs/%s"
TIME_FORMAT = consts.TimeFormat.TIME_FORMAT_ISO8601
TIME_FORMAT = consts.TimeFormat.ISO8601
@reporter.configure("json")

View File

@ -58,7 +58,7 @@ class TestTaskSamples(unittest.TestCase):
db.CONF, connection="sqlite:///%s/db" % rally.tmp_dir)
# let's use pre-created users to make TestTaskSamples quicker
deployment = api.Deployment.get("MAIN")
deployment = api._Deployment._get("MAIN")
admin_cred = deployment.get_credentials_for("openstack")["admin"]
ctx = {"admin": {"credential": admin_cred},
@ -69,6 +69,7 @@ class TestTaskSamples(unittest.TestCase):
config = deployment["config"]
os_creds = config["creds"]["openstack"]
user = copy.copy(os_creds["admin"])
user["username"] = ctx["users"][0]["credential"].username
user["password"] = ctx["users"][0]["credential"].password

View File

@ -132,7 +132,7 @@ class DeploymentCommandsTestCase(test.TestCase):
mock_deployment_commands_list.assert_called_once_with(
self.fake_api, deployment_list=[{"uuid": "uuid"}])
mock_deployment_commands_use.assert_called_once_with(
self.fake_api, "uuid")
self.fake_api, self.fake_api.deployment.create.return_value)
def test_recreate(self):
deployment_id = "43924f8b-9371-4152-af9f-4cf02b4eced4"
@ -237,18 +237,17 @@ class DeploymentCommandsTestCase(test.TestCase):
@mock.patch("rally.cli.commands.deployment.utils.Struct")
def test_show(self, mock_struct, mock_print_list):
deployment_id = "b1a6153e-a314-4cb3-b63b-cf08c1a416c3"
value = {
"admin": fakes.fake_credential(
auth_url="url",
username="u",
password="p",
tenant_name="t",
region_name="r",
endpoint_type=consts.EndpointType.INTERNAL),
"users": []
}
deployment = self.fake_api.deployment.get.return_value
deployment.get_credentials_for.return_value = value
value = {"admin": {"auth_url": "url",
"username": "u",
"password": "p",
"tenant_name": "t",
"region_name": "r",
"endpoint_type": consts.EndpointType.INTERNAL},
"users": []}
deployment = self.fake_api.deployment.get
deployment.return_value = {"credentials": {"openstack": [
{"admin": value["admin"],
"users": []}]}}
self.deployment.show(self.fake_api, deployment_id)
self.fake_api.deployment.get.assert_called_once_with(deployment_id)
@ -273,12 +272,12 @@ class DeploymentCommandsTestCase(test.TestCase):
deployment_id = "593b683c-4b16-4b2b-a56b-e162bd60f10b"
self.fake_api.deployment.get.return_value = fakes.FakeDeployment(
uuid=deployment_id,
admin=fakes.fake_credential(**{"auth_url": "fake_auth_url",
"username": "fake_username",
"password": "fake_password",
"tenant_name": "fake_tenant_name",
"endpoint": "fake_endpoint",
"region_name": None}))
admin={"auth_url": "fake_auth_url",
"username": "fake_username",
"password": "fake_password",
"tenant_name": "fake_tenant_name",
"endpoint": "fake_endpoint",
"region_name": None})
with mock.patch("rally.cli.commands.deployment.open", mock.mock_open(),
create=True) as mock_file:
@ -310,7 +309,7 @@ class DeploymentCommandsTestCase(test.TestCase):
self.fake_api.deployment.get.return_value = fakes.FakeDeployment(
uuid=deployment_id,
admin=fakes.fake_credential(**{
admin={
"auth_url": "http://localhost:5000/v3",
"username": "fake_username",
"password": "fake_password",
@ -318,7 +317,7 @@ class DeploymentCommandsTestCase(test.TestCase):
"endpoint": "fake_endpoint",
"region_name": None,
"user_domain_name": "fake_user_domain",
"project_domain_name": "fake_project_domain"}))
"project_domain_name": "fake_project_domain"})
with mock.patch("rally.cli.commands.deployment.open", mock.mock_open(),
create=True) as mock_file:
@ -360,7 +359,7 @@ class DeploymentCommandsTestCase(test.TestCase):
mock_update_globals_file.assert_called_once_with(
envutils.ENV_DEPLOYMENT, "fake_uuid")
mock__update_openrc_deployment_file.assert_called_once_with(
"fake_uuid", {"foo": "fake_credentials"})
"fake_uuid", fake_credential)
def test_deployment_not_found(self):
deployment_id = "e87e4dca-b515-4477-888d-5f6103f13b42"
@ -374,33 +373,30 @@ class DeploymentCommandsTestCase(test.TestCase):
sample_credential = fakes.fake_credential(
auth_url="http://192.168.1.1:5000/v2.0/",
username="admin", password="adminpass")
deployment = {"admin": sample_credential,
"users": [sample_credential]}
deployment = {"uuid": deployment_id,
"credentials": {"openstack": [
{"admin": sample_credential,
"users": [sample_credential]}]}}
self.fake_api.deployment.get.return_value = deployment
self.fake_api.deployment.check.return_value = {}
self.deployment.check(self.fake_api, deployment_id)
self.fake_api.deployment.get.assert_called_once_with(deployment_id)
self.fake_api.deployment.check.assert_called_once_with(deployment)
self.fake_api.deployment.check.assert_called_once_with(deployment_id)
headers = ["services", "type", "status"]
mock_print_list.assert_called_once_with([], headers)
def test_deployment_check_not_exist(self):
deployment_id = "e87e4dca-b515-4477-888d-5f6103f13b42"
exc = exceptions.DeploymentNotFound(deployment=deployment_id)
self.fake_api.deployment.get.side_effect = exc
self.assertEqual(self.deployment.check(
self.fake_api, deployment_id), 1)
def test_deployment_check_raise(self):
deployment_id = "e87e4dca-b515-4477-888d-5f6103f13b42"
sample_credential = fakes.fake_credential(
auth_url="http://192.168.1.1:5000/v2.0/",
username="admin", password="adminpass")
deployment = self.fake_api.deployment.get.return_value
deployment.get_credentials_for.return_value = {
"admin": sample_credential, "users": []}
deployment = {"uuid": deployment_id,
"credentials": {"openstack": [
{"admin": sample_credential,
"users": [sample_credential]}]}}
self.fake_api.deployment.get.return_value = deployment
refused = keystone_exceptions.ConnectionRefused()
self.fake_api.deployment.check.side_effect = refused
self.assertEqual(self.deployment.check(

View File

@ -15,6 +15,7 @@
"""Tests for db.deploy layer."""
import datetime as dt
import jsonschema
import mock
@ -25,6 +26,8 @@ from tests.unit import test
class DeploymentTestCase(test.TestCase):
TIME_FORMAT = consts.TimeFormat.ISO8601
def setUp(self):
super(DeploymentTestCase, self).setUp()
self.deployment = {
@ -229,3 +232,53 @@ class DeploymentTestCase(test.TestCase):
{"completed_at": "fake_time",
"status": consts.DeployStatus.DEPLOY_FINISHED}
)
def test_to_dict(self):
self.deployment = {
"status": "deploy->finished",
"parent_uuid": None,
"updated_at": dt.datetime(2017, 3, 10, 9, 5, 9, 117427),
"completed_at": dt.datetime(2017, 3, 10, 12, 5, 9, 94981),
"credentials":
{"openstack":
[{"admin":
{"username": "foo_admin_name",
"endpoint": None,
"region_name": "FooRegionOne",
"https_insecure": False,
"permission": "foo_perm",
"tenant_name": "foo_tenant",
"user_domain_name": "Default",
"https_cacert": "",
"domain_name": None,
"endpoint_type": None,
"auth_url": "foo_auth_url",
"password": "admin",
"project_domain_name": "Default"},
"users": []}]},
"started_at": dt.datetime(2017, 3, 10, 12, 5, 9, 78779),
"id": 1,
"name": "foo_deployment_name",
"uuid": "eeecf2c6-8b5d-4ed7-92e5-b7cdc335e885",
"created_at": dt.datetime(2017, 3, 10, 9, 5, 9, 68652),
"config": {
"endpoint": None,
"region_name": "FooRegionOne",
"https_insecure": False,
"admin": {
"username": "foo_admin_name",
"password": "foo_admin_pwd",
"user_domain_name": "Default",
"project_name": "foo_prj_name",
"project_domain_name": "Default"},
"https_cacert": "",
"endpoint_type": None,
"auth_url": "foo_auth_url",
"type": "ExistingCloud"}}
deploy = objects.Deployment(deployment=self.deployment)
expected_result = deploy.to_dict()
for field in ["created_at", "completed_at",
"started_at", "updated_at"]:
self.deployment[field] = self.deployment[field].strftime(
self.TIME_FORMAT)
self.assertEqual(expected_result, self.deployment)

View File

@ -354,7 +354,7 @@ class DeploymentAPITestCase(BaseDeploymentTestCase):
mock_deployment_create.return_value = self.deployment
mock_deployment_update.return_value = self.deployment
dep = api._Deployment.create(self.deployment_config, "fake_deployment")
self.assertIsInstance(dep, objects.Deployment)
self.assertIsInstance(dep, dict)
mock_deployment_create.assert_called_once_with({
"name": "fake_deployment",
"config": self.deployment_config,
@ -487,14 +487,16 @@ class DeploymentAPITestCase(BaseDeploymentTestCase):
for key in self.deployment:
self.assertEqual(ret[key], self.deployment[key])
def test_deployment_check(self):
@mock.patch("rally.common.objects.Deployment.get")
def test_deployment_check(self, mock_deployment_get):
fake_credential1 = fakes.fake_credential()
fake_credential2 = fakes.fake_credential()
deployment = mock.Mock(spec=objects.Deployment)
deployment.get_credentials_for.return_value = {
mock_deployment_get.return_value.get_credentials_for.return_value = {
"admin": fake_credential1, "users": [fake_credential2]}
result = api._Deployment.check(deployment)
result = api._Deployment.check("uuid")
fake_credential1.verify_connection.assert_called_once_with()
fake_credential2.verify_connection.assert_called_once_with()
self.assertEqual(fake_credential1.list_services.return_value, result)