Merge "compute: Add 'server * --all-projects' option"
This commit is contained in:
commit
011991bcf3
@ -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()
|
||||
|
||||
|
||||
|
@ -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):
|
||||
|
||||
|
@ -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.
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user