Skip to content

Commit 011991b

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "compute: Add 'server * --all-projects' option"
2 parents e8509d8 + 1a6df70 commit 011991b

4 files changed

Lines changed: 136 additions & 8 deletions

File tree

openstackclient/compute/v2/server.py

Lines changed: 62 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
from osc_lib.command import command
3232
from osc_lib import exceptions
3333
from osc_lib import utils
34+
from oslo_utils import strutils
3435

3536
from openstackclient.i18n import _
3637
from openstackclient.identity import common as identity_common
@@ -193,6 +194,24 @@ def _prep_server_detail(compute_client, image_client, server, refresh=True):
193194
return info
194195

195196

197+
def boolenv(*vars, default=False):
198+
"""Search for the first defined of possibly many bool-like env vars.
199+
200+
Returns the first environment variable defined in vars, or returns the
201+
default.
202+
203+
:param vars: Arbitrary strings to search for. Case sensitive.
204+
:param default: The default to return if no value found.
205+
:returns: A boolean corresponding to the value found, else the default if
206+
no value found.
207+
"""
208+
for v in vars:
209+
value = os.environ.get(v, None)
210+
if value:
211+
return strutils.bool_from_string(value)
212+
return default
213+
214+
196215
class AddFixedIP(command.Command):
197216
_description = _("Add fixed IP address to server")
198217

@@ -1322,6 +1341,15 @@ def get_parser(self, prog_name):
13221341
action='store_true',
13231342
help=_('Force delete server(s)'),
13241343
)
1344+
parser.add_argument(
1345+
'--all-projects',
1346+
action='store_true',
1347+
default=boolenv('ALL_PROJECTS'),
1348+
help=_(
1349+
'Delete server(s) in another project by name (admin only)'
1350+
'(can be specified using the ALL_PROJECTS envvar)'
1351+
),
1352+
)
13251353
parser.add_argument(
13261354
'--wait',
13271355
action='store_true',
@@ -1339,19 +1367,22 @@ def _show_progress(progress):
13391367
compute_client = self.app.client_manager.compute
13401368
for server in parsed_args.server:
13411369
server_obj = utils.find_resource(
1342-
compute_client.servers, server)
1370+
compute_client.servers, server,
1371+
all_tenants=parsed_args.all_projects)
13431372

13441373
if parsed_args.force:
13451374
compute_client.servers.force_delete(server_obj.id)
13461375
else:
13471376
compute_client.servers.delete(server_obj.id)
13481377

13491378
if parsed_args.wait:
1350-
if not utils.wait_for_delete(compute_client.servers,
1351-
server_obj.id,
1352-
callback=_show_progress):
1353-
LOG.error(_('Error deleting server: %s'),
1354-
server_obj.id)
1379+
if not utils.wait_for_delete(
1380+
compute_client.servers,
1381+
server_obj.id,
1382+
callback=_show_progress,
1383+
):
1384+
msg = _('Error deleting server: %s')
1385+
LOG.error(msg, server_obj.id)
13551386
self.app.stdout.write(_('Error deleting server\n'))
13561387
raise SystemExit
13571388

@@ -1446,8 +1477,11 @@ def get_parser(self, prog_name):
14461477
parser.add_argument(
14471478
'--all-projects',
14481479
action='store_true',
1449-
default=bool(int(os.environ.get("ALL_PROJECTS", 0))),
1450-
help=_('Include all projects (admin only)'),
1480+
default=boolenv('ALL_PROJECTS'),
1481+
help=_(
1482+
'Include all projects (admin only) '
1483+
'(can be specified using the ALL_PROJECTS envvar)'
1484+
),
14511485
)
14521486
parser.add_argument(
14531487
'--project',
@@ -3939,6 +3973,15 @@ def get_parser(self, prog_name):
39393973
nargs="+",
39403974
help=_('Server(s) to start (name or ID)'),
39413975
)
3976+
parser.add_argument(
3977+
'--all-projects',
3978+
action='store_true',
3979+
default=boolenv('ALL_PROJECTS'),
3980+
help=_(
3981+
'Start server(s) in another project by name (admin only)'
3982+
'(can be specified using the ALL_PROJECTS envvar)'
3983+
),
3984+
)
39423985
return parser
39433986

39443987
def take_action(self, parsed_args):
@@ -3947,6 +3990,7 @@ def take_action(self, parsed_args):
39473990
utils.find_resource(
39483991
compute_client.servers,
39493992
server,
3993+
all_tenants=parsed_args.all_projects,
39503994
).start()
39513995

39523996

@@ -3961,6 +4005,15 @@ def get_parser(self, prog_name):
39614005
nargs="+",
39624006
help=_('Server(s) to stop (name or ID)'),
39634007
)
4008+
parser.add_argument(
4009+
'--all-projects',
4010+
action='store_true',
4011+
default=boolenv('ALL_PROJECTS'),
4012+
help=_(
4013+
'Stop server(s) in another project by name (admin only)'
4014+
'(can be specified using the ALL_PROJECTS envvar)'
4015+
),
4016+
)
39644017
return parser
39654018

39664019
def take_action(self, parsed_args):
@@ -3969,6 +4022,7 @@ def take_action(self, parsed_args):
39694022
utils.find_resource(
39704023
compute_client.servers,
39714024
server,
4025+
all_tenants=parsed_args.all_projects,
39724026
).stop()
39734027

39744028

openstackclient/tests/unit/compute/v2/test_server.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2913,6 +2913,28 @@ def test_server_delete_multi_servers(self):
29132913
self.servers_mock.delete.assert_has_calls(calls)
29142914
self.assertIsNone(result)
29152915

2916+
@mock.patch.object(common_utils, 'find_resource')
2917+
def test_server_delete_with_all_projects(self, mock_find_resource):
2918+
servers = self.setup_servers_mock(count=1)
2919+
mock_find_resource.side_effect = compute_fakes.FakeServer.get_servers(
2920+
servers, 0,
2921+
)
2922+
2923+
arglist = [
2924+
servers[0].id,
2925+
'--all-projects',
2926+
]
2927+
verifylist = [
2928+
('server', [servers[0].id]),
2929+
]
2930+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
2931+
2932+
self.cmd.take_action(parsed_args)
2933+
2934+
mock_find_resource.assert_called_once_with(
2935+
mock.ANY, servers[0].id, all_tenants=True,
2936+
)
2937+
29162938
@mock.patch.object(common_utils, 'wait_for_delete', return_value=True)
29172939
def test_server_delete_wait_ok(self, mock_wait_for_delete):
29182940
servers = self.setup_servers_mock(count=1)
@@ -6781,6 +6803,28 @@ def test_server_start_one_server(self):
67816803
def test_server_start_multi_servers(self):
67826804
self.run_method_with_servers('start', 3)
67836805

6806+
@mock.patch.object(common_utils, 'find_resource')
6807+
def test_server_start_with_all_projects(self, mock_find_resource):
6808+
servers = self.setup_servers_mock(count=1)
6809+
mock_find_resource.side_effect = compute_fakes.FakeServer.get_servers(
6810+
servers, 0,
6811+
)
6812+
6813+
arglist = [
6814+
servers[0].id,
6815+
'--all-projects',
6816+
]
6817+
verifylist = [
6818+
('server', [servers[0].id]),
6819+
]
6820+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
6821+
6822+
self.cmd.take_action(parsed_args)
6823+
6824+
mock_find_resource.assert_called_once_with(
6825+
mock.ANY, servers[0].id, all_tenants=True,
6826+
)
6827+
67846828

67856829
class TestServerStop(TestServer):
67866830

@@ -6801,6 +6845,28 @@ def test_server_stop_one_server(self):
68016845
def test_server_stop_multi_servers(self):
68026846
self.run_method_with_servers('stop', 3)
68036847

6848+
@mock.patch.object(common_utils, 'find_resource')
6849+
def test_server_start_with_all_projects(self, mock_find_resource):
6850+
servers = self.setup_servers_mock(count=1)
6851+
mock_find_resource.side_effect = compute_fakes.FakeServer.get_servers(
6852+
servers, 0,
6853+
)
6854+
6855+
arglist = [
6856+
servers[0].id,
6857+
'--all-projects',
6858+
]
6859+
verifylist = [
6860+
('server', [servers[0].id]),
6861+
]
6862+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
6863+
6864+
self.cmd.take_action(parsed_args)
6865+
6866+
mock_find_resource.assert_called_once_with(
6867+
mock.ANY, servers[0].id, all_tenants=True,
6868+
)
6869+
68046870

68056871
class TestServerSuspend(TestServer):
68066872

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
features:
3+
- |
4+
The ``server delete``, ``server start`` and ``server stop`` commands now
5+
support the ``--all-projects`` option. This allows you to perform the
6+
specified action on a server in another project using the server name.
7+
This is an admin-only action by default.

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ iso8601>=0.1.11 # MIT
88
openstacksdk>=0.53.0 # Apache-2.0
99
osc-lib>=2.3.0 # Apache-2.0
1010
oslo.i18n>=3.15.3 # Apache-2.0
11+
oslo.utils>=3.33.0 # Apache-2.0
1112
python-keystoneclient>=3.22.0 # Apache-2.0
1213
python-novaclient>=17.0.0 # Apache-2.0
1314
python-cinderclient>=3.3.0 # Apache-2.0

0 commit comments

Comments
 (0)