diff --git a/neutron/db/securitygroups_db.py b/neutron/db/securitygroups_db.py index 6fc0d870ec..b64fe3869c 100644 --- a/neutron/db/securitygroups_db.py +++ b/neutron/db/securitygroups_db.py @@ -296,7 +296,11 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase): def _get_ip_proto_number(self, protocol): if protocol is None: return - return IP_PROTOCOL_MAP.get(protocol, protocol) + # According to bug 1381379, protocol is always set to string to avoid + # problems with comparing int and string in PostgreSQL. Here this + # string is converted to int to give an opportunity to use it as + # before. + return int(IP_PROTOCOL_MAP.get(protocol, protocol)) def _validate_port_range(self, rule): """Check that port_range is valid.""" diff --git a/neutron/extensions/securitygroup.py b/neutron/extensions/securitygroup.py index 89b9d8a74b..3524117ee9 100644 --- a/neutron/extensions/securitygroup.py +++ b/neutron/extensions/securitygroup.py @@ -116,7 +116,10 @@ def convert_protocol(value): try: val = int(value) if val >= 0 and val <= 255: - return value + # Set value of protocol number to string due to bug 1381379, + # PostgreSQL fails when it tries to compare integer with string, + # that exists in db. + return str(value) raise SecurityGroupRuleInvalidProtocol( protocol=value, values=sg_supported_protocols) except (ValueError, TypeError): diff --git a/neutron/tests/unit/test_extension_security_group.py b/neutron/tests/unit/test_extension_security_group.py index 8643240f7a..e0061940b0 100644 --- a/neutron/tests/unit/test_extension_security_group.py +++ b/neutron/tests/unit/test_extension_security_group.py @@ -1441,3 +1441,6 @@ class TestConvertProtocol(base.BaseTestCase): for val in ['bad', '256', '-1']: self.assertRaises(ext_sg.SecurityGroupRuleInvalidProtocol, ext_sg.convert_protocol, val) + + def test_convert_numeric_protocol_to_string(self): + self.assertIsInstance(ext_sg.convert_protocol(2), str)