Skip to content

Commit 5e62411

Browse files
committed
Support for stateless security groups
Add support for stateful attribute of security groups, using --stateful and --no-stateful flag on security group. This allows a user to create security groups with stateful false. Change-Id: Ifd20b5fc47fd0ea0bb5aeda84820dcc0fb1e8847 Blueprint: stateless-security-groups Depends-On: https://review.opendev.org/711513/
1 parent e07324e commit 5e62411

5 files changed

Lines changed: 54 additions & 1 deletion

File tree

openstackclient/network/v2/security_group.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,19 @@ def update_parser_network(self, parser):
120120
metavar='<project>',
121121
help=self.enhance_help_neutron(_("Owner's project (name or ID)"))
122122
)
123+
stateful_group = parser.add_mutually_exclusive_group()
124+
stateful_group.add_argument(
125+
"--stateful",
126+
action='store_true',
127+
default=None,
128+
help=_("Security group is stateful (Default)")
129+
)
130+
stateful_group.add_argument(
131+
"--stateless",
132+
action='store_true',
133+
default=None,
134+
help=_("Security group is stateless")
135+
)
123136
identity_common.add_project_domain_option_to_parser(
124137
parser, enhance_help=self.enhance_help_neutron)
125138
_tag.add_tag_option_to_parser_for_create(
@@ -138,6 +151,10 @@ def take_action_network(self, client, parsed_args):
138151
attrs = {}
139152
attrs['name'] = parsed_args.name
140153
attrs['description'] = self._get_description(parsed_args)
154+
if parsed_args.stateful:
155+
attrs['stateful'] = True
156+
if parsed_args.stateless:
157+
attrs['stateful'] = False
141158
if parsed_args.project is not None:
142159
identity_client = self.app.client_manager.identity
143160
project_id = identity_common.find_project(
@@ -313,6 +330,19 @@ def update_parser_common(self, parser):
313330
metavar="<description>",
314331
help=_("New security group description")
315332
)
333+
stateful_group = parser.add_mutually_exclusive_group()
334+
stateful_group.add_argument(
335+
"--stateful",
336+
action='store_true',
337+
default=None,
338+
help=_("Security group is stateful (Default)")
339+
)
340+
stateful_group.add_argument(
341+
"--stateless",
342+
action='store_true',
343+
default=None,
344+
help=_("Security group is stateless")
345+
)
316346
return parser
317347

318348
def update_parser_network(self, parser):
@@ -329,6 +359,10 @@ def take_action_network(self, client, parsed_args):
329359
attrs['name'] = parsed_args.name
330360
if parsed_args.description is not None:
331361
attrs['description'] = parsed_args.description
362+
if parsed_args.stateful:
363+
attrs['stateful'] = True
364+
if parsed_args.stateless:
365+
attrs['stateful'] = False
332366
# NOTE(rtheis): Previous behavior did not raise a CommandError
333367
# if there were no updates. Maintain this behavior and issue
334368
# the update.

openstackclient/tests/functional/network/v2/test_security_group.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,18 @@ def test_security_group_list(self):
4242
def test_security_group_set(self):
4343
other_name = uuid.uuid4().hex
4444
raw_output = self.openstack(
45-
'security group set --description NSA --name ' +
45+
'security group set --description NSA --stateless --name ' +
4646
other_name + ' ' + self.NAME
4747
)
4848
self.assertEqual('', raw_output)
4949

5050
cmd_output = json.loads(self.openstack(
5151
'security group show -f json ' + other_name))
5252
self.assertEqual('NSA', cmd_output['description'])
53+
self.assertFalse(cmd_output['stateful'])
5354

5455
def test_security_group_show(self):
5556
cmd_output = json.loads(self.openstack(
5657
'security group show -f json ' + self.NAME))
5758
self.assertEqual(self.NAME, cmd_output['name'])
59+
self.assertTrue(cmd_output['stateful'])

openstackclient/tests/unit/network/v2/fakes.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,6 +1226,7 @@ def create_one_security_group(attrs=None):
12261226
'id': 'security-group-id-' + uuid.uuid4().hex,
12271227
'name': 'security-group-name-' + uuid.uuid4().hex,
12281228
'description': 'security-group-description-' + uuid.uuid4().hex,
1229+
'stateful': True,
12291230
'project_id': 'project-id-' + uuid.uuid4().hex,
12301231
'security_group_rules': [],
12311232
'tags': []

openstackclient/tests/unit/network/v2/test_security_group_network.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ class TestCreateSecurityGroupNetwork(TestSecurityGroupNetwork):
4949
'name',
5050
'project_id',
5151
'rules',
52+
'stateful',
5253
'tags',
5354
)
5455

@@ -58,6 +59,7 @@ class TestCreateSecurityGroupNetwork(TestSecurityGroupNetwork):
5859
_security_group.name,
5960
_security_group.project_id,
6061
security_group.NetworkSecurityGroupRulesColumn([]),
62+
_security_group.stateful,
6163
_security_group.tags,
6264
)
6365

@@ -101,20 +103,23 @@ def test_create_all_options(self):
101103
'--description', self._security_group.description,
102104
'--project', self.project.name,
103105
'--project-domain', self.domain.name,
106+
'--stateful',
104107
self._security_group.name,
105108
]
106109
verifylist = [
107110
('description', self._security_group.description),
108111
('name', self._security_group.name),
109112
('project', self.project.name),
110113
('project_domain', self.domain.name),
114+
('stateful', self._security_group.stateful),
111115
]
112116
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
113117

114118
columns, data = self.cmd.take_action(parsed_args)
115119

116120
self.network.create_security_group.assert_called_once_with(**{
117121
'description': self._security_group.description,
122+
'stateful': self._security_group.stateful,
118123
'name': self._security_group.name,
119124
'tenant_id': self.project.id,
120125
})
@@ -414,11 +419,13 @@ def test_set_all_options(self):
414419
arglist = [
415420
'--name', new_name,
416421
'--description', new_description,
422+
'--stateful',
417423
self._security_group.name,
418424
]
419425
verifylist = [
420426
('description', new_description),
421427
('group', self._security_group.name),
428+
('stateful', self._security_group.stateful),
422429
('name', new_name),
423430
]
424431

@@ -428,6 +435,7 @@ def test_set_all_options(self):
428435
attrs = {
429436
'description': new_description,
430437
'name': new_name,
438+
'stateful': True,
431439
}
432440
self.network.update_security_group.assert_called_once_with(
433441
self._security_group,
@@ -482,6 +490,7 @@ class TestShowSecurityGroupNetwork(TestSecurityGroupNetwork):
482490
'name',
483491
'project_id',
484492
'rules',
493+
'stateful',
485494
'tags',
486495
)
487496

@@ -492,6 +501,7 @@ class TestShowSecurityGroupNetwork(TestSecurityGroupNetwork):
492501
_security_group.project_id,
493502
security_group.NetworkSecurityGroupRulesColumn(
494503
[_security_group_rule._info]),
504+
_security_group.stateful,
495505
_security_group.tags,
496506
)
497507

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
features:
3+
- |
4+
Add ``--stateful`` and ``--stateless`` option to the
5+
``security group create`` and ``security group set`` commands
6+
to support stateful and stateless security groups.

0 commit comments

Comments
 (0)