Files
skrypty_narzedzia/nmcli_configurator.py
2025-06-25 09:13:49 +02:00

154 lines
5.3 KiB
Python

import subprocess
def detect_rt_tables_path():
return "/etc/iproute2/rt_tables"
def list_connections():
output = subprocess.check_output(["nmcli", "-t", "-f", "uuid,name,type,device", "connection", "show"]).decode()
print("\n[DEBUG] Surowe dane z nmcli:")
print(output)
conns = []
for line in output.strip().splitlines():
parts = line.strip().split(":", 3)
if len(parts) < 4:
continue
uuid, name, typ, dev = parts
if typ.strip() in ["ethernet", "802-3-ethernet"]:
dev = dev.strip() if dev.strip() else "<brak>"
conns.append({"uuid": uuid, "name": name, "device": dev})
return conns
def prompt_config(conn):
default_iface = conn['device']
if not default_iface:
default_iface = input(f"Podaj nazwę interfejsu dla połączenia '{conn['name']}' ({conn['uuid']}): ").strip()
print(f"\n--- Konfiguracja dla interfejsu: {default_iface} ({conn['name']}) ---")
ip = input("Adres IP/maska (np. 10.87.2.121/24): ").strip()
# domyślna brama z IP
ip_parts = ip.split(".")
default_gw = f"{ip_parts[0]}.{ip_parts[1]}.{ip_parts[2]}.1" if len(ip_parts) >= 4 else ""
gw_input = input(f"Brama (enter = brak, d = {default_gw}): ").strip().lower()
if gw_input == "d":
gw = default_gw
elif gw_input == "":
gw = None
else:
gw = gw_input
third_octet = ip_parts[2] if len(ip_parts) >= 3 else "100"
default_table = third_octet
default_prio = third_octet
table = input(f"Numer tablicy routingu [domyślnie {default_table}]: ").strip() or default_table
prio = input(f"Priorytet dla rule [domyślnie {default_prio}]: ").strip() or default_prio
return {
"uuid": conn["uuid"],
"iface": default_iface,
"ip": ip,
"gateway": gw,
"table": table,
"priority": prio
}
def ask_disable_ipv6(devices):
choice = input("\nWyłączyć IPv6? (tak/wszystkie/nie/[lista interfejsów oddzielona spacją]): ").strip().lower()
if choice in ["tak", "yes", "y", "wszystkie"]:
return set(devices)
elif choice in ["nie", "no", "n"]:
return set()
else:
return set(choice.split())
def ask_main_gateway_iface(devices):
print("\nDostępne interfejsy: " + ", ".join(devices))
main_iface = input("Podaj nazwę interfejsu, który ma mieć bramę główną (main), enter jeśli żaden: ").strip()
return main_iface if main_iface in devices else None
def generate_commands(configs, disable_ipv6_ifaces, main_iface):
lines = []
rt_tables = set()
for c in configs:
uuid = c["uuid"]
iface = c["iface"]
ip = c["ip"]
gateway = c["gateway"]
table = c["table"]
priority = c["priority"]
lines.append(f"# Konfiguracja: {iface} ({uuid}) → {ip} gw {gateway or '-'} table {table}")
# Ustawienia podstawowe
lines.append(f"nmcli con modify {uuid} connection.interface-name {iface}")
lines.append(f"nmcli con modify {uuid} ipv4.addresses {ip} ipv4.method manual")
lines.append(f"nmcli con modify {uuid} ipv4.never-default yes")
# IPv6 wyłączony jeśli wskazano
if iface in disable_ipv6_ifaces:
lines.append(f"nmcli con modify {uuid} ipv6.method ignore")
# Parsowanie adresu IP bez maski
ip_only = ip.split("/")[0]
# Obsługa tras i reguł tylko jeśli podano bramę
if gateway:
if iface == main_iface:
# tylko tu ustawiamy bramę domyślną
lines.append(f"nmcli con modify {uuid} ipv4.gateway {gateway}")
else:
# trasa i reguła do osobnej tablicy
lines.append(f"nmcli con modify {uuid} +ipv4.routes \"0.0.0.0/0 {gateway} table={table}\"")
lines.append(f"nmcli con modify {uuid} ipv4.routing-rules \"priority {priority} from {ip_only}/32 table {table}\"")
rt_tables.add(f"{table} rt{table}")
lines.append("") # pusta linia dla czytelności
# Restart połączeń
lines.append("# Restart połączeń")
for c in configs:
lines.append(f"nmcli con down {c['uuid']} || true")
lines.append(f"nmcli con up {c['uuid']}")
# Dodaj wpisy do rt_tables tylko dla użytych tablic
rt_path = detect_rt_tables_path()
lines.append(f"\n# Wpisy do {rt_path}")
if "rt_tables.d" in rt_path:
lines.append("mkdir -p /etc/iproute2/rt_tables.d")
for rt in sorted(rt_tables):
lines.append(f"echo \"{rt}\" | sudo tee -a {rt_path} > /dev/null")
return "\n".join(lines)
def main():
connections = list_connections()
print("\n[DEBUG] Wykryto połączenia:")
for c in connections:
print(f"- {c['name']} ({c['uuid']}) → {c['device']}")
if len(connections) == 0:
print("Brak połączeń ethernet.")
return
devices = [c["device"] for c in connections]
disable_ipv6_ifaces = ask_disable_ipv6(devices)
main_iface = ask_main_gateway_iface(devices)
configs = [prompt_config(c) for c in connections]
result = generate_commands(configs, disable_ipv6_ifaces, main_iface)
print("\n=== Wygenerowane polecenia ===\n")
print(result)
with open("nmcli_setup.sh", "w") as f:
f.write(result)
print("\nZapisano do pliku: nmcli_setup.sh")
if __name__ == "__main__":
main()