Refactor sync_routing.py: download file dari scheduler MikroTik
This commit is contained in:
27
bgp_export_script.rsc
Normal file
27
bgp_export_script.rsc
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/system/script remove [find name="bgp_lokal_export"]
|
||||||
|
|
||||||
|
/system/script add name=bgp_lokal_export dont-require-permissions=yes source={ \
|
||||||
|
:local fname "bgp_lokal_export"; \
|
||||||
|
:log info "BGP Export: mulai..."; \
|
||||||
|
:local output ""; \
|
||||||
|
:local cnt 0; \
|
||||||
|
:foreach r in=[/routing/route find where distance=15] do={ \
|
||||||
|
:local dst [/routing/route get \$r dst-address]; \
|
||||||
|
:if (\$dst != "0.0.0.0/0" && \$dst != "::/0") do={ \
|
||||||
|
:set output ("\$output\$dst\n"); \
|
||||||
|
:set cnt (\$cnt + 1); \
|
||||||
|
}; \
|
||||||
|
}; \
|
||||||
|
:log info "BGP Export: CDN selesai"; \
|
||||||
|
:foreach r in=[/routing/route find where distance=200] do={ \
|
||||||
|
:local dst [/routing/route get \$r dst-address]; \
|
||||||
|
:if (\$dst != "0.0.0.0/0" && \$dst != "::/0") do={ \
|
||||||
|
:set output ("\$output\$dst\n"); \
|
||||||
|
:set cnt (\$cnt + 1); \
|
||||||
|
}; \
|
||||||
|
}; \
|
||||||
|
/file print file=\$fname; \
|
||||||
|
:delay 2s; \
|
||||||
|
/file set "\$fname.txt" contents=\$output; \
|
||||||
|
:log info "BGP Export: selesai"; \
|
||||||
|
}
|
||||||
101
sync_routing.py
101
sync_routing.py
@@ -18,57 +18,70 @@ API_URL = f"http://{BGP_ROUTER_IP}/rest/routing/route"
|
|||||||
auth = (BGP_ROUTER_USER, BGP_ROUTER_PASSWORD)
|
auth = (BGP_ROUTER_USER, BGP_ROUTER_PASSWORD)
|
||||||
|
|
||||||
def get_local_bgp_routes():
|
def get_local_bgp_routes():
|
||||||
"""Mengambil rentang IP Lokal/CDN dari tabel routing BGP secara efisien menggunakan parameter query API MikroTik"""
|
"""Download file bgp_lokal_export.txt dari router BGP.
|
||||||
|
|
||||||
|
File ini diekspor secara berkala oleh scheduler MikroTik (bgp_lokal_scheduler)
|
||||||
|
yang menjalankan script bgp_lokal_export setiap hari jam 04:00.
|
||||||
|
File berisi daftar dst-address dari rute CDN (distance=15) dan NIX (distance=200).
|
||||||
|
"""
|
||||||
|
import urllib3
|
||||||
|
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||||
|
|
||||||
print(f"Menghubungi router {BGP_ROUTER_IP} via REST API...")
|
print(f"Menghubungi router {BGP_ROUTER_IP} via REST API...")
|
||||||
|
|
||||||
all_local_ips = []
|
session = requests.Session()
|
||||||
|
session.auth = auth
|
||||||
|
session.verify = False
|
||||||
|
|
||||||
|
api_url = f"http://{BGP_ROUTER_IP}/rest"
|
||||||
|
export_file = "bgp_lokal_export.txt"
|
||||||
|
|
||||||
|
# 1. Cek apakah file export ada di router
|
||||||
|
print(f"Mengecek file {export_file} di router...")
|
||||||
try:
|
try:
|
||||||
# PENGAMBILAN RUTE KONTEN / CDN
|
res = session.get(f"{api_url}/file", params={"name": export_file}, timeout=10)
|
||||||
# Di RouterOS v7, rute CDN diset distance-nya menjadi -5 dari base eBGP (20), sehingga menjadi 15.
|
if res.status_code == 200:
|
||||||
# Kita menggunakan query string "?distance=15&.proplist=dst-address" agar routeros
|
files = res.json()
|
||||||
# hanya me-return rute yang bersangkutan secara instan tanpa perlu meloop 900.000 rute.
|
if not files:
|
||||||
print("Mengambil rute Konten / CDN (Distance 15)... Ini dapat memakan waktu hingga satu menit.")
|
print(f" -> File {export_file} tidak ditemukan di router!")
|
||||||
res_cdn = requests.get(
|
print(" Pastikan script bgp_lokal_export sudah dibuat dan dijalankan di router.")
|
||||||
API_URL,
|
print(" Lihat instruksi di setup_scheduler.md")
|
||||||
auth=auth,
|
return []
|
||||||
params={"distance": "15", ".proplist": "dst-address"},
|
|
||||||
verify=False,
|
|
||||||
timeout=120
|
|
||||||
)
|
|
||||||
if res_cdn.status_code == 200:
|
|
||||||
cdn_routes = res_cdn.json()
|
|
||||||
ids = [r.get("dst-address") for r in cdn_routes if r.get("dst-address")]
|
|
||||||
print(f" -> Berhasil mengambil {len(ids)} rute CDN.")
|
|
||||||
all_local_ips.extend(ids)
|
|
||||||
else:
|
|
||||||
print(f" -> Error CDN: {res_cdn.status_code} - {res_cdn.text}")
|
|
||||||
|
|
||||||
# PENGAMBILAN RUTE NIX / LOKAL OpenIXP
|
size = files[0].get("size", "0")
|
||||||
# Berdasarkan konfigurasi bgp-router.rsc, peer NIX menggunakan local.role=ibgp (Distance base: 200).
|
print(f" -> File ditemukan ({size} bytes)")
|
||||||
print("Mengambil rute NIX / OpenIXP (Distance 200)... Ini dapat memakan waktu hingga satu menit.")
|
|
||||||
res_nix = requests.get(
|
|
||||||
API_URL,
|
|
||||||
auth=auth,
|
|
||||||
params={"distance": "200", ".proplist": "dst-address"},
|
|
||||||
verify=False,
|
|
||||||
timeout=120
|
|
||||||
)
|
|
||||||
if res_nix.status_code == 200:
|
|
||||||
nix_routes = res_nix.json()
|
|
||||||
ids = [r.get("dst-address") for r in nix_routes if r.get("dst-address")]
|
|
||||||
print(f" -> Berhasil mengambil {len(ids)} rute NIX.")
|
|
||||||
all_local_ips.extend(ids)
|
|
||||||
else:
|
else:
|
||||||
print(f" -> Error NIX: {res_nix.status_code} - {res_nix.text}")
|
print(f" -> Error cek file: {res.status_code}")
|
||||||
|
return []
|
||||||
# Hapus default routes (0.0.0.0/0 dan ::/0) jika ada
|
except Exception as e:
|
||||||
all_local_ips = [ip for ip in all_local_ips if ip not in ("0.0.0.0/0", "::/0")]
|
print(f" -> Gagal koneksi ke router: {e}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
# 2. Download isi file via /execute :put
|
||||||
|
print(f"Mengunduh isi {export_file}...")
|
||||||
|
try:
|
||||||
|
res = session.post(f"{api_url}/execute",
|
||||||
|
json={"script": f':put [/file get {export_file} contents]'},
|
||||||
|
timeout=30)
|
||||||
|
|
||||||
return list(set(all_local_ips)) # Kembalikan list unik
|
if res.status_code == 200:
|
||||||
|
content = res.json().get("ret", "")
|
||||||
except requests.exceptions.RequestException as e:
|
if content:
|
||||||
print(f"Gagal mengambil data dari router via API: {e}")
|
# Parse: setiap baris adalah dst-address (contoh: 103.10.0.0/16)
|
||||||
|
routes = [line.strip() for line in content.split("\n")
|
||||||
|
if line.strip() and "/" in line.strip()]
|
||||||
|
# Hapus default routes
|
||||||
|
routes = [r for r in routes if r not in ("0.0.0.0/0", "::/0")]
|
||||||
|
print(f" -> Berhasil: {len(routes)} rute lokal diunduh")
|
||||||
|
return list(set(routes))
|
||||||
|
else:
|
||||||
|
print(" -> File kosong!")
|
||||||
|
return []
|
||||||
|
else:
|
||||||
|
print(f" -> Error download: {res.status_code} - {res.text[:100]}")
|
||||||
|
return []
|
||||||
|
except Exception as e:
|
||||||
|
print(f" -> Exception: {e}")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def generate_address_list_script(route_list, list_name, filename):
|
def generate_address_list_script(route_list, list_name, filename):
|
||||||
|
|||||||
Reference in New Issue
Block a user