Add rally env cleanup command
This command should trigger cleanup of resources for the specified environment. Change-Id: I4c638d9a5ae5caadf0e5b9cdb78ec589e770cddf
This commit is contained in:
parent
760e926643
commit
0b110cb2c0
@ -20,6 +20,11 @@ Changelog
|
||||
[Unreleased]
|
||||
------------
|
||||
|
||||
Added
|
||||
~~~~~
|
||||
|
||||
* Introducing ``rally env cleanup`` command for performing disaster cleanup.
|
||||
|
||||
Changed
|
||||
~~~~~~~
|
||||
|
||||
@ -30,10 +35,11 @@ Changed
|
||||
allows us to show only those workloads which we are interested in (see the
|
||||
examples below).
|
||||
Examples:
|
||||
1. show only failed workloads
|
||||
``rally task detailed --filter-by sla-failures``
|
||||
2. show only those workloads which include the next scenario plugin(s)
|
||||
``rally task detailed --filter-by scenarios=scenario1[,scenarios2...]``
|
||||
|
||||
1. show only failed workloads
|
||||
``rally task detailed --filter-by sla-failures``
|
||||
2. show only those workloads which include the next scenario plugin(s)
|
||||
``rally task detailed --filter-by scenarios=scenario1[,scenarios2...]``
|
||||
|
||||
Removed
|
||||
~~~~~~~
|
||||
|
@ -33,6 +33,7 @@ _rally()
|
||||
OPTS["deployment_show"]="--deployment"
|
||||
OPTS["deployment_use"]="--deployment"
|
||||
OPTS["env_check"]="--env --json --detailed"
|
||||
OPTS["env_cleanup"]="--json --env"
|
||||
OPTS["env_create"]="--name --description --extras --from-sysenv --spec --json --no-use"
|
||||
OPTS["env_delete"]="--env --force"
|
||||
OPTS["env_destroy"]="--env --skip-cleanup --json --detailed"
|
||||
|
@ -101,6 +101,48 @@ class EnvCommands(object):
|
||||
self._show(env.data, to_json=to_json, only_spec=False)
|
||||
return 0
|
||||
|
||||
@cliutils.args("--json", action="store_true", dest="to_json",
|
||||
help="Format output as JSON.")
|
||||
@cliutils.args("--env", dest="env", type=str,
|
||||
metavar="<uuid>", required=False,
|
||||
help="UUID or name of the env.")
|
||||
@envutils.with_default_env()
|
||||
def cleanup(self, api, env=None, to_json=False):
|
||||
"""Perform disaster cleanup for specified environment.
|
||||
|
||||
Cases when Rally can leave undeleted resources after performing
|
||||
workload:
|
||||
|
||||
- Rally execution was interrupted and cleanup was not performed
|
||||
- The environment or a particular platform became unreachable which
|
||||
fail Rally execution of cleanup
|
||||
"""
|
||||
env = env_mgr.EnvManager.get(env)
|
||||
_print("Cleaning up resources for %s" % env, to_json)
|
||||
result = env.cleanup()
|
||||
|
||||
if to_json:
|
||||
print(json.dumps(result, indent=2))
|
||||
return int(any([p["errors"] for p in result.values()]))
|
||||
|
||||
print("Cleaning is finished. See the results bellow.")
|
||||
|
||||
return_code = 0
|
||||
for platform in sorted(result):
|
||||
cleanup_info = result[platform]
|
||||
print("\nInformation for %s platform." % platform)
|
||||
print("=" * 80)
|
||||
print("Status: %s" % cleanup_info["message"])
|
||||
for key in ("discovered", "deleted", "failed"):
|
||||
print("Total %s: %s" % (key, cleanup_info[key]))
|
||||
if cleanup_info["errors"]:
|
||||
return_code = 1
|
||||
errors = "\t- ".join(e["message"]
|
||||
for e in cleanup_info["errors"])
|
||||
print("Errors:\n\t- %s" % errors)
|
||||
|
||||
return return_code
|
||||
|
||||
@cliutils.args("--env", dest="env", type=str,
|
||||
metavar="<uuid>", required=False,
|
||||
help="UUID or name of the env.")
|
||||
@ -124,6 +166,7 @@ class EnvCommands(object):
|
||||
% (NO, env, result["destroy_info"]["message"]), to_json)
|
||||
else:
|
||||
_print("%s Successfully destroyed env %s" % (YES, env), to_json)
|
||||
|
||||
if detailed or to_json:
|
||||
print(json.dumps(result, indent=2))
|
||||
|
||||
@ -136,7 +179,7 @@ class EnvCommands(object):
|
||||
help="Delete DB records even if env is not destroyed.")
|
||||
@envutils.with_default_env()
|
||||
def delete(self, api, env=None, force=False):
|
||||
"""Deletes all records related to Env from db."""
|
||||
"""Deletes all records related to the environment from db."""
|
||||
env_mgr.EnvManager.get(env).delete(force=force)
|
||||
# TODO(boris-42): clear env variables if default one is deleted
|
||||
|
||||
@ -196,6 +239,7 @@ class EnvCommands(object):
|
||||
@cliutils.suppress_warnings
|
||||
@envutils.with_default_env()
|
||||
def show(self, api, env=None, to_json=False, only_spec=False):
|
||||
"""Show base information about the environment record."""
|
||||
env_data = env_mgr.EnvManager.get(env).data
|
||||
self._show(env_data, to_json=to_json, only_spec=only_spec)
|
||||
|
||||
@ -206,7 +250,7 @@ class EnvCommands(object):
|
||||
help="Format output as JSON.")
|
||||
@envutils.with_default_env()
|
||||
def info(self, api, env=None, to_json=False):
|
||||
"""Show environment information."""
|
||||
"""Retrieve and show environment information."""
|
||||
env = env_mgr.EnvManager.get(env)
|
||||
env_info = env.get_info()
|
||||
return_code = int(any(v.get("error") for v in env_info.values()))
|
||||
|
@ -153,6 +153,86 @@ class EnvCommandsTestCase(test.TestCase):
|
||||
mock.call(mock.ANY)
|
||||
])
|
||||
|
||||
@mock.patch("rally.env.env_mgr.EnvManager.get")
|
||||
@mock.patch("rally.cli.commands.env.print")
|
||||
def test_cleanup(self, mock_print, mock_env_manager_get):
|
||||
env_ = mock.Mock()
|
||||
env_inst = mock_env_manager_get.return_value
|
||||
env_inst.cleanup.return_value = {
|
||||
"existing@docker": {
|
||||
"message": "Success",
|
||||
"discovered": 5,
|
||||
"deleted": 5,
|
||||
"failed": 0,
|
||||
"errors": []
|
||||
},
|
||||
"existing@openstack": {
|
||||
"message": "It is OpenStack. several failures are ok :)",
|
||||
"discovered": 10,
|
||||
"deleted": 8,
|
||||
"failed": 2,
|
||||
"errors": [
|
||||
{"message": "Port disappeared",
|
||||
"traceback": "traceback"}
|
||||
]
|
||||
}
|
||||
}
|
||||
self.assertEqual(1, self.env.cleanup(self.api, env_))
|
||||
mock_env_manager_get.assert_called_once_with(env_)
|
||||
env_inst.cleanup.assert_called_once_with()
|
||||
|
||||
actual_print = "\n".join(
|
||||
[call_args[0]
|
||||
for call_args, _call_kwargs in mock_print.call_args_list])
|
||||
expected_print = (
|
||||
"Cleaning up resources for %(env)s\n"
|
||||
"Cleaning is finished. See the results bellow.\n"
|
||||
"\n"
|
||||
"Information for existing@docker platform.\n"
|
||||
"%(hr)s\n"
|
||||
"Status: Success\n"
|
||||
"Total discovered: 5\n"
|
||||
"Total deleted: 5\n"
|
||||
"Total failed: 0\n"
|
||||
"\n"
|
||||
"Information for existing@openstack platform.\n"
|
||||
"%(hr)s\n"
|
||||
"Status: It is OpenStack. several failures are ok :)\n"
|
||||
"Total discovered: 10\n"
|
||||
"Total deleted: 8\n"
|
||||
"Total failed: 2\n"
|
||||
"Errors:\n"
|
||||
"\t- Port disappeared" % {"env": env_inst, "hr": "=" * 80})
|
||||
self.assertEqual(expected_print, actual_print)
|
||||
|
||||
@mock.patch("rally.env.env_mgr.EnvManager.get")
|
||||
@mock.patch("rally.cli.commands.env.print")
|
||||
def test_cleanup_to_json(self, mock_print, mock_env_manager_get):
|
||||
env_ = mock.Mock()
|
||||
env_inst = mock_env_manager_get.return_value
|
||||
env_inst.cleanup.return_value = {
|
||||
"existing@docker": {
|
||||
"message": "Success",
|
||||
"discovered": 5,
|
||||
"deleted": 5,
|
||||
"failed": 0,
|
||||
"errors": []
|
||||
},
|
||||
"existing@openstack": {
|
||||
"message": "It is OpenStack. several failures are ok :)",
|
||||
"discovered": 10,
|
||||
"deleted": 8,
|
||||
"failed": 2,
|
||||
"errors": [
|
||||
{"message": "Port disappeared",
|
||||
"traceback": "traceback"}
|
||||
]
|
||||
}
|
||||
}
|
||||
self.assertEqual(1, self.env.cleanup(self.api, env_, to_json=True))
|
||||
mock_print.assert_called_once_with(
|
||||
json.dumps(env_inst.cleanup.return_value, indent=2))
|
||||
|
||||
@mock.patch("rally.env.env_mgr.EnvManager.get")
|
||||
@mock.patch("rally.cli.commands.env.print")
|
||||
def test_destroy(self, mock_print, mock_env_manager_get):
|
||||
|
Loading…
Reference in New Issue
Block a user