From 2ee5c2dbe8b74c4c6415483f77b56a5d714afc4b Mon Sep 17 00:00:00 2001 From: Reedip Date: Fri, 10 Feb 2017 19:31:35 -0500 Subject: [PATCH] Add CIDR for canonical format conversion Currently, CIDR was not checked while converting address to the canonical format in [1]. As most inputs to the neutron server would have CIDR, therefore this patch handles this issue. [1]:Ic9afa5f90fba783748f7c56e8fba02e06af69748 Change-Id: Ia5f0880ea2a4d76296c1ff9bc0abab71a6294007 --- neutron_lib/api/converters.py | 18 ++++++++++++++++++ .../tests/unit/api/test_conversions.py | 19 ++++++++++++++++++- ...for_canonical_format-4e7925d76a27a19d.yaml | 5 +++++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 releasenotes/notes/cidr_for_canonical_format-4e7925d76a27a19d.yaml diff --git a/neutron_lib/api/converters.py b/neutron_lib/api/converters.py index bc3efa329..cc433d811 100644 --- a/neutron_lib/api/converters.py +++ b/neutron_lib/api/converters.py @@ -185,6 +185,24 @@ def convert_ip_to_canonical_format(value): return value +def convert_cidr_to_canonical_format(value): + """CIDR is validated and converted to canonical format. + + :param value: The CIDR which needs to be checked. + :returns: - 'value' if 'value' is CIDR with IPv4 address, + - CIDR with canonical IPv6 address if 'value' is IPv6 CIDR. + :raises: - InvalidInput if 'value' is None, not a valid CIDR or + invalid IP Format. + """ + error_message = _("%s is not in a CIDR format") % value + try: + cidr = netaddr.IPNetwork(value) + return str(convert_ip_to_canonical_format( + cidr.ip)) + "/" + str(cidr.prefixlen) + except netaddr.core.AddrFormatError: + raise n_exc.InvalidInput(error_message=error_message) + + def convert_string_to_case_insensitive(data): """Convert a string value into a lower case string. diff --git a/neutron_lib/tests/unit/api/test_conversions.py b/neutron_lib/tests/unit/api/test_conversions.py index efe9a8124..33f5da86a 100644 --- a/neutron_lib/tests/unit/api/test_conversions.py +++ b/neutron_lib/tests/unit/api/test_conversions.py @@ -171,7 +171,7 @@ class TestConvertToList(base.BaseTestCase): self.assertEqual([item], converters.convert_to_list(item)) -class TestConvertIPv6CanonicalFormat(base.BaseTestCase): +class TestConvertIPv6AddrCanonicalFormat(base.BaseTestCase): def test_convert_ipv6_address_extended_add_with_zeroes(self): result = converters.convert_ip_to_canonical_format( @@ -202,6 +202,23 @@ class TestConvertIPv6CanonicalFormat(base.BaseTestCase): self.assertEqual("on", result) +class TestConvertIPv6CIDRCanonicalFormat(base.BaseTestCase): + + def test_convert_ipv4_address_with_CIDR(self): + result = converters.convert_cidr_to_canonical_format(u'192.168.1.1/24') + self.assertEqual(u'192.168.1.1/24', result) + + def test_convert_ipv6_extended_addr_withcidr_to_compressed(self): + result = converters.convert_cidr_to_canonical_format( + u'Fe80:0:0:0:0:0:0:1/64') + self.assertEqual(u'fe80::1/64', result) + + def test_convert_non_ip_addr_with_slash(self): + with testtools.ExpectedException(n_exc.InvalidInput): + converters.convert_cidr_to_canonical_format( + u"Dormamu/DarkSeid/Vulture") + + class TestConvertStringToCaseInsensitive(base.BaseTestCase): def test_convert_string_to_lower(self): diff --git a/releasenotes/notes/cidr_for_canonical_format-4e7925d76a27a19d.yaml b/releasenotes/notes/cidr_for_canonical_format-4e7925d76a27a19d.yaml new file mode 100644 index 000000000..69a46f509 --- /dev/null +++ b/releasenotes/notes/cidr_for_canonical_format-4e7925d76a27a19d.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + A new converter is added to facilitate converting IPv6 CIDRs to canonical format. This way + IPv6 CIDRs can be specified in multiple formats but would be handled in their canonical format.