From e92d3ebc6789ec033e4507a6fece2e37df57dc9f Mon Sep 17 00:00:00 2001 From: Stefan Pratter Date: Thu, 29 Sep 2022 09:03:31 +0000 Subject: [PATCH] IX-F importer fails on nulled ipv4 / ipv6 properties in vlan_list entries #1244 --- peeringdb_server/ixf.py | 9 ++++ tests/data/ixf/vlan/test9.expected | 4 ++ tests/data/ixf/vlan/test9.input | 9 ++++ .../ixf.member.null.ip.vlan.json | 51 +++++++++++++++++++ tests/test_ixf_member_import_protocol.py | 31 +++++++++++ 5 files changed, 104 insertions(+) create mode 100644 tests/data/ixf/vlan/test9.expected create mode 100644 tests/data/ixf/vlan/test9.input create mode 100644 tests/data/json_members_list/ixf.member.null.ip.vlan.json diff --git a/peeringdb_server/ixf.py b/peeringdb_server/ixf.py index 5e07b7c0..aac80f57 100644 --- a/peeringdb_server/ixf.py +++ b/peeringdb_server/ixf.py @@ -377,6 +377,15 @@ def sanitize_vlans(self, vlans): id = vlan.get("vlan_id", 0) + # the ix-f schema allows setting ipv4 and ipv6 to + # null, in which case remove the property + + if "ipv4" in vlan and not vlan.get("ipv4"): + del vlan["ipv4"] + + if "ipv6" in vlan and not vlan.get("ipv6"): + del vlan["ipv6"] + # neither ipv4 nor ipv6 is specified, there is # nothing to sanitize here, so skip diff --git a/tests/data/ixf/vlan/test9.expected b/tests/data/ixf/vlan/test9.expected new file mode 100644 index 00000000..d770c79e --- /dev/null +++ b/tests/data/ixf/vlan/test9.expected @@ -0,0 +1,4 @@ +{ + "vlan_list": [ + ] +} diff --git a/tests/data/ixf/vlan/test9.input b/tests/data/ixf/vlan/test9.input new file mode 100644 index 00000000..8f471999 --- /dev/null +++ b/tests/data/ixf/vlan/test9.input @@ -0,0 +1,9 @@ +{ + "vlan_list": [ + { + "vlan_id":2, + "ipv4":null, + "ipv6":null + } + ] +} diff --git a/tests/data/json_members_list/ixf.member.null.ip.vlan.json b/tests/data/json_members_list/ixf.member.null.ip.vlan.json new file mode 100644 index 00000000..eeece3c5 --- /dev/null +++ b/tests/data/json_members_list/ixf.member.null.ip.vlan.json @@ -0,0 +1,51 @@ +{ + "timestamp": "2020-07-13T09:23:47Z", + "version": "1.0", + "ixp_list": [ + { + "shortname": "Test Exchange", + "ixp_id": 1, + "ixf_id": 1 + } + ], + "member_list": [ + { + "asnum": 1001, + "member_type": "peering", + "name": "Netflix", + "url": "http://netflix.com/", + "contact_email": [ + "peering@netflix.com", + "mrpeering@netflix.com" + ], + "contact_phone": [ + "+1 1234 5678" + ], + "contact_hours": "8/5", + "peering_policy": "open", + "peering_policy_url": "https://www.netflix.com/openconnect/", + "member_since": "2009-02-04T00:00:00Z", + "connection_list": [ + { + "ixp_id": 42, + "connected_since": "2009-02-04T00:00:00Z", + "state": "connected", + "if_list": [ + { + "switch_id": 1, + "if_speed": 20000, + "if_type": "LR4" + } + ], + "vlan_list": [ + { + "vlan_id": 1, + "ipv4": null, + "ipv6": null + } + ] + } + ] + } + ] +} diff --git a/tests/test_ixf_member_import_protocol.py b/tests/test_ixf_member_import_protocol.py index 166a15d1..728da7fa 100644 --- a/tests/test_ixf_member_import_protocol.py +++ b/tests/test_ixf_member_import_protocol.py @@ -2297,6 +2297,37 @@ def test_mark_invalid_multiple_vlans(entities, save): # Test idempotent assert_idempotent(importer, ixlan, data) +@pytest.mark.django_db +def test_vlan_null_ips(entities, save): + """ + The IX-F data contains a vlan that has null values for ipv4 and ipv6 + Importer should treat them the same as if they werent set at all (#1244) + """ + + data = setup_test_data("ixf.member.null.ip.vlan") + ixlan = entities["ixlan"][0] + + importer = ixf.Importer() + importer.sanitize(data) + + if not save: + return assert_idempotent(importer, ixlan, data, save=False) + + importer.update(ixlan, data=data) + importer.notify_proposals() + + assert importer.ixlan.ixf_ixp_import_error_notified is None + assert importer.ixlan.ixf_ixp_import_error is None + assert_no_emails(ix=ixlan.ix) + + # Assert idempotent / lock + importer.sanitize(data) + importer.update(ixlan, data=data) + + assert importer.ixlan.ixf_ixp_import_error_notified is None + assert importer.ixlan.ixf_ixp_import_error is None + assert_no_emails(ix=ixlan.ix) + @pytest.mark.django_db def test_vlan_list_empty(entities, save):