Merge "compute: Add 'server * --all-projects' option"

This commit is contained in:
Zuul 2021-03-03 17:01:33 +00:00 committed by Gerrit Code Review
commit 011991bcf3
4 changed files with 136 additions and 8 deletions

View File

@ -31,6 +31,7 @@ from osc_lib.cli import parseractions
from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
from oslo_utils import strutils
from openstackclient.i18n import _
from openstackclient.identity import common as identity_common
@ -193,6 +194,24 @@ def _prep_server_detail(compute_client, image_client, server, refresh=True):
return info
def boolenv(*vars, default=False):
"""Search for the first defined of possibly many bool-like env vars.
Returns the first environment variable defined in vars, or returns the
default.
:param vars: Arbitrary strings to search for. Case sensitive.
:param default: The default to return if no value found.
:returns: A boolean corresponding to the value found, else the default if
no value found.
"""
for v in vars:
value = os.environ.get(v, None)
if value:
return strutils.bool_from_string(value)
return default
class AddFixedIP(command.Command):
_description = _("Add fixed IP address to server")
@ -1322,6 +1341,15 @@ class DeleteServer(command.Command):
action='store_true',
help=_('Force delete server(s)'),
)
parser.add_argument(
'--all-projects',
action='store_true',
default=boolenv('ALL_PROJECTS'),
help=_(
'Delete server(s) in another project by name (admin only)'
'(can be specified using the ALL_PROJECTS envvar)'
),
)
parser.add_argument(
'--wait',
action='store_true',
@ -1339,7 +1367,8 @@ class DeleteServer(command.Command):
compute_client = self.app.client_manager.compute
for server in parsed_args.server:
server_obj = utils.find_resource(
compute_client.servers, server)
compute_client.servers, server,
all_tenants=parsed_args.all_projects)
if parsed_args.force:
compute_client.servers.force_delete(server_obj.id)
@ -1347,11 +1376,13 @@ class DeleteServer(command.Command):
compute_client.servers.delete(server_obj.id)
if parsed_args.wait:
if not utils.wait_for_delete(compute_client.servers,
server_obj.id,
callback=_show_progress):
LOG.error(_('Error deleting server: %s'),
server_obj.id)
if not utils.wait_for_delete(
compute_client.servers,
server_obj.id,
callback=_show_progress,
):
msg = _('Error deleting server: %s')
LOG.error(msg, server_obj.id)
self.app.stdout.write(_('Error deleting server\n'))
raise SystemExit
@ -1446,8 +1477,11 @@ class ListServer(command.Lister):
parser.add_argument(
'--all-projects',
action='store_true',
default=bool(int(os.environ.get("ALL_PROJECTS", 0))),
help=_('Include all projects (admin only)'),
default=boolenv('ALL_PROJECTS'),
help=_(
'Include all projects (admin only) '
'(can be specified using the ALL_PROJECTS envvar)'
),
)
parser.add_argument(
'--project',
@ -3939,6 +3973,15 @@ class StartServer(command.Command):
nargs="+",
help=_('Server(s) to start (name or ID)'),
)
parser.add_argument(
'--all-projects',
action='store_true',
default=boolenv('ALL_PROJECTS'),
help=_(
'Start server(s) in another project by name (admin only)'
'(can be specified using the ALL_PROJECTS envvar)'
),
)
return parser
def take_action(self, parsed_args):
@ -3947,6 +3990,7 @@ class StartServer(command.Command):
utils.find_resource(
compute_client.servers,
server,
all_tenants=parsed_args.all_projects,
).start()
@ -3961,6 +4005,15 @@ class StopServer(command.Command):
nargs="+",
help=_('Server(s) to stop (name or ID)'),
)
parser.add_argument(
'--all-projects',
action='store_true',
default=boolenv('ALL_PROJECTS'),
help=_(
'Stop server(s) in another project by name (admin only)'
'(can be specified using the ALL_PROJECTS envvar)'
),
)
return parser
def take_action(self, parsed_args):
@ -3969,6 +4022,7 @@ class StopServer(command.Command):
utils.find_resource(
compute_client.servers,
server,
all_tenants=parsed_args.all_projects,
).stop()

View File

@ -2913,6 +2913,28 @@ class TestServerDelete(TestServer):
self.servers_mock.delete.assert_has_calls(calls)
self.assertIsNone(result)
@mock.patch.object(common_utils, 'find_resource')
def test_server_delete_with_all_projects(self, mock_find_resource):
servers = self.setup_servers_mock(count=1)
mock_find_resource.side_effect = compute_fakes.FakeServer.get_servers(
servers, 0,
)
arglist = [
servers[0].id,
'--all-projects',
]
verifylist = [
('server', [servers[0].id]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
mock_find_resource.assert_called_once_with(
mock.ANY, servers[0].id, all_tenants=True,
)
@mock.patch.object(common_utils, 'wait_for_delete', return_value=True)
def test_server_delete_wait_ok(self, mock_wait_for_delete):
servers = self.setup_servers_mock(count=1)
@ -6781,6 +6803,28 @@ class TestServerStart(TestServer):
def test_server_start_multi_servers(self):
self.run_method_with_servers('start', 3)
@mock.patch.object(common_utils, 'find_resource')
def test_server_start_with_all_projects(self, mock_find_resource):
servers = self.setup_servers_mock(count=1)
mock_find_resource.side_effect = compute_fakes.FakeServer.get_servers(
servers, 0,
)
arglist = [
servers[0].id,
'--all-projects',
]
verifylist = [
('server', [servers[0].id]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
mock_find_resource.assert_called_once_with(
mock.ANY, servers[0].id, all_tenants=True,
)
class TestServerStop(TestServer):
@ -6801,6 +6845,28 @@ class TestServerStop(TestServer):
def test_server_stop_multi_servers(self):
self.run_method_with_servers('stop', 3)
@mock.patch.object(common_utils, 'find_resource')
def test_server_start_with_all_projects(self, mock_find_resource):
servers = self.setup_servers_mock(count=1)
mock_find_resource.side_effect = compute_fakes.FakeServer.get_servers(
servers, 0,
)
arglist = [
servers[0].id,
'--all-projects',
]
verifylist = [
('server', [servers[0].id]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
mock_find_resource.assert_called_once_with(
mock.ANY, servers[0].id, all_tenants=True,
)
class TestServerSuspend(TestServer):

View File

@ -0,0 +1,7 @@
---
features:
- |
The ``server delete``, ``server start`` and ``server stop`` commands now
support the ``--all-projects`` option. This allows you to perform the
specified action on a server in another project using the server name.
This is an admin-only action by default.

View File

@ -8,6 +8,7 @@ iso8601>=0.1.11 # MIT
openstacksdk>=0.53.0 # Apache-2.0
osc-lib>=2.3.0 # Apache-2.0
oslo.i18n>=3.15.3 # Apache-2.0
oslo.utils>=3.33.0 # Apache-2.0
python-keystoneclient>=3.22.0 # Apache-2.0
python-novaclient>=17.0.0 # Apache-2.0
python-cinderclient>=3.3.0 # Apache-2.0