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]
|
[Unreleased]
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
Added
|
||||||
|
~~~~~
|
||||||
|
|
||||||
|
* Introducing ``rally env cleanup`` command for performing disaster cleanup.
|
||||||
|
|
||||||
Changed
|
Changed
|
||||||
~~~~~~~
|
~~~~~~~
|
||||||
|
|
||||||
@ -30,10 +35,11 @@ Changed
|
|||||||
allows us to show only those workloads which we are interested in (see the
|
allows us to show only those workloads which we are interested in (see the
|
||||||
examples below).
|
examples below).
|
||||||
Examples:
|
Examples:
|
||||||
1. show only failed workloads
|
|
||||||
``rally task detailed --filter-by sla-failures``
|
1. show only failed workloads
|
||||||
2. show only those workloads which include the next scenario plugin(s)
|
``rally task detailed --filter-by sla-failures``
|
||||||
``rally task detailed --filter-by scenarios=scenario1[,scenarios2...]``
|
2. show only those workloads which include the next scenario plugin(s)
|
||||||
|
``rally task detailed --filter-by scenarios=scenario1[,scenarios2...]``
|
||||||
|
|
||||||
Removed
|
Removed
|
||||||
~~~~~~~
|
~~~~~~~
|
||||||
|
@ -33,6 +33,7 @@ _rally()
|
|||||||
OPTS["deployment_show"]="--deployment"
|
OPTS["deployment_show"]="--deployment"
|
||||||
OPTS["deployment_use"]="--deployment"
|
OPTS["deployment_use"]="--deployment"
|
||||||
OPTS["env_check"]="--env --json --detailed"
|
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_create"]="--name --description --extras --from-sysenv --spec --json --no-use"
|
||||||
OPTS["env_delete"]="--env --force"
|
OPTS["env_delete"]="--env --force"
|
||||||
OPTS["env_destroy"]="--env --skip-cleanup --json --detailed"
|
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)
|
self._show(env.data, to_json=to_json, only_spec=False)
|
||||||
return 0
|
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,
|
@cliutils.args("--env", dest="env", type=str,
|
||||||
metavar="<uuid>", required=False,
|
metavar="<uuid>", required=False,
|
||||||
help="UUID or name of the env.")
|
help="UUID or name of the env.")
|
||||||
@ -124,6 +166,7 @@ class EnvCommands(object):
|
|||||||
% (NO, env, result["destroy_info"]["message"]), to_json)
|
% (NO, env, result["destroy_info"]["message"]), to_json)
|
||||||
else:
|
else:
|
||||||
_print("%s Successfully destroyed env %s" % (YES, env), to_json)
|
_print("%s Successfully destroyed env %s" % (YES, env), to_json)
|
||||||
|
|
||||||
if detailed or to_json:
|
if detailed or to_json:
|
||||||
print(json.dumps(result, indent=2))
|
print(json.dumps(result, indent=2))
|
||||||
|
|
||||||
@ -136,7 +179,7 @@ class EnvCommands(object):
|
|||||||
help="Delete DB records even if env is not destroyed.")
|
help="Delete DB records even if env is not destroyed.")
|
||||||
@envutils.with_default_env()
|
@envutils.with_default_env()
|
||||||
def delete(self, api, env=None, force=False):
|
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)
|
env_mgr.EnvManager.get(env).delete(force=force)
|
||||||
# TODO(boris-42): clear env variables if default one is deleted
|
# TODO(boris-42): clear env variables if default one is deleted
|
||||||
|
|
||||||
@ -196,6 +239,7 @@ class EnvCommands(object):
|
|||||||
@cliutils.suppress_warnings
|
@cliutils.suppress_warnings
|
||||||
@envutils.with_default_env()
|
@envutils.with_default_env()
|
||||||
def show(self, api, env=None, to_json=False, only_spec=False):
|
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
|
env_data = env_mgr.EnvManager.get(env).data
|
||||||
self._show(env_data, to_json=to_json, only_spec=only_spec)
|
self._show(env_data, to_json=to_json, only_spec=only_spec)
|
||||||
|
|
||||||
@ -206,7 +250,7 @@ class EnvCommands(object):
|
|||||||
help="Format output as JSON.")
|
help="Format output as JSON.")
|
||||||
@envutils.with_default_env()
|
@envutils.with_default_env()
|
||||||
def info(self, api, env=None, to_json=False):
|
def info(self, api, env=None, to_json=False):
|
||||||
"""Show environment information."""
|
"""Retrieve and show environment information."""
|
||||||
env = env_mgr.EnvManager.get(env)
|
env = env_mgr.EnvManager.get(env)
|
||||||
env_info = env.get_info()
|
env_info = env.get_info()
|
||||||
return_code = int(any(v.get("error") for v in env_info.values()))
|
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.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.env.env_mgr.EnvManager.get")
|
||||||
@mock.patch("rally.cli.commands.env.print")
|
@mock.patch("rally.cli.commands.env.print")
|
||||||
def test_destroy(self, mock_print, mock_env_manager_get):
|
def test_destroy(self, mock_print, mock_env_manager_get):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user