1
0
mirror of https://github.com/peeringdb/peeringdb.git synced 2024-05-11 05:55:09 +00:00

Additional IRR validators (#690)

* increase rdap lookup timeout to 2.5

* Allow as set hierarchy according to RFC 2622 5.0 during IRR validation (#151)

* fix wording of validation error message (#151)

* allow single as in irr validation (#151)
allow as rs-set combination in irr validation (#151)

Co-authored-by: Stefan Pratter <stefan@20c.com>
This commit is contained in:
Matt Griswold
2020-04-17 19:57:23 -05:00
committed by GitHub
parent f2d1316fc6
commit 58371e3868
5 changed files with 61 additions and 3 deletions

View File

@@ -163,6 +163,9 @@ set_option("DATA_QUALITY_MIN_PREFIXLEN_V6", 64)
# maximum value to allow for prefix length on a v6 prefix
set_option("DATA_QUALITY_MAX_PREFIXLEN_V6", 116)
# maximum value to allow for irr set hierarchy depth
set_option("DATA_QUALITY_MAX_IRR_DEPTH", 3)
RATELIMITS = {
"request_login_POST": "4/m",
"request_translation": "2/m",

View File

@@ -120,6 +120,7 @@ class RdapLookup(rdap.RdapClient):
config = dict(
bootstrap_url=settings.RDAP_URL.rstrip("/"),
lacnic_apikey=settings.RDAP_LACNIC_APIKEY,
timeout=2.5,
)
super(RdapLookup, self).__init__(config)

View File

@@ -180,23 +180,62 @@ def validate_irr_as_set(value):
for item in value.split(","):
item = item.upper()
source = None
as_set = None
# <name>@<source>
parts_match = re.match("^(AS|RS)-([\w\d\-]+)@(\w+)$", item)
parts_match = re.match("^([\w\d\-:]+)@(\w+)$", item)
if parts_match:
source = parts_match.group(3)
source = parts_match.group(2)
as_set = parts_match.group(1)
# <source>::<name>
else:
parts_match = re.match("^(\w+)::(AS|RS)-([\w\d\-]+)$", item)
parts_match = re.match("^(\w+)::([\w\d\-:]+)$", item)
if parts_match:
source = parts_match.group(1)
as_set = parts_match.group(2)
else:
raise ValidationError(_("Invalid formatting: {} - should be AS-SET@SOURCE or SOURCE::AS-SET").format(item))
if source not in IRR_SOURCE:
raise ValidationError(_("Unknown IRR source: {}").format(source))
# validate set name and as hierarchy
as_parts = as_set.split(":")
if len(as_parts) > settings.DATA_QUALITY_MAX_IRR_DEPTH:
raise ValidationError(
_("Maximum AS-SET hierarchy depth: {}").format(
settings.DATA_QUALITY_MAX_IRR_DEPTH
)
)
set_found = False
typ = None
types = []
for part in as_parts:
match_set = re.match("^(AS|RS)-[\w\d\-]+$", part)
match_as = re.match("^(AS)[\d]+$", part)
# set name found
if match_set:
set_found = True
types.append(match_set.group(1))
elif not match_as:
raise ValidationError(_("Invalid formatting: {} - should be RS-SET, AS-SET or AS123").format(part))
if len(list(set(types))) > 1:
raise ValidationError(
_("All parts of an hierarchical name have to be of the same type")
)
if not set_found and len(as_parts) > 1:
raise ValidationError(_("At least one component must be an actual set name"))
validated.append(item)
return " ".join(validated)

View File

@@ -154,6 +154,7 @@ settings.configure(
DATA_QUALITY_MAX_PREFIXLEN_V4=28,
DATA_QUALITY_MIN_PREFIXLEN_V6=64,
DATA_QUALITY_MAX_PREFIXLEN_V6=116,
DATA_QUALITY_MAX_IRR_DEPTH=3,
TUTORIAL_MODE=False,
CAPTCHA_TEST_MODE=True,
SITE_ID=1,

View File

@@ -156,11 +156,20 @@ def test_validate_prefix_overlap():
# success validation
("RIPE::AS-FOO", "RIPE::AS-FOO"),
("AS-FOO@RIPE", "AS-FOO@RIPE"),
("AS-FOO-BAR@RIPE", "AS-FOO-BAR@RIPE"),
("ripe::as-foo", "RIPE::AS-FOO"),
("as-foo@ripe", "AS-FOO@RIPE"),
("as-foo@ripe as-bar@ripe", "AS-FOO@RIPE AS-BAR@RIPE"),
("as-foo@ripe,as-bar@ripe", "AS-FOO@RIPE AS-BAR@RIPE"),
("as-foo@ripe, as-bar@ripe", "AS-FOO@RIPE AS-BAR@RIPE"),
(
"RIPE::AS12345:AS-FOO RIPE::AS12345:AS-FOO:AS9876",
"RIPE::AS12345:AS-FOO RIPE::AS12345:AS-FOO:AS9876"
),
("ripe::as-foo:as123:as345", "RIPE::AS-FOO:AS123:AS345"),
("RIPE::AS12345", "RIPE::AS12345"),
("AS12345@RIPE", "AS12345@RIPE"),
("RIPE::AS123456:RS-FOO", "RIPE::AS123456:RS-FOO"),
# fail validation
("AS-FOO", False),
@@ -170,6 +179,11 @@ def test_validate_prefix_overlap():
("UNKNOWN::ASFOO", False),
("AS-FOO RIPE:AS-FOO", False),
("AS-FOO AS-FOO@RIPE", False),
("RIPE::RS15562:RS-FOO", False),
("RIPE::AS123456:RS-FOO:AS-FOO", False),
# > DATA_QUALITY_MAX_IRR_DEPTH
("ripe::as-foo:as123:as345:as678", False),
])
def test_validate_irr_as_set(value, validated):
if not validated: