Skip to content

pdb_rir_status script removed live ASN#81

Open
gablooge wants to merge 3 commits into
20c:mainfrom
gablooge:gh_2001
Open

pdb_rir_status script removed live ASN#81
gablooge wants to merge 3 commits into
20c:mainfrom
gablooge:gh_2001

Conversation

@gablooge

Copy link
Copy Markdown
Contributor

Fix: pdb_rir_status deleted a live ASN due to unvalidated RIR data (#2001)

Background

pdb_rir_status deleted AS219272 from PeeringDB even though the ASN was—and had been for days—allocated in RIPE's published delegated-stats file and live in RDAP/whois.

Root cause

The deletion decision trusted a single, unvalidated data source: PeeringDB's local copy of the RIR delegated-*-extended-latest snapshot.

get_status(asn) returns None in three indistinguishable situations:

  • The ASN is genuinely unassigned.
  • Our local copy is stale, truncated, or partial.
  • The ASN is legitimately allocated but not yet present in the current snapshot.

RIPE republishes delegated statistics daily, so a newly allocated ASN may not appear in the snapshot for up to a day or two. Any of these cases caused a network to be flagged, warned, and (after KEEP_RIR_STATUS) deleted. With KEEP_RIR_STATUS=1, the deletion window is actually shorter than that publication lag.

Two gaps combined to make this happen for a live ASN:

  1. No integrity checking on the downloaded file.
    The fetch performed neither raise_for_status() nor any completeness validation, so truncated responses or error pages could be written to the cache and trusted. Since delegated ASN files are large, an interrupted download simply omits records.

  2. No independent confirmation before an irreversible delete.
    Absence from the local delegated snapshot alone was sufficient to delete a network, even though the delegated file is only a daily snapshot and naturally lags real-world allocations.

Fix — defense in depth

rdap (RIRAssignmentLookup) — trust the data before using it

  • Validate every download using both raise_for_status() and a completeness check that compares the parsed ASN record count against the file's own <rir>|*|asn|*|N|summary record.
  • Reject truncated, empty, or non-delegated responses.
  • Verified that the summary count matches the ASN record count for all five RIRs, including range records, so the validation does not produce false positives on valid files.
  • Never overwrite a valid cache with a failed or truncated download.
  • Automatically re-download stale or corrupt cache files (self-healing).
  • Raise the new RIRAssignmentError only when no valid dataset can be obtained.
  • Use atomic cache writes (PID-specific temporary file + os.replace()) so interrupted writes cannot leave partial cache files behind.
  • Refresh cache entries based on elapsed seconds rather than timedelta.days, fixing the previous behavior where cache_days=1 could actually refresh after nearly 48 hours.

Result: get_status() returning None now means "absent from a validated, complete delegated file" instead of "absent from whatever happened to be cached."

peeringdb (pdb_rir_status) — verify before deleting

Before performing the irreversible net.delete():

  • Perform a live RDAP lookup.
  • Skip (defer) deletion if RDAP still resolves the ASN.
  • Delete only when RDAP positively confirms the ASN no longer exists.
  • Defer deletion if RDAP returns an error rather than risking removal due to a transient failure.

The RDAP lookup only runs for the small number of networks that have already passed every other deletion gate, so the additional traffic is negligible.

This behavior is controlled by the new setting:

  • RIR_STATUS_VERIFY_BEFORE_DELETE (default: True)

These two layers use independent data sources (delegated snapshot vs. live RDAP) and only make deletion more conservative. A false deletion would now require both sources to be wrong simultaneously.

Settings

  • RIR_STATUS_VERIFY_BEFORE_DELETE (bool, default True) — enables the pre-delete RDAP verification.

Testing

rdap

Added tests covering:

  • completeness validation
  • empty/non-delegated response rejection
  • truncated downloads preserving an existing valid cache
  • self-healing of corrupt cache files
  • raising when no usable data exists
  • cache expiration using elapsed seconds

Sample fixtures were added under tests/data/assignment/.

peeringdb

Added tests covering:

  • skipping deletion when RDAP resolves the ASN
  • deleting when RDAP confirms the ASN is gone
  • deferring deletion on RDAP errors
  • verifying that RDAP is called only at the final deletion gate (not for healthy, newly warned, or recovering networks)
  • mixed delete/defer/recover runs without cross-contamination

Existing timer-gated deletion tests explicitly disable the verification flag.

Rollout

The PeeringDB verification uses only the already-released rdap API, so it becomes effective immediately.

The rdap hardening requires a new rdap release and a dependency bump in PeeringDB before those protections take effect there.

Deferred follow-ups

  • Wrap the load_data abort in a CommandError to present a clean operator-facing error instead of a traceback (cosmetic only; behavior is unchanged).
  • Optionally create a DeskPro ticket for networks that repeatedly defer deletion (RDAP continues to resolve while delegated RIR data continues to report the ASN as reclaimed). This would provide a useful signal for investigating upstream data-quality issues.

@codecov

codecov Bot commented Jul 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.96%. Comparing base (e8e35f2) to head (a452836).

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #81      +/-   ##
==========================================
+ Coverage   87.98%   88.96%   +0.97%     
==========================================
  Files          20       20              
  Lines        1182     1241      +59     
==========================================
+ Hits         1040     1104      +64     
+ Misses        142      137       -5     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant