From 16b00b36462743203bae199cd411dd9409d19ace Mon Sep 17 00:00:00 2001 From: Wartana Date: Thu, 26 Feb 2026 11:00:45 +0800 Subject: [PATCH] Auto dual limit (int 50%, local 100%) generation script --- update_mangle_queue.py | 157 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 update_mangle_queue.py diff --git a/update_mangle_queue.py b/update_mangle_queue.py new file mode 100644 index 0000000..9c12fc6 --- /dev/null +++ b/update_mangle_queue.py @@ -0,0 +1,157 @@ +import requests +import json +import os +import time +import urllib3 + +urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) + +def get_router_credentials(config_path, isp_name="dimensi", router_name="router-dimensi-dell"): + try: + with open(config_path, 'r') as f: + config = json.load(f) + routers = config.get("isps", {}).get(isp_name, {}).get("routers", {}) + return routers.get(router_name) + except Exception as e: + print(f"Error membaca config: {e}") + return None + +def update_mangle_and_queue(): + router = get_router_credentials("/home/wartana/myApp/billing-mcp/config.json") + if not router: + print("Kredensial router-dimensi-dell tidak ditemukan di config.") + return + + host = router["host"] + user = router["user"] + password = router["pass"] + port = router["port"] + + api_url = f"http://{host}/rest" + if port != 80: + api_url = f"http://{host}:{port}/rest" + + session = requests.Session() + session.auth = (user, password) + session.verify = False + + print(f"--- Menghubungi router {host}:{port} ---") + + # 1. CLEANUP (Hapus Mangle Mark-Packet, Queue Type 1/2 lama kalo ada, Queue Tree Lokal, dll jika script dijalankan berulang) + print("Membersihkan Mangle & Queue peninggalan lama...") + cleanup_script = """ +/ip/firewall/mangle/remove [find chain=forward action=mark-packet] +/queue/tree/remove [find name~"_LOKAL"] +/queue/tree/remove [find name~"_local"] +/queue/type/remove [find name~"_half"] + """ + try: + session.post(f"{api_url}/execute", json={"script": cleanup_script}, timeout=30) + except Exception as e: + pass + + time.sleep(3) # Tunggu router bernafas + + # 2. DEFINISI PROFIL + # Format: [Profile Name, Full Speed (Mbps), Half Speed (Mbps), Original Limit DL, Original Limit UL] + # Catatan: Ini didasarkan pada file 178-queue-tree.rsc yang diupload + profiles = [ + # Hemat dan EXPIRED kita tangani special + ("star_10", 10, 5, "2G", "500M"), + ("star_20", 20, 10, "3G", "500M"), + ("star_30", 30, 15, "3G", "500M"), + ("star_50", 50, 25, "3G", "500M"), + ("star_100", 100, 50, "3G", "500M"), + ("star_150", 150, 75, "3G", "500M"), + ("star_200", 200, 100, "3G", "500M"), + ("star_500", 500, 250, "3G", "500M") + ] + + commands = [] + + # --- A. SETUP QUEUE TYPES & QUEUE PARENT LOKAL --- + + # Bikin Queue Parent LOKAL + commands.append("/queue/tree/add max-limit=5G name=1_all_dl_Dimensi_LOKAL parent=global queue=default") + commands.append("/queue/tree/add max-limit=5G name=5_all_ul_Dimensi_LOKAL parent=global queue=default") + + print("Menyusun skrip untuk Profil Spesial (EXPIRED & Hemat)...") + + # PROFIL EXPIRED (Semua dilimit mati, pakai queue default saja) + commands.append("/ip/firewall/mangle/add action=mark-packet chain=forward dst-address-list=EXPIRED new-packet-mark=EXPIRED_dl passthrough=no") + commands.append("/ip/firewall/mangle/add action=mark-packet chain=forward src-address-list=EXPIRED new-packet-mark=EXPIRED_ul passthrough=no") + # Queue Tree EXPIRED sudah ada di 178 eksisting, jadi kita tak ubah + + # PROFIL HEMAT (Bypass LOKAL penuh, Tidak di split speed) + # Catatan: Hemat itu "Up to X", kita biarkan max-limit ikut apa yang ada di tree. Intinya LOKAL 5G loss, INT nya biarkan seperti biasa max-limit 3G (PCQ default hemat 6M). + commands.append("/ip/firewall/mangle/add action=mark-packet chain=forward dst-address-list=hemat src-address-list=!ip-lokal new-packet-mark=hemat_dl passthrough=no") + commands.append("/ip/firewall/mangle/add action=mark-packet chain=forward src-address-list=hemat dst-address-list=!ip-lokal new-packet-mark=hemat_up passthrough=no") + commands.append("/ip/firewall/mangle/add action=mark-packet chain=forward dst-address-list=hemat src-address-list=ip-lokal new-packet-mark=hemat_dl_local passthrough=no") + commands.append("/ip/firewall/mangle/add action=mark-packet chain=forward src-address-list=hemat dst-address-list=ip-lokal new-packet-mark=hemat_up_local passthrough=no") + # Child Queue Lokal HEMAT + commands.append("/queue/tree/add max-limit=5G name=hemat_dl_local packet-mark=hemat_dl_local parent=1_all_dl_Dimensi_LOKAL queue=hemat_dl_6m") + commands.append("/queue/tree/add max-limit=5G name=hemat_ul_local packet-mark=hemat_up_local parent=5_all_ul_Dimensi_LOKAL queue=hemat_up_6m") + + + # --- B. SETUP PROFIL STAR REGULAR (Limit Int = Setengah) --- + print(f"Menyusun skrip Mangle & Queue Tree untuk {len(profiles)} Profil Star...") + for p in profiles: + name, full, half, dl_limit, ul_limit = p + + # Penamaan Packet Marks + dl_int = f"{name}_dl" + up_int = f"{name}_up" # cat: di 178 mangle asli pake _up, bukan _ul + dl_loc = f"{name}_dl_local" + up_loc = f"{name}_up_local" + + # 1. BIKIN MANGLE INT (!ip-lokal) & LOKAL (ip-lokal) + commands.append(f"/ip/firewall/mangle/add action=mark-packet chain=forward dst-address-list={name} src-address-list=!ip-lokal new-packet-mark={dl_int} passthrough=no") + commands.append(f"/ip/firewall/mangle/add action=mark-packet chain=forward src-address-list={name} dst-address-list=!ip-lokal new-packet-mark={up_int} passthrough=no") + + commands.append(f"/ip/firewall/mangle/add action=mark-packet chain=forward dst-address-list={name} src-address-list=ip-lokal new-packet-mark={dl_loc} passthrough=no") + commands.append(f"/ip/firewall/mangle/add action=mark-packet chain=forward src-address-list={name} dst-address-list=ip-lokal new-packet-mark={up_loc} passthrough=no") + + # 2. UBAH/BUAT BIKIN QUEUE TYPES SETENGAH (Hanya jika belum ada). + # Kita menggunakan _half sebagai penanda + pcq_dl_half = f"pcq_dl_{half}m_half" + pcq_up_half = f"pcq_up_{half}m_half" + + commands.append(f"/queue/type/add kind=pcq name={pcq_dl_half} pcq-classifier=dst-address pcq-rate={half}M") + commands.append(f"/queue/type/add kind=pcq name={pcq_up_half} pcq-classifier=src-address pcq-rate={half}M") + + # Bikin pcq_dl lokal asalnya (Kalo kelewatan ga terconfig di router): + pcq_dl_full = f"pcq_dl_{full}m" + pcq_up_full = f"pcq_up_{full}m" # Cat: kadang di router pake queue=pcq_up_10m, kadang pcq_ul_200m! + # Kita deteksi nama queue ori uploadnya apa dari 178-queue-tree: + q_up_ori = f"pcq_up_{full}m" + if full in [200, 500]: # di config khusus pake 'ul' + q_up_ori = f"pcq_ul_{full}m" + + # 3. SET QUEUE INTERNASIONAL (Yg Lama) PAKE PCQ SETENGAH + # Asumsinya tree star_10_dl dan star_10_ul (karena mangle _up tapi nama queue tree .rsc Anda ada yg _ul misal star_10_ul) + commands.append(f"/queue/tree/set [find name=\"{name}_dl\"] queue={pcq_dl_half}") + commands.append(f"/queue/tree/set [find name=\"{name}_ul\"] queue={pcq_up_half}") + + # 4. BIKIN CHILD QUEUE LOKAL YANG BARU (Gunakan rate FULL / Queue eksisting PCQ ori) + commands.append(f"/queue/tree/add max-limit=5G name={name}_dl_local packet-mark={dl_loc} parent=1_all_dl_Dimensi_LOKAL queue={pcq_dl_full}") + commands.append(f"/queue/tree/add max-limit=5G name={name}_ul_local packet-mark={up_loc} parent=5_all_ul_Dimensi_LOKAL queue={q_up_ori}") + + # --- EKSEKUSI SEMUA COMMAND SEBAGAI MIKROTIK BATCH SCRIPT --- + script_code = "\n".join(commands) + + print(f"Mengeksekusi {len(commands)} baris konfigurasi Mangle, Type, dan Queue Tree dual-stack...") + + payload = {"script": script_code} + + try: + res = session.post(f"{api_url}/execute", json=payload, timeout=30) + if res.status_code in (200, 201): + print("Berhasil! Mangle & Queue Lokal (Full) vs Int (Half) telah disinkronisasi.") + print(f"Respon MikroTik: {res.text.strip()}") + else: + print(f"Kegagalan saat inject konfigurasi: {res.text}") + except Exception as e: + print(f"Error eksekusi: {e}") + +if __name__ == "__main__": + update_mangle_and_queue()