[CLI] Allow changing deployment config on recreate
* Added --filename option to deployment recreate that will update configuration from provided file. Change-Id: Icefca03fd86ab8977d0910bf192187c713cb355f
This commit is contained in:
parent
e70a75190f
commit
5ee6a18df2
@ -23,7 +23,7 @@ _rally()
|
||||
OPTS["deployment_create"]="--name --fromenv --filename --no-use"
|
||||
OPTS["deployment_destroy"]="--deployment"
|
||||
OPTS["deployment_list"]=""
|
||||
OPTS["deployment_recreate"]="--deployment"
|
||||
OPTS["deployment_recreate"]="--filename --deployment"
|
||||
OPTS["deployment_show"]="--deployment"
|
||||
OPTS["deployment_use"]="--deployment"
|
||||
OPTS["plugin_list"]="--name --namespace --plugin-base"
|
||||
|
19
rally/api.py
19
rally/api.py
@ -103,16 +103,33 @@ class _Deployment(object):
|
||||
deployment.delete()
|
||||
|
||||
@classmethod
|
||||
def recreate(cls, deployment):
|
||||
def recreate(cls, deployment, config=None):
|
||||
"""Performs a cleanup and then makes a deployment again.
|
||||
|
||||
:param deployment: UUID or name of the deployment
|
||||
:param config: an optional dict with deployment config to update before
|
||||
redeploy
|
||||
"""
|
||||
deployment = objects.Deployment.get(deployment)
|
||||
deployer = deploy_engine.Engine.get_engine(
|
||||
deployment["config"]["type"], deployment)
|
||||
|
||||
if config:
|
||||
if deployment["config"]["type"] != config["type"]:
|
||||
raise exceptions.RallyException(
|
||||
"Can't change deployment type.")
|
||||
try:
|
||||
deployer.validate(config)
|
||||
except jsonschema.ValidationError:
|
||||
LOG.error(_LE("Config schema validation error."))
|
||||
raise
|
||||
|
||||
with deployer:
|
||||
deployer.make_cleanup()
|
||||
|
||||
if config:
|
||||
deployment.update_config(config)
|
||||
|
||||
credentials = deployer.make_deploy()
|
||||
deployment.update_credentials(credentials)
|
||||
|
||||
|
@ -111,12 +111,14 @@ class DeploymentCommands(object):
|
||||
if do_use:
|
||||
self.use(api, deployment["uuid"])
|
||||
|
||||
@cliutils.args("--filename", type=str, required=False, metavar="<path>",
|
||||
help="Path to the configuration file of the deployment.")
|
||||
@cliutils.args("--deployment", dest="deployment", type=str,
|
||||
metavar="<uuid>", required=False,
|
||||
help="UUID or name of the deployment.")
|
||||
@envutils.with_default_deployment()
|
||||
@plugins.ensure_plugins_are_loaded
|
||||
def recreate(self, api, deployment=None):
|
||||
def recreate(self, api, deployment=None, filename=None):
|
||||
"""Destroy and create an existing deployment.
|
||||
|
||||
Unlike 'deployment destroy', the deployment database record
|
||||
@ -124,7 +126,12 @@ class DeploymentCommands(object):
|
||||
|
||||
:param deployment: UUID or name of the deployment
|
||||
"""
|
||||
api.deployment.recreate(deployment)
|
||||
config = None
|
||||
if filename:
|
||||
with open(filename, "rb") as deploy_file:
|
||||
config = yaml.safe_load(deploy_file.read())
|
||||
|
||||
api.deployment.recreate(deployment, config)
|
||||
|
||||
@cliutils.args("--deployment", dest="deployment", type=str,
|
||||
metavar="<uuid>", required=False,
|
||||
|
@ -73,11 +73,11 @@ class Engine(plugin.Plugin):
|
||||
self.deployment = deployment
|
||||
self.config = deployment["config"]
|
||||
|
||||
def validate(self):
|
||||
def validate(self, config=None):
|
||||
# TODO(sskripnick): remove this checking when config schema
|
||||
# is done for all available engines
|
||||
if hasattr(self, "CONFIG_SCHEMA"):
|
||||
jsonschema.validate(self.config, self.CONFIG_SCHEMA)
|
||||
jsonschema.validate(config or self.config, self.CONFIG_SCHEMA)
|
||||
|
||||
# FIXME(boris-42): Get rid of this method
|
||||
def get_provider(self):
|
||||
|
@ -83,6 +83,18 @@ class DeploymentTestCase(unittest.TestCase):
|
||||
self.rally("deployment recreate --deployment t_create_env")
|
||||
self.assertIn("t_create_env", self.rally("deployment list"))
|
||||
|
||||
def test_recreate_from_file(self):
|
||||
self.rally.env.update(utils.TEST_ENV)
|
||||
self.rally("deployment create --name t_create_env --fromenv")
|
||||
config = json.loads(self.rally("deployment config"))
|
||||
config["auth_url"] = "http://foo/"
|
||||
file = utils.JsonTempFile(config)
|
||||
self.rally("deployment recreate --deployment t_create_env "
|
||||
"--filename %s" % file.filename)
|
||||
self.assertIn("t_create_env", self.rally("deployment list"))
|
||||
self.assertEqual(config,
|
||||
json.loads(self.rally("deployment config")))
|
||||
|
||||
def test_use(self):
|
||||
self.rally.env.update(utils.TEST_ENV)
|
||||
output = self.rally(
|
||||
|
@ -53,7 +53,7 @@ class RallyCliError(Exception):
|
||||
return self.msg
|
||||
|
||||
|
||||
class TaskConfig(object):
|
||||
class JsonTempFile(object):
|
||||
|
||||
def __init__(self, config):
|
||||
config_file = tempfile.NamedTemporaryFile(delete=False)
|
||||
@ -65,6 +65,10 @@ class TaskConfig(object):
|
||||
os.unlink(self.filename)
|
||||
|
||||
|
||||
class TaskConfig(JsonTempFile):
|
||||
pass
|
||||
|
||||
|
||||
class Rally(object):
|
||||
"""Create and represent separate rally installation.
|
||||
|
||||
|
@ -131,7 +131,17 @@ class DeploymentCommandsTestCase(test.TestCase):
|
||||
deployment_id = "43924f8b-9371-4152-af9f-4cf02b4eced4"
|
||||
self.deployment.recreate(self.fake_api, deployment_id)
|
||||
self.fake_api.deployment.recreate.assert_called_once_with(
|
||||
deployment_id)
|
||||
deployment_id, None)
|
||||
|
||||
@mock.patch("rally.cli.commands.deployment.open",
|
||||
side_effect=mock.mock_open(read_data="{\"some\": \"json\"}"),
|
||||
create=True)
|
||||
def test_recreate_config(self, mock_open):
|
||||
deployment_id = "43924f8b-9371-4152-af9f-4cf02b4eced4"
|
||||
self.deployment.recreate(self.fake_api, deployment_id,
|
||||
filename="my.json")
|
||||
self.fake_api.deployment.recreate.assert_called_once_with(
|
||||
deployment_id, {"some": "json"})
|
||||
|
||||
@mock.patch("rally.cli.commands.deployment.envutils.get_global")
|
||||
def test_recreate_no_deployment_id(self, mock_get_global):
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
"""Test for api."""
|
||||
|
||||
import copy
|
||||
import os
|
||||
|
||||
import ddt
|
||||
@ -421,6 +422,50 @@ class DeploymentAPITestCase(BaseDeploymentTestCase):
|
||||
})
|
||||
])
|
||||
|
||||
@mock.patch("rally.common.objects.deploy.db.deployment_update")
|
||||
@mock.patch("rally.common.objects.deploy.db.deployment_get")
|
||||
def test_recreate_config(self, mock_deployment_get,
|
||||
mock_deployment_update):
|
||||
mock_deployment_get.return_value = self.deployment
|
||||
mock_deployment_update.return_value = self.deployment
|
||||
config = copy.deepcopy(self.deployment_config)
|
||||
config["admin"] = {"username": "admin",
|
||||
"password": "pass1",
|
||||
"tenant_name": "demo"}
|
||||
config["users"] = [{"username": "user1",
|
||||
"password": "pass2",
|
||||
"tenant_name": "demo"}]
|
||||
|
||||
api._Deployment.recreate(self.deployment_uuid, config)
|
||||
mock_deployment_get.assert_called_once_with(self.deployment_uuid)
|
||||
mock_deployment_update.assert_has_calls([
|
||||
mock.call(self.deployment_uuid, {"config": config}),
|
||||
])
|
||||
|
||||
@mock.patch("rally.common.objects.deploy.db.deployment_update")
|
||||
@mock.patch("rally.common.objects.deploy.db.deployment_get")
|
||||
def test_recreate_config_invalid(self, mock_deployment_get,
|
||||
mock_deployment_update):
|
||||
mock_deployment_get.return_value = self.deployment
|
||||
mock_deployment_update.return_value = self.deployment
|
||||
config = copy.deepcopy(self.deployment_config)
|
||||
config["admin"] = {"foo": "bar"}
|
||||
|
||||
self.assertRaises(jsonschema.ValidationError, api._Deployment.recreate,
|
||||
self.deployment_uuid, config)
|
||||
|
||||
@mock.patch("rally.common.objects.deploy.db.deployment_update")
|
||||
@mock.patch("rally.common.objects.deploy.db.deployment_get")
|
||||
def test_recreate_config_wrong_type(self, mock_deployment_get,
|
||||
mock_deployment_update):
|
||||
mock_deployment_get.return_value = self.deployment
|
||||
mock_deployment_update.return_value = self.deployment
|
||||
config = copy.deepcopy(self.deployment_config)
|
||||
config["type"] = "foo"
|
||||
|
||||
self.assertRaises(exceptions.RallyException, api._Deployment.recreate,
|
||||
self.deployment_uuid, config)
|
||||
|
||||
@mock.patch("rally.common.objects.deploy.db.deployment_get")
|
||||
def test_get(self, mock_deployment_get):
|
||||
deployment_id = "aaaa-bbbb-cccc-dddd"
|
||||
|
Loading…
Reference in New Issue
Block a user