Outils pour utilisateurs

Outils du site


scripts

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
scripts [2025/12/04 14:22] – [SCRIPTS] huracanscripts [2025/12/04 14:31] (Version actuelle) – [PYTHON] huracan
Ligne 17: Ligne 17:
  
 Script pour commandes multithread sur plusieurs switchs Script pour commandes multithread sur plusieurs switchs
 +
 + #!/usr/bin/env python3
 + from concurrent.futures import ThreadPoolExecutor, as_completed
 + from datetime import datetime
 + from getpass import getpass
 + import threading
 + from pathlib import Path
 + import os
 + import socket
 + from netmiko import ConnectHandler
 +  
 + SWITCH_FILE = "switches.txt"
 + MAX_WORKERS = 20
 +  
 + print_lock = threading.Lock()
 +  
 +  
 + def safe_print(*a, **kw):
 + with print_lock:
 + print(*a, **kw, flush=True)
 +  
 +  
 + def load_hosts(path):
 + p = Path(path)
 + if not p.exists():
 + return []
 + return [x.strip() for x in p.read_text().splitlines() if x.strip()]
 +  
 +  
 + # --------- AJOUT : TEST SSH AVANT CONNEXION -----------
 + def test_ssh_port(host, port=22, timeout=2):
 + try:
 + with socket.create_connection((host, port), timeout=timeout):
 + return True
 + except:
 + return False
 + # -------------------------------------------------------
 +  
 +  
 + def run_on_switch(host, username, password, commands):
 + result = {
 + "host": host,
 + "success": False,
 + "error": None,
 + "lines": [],
 + "start": datetime.now(),
 + "end": None,
 + }
 +  
 + # --- Test SSH avant toute connexion ---
 + if not test_ssh_port(host):
 + result["error"] = "SSH inaccessible (port 22 fermé / host down)"
 + result["end"] = datetime.now()
 + return result
 +  
 + try:
 + device = {
 + "device_type": "cisco_ios",
 + "host": host,
 + "username": username,
 + "password": password,
 + }
 +  
 + conn = ConnectHandler(**device)
 +  
 + except Exception as e:
 + result["error"] = f"SSH ERROR : {e}"
 + result["end"] = datetime.now()
 + return result
 +  
 + try:
 + conn.send_command("terminal length 0")
 +  
 + for cmd in commands:
 + out = conn.send_command(cmd, read_timeout=20)
 + for line in out.splitlines():
 + safe_print(f"[{host}] {line}")
 + result["lines"].append(line)
 +  
 + result["success"] = True
 +  
 + except Exception as e:
 + result["error"] = f"COMMAND ERROR : {e}"
 +  
 + finally:
 + conn.disconnect()
 + result["end"] = datetime.now()
 +  
 + return result
 +  
 +  
 + def choose_switches(hosts):
 + while True:
 + safe_print("\n====== SÉLECTION DES SWITCHES ======")
 + for i, h in enumerate(hosts, 1):
 + safe_print(f"{i}) {h}")
 +  
 + safe_print("\nOptions :")
 + safe_print("  X    -> numéro d’un switch")
 + safe_print("  1,3  -> plusieurs switchs")
 + safe_print("  all  -> tous les switches")
 + safe_print("  back -> revenir")
 + safe_print("====================================")
 +  
 + choice = input("Votre sélection : ").strip().lower()
 +  
 + if choice == "back":
 + return None
 +  
 + if choice == "all":
 + return hosts
 +  
 + try:
 + indices = [int(x.strip()) for x in choice.split(",")]
 + selected = [hosts[i - 1] for i in indices if 1 <= i <= len(hosts)]
 + if selected:
 + return selected
 + except:
 + pass
 +  
 + safe_print("Sélection invalide.")
 +  
 +  
 + def main():
 + hosts = load_hosts(SWITCH_FILE)
 + if not hosts:
 + safe_print(f"Erreur : fichier {SWITCH_FILE} introuvable ou vide.")
 + return
 +  
 + safe_print(f"{len(hosts)} switches chargés.")
 +  
 + username = input("Identifiant SSH : ").strip()
 + password = getpass("Mot de passe SSH : ")
 +  
 + current_selection = hosts  # par défaut : tous
 +  
 + while True:
 + safe_print("\n====== MENU PRINCIPAL ======")
 + safe_print("Switches sélectionnés :")
 + for h in current_selection:
 + safe_print(f"  - {h}")
 +  
 + safe_print("\nOptions :")
 + safe_print("  cmd   -> taper des commandes")
 + safe_print("  sel   -> changer la sélection")
 + safe_print("  clear -> effacer l'écran")
 + safe_print("  exit  -> quitter")
 + safe_print("============================")
 +  
 + choice = input("> ").strip().lower()
 +  
 + if choice == "exit":
 + return
 +  
 + if choice == "clear":
 + os.system("cls" if os.name == "nt" else "clear")
 + continue
 +  
 + if choice == "sel":
 + new_sel = choose_switches(hosts)
 + if new_sel:
 + current_selection = new_sel
 + continue
 +  
 + if choice == "cmd":
 + safe_print("Entrez vos commandes (ligne vide pour lancer l'exécution).")
 + commands = []
 +  
 + while True:
 + cmd = input("> ").strip()
 + if cmd == "":
 + if commands:
 + break
 + else:
 + continue
 + commands.append(cmd)
 +  
 + safe_print("\n====== EXÉCUTION ======\n")
 +  
 + start_all = datetime.now()
 +  
 + results = []
 + with ThreadPoolExecutor(max_workers=min(MAX_WORKERS, len(current_selection))) as pool:
 + future_map = {
 + pool.submit(run_on_switch, h, username, password, commands): h
 + for h in current_selection
 + }
 +  
 + for f in as_completed(future_map):
 + results.append(f.result())
 +  
 + # --- Résumé synthétique ---
 + safe_print("\n======= RÉSUMÉ =======")
 + for r in results:
 + host = r["host"]
 + status = "OK" if r["success"] else "ERREUR"
 + lines = len(r["lines"])
 + dur = (r["end"] - r["start"]).total_seconds()
 + safe_print(f"- {host}: {status} | lignes: {lines} | durée: {dur:.1f}s")
 + if r["error"]:
 + safe_print(f"    -> {r['error']}")
 +  
 + total = (datetime.now() - start_all).total_seconds()
 + safe_print(f"Durée totale : {total:.1f}s")
 + safe_print("=======================\n")
 +  
 +  
 + if __name__ == "__main__":
 + main()
  
  
scripts.1764854539.txt.gz · Dernière modification : 2025/12/04 14:22 de huracan

DokuWiki Appliance - Powered by TurnKey Linux