Add support for protocol numbers

This patch adds support for passing in protocol numbers into the API.
For example, 1 instead of ICMP. This allows all protocols besides
just TCP/UDP/ICMP to be used. This patch includes changes to support
this for the NVP Plugin. Existing plugins using securitygroups_rpc_base
and OVSHybridIptablesFirewallDriver require no change to leverage this.

Implements blueprint security-group-rules-protocol-numbers

Change-Id: I7d3b6986d9d0dadbefac0ea7798475a573dac046
This commit is contained in:
Aaron Rosen 2013-06-06 15:06:24 -07:00
parent 9105172d46
commit 8708bc538e
3 changed files with 26 additions and 13 deletions

View File

@ -57,7 +57,8 @@ class SecurityGroupDefaultAlreadyExists(qexception.InUse):
class SecurityGroupRuleInvalidProtocol(qexception.InvalidInput):
message = _("Security group rule protocol %(protocol)s not supported. "
"Only protocol values %(values)s supported.")
"Only protocol values %(values)s and their integer "
"representation (0 to 255) are supported.")
class SecurityGroupRulesNotSingleTenant(qexception.InvalidInput):
@ -95,11 +96,20 @@ class SecurityGroupRuleExists(qexception.InUse):
message = _("Security group rule already exists. Group id is %(id)s.")
def convert_protocol_to_case_insensitive(value):
def convert_protocol(value):
if value is None:
return value
return
try:
val = int(value)
if val >= 0 and val <= 255:
return val
raise SecurityGroupRuleInvalidProtocol(
protocol=value, values=sg_supported_protocols)
except (ValueError, TypeError):
if value.lower() in sg_supported_protocols:
return value.lower()
raise SecurityGroupRuleInvalidProtocol(
protocol=value, values=sg_supported_protocols)
except AttributeError:
raise SecurityGroupRuleInvalidProtocol(
protocol=value, values=sg_supported_protocols)
@ -178,8 +188,7 @@ RESOURCE_ATTRIBUTE_MAP = {
'validate': {'type:values': ['ingress', 'egress']}},
'protocol': {'allow_post': True, 'allow_put': False,
'is_visible': True, 'default': None,
'convert_to': convert_protocol_to_case_insensitive,
'validate': {'type:values': sg_supported_protocols}},
'convert_to': convert_protocol},
'port_range_min': {'allow_post': True, 'allow_put': False,
'convert_to': convert_validate_port_value,
'default': None, 'is_visible': True},

View File

@ -45,7 +45,11 @@ class NVPSecurityGroups(object):
elif param == 'remote_group_id':
nvp_rule['profile_uuid'] = rule['remote_group_id']
elif param == 'protocol':
nvp_rule['protocol'] = protocol_num_look_up[rule['protocol']]
try:
nvp_rule['protocol'] = int(rule['protocol'])
except (ValueError, TypeError):
nvp_rule['protocol'] = (
protocol_num_look_up[rule['protocol']])
else:
nvp_rule[param] = value
return nvp_rule

View File

@ -404,11 +404,11 @@ class TestSecurityGroups(SecurityGroupDBTestCase):
rule = self._build_security_group_rule(
security_group_id, 'ingress', 'tcp', '22', '22', None, None,
ethertype=ethertype)
res = self._create_security_group_rule('json', rule)
self.deserialize('json', res)
res = self._create_security_group_rule(self.fmt, rule)
self.deserialize(self.fmt, res)
self.assertEqual(res.status_int, 400)
def test_create_security_group_rule_protocol_invalid_as_number(self):
def test_create_security_group_rule_protocol_as_number(self):
name = 'webservers'
description = 'my webservers'
with self.security_group(name, description) as sg:
@ -417,9 +417,9 @@ class TestSecurityGroups(SecurityGroupDBTestCase):
rule = self._build_security_group_rule(
security_group_id, 'ingress', protocol, '22', '22',
None, None)
res = self._create_security_group_rule('json', rule)
self.deserialize('json', res)
self.assertEqual(res.status_int, 400)
res = self._create_security_group_rule(self.fmt, rule)
self.deserialize(self.fmt, res)
self.assertEqual(res.status_int, 201)
def test_create_security_group_rule_case_insensitive(self):
name = 'webservers'