mirror of
https://github.com/quantum5/arin-irr.git
synced 2025-04-24 03:21: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