From 8708bc538e2515899cf874e1e5e2275360fb5ef6 Mon Sep 17 00:00:00 2001 From: Aaron Rosen Date: Thu, 6 Jun 2013 15:06:24 -0700 Subject: [PATCH] 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 --- quantum/extensions/securitygroup.py | 21 +++++++++++++------ .../plugins/nicira/common/securitygroups.py | 6 +++++- .../unit/test_extension_security_group.py | 12 +++++------ 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/quantum/extensions/securitygroup.py b/quantum/extensions/securitygroup.py index 3609af5a5..f3ec56f31 100644 --- a/quantum/extensions/securitygroup.py +++ b/quantum/extensions/securitygroup.py @@ -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: - return value.lower() + 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}, diff --git a/quantum/plugins/nicira/common/securitygroups.py b/quantum/plugins/nicira/common/securitygroups.py index db80f7084..6e0cbc660 100644 --- a/quantum/plugins/nicira/common/securitygroups.py +++ b/quantum/plugins/nicira/common/securitygroups.py @@ -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 diff --git a/quantum/tests/unit/test_extension_security_group.py b/quantum/tests/unit/test_extension_security_group.py index 31c76a09c..5fa85568c 100644 --- a/quantum/tests/unit/test_extension_security_group.py +++ b/quantum/tests/unit/test_extension_security_group.py @@ -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' -- 2.45.2