From 9c3f24776ca144d2ee8d81786d125d0c5f3853b4 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 7 Mar 2026 17:08:31 +0000 Subject: [PATCH] =?UTF-8?q?Nom=20libre=20pour=20l'agent=20d=C3=A9ploy?= =?UTF-8?q?=C3=A9=20:=20=C3=A9tape=20enter=5Fname=20+=20JID=20sugg=C3=A9r?= =?UTF-8?q?=C3=A9=20automatiquement?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - state machine : nouvelle étape enter_name après choose_agent - XMPP JID suggéré par défaut : {nom}@xmpp.ovh (modifiable) - MQTT inbox/service/install_path basés sur le nom libre - notify_agent1 publie sur agents/register avec le bon format JSON Co-Authored-By: Claude Sonnet 4.6 --- agent2_deploy.py | 66 +++++++++++++++++++++++++++++++++--------------- deployer.py | 20 +++++++++------ 2 files changed, 57 insertions(+), 29 deletions(-) diff --git a/agent2_deploy.py b/agent2_deploy.py index 77f5144..9189859 100644 --- a/agent2_deploy.py +++ b/agent2_deploy.py @@ -60,16 +60,18 @@ def register_to_agent1(): mqtt_publish("agents/register", payload) print("[REGISTER] Déclaration envoyée à agent1.") -def notify_agent1(agent_type: str, host: str, xmpp_jid: str, mqtt_inbox: str): - """Informe agent1 du nouveau déploiement.""" - msg = ( - "[DEPLOY] Nouvel agent déployé.\n" - " Type : {}\n" - " Hôte : {}\n" - " XMPP JID : {}\n" - " MQTT : {}" - ).format(agent_type, host, xmpp_jid, mqtt_inbox) - mqtt_publish(AGENT1_INBOX, msg) +def notify_agent1(agent_name: str, agent_type: str, host: str, xmpp_jid: str, speciality: str): + """Publie sur agents/register pour que agent1 enregistre le nouvel agent.""" + import json as _json + payload = _json.dumps({ + "agent" : agent_name, + "jid" : xmpp_jid, + "mqtt_inbox": "agents/{}/inbox".format(agent_name), + "speciality": speciality, + "host" : host, + "type" : agent_type, + }) + mqtt_publish("agents/register", payload) # ── MACHINE À ÉTATS ─────────────────────────────────────────────────────── # sessions[jid] = dict avec toutes les infos collectées + état courant @@ -102,6 +104,7 @@ def start_session(jid: str) -> str: sessions[jid] = { "state" : "choose_agent", "agent_type" : None, + "agent_name" : None, # nom libre choisi par l'utilisateur (ex: trouducul) "target_ip" : None, "ssh_user" : None, "auth_type" : None, # "password" ou "key" @@ -146,8 +149,24 @@ def handle_session(jid: str, text: str) -> str | None: session["agent_type"] = text else: return "Agent inconnu. Tapez le numéro ou le nom exact.\n\n" + list_agents() + session["state"] = "enter_name" + return ( + "Agent choisi : {}.\n\n" + "Quel nom donner à cet agent ?\n" + "Ce nom sera utilisé dans vos commandes (ex: \"mets à jour trouducul\"),\n" + "comme nom du service systemd et comme identifiant MQTT.\n" + "Lettres, chiffres, tirets et underscores uniquement." + ).format(session["agent_type"]) + + # ── enter_name ──────────────────────────────────────────────────────── + elif state == "enter_name": + import re + name = text.strip().lower() + if not name or not re.match(r'^[a-z0-9_-]+$', name): + return "Nom invalide. Utilisez uniquement des lettres, chiffres, tirets ou underscores." + session["agent_name"] = name session["state"] = "enter_ip" - return "Agent choisi : {}.\n\nAdresse IP de la machine cible ?".format(session["agent_type"]) + return "Nom choisi : {}.\n\nAdresse IP de la machine cible ?".format(name) # ── enter_ip ────────────────────────────────────────────────────────── elif state == "enter_ip": @@ -186,17 +205,18 @@ def handle_session(jid: str, text: str) -> str | None: else: session["ssh_key_path"] = text session["state"] = "enter_xmpp_jid" - agent_type = session["agent_type"] + default_jid = "{}@xmpp.ovh".format(session["agent_name"]) return ( - "JID XMPP pour cet agent sur la machine distante ?\n" - "(ex: {}@xmpp.ovh)".format(agent_type) + "Adresse XMPP (JID) pour cet agent ?\n" + "(entrée vide = {})".format(default_jid) ) # ── enter_xmpp_jid ─────────────────────────────────────────────────── elif state == "enter_xmpp_jid": - session["xmpp_jid"] = text + default_jid = "{}@xmpp.ovh".format(session["agent_name"]) + session["xmpp_jid"] = text if text else default_jid session["state"] = "enter_xmpp_pass" - return "Mot de passe XMPP pour {} :".format(text) + return "Mot de passe XMPP pour {} :".format(session["xmpp_jid"]) # ── enter_xmpp_pass ────────────────────────────────────────────────── elif state == "enter_xmpp_pass": @@ -216,23 +236,25 @@ def handle_session(jid: str, text: str) -> str | None: agent_info = catalog[s["agent_type"]] return ( "Récapitulatif du déploiement :\n" - " Agent : {agent_type}\n" + " Type : {agent_type}\n" + " Nom : {agent_name}\n" " Repo : {repo}\n" " Machine : {ssh_user}@{target_ip}\n" " Auth SSH : {auth}\n" " XMPP JID : {xmpp_jid}\n" " MQTT broker: {mqtt_host}\n" - " MQTT inbox : {mqtt_inbox}\n\n" + " MQTT inbox : agents/{agent_name}/inbox\n" + " Service : {agent_name}.service\n\n" "Confirmer le déploiement ? (oui / non)" ).format( agent_type=s["agent_type"], + agent_name=s["agent_name"], repo=agent_info["repo_url"], ssh_user=s["ssh_user"], target_ip=s["target_ip"], auth="clé SSH" if s["auth_type"] == "key" else "mot de passe", xmpp_jid=s["xmpp_jid"], mqtt_host=s["mqtt_host"], - mqtt_inbox=agent_info["mqtt_inbox"], ) # ── confirm ─────────────────────────────────────────────────────────── @@ -316,6 +338,7 @@ class DeployBot(ClientXMPP): host = session["target_ip"], ssh_user = session["ssh_user"], agent_type = session["agent_type"], + agent_name = session["agent_name"], xmpp_jid = session["xmpp_jid"], xmpp_pass = session["xmpp_pass"], mqtt_host = session["mqtt_host"], @@ -325,12 +348,13 @@ class DeployBot(ClientXMPP): ) if success: - mqtt_inbox = catalog[session["agent_type"]]["mqtt_inbox"] + speciality = catalog[session["agent_type"]]["description"] notify_agent1( + agent_name = session["agent_name"], agent_type = session["agent_type"], host = session["target_ip"], xmpp_jid = session["xmpp_jid"], - mqtt_inbox = mqtt_inbox, + speciality = speciality, ) self.reply(jid, result) else: diff --git a/deployer.py b/deployer.py index 4aca5da..3367164 100644 --- a/deployer.py +++ b/deployer.py @@ -48,6 +48,7 @@ def deploy_agent( host: str, ssh_user: str, agent_type: str, + agent_name: str, xmpp_jid: str, xmpp_pass: str, mqtt_host: str, @@ -57,6 +58,7 @@ def deploy_agent( ) -> tuple[bool, str]: """ Déploie un agent sur la machine distante. + agent_name : nom libre choisi par l'utilisateur (ex: trouducul) progress_cb(msg) : callback appelé à chaque étape pour informer l'utilisateur. Retourne (succès, message_final). """ @@ -65,13 +67,15 @@ def deploy_agent( return False, "Agent inconnu : {}".format(agent_type) agent = catalog[agent_type] - install_path = agent["install_path"] repo_url = agent["repo_url"] - service_name = agent["service_name"] main_script = agent["main_script"] deps = " ".join(agent["dependencies"]) - mqtt_inbox = agent["mqtt_inbox"] - mqtt_outbox = agent["mqtt_outbox"] + + # Le nom libre détermine install_path, service, MQTT + install_path = "/opt/{}".format(agent_name) + service_name = agent_name + mqtt_inbox = "agents/{}/inbox".format(agent_name) + mqtt_outbox = "agents/agent1/inbox" try: # ── Connexion SSH ────────────────────────────────────────────────── @@ -119,7 +123,7 @@ def deploy_agent( "db_path" : "{}/memory.db".format(install_path), "mqtt_host" : mqtt_host, "mqtt_port" : 1883, - "mqtt_client_id": agent_type, + "mqtt_client_id": agent_name, "mqtt_inbox" : mqtt_inbox, "mqtt_outbox" : mqtt_outbox, } @@ -146,7 +150,7 @@ StandardError=journal [Install] WantedBy=multi-user.target -""".format(name=agent_type, path=install_path, script=main_script) +""".format(name=agent_name, path=install_path, script=main_script) write_remote_file(client, "/etc/systemd/system/{}.service".format(service_name), @@ -163,11 +167,11 @@ WantedBy=multi-user.target client.close() summary = ( - "Déploiement de {} terminé sur {} !\n" + "Déploiement de «{}» ({}) terminé sur {} !\n" " JID XMPP : {}\n" " MQTT inbox : {}\n" " Service : systemctl status {}" - ).format(agent_type, host, xmpp_jid, mqtt_inbox, service_name) + ).format(agent_name, agent_type, host, xmpp_jid, mqtt_inbox, service_name) return True, summary