mirror of
https://github.com/quantum5/arin-irr.git
synced 2025-04-24 11:31:57 -04:00
Add basic AS200351 aut-num and routing policy
This commit is contained in:
parent
a4710940eb
commit
633a168ac8
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
.api-key
|
80
AS200351.rpsl
Normal file
80
AS200351.rpsl
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
aut-num: AS200351
|
||||||
|
as-name: DQN-AS-ANYCAST
|
||||||
|
descr: Dynamic Quantum Networks
|
||||||
|
descr: https://as200351.net
|
||||||
|
descr: https://quantum5.ca
|
||||||
|
remarks: +-------------------------------------------------------------+
|
||||||
|
remarks: | ____ _ |
|
||||||
|
remarks: | / __ \__ ______ ____ _____ ___ (_)____ |
|
||||||
|
remarks: | / / / / / / / __ \/ __ `/ __ `__ \/ / ___/ |
|
||||||
|
remarks: | / /_/ / /_/ / / / / /_/ / / / / / / / /__ |
|
||||||
|
remarks: | /_____/\__, /_/ /_/\__,_/_/ /_/ /_/_/\___/ |
|
||||||
|
remarks: | /____/ ____ __ |
|
||||||
|
remarks: | / __ \__ ______ _____ / /___ ______ ___ |
|
||||||
|
remarks: | / / / / / / / __ `/ __ \/ __/ / / / __ `__ \ |
|
||||||
|
remarks: | / /_/ / /_/ / /_/ / / / / /_/ /_/ / / / / / / |
|
||||||
|
remarks: | \___\_\__,_/\__,_/_/ /_/\__/\__,_/_/ /_/ /_/ |
|
||||||
|
remarks: | _ __ __ __ |
|
||||||
|
remarks: | / | / /__ / /__ ______ _____/ /_______ |
|
||||||
|
remarks: | / |/ / _ \/ __/ | /| / / __ \/ ___/ //_/ ___/ |
|
||||||
|
remarks: | / /| / __/ /_ | |/ |/ / /_/ / / / ,< (__ ) |
|
||||||
|
remarks: | /_/ |_/\___/\__/ |__/|__/\____/_/ /_/|_/____/ |
|
||||||
|
remarks: | |
|
||||||
|
remarks: +-------------------------------------------------------------+
|
||||||
|
remarks:
|
||||||
|
remarks: ===================== ROUTING INFORMATION =====================
|
||||||
|
remarks: ====== upstreams ======
|
||||||
|
import: from AS200351:as-upstreams accept ANY
|
||||||
|
mp-import: afi any.unicast from AS200351:as-upstreams accept ANY
|
||||||
|
export: to AS200351:as-upstreams announce AS200351:as-all
|
||||||
|
mp-export: afi any.unicast to AS200351:as-upstreams announce AS200351:as-all
|
||||||
|
remarks:
|
||||||
|
remarks: ====== IXP: ONIX ======
|
||||||
|
remarks: * IPv4: 149.112.50.51
|
||||||
|
remarks: * IPv6: 2001:504:125:e1::51
|
||||||
|
import: from AS57369 accept AS57369:AS-ONIX
|
||||||
|
mp-import: afi any.unicast from AS57369 accept AS57369:AS-ONIX
|
||||||
|
export: to AS57369 announce AS200351:as-all
|
||||||
|
mp-export: afi any.unicast to AS57369 announce AS200351:as-all
|
||||||
|
remarks:
|
||||||
|
remarks: ===== IXP: FogIXP =====
|
||||||
|
remarks: * IPv4: 185.1.147.210
|
||||||
|
remarks: * IPv6: 2001:7f8:ca:1:0:20:0351:1
|
||||||
|
import: from AS47498 accept AS-FOGIXP
|
||||||
|
mp-import: afi any.unicast from AS47498 accept AS-FOGIXP
|
||||||
|
export: to AS47498 announce AS200351:as-all
|
||||||
|
mp-export: afi any.unicast to AS47498 announce AS200351:as-all
|
||||||
|
remarks:
|
||||||
|
remarks: ===== IXP: AccurIX ====
|
||||||
|
remarks: * IPv4: 149.112.74.8
|
||||||
|
remarks: * IPv6: 2001:504:132::8
|
||||||
|
import: from AS57194 accept AS57194:as-accurix-members
|
||||||
|
mp-import: afi any.unicast from AS57194 accept AS57194:as-accurix-members
|
||||||
|
export: to AS57194 announce AS200351:as-all
|
||||||
|
mp-export: afi any.unicast to AS57194 announce AS200351:as-all
|
||||||
|
remarks:
|
||||||
|
remarks: ===== IXP: FrysIX =====
|
||||||
|
remarks: * IPv4: 185.1.203.229
|
||||||
|
remarks: * IPv6: 2001:7f8:10f::3:e9f:229
|
||||||
|
import: from AS56393 accept AS-FRYS-IX-CONNECTED
|
||||||
|
mp-import: afi any.unicast from AS56393 accept AS-FRYS-IX-CONNECTED
|
||||||
|
export: to AS56393 announce AS200351:as-all
|
||||||
|
mp-export: afi any.unicast to AS56393 announce AS200351:as-all
|
||||||
|
remarks:
|
||||||
|
remarks: ====== IXP: KCIX ======
|
||||||
|
remarks: * IPv4: 206.51.7.216
|
||||||
|
remarks: * IPv6: 2001:504:1b:1::216
|
||||||
|
remarks:
|
||||||
|
remarks: ===== IXP: STLIX ======
|
||||||
|
remarks: * IPv4: 206.83.12.70
|
||||||
|
remarks: * IPv6: 2001:504:98::70
|
||||||
|
remarks:
|
||||||
|
remarks: ===== IXP: HOUIX ======
|
||||||
|
remarks: * IPv4: 206.83.136.41
|
||||||
|
remarks: * IPv6: 2001:504:9E::41
|
||||||
|
remarks:
|
||||||
|
remarks: ==================== OWNERSHIP INFORMATION ====================
|
||||||
|
admin-c: DQNA-ARIN
|
||||||
|
tech-c: DQNOC-ARIN
|
||||||
|
mnt-by: MNT-GC-1348
|
||||||
|
source: ARIN
|
37
AS200351@AS-UPSTREAMS.rpsl
Normal file
37
AS200351@AS-UPSTREAMS.rpsl
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
as-set: AS200351:AS-UPSTREAMS
|
||||||
|
descr: AS200351's Upstreams
|
||||||
|
remarks: ==== Frantech Solutions ====
|
||||||
|
members: AS53667
|
||||||
|
remarks: ===== Constant / Vultr =====
|
||||||
|
members: AS20473
|
||||||
|
remarks: ===== Cloudie Networks =====
|
||||||
|
members: AS924
|
||||||
|
remarks: === Accuris Technologies ===
|
||||||
|
members: AS52210
|
||||||
|
remarks: ==== Hurricane Electric ====
|
||||||
|
members: AS6939
|
||||||
|
remarks: ======== iFog GmbH =========
|
||||||
|
members: AS34927, AS209533
|
||||||
|
remarks: ======= FreeTransit ========
|
||||||
|
members: AS41051
|
||||||
|
remarks: === F4 Networks / Rozint ===
|
||||||
|
members: AS21738, AS25759
|
||||||
|
remarks: ========== Suble ===========
|
||||||
|
members: AS199545
|
||||||
|
remarks: ======== Tschajera =========
|
||||||
|
members: AS209022
|
||||||
|
remarks: ========= HyeHost ==========
|
||||||
|
members: AS47272
|
||||||
|
remarks: ========= Diederik =========
|
||||||
|
members: AS50917
|
||||||
|
remarks: ==== Snaju / DartNode ======
|
||||||
|
members: AS399646
|
||||||
|
remarks: ===== Jon Arve Vanvik ======
|
||||||
|
members: AS210475
|
||||||
|
remarks: ========= FlowVPS ==========
|
||||||
|
members: AS37988
|
||||||
|
remarks: ============================
|
||||||
|
admin-c: DQNA-ARIN
|
||||||
|
tech-c: DQNOC-ARIN
|
||||||
|
mnt-by: MNT-GC-1348
|
||||||
|
source: ARIN
|
124
update-irr.py
Executable file
124
update-irr.py
Executable file
|
@ -0,0 +1,124 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import getpass
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
|
REGISTRY = 'https://reg.arin.net/rest/irr'
|
||||||
|
|
||||||
|
|
||||||
|
class BaseResource(ABC):
|
||||||
|
type: str
|
||||||
|
|
||||||
|
def __init__(self, name, rpsl):
|
||||||
|
self.name = name
|
||||||
|
self.rpsl = rpsl
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def validate(self): ...
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_create_url(self): ...
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_update_url(self): ...
|
||||||
|
|
||||||
|
|
||||||
|
class AsSetResource(BaseResource):
|
||||||
|
def __init__(self, name, rpsl):
|
||||||
|
self.type = 'as-set'
|
||||||
|
super().__init__(name, rpsl)
|
||||||
|
|
||||||
|
def validate(self):
|
||||||
|
if not re.match(f'^as-set:\s+{re.escape(self.name)}$', self.rpsl, re.M):
|
||||||
|
raise ValueError(f'Expected aut-num: {self.name} in RPSL')
|
||||||
|
|
||||||
|
def get_create_url(self):
|
||||||
|
return f'{REGISTRY}/as-set'
|
||||||
|
|
||||||
|
def get_update_url(self):
|
||||||
|
return f'{REGISTRY}/as-set/{self.name}'
|
||||||
|
|
||||||
|
|
||||||
|
class AutNumResource(BaseResource):
|
||||||
|
def __init__(self, name, rpsl):
|
||||||
|
self.type = 'aut-num'
|
||||||
|
super().__init__(name, rpsl)
|
||||||
|
|
||||||
|
def validate(self):
|
||||||
|
if not re.match(f'^aut-num:\s+{re.escape(self.name)}$', self.rpsl, re.M):
|
||||||
|
raise ValueError(f'Expected aut-num: {self.name} in RPSL')
|
||||||
|
|
||||||
|
def get_create_url(self):
|
||||||
|
return f'{REGISTRY}/aut-num/{self.name}'
|
||||||
|
|
||||||
|
def get_update_url(self):
|
||||||
|
return f'{REGISTRY}/aut-num/{self.name}'
|
||||||
|
|
||||||
|
|
||||||
|
def get_resource(path, rpsl):
|
||||||
|
if (m := re.match('^(AS\d+)\.rpsl$', path)):
|
||||||
|
return AutNumResource(m.group(1), rpsl)
|
||||||
|
elif (m := re.match('^((?:AS\d+@)?(AS-[A-Z0-9-]+@)*AS-[A-Z0-9-]+)\.rpsl$', path)):
|
||||||
|
return AsSetResource(m.group(1).replace('@', ':'), rpsl)
|
||||||
|
|
||||||
|
|
||||||
|
def get_api_key():
|
||||||
|
key_file = Path(__file__).parent / '.api-key'
|
||||||
|
if key_file.exists():
|
||||||
|
with open(key_file) as f:
|
||||||
|
return f.read().strip()
|
||||||
|
|
||||||
|
return getpass.getpass('ARIN api key: ')
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
prog=sys.argv[0],
|
||||||
|
description='Updates the ARIN IRR database with RPSL files'
|
||||||
|
)
|
||||||
|
parser.add_argument('filename', type=argparse.FileType('r'))
|
||||||
|
parser.add_argument('-c', '--create', action='store_true')
|
||||||
|
parser.add_argument(
|
||||||
|
'-o', '--org',
|
||||||
|
help='Organization handle (e.g. when creating an as-set)'
|
||||||
|
)
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
with args.filename as f:
|
||||||
|
rpsl = f.read()
|
||||||
|
|
||||||
|
resource = get_resource(args.filename.name, rpsl)
|
||||||
|
if not resource:
|
||||||
|
print(f"Can't identify resource type from {args.filename.name}")
|
||||||
|
raise SystemExit(1)
|
||||||
|
|
||||||
|
resource.validate()
|
||||||
|
|
||||||
|
params = {'apikey': get_api_key()}
|
||||||
|
if args.org:
|
||||||
|
params['orgHandle'] = args.org
|
||||||
|
|
||||||
|
if args.create:
|
||||||
|
verb = 'POST'
|
||||||
|
url = resource.get_create_url()
|
||||||
|
else:
|
||||||
|
verb = 'PUT'
|
||||||
|
url = resource.get_update_url()
|
||||||
|
|
||||||
|
r = requests.request(verb, url=url, params=params, data=resource.rpsl, headers={
|
||||||
|
'Accept': 'application/rpsl',
|
||||||
|
'Content-Type': 'application/rpsl',
|
||||||
|
})
|
||||||
|
|
||||||
|
print(r.content.decode('utf-8', 'replace'))
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
Loading…
Reference in a new issue