Add nmcli_configurator.py
This commit is contained in:
153
nmcli_configurator.py
Normal file
153
nmcli_configurator.py
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
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()
|
Reference in New Issue
Block a user