Skip to content

Commit 6698f14

Browse files
Jenkinsopenstack-gerrit
authored andcommitted
Merge "type should be required for v2.0 service create"
2 parents 2ef136f + 4a07e63 commit 6698f14

2 files changed

Lines changed: 104 additions & 12 deletions

File tree

‎openstackclient/identity/v2_0/service.py‎

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
"""Service action implementations"""
1717

18+
import argparse
1819
import logging
1920
import six
2021

@@ -36,15 +37,20 @@ class CreateService(show.ShowOne):
3637
def get_parser(self, prog_name):
3738
parser = super(CreateService, self).get_parser(prog_name)
3839
parser.add_argument(
39-
'name',
40-
metavar='<service-name>',
41-
help=_('New service name'),
40+
'type_or_name',
41+
metavar='<type>',
42+
help=_('New service type (compute, image, identity, volume, etc)'),
4243
)
43-
parser.add_argument(
44+
type_or_name_group = parser.add_mutually_exclusive_group()
45+
type_or_name_group.add_argument(
4446
'--type',
4547
metavar='<service-type>',
46-
required=True,
47-
help=_('New service type (compute, image, identity, volume, etc)'),
48+
help=argparse.SUPPRESS,
49+
)
50+
type_or_name_group.add_argument(
51+
'--name',
52+
metavar='<name>',
53+
help=_('New service name'),
4854
)
4955
parser.add_argument(
5056
'--description',
@@ -57,9 +63,28 @@ def take_action(self, parsed_args):
5763
self.log.debug('take_action(%s)', parsed_args)
5864
identity_client = self.app.client_manager.identity
5965

66+
type_or_name = parsed_args.type_or_name
67+
name = parsed_args.name
68+
type = parsed_args.type
69+
70+
# If only a single positional is present, it's a <type>.
71+
# This is not currently legal so it is considered a new case.
72+
if not type and not name:
73+
type = type_or_name
74+
# If --type option is present then positional is handled as <name>;
75+
# display deprecation message.
76+
elif type:
77+
name = type_or_name
78+
self.log.warning(_('The argument --type is deprecated, use service'
79+
' create --name <service-name> type instead.'))
80+
# If --name option is present the positional is handled as <type>.
81+
# Making --type optional is new, but back-compatible
82+
elif name:
83+
type = type_or_name
84+
6085
service = identity_client.services.create(
61-
parsed_args.name,
62-
parsed_args.type,
86+
name,
87+
type,
6388
parsed_args.description)
6489

6590
info = {}

‎openstackclient/tests/identity/v2_0/test_service.py‎

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,80 @@ def setUp(self):
4444
# Get the command object to test
4545
self.cmd = service.CreateService(self.app, None)
4646

47-
def test_service_create_name_type(self):
47+
def test_service_create_with_type_positional(self):
48+
arglist = [
49+
identity_fakes.service_type,
50+
]
51+
verifylist = [
52+
('type_or_name', identity_fakes.service_type),
53+
('type', None),
54+
('description', None),
55+
('name', None),
56+
]
57+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
58+
59+
# DisplayCommandBase.take_action() returns two tuples
60+
columns, data = self.cmd.take_action(parsed_args)
61+
62+
# ServiceManager.create(name, service_type, description)
63+
self.services_mock.create.assert_called_with(
64+
None,
65+
identity_fakes.service_type,
66+
None,
67+
)
68+
69+
collist = ('description', 'id', 'name', 'type')
70+
self.assertEqual(columns, collist)
71+
datalist = (
72+
identity_fakes.service_description,
73+
identity_fakes.service_id,
74+
identity_fakes.service_name,
75+
identity_fakes.service_type,
76+
)
77+
self.assertEqual(data, datalist)
78+
79+
def test_service_create_with_type_option(self):
4880
arglist = [
4981
'--type', identity_fakes.service_type,
5082
identity_fakes.service_name,
5183
]
5284
verifylist = [
85+
('type_or_name', identity_fakes.service_name),
5386
('type', identity_fakes.service_type),
5487
('description', None),
88+
('name', None),
89+
]
90+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
91+
92+
# DisplayCommandBase.take_action() returns two tuples
93+
columns, data = self.cmd.take_action(parsed_args)
94+
95+
# ServiceManager.create(name, service_type, description)
96+
self.services_mock.create.assert_called_with(
97+
identity_fakes.service_name,
98+
identity_fakes.service_type,
99+
None,
100+
)
101+
102+
collist = ('description', 'id', 'name', 'type')
103+
self.assertEqual(columns, collist)
104+
datalist = (
105+
identity_fakes.service_description,
106+
identity_fakes.service_id,
107+
identity_fakes.service_name,
108+
identity_fakes.service_type,
109+
)
110+
self.assertEqual(data, datalist)
111+
112+
def test_service_create_with_name_option(self):
113+
arglist = [
114+
'--name', identity_fakes.service_name,
115+
identity_fakes.service_type,
116+
]
117+
verifylist = [
118+
('type_or_name', identity_fakes.service_type),
119+
('type', None),
120+
('description', None),
55121
('name', identity_fakes.service_name),
56122
]
57123
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -78,12 +144,13 @@ def test_service_create_name_type(self):
78144

79145
def test_service_create_description(self):
80146
arglist = [
81-
'--type', identity_fakes.service_type,
147+
'--name', identity_fakes.service_name,
82148
'--description', identity_fakes.service_description,
83-
identity_fakes.service_name,
149+
identity_fakes.service_type,
84150
]
85151
verifylist = [
86-
('type', identity_fakes.service_type),
152+
('type_or_name', identity_fakes.service_type),
153+
('type', None),
87154
('description', identity_fakes.service_description),
88155
('name', identity_fakes.service_name),
89156
]

0 commit comments

Comments
 (0)