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

View File

@ -42,7 +42,7 @@ class SecurityGroupTests(common.NetworkTests):
def test_security_group_set(self): def test_security_group_set(self):
other_name = uuid.uuid4().hex other_name = uuid.uuid4().hex
raw_output = self.openstack( raw_output = self.openstack(
'security group set --description NSA --name ' + 'security group set --description NSA --stateless --name ' +
other_name + ' ' + self.NAME other_name + ' ' + self.NAME
) )
self.assertEqual('', raw_output) self.assertEqual('', raw_output)
@ -50,8 +50,10 @@ class SecurityGroupTests(common.NetworkTests):
cmd_output = json.loads(self.openstack( cmd_output = json.loads(self.openstack(
'security group show -f json ' + other_name)) 'security group show -f json ' + other_name))
self.assertEqual('NSA', cmd_output['description']) self.assertEqual('NSA', cmd_output['description'])
self.assertFalse(cmd_output['stateful'])
def test_security_group_show(self): def test_security_group_show(self):
cmd_output = json.loads(self.openstack( cmd_output = json.loads(self.openstack(
'security group show -f json ' + self.NAME)) 'security group show -f json ' + self.NAME))
self.assertEqual(self.NAME, cmd_output['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, 'id': 'security-group-id-' + uuid.uuid4().hex,
'name': 'security-group-name-' + uuid.uuid4().hex, 'name': 'security-group-name-' + uuid.uuid4().hex,
'description': 'security-group-description-' + uuid.uuid4().hex, 'description': 'security-group-description-' + uuid.uuid4().hex,
'stateful': True,
'project_id': 'project-id-' + uuid.uuid4().hex, 'project_id': 'project-id-' + uuid.uuid4().hex,
'security_group_rules': [], 'security_group_rules': [],
'tags': [] 'tags': []

View File

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