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/
This commit is contained in:
Tom Stappaerts 2020-03-05 17:54:55 +01:00
parent e07324e30f
commit 5e62411e5f
5 changed files with 54 additions and 1 deletions

View File

@ -120,6 +120,19 @@ class CreateSecurityGroup(common.NetworkAndComputeShowOne):
metavar='<project>',
help=self.enhance_help_neutron(_("Owner's project (name or ID)"))
)
stateful_group = parser.add_mutually_exclusive_group()
stateful_group.add_argument(
"--stateful",
action='store_true',
default=None,
help=_("Security group is stateful (Default)")
)
stateful_group.add_argument(
"--stateless",
action='store_true',
default=None,
help=_("Security group is stateless")
)
identity_common.add_project_domain_option_to_parser(
parser, enhance_help=self.enhance_help_neutron)
_tag.add_tag_option_to_parser_for_create(
@ -138,6 +151,10 @@ class CreateSecurityGroup(common.NetworkAndComputeShowOne):
attrs = {}
attrs['name'] = parsed_args.name
attrs['description'] = self._get_description(parsed_args)
if parsed_args.stateful:
attrs['stateful'] = True
if parsed_args.stateless:
attrs['stateful'] = False
if parsed_args.project is not None:
identity_client = self.app.client_manager.identity
project_id = identity_common.find_project(
@ -313,6 +330,19 @@ class SetSecurityGroup(common.NetworkAndComputeCommand):
metavar="<description>",
help=_("New security group description")
)
stateful_group = parser.add_mutually_exclusive_group()
stateful_group.add_argument(
"--stateful",
action='store_true',
default=None,
help=_("Security group is stateful (Default)")
)
stateful_group.add_argument(
"--stateless",
action='store_true',
default=None,
help=_("Security group is stateless")
)
return parser
def update_parser_network(self, parser):
@ -329,6 +359,10 @@ class SetSecurityGroup(common.NetworkAndComputeCommand):
attrs['name'] = parsed_args.name
if parsed_args.description is not None:
attrs['description'] = parsed_args.description
if parsed_args.stateful:
attrs['stateful'] = True
if parsed_args.stateless:
attrs['stateful'] = False
# NOTE(rtheis): Previous behavior did not raise a CommandError
# if there were no updates. Maintain this behavior and issue
# the update.

View File

@ -42,7 +42,7 @@ class SecurityGroupTests(common.NetworkTests):
def test_security_group_set(self):
other_name = uuid.uuid4().hex
raw_output = self.openstack(
'security group set --description NSA --name ' +
'security group set --description NSA --stateless --name ' +
other_name + ' ' + self.NAME
)
self.assertEqual('', raw_output)
@ -50,8 +50,10 @@ class SecurityGroupTests(common.NetworkTests):
cmd_output = json.loads(self.openstack(
'security group show -f json ' + other_name))
self.assertEqual('NSA', cmd_output['description'])
self.assertFalse(cmd_output['stateful'])
def test_security_group_show(self):
cmd_output = json.loads(self.openstack(
'security group show -f json ' + self.NAME))
self.assertEqual(self.NAME, cmd_output['name'])
self.assertTrue(cmd_output['stateful'])

View File

@ -1226,6 +1226,7 @@ class FakeSecurityGroup(object):
'id': 'security-group-id-' + uuid.uuid4().hex,
'name': 'security-group-name-' + uuid.uuid4().hex,
'description': 'security-group-description-' + uuid.uuid4().hex,
'stateful': True,
'project_id': 'project-id-' + uuid.uuid4().hex,
'security_group_rules': [],
'tags': []

View File

@ -49,6 +49,7 @@ class TestCreateSecurityGroupNetwork(TestSecurityGroupNetwork):
'name',
'project_id',
'rules',
'stateful',
'tags',
)
@ -58,6 +59,7 @@ class TestCreateSecurityGroupNetwork(TestSecurityGroupNetwork):
_security_group.name,
_security_group.project_id,
security_group.NetworkSecurityGroupRulesColumn([]),
_security_group.stateful,
_security_group.tags,
)
@ -101,6 +103,7 @@ class TestCreateSecurityGroupNetwork(TestSecurityGroupNetwork):
'--description', self._security_group.description,
'--project', self.project.name,
'--project-domain', self.domain.name,
'--stateful',
self._security_group.name,
]
verifylist = [
@ -108,6 +111,7 @@ class TestCreateSecurityGroupNetwork(TestSecurityGroupNetwork):
('name', self._security_group.name),
('project', self.project.name),
('project_domain', self.domain.name),
('stateful', self._security_group.stateful),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@ -115,6 +119,7 @@ class TestCreateSecurityGroupNetwork(TestSecurityGroupNetwork):
self.network.create_security_group.assert_called_once_with(**{
'description': self._security_group.description,
'stateful': self._security_group.stateful,
'name': self._security_group.name,
'tenant_id': self.project.id,
})
@ -414,11 +419,13 @@ class TestSetSecurityGroupNetwork(TestSecurityGroupNetwork):
arglist = [
'--name', new_name,
'--description', new_description,
'--stateful',
self._security_group.name,
]
verifylist = [
('description', new_description),
('group', self._security_group.name),
('stateful', self._security_group.stateful),
('name', new_name),
]
@ -428,6 +435,7 @@ class TestSetSecurityGroupNetwork(TestSecurityGroupNetwork):
attrs = {
'description': new_description,
'name': new_name,
'stateful': True,
}
self.network.update_security_group.assert_called_once_with(
self._security_group,
@ -482,6 +490,7 @@ class TestShowSecurityGroupNetwork(TestSecurityGroupNetwork):
'name',
'project_id',
'rules',
'stateful',
'tags',
)
@ -492,6 +501,7 @@ class TestShowSecurityGroupNetwork(TestSecurityGroupNetwork):
_security_group.project_id,
security_group.NetworkSecurityGroupRulesColumn(
[_security_group_rule._info]),
_security_group.stateful,
_security_group.tags,
)

View File

@ -0,0 +1,6 @@
---
features:
- |
Add ``--stateful`` and ``--stateless`` option to the
``security group create`` and ``security group set`` commands
to support stateful and stateless security groups.