Skip to content

Commit 68891c7

Browse files
authored
Add ARIN support for IRR route objects and RPKI ROAs (#1)
* Add ARIN support for IRR route objects and RPKI ROAs * Add --registry flag and run RIPE/ARIN before RADb Adds --registry (repeatable) to select which registries to update. Without it, all configured registries run. Reorders execution to RIPE → ARIN → RADb so upstream IRR state is set before RADb syncs. * Fix ARIN route and ROA API compatibility - Route body: description uses required <line number="N"> children instead of a plain text node (schema requirement) - ROA transaction: add required <name> element; sanitize to allowed chars (a-z A-Z 0-9 _ - space) - ROA parsing: strip leading zeros from IPv4 octets returned by ARIN - ARIN credentials: add optional test_api_key for OTE environment, used automatically in test mode when present * Add delete support for ARIN route objects and ROAs Routes and ROAs can be marked with delete: true in config to trigger deletion on the next run. ROA deletion uses the existing diff logic: delete-marked entries are included in managed prefixes but excluded from desired, so existing ROAs for that prefix are removed. Also fixes autoLink attribute casing on roaHandle (was autolink), and improves ROA dry-run to fetch current state and show accurate add/delete counts. * Add --setup-ote to replicate ARIN production into OTE Fetches routes and ROAs from ARIN production and syncs them into the OTE environment. Useful after OTE resets (monthly wipe) or when new production routes need to be available for testing. Requires arin.credentials.test_api_key in config.
1 parent 7a4016f commit 68891c7

9 files changed

Lines changed: 698 additions & 14 deletions

File tree

README.md

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# rir-updater
22

3-
CLI tool for syncing route objects to RIPE NCC and RADb, and RPKI ROAs to RIPE.
3+
CLI tool for syncing route objects to RIPE NCC, ARIN, and RADb, and RPKI ROAs to RIPE and ARIN.
44

55
## Requirements
66

@@ -16,7 +16,7 @@ uv sync
1616

1717
## Configuration
1818

19-
Copy `config.example.yaml` and fill in your values. Both `ripe` and `radb` sections are optional — include only the registries you use.
19+
Copy `config.example.yaml` and fill in your values. All registry sections (`ripe`, `arin`, `radb`) are optional — include only the registries you use.
2020

2121
```yaml
2222
ripe:
@@ -44,6 +44,25 @@ ripe:
4444
origin: "AS12345"
4545
max_length: 32
4646

47+
arin:
48+
org_handle: "EXAMPLEORG-1"
49+
credentials:
50+
api_key: "op://vault/item/arin-api-key"
51+
routes:
52+
- prefix: "192.0.2.0/24"
53+
origin: "AS12345"
54+
description: "Example IPv4 prefix"
55+
- prefix: "2001:db8::/32"
56+
origin: "AS12345"
57+
description: "Example IPv6 prefix"
58+
roas:
59+
- prefix: "192.0.2.0/24"
60+
origin: "AS12345"
61+
max_length: 24
62+
- prefix: "2001:db8::/32"
63+
origin: "AS12345"
64+
max_length: 32
65+
4766
radb:
4867
maintainer: "MAINT-AS12345"
4968
contact_email: "admin@example.com"
@@ -76,6 +95,15 @@ Secrets are fetched from 1Password via the `op` CLI. The `credentials` block in
7695
| `test_db_username` | RIPE test DB username (optional, overrides `db_username` in test mode) |
7796
| `test_db_password` | RIPE test DB password (optional, overrides `db_password` in test mode) |
7897

98+
### ARIN
99+
100+
| Field | Used for |
101+
|-------|----------|
102+
| `api_key` | ARIN API key for all IRR and RPKI requests (production) |
103+
| `test_api_key` | ARIN OTE API key (optional, overrides `api_key` in test mode) |
104+
105+
The production API key must be linked to a POC with authority over your organization's resources. Create one at ARIN Online → Settings → Security Info → Manage API Keys. OTE keys are created the same way at `account.ote.arin.net`.
106+
79107
### RADb
80108

81109
| Field | Used for |
@@ -89,20 +117,30 @@ References use the `op://vault/item/field` format. You must be signed in to the
89117
## Usage
90118

91119
```bash
92-
# Dry-run against the RIPE test database and RADb (default)
120+
# Dry-run all configured registries (test environments where applicable)
93121
uv run rir-updater config.yaml
94122
95-
# Dry-run against RIPE production
96-
uv run rir-updater config.yaml --production
123+
# Dry-run a specific registry only
124+
uv run rir-updater config.yaml --registry arin
125+
uv run rir-updater config.yaml --registry ripe --registry radb
97126
98-
# Apply changes to RIPE production and RADb
127+
# Apply changes to all registries in production
99128
uv run rir-updater config.yaml --production --commit
100129
130+
# Apply changes to ARIN only (production)
131+
uv run rir-updater config.yaml --registry arin --production --commit
132+
101133
# Set up the RIPE test database with objects replicated from production
102134
uv run rir-updater config.yaml --setup-test
135+
136+
# Replicate ARIN production routes and ROAs into the OTE environment
137+
uv run rir-updater config.yaml --setup-ote # dry-run
138+
uv run rir-updater config.yaml --setup-ote --commit # apply
103139
```
104140

105-
RADb always runs against production — `--production` and `--setup-test` only affect the RIPE section.
141+
RADb always runs against production — `--production` only affects the RIPE and ARIN sections. ARIN uses its OT&E environment in test mode (`reg.ote.arin.net`) and production otherwise.
142+
143+
When no `--registry` flags are given, all registries present in the config are updated. Updates run in order: RIPE → ARIN → RADb.
106144

107145
### RIPE test database bootstrap
108146

config.example.yaml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,26 @@ ripe:
2323
- prefix: "2001:db8::/32"
2424
origin: "AS12345"
2525

26+
arin:
27+
org_handle: "EXAMPLEORG-1"
28+
credentials:
29+
api_key: "op://vault/item/arin-api-key"
30+
test_api_key: "op://vault/item/arin-ote-api-key" # optional: overrides api_key for OTE
31+
routes:
32+
- prefix: "192.0.2.0/24"
33+
origin: "AS12345"
34+
description: "Example IPv4 prefix"
35+
- prefix: "2001:db8::/32"
36+
origin: "AS12345"
37+
description: "Example IPv6 prefix"
38+
roas: # optional
39+
- prefix: "192.0.2.0/24"
40+
origin: "AS12345"
41+
max_length: 24
42+
- prefix: "2001:db8::/32"
43+
origin: "AS12345"
44+
max_length: 32
45+
2646
radb:
2747
maintainer: "MAINT-AS12345"
2848
contact_email: "admin@example.com"

src/rir_updater/arin/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)