Commit Graph

167 Commits

Author SHA1 Message Date
c63b3a9119 feat(snapshots): page de gestion snapshots VM (listing + filtre auteur/age + suppression)
Service snapshot_mgmt_service.py:
- list_snapshots(db, vcenter_filter_id=None): itere les vCenters actifs, walk recursif
  des snapshot tree de chaque VM, retourne (vcenter, vm, snap_name, snap_id, vm_moid,
  created_at, age_days, author, description, is_current)
- delete_snapshot(db, vcenter_id, vm_moid, snap_id, remove_children=False): supprime
  un snapshot par moRef, attend la fin de la task vCenter
- Auteur deduit du prefixe du nom (format PatchCenter '<auteur>_YYYY-MM-DD_<suffixe>')

Router /snapshots:
- GET /snapshots: page principale (filtres + table)
- POST /snapshots/list: AJAX scan vCenters, retourne JSON
- POST /snapshots/delete: AJAX suppression batch, double confirmation cote UI

Template snapshots.html:
- Filtres: vCenter, auteur, 'Mes snapshots uniquement' (preselectionne user courant),
  age min en jours (defaut 3)
- Table avec checkboxes, sel-all, badge age (vert <3j, orange 3-7j, rouge >7j)
- Bouton 'Charger/Refresh' (lazy load, eviter scan auto au pageload)
- Bouton 'Supprimer la selection' avec 2 confirmations + liste des snapshots
- Recharge auto apres suppression

Nav: lien '📸 Snapshots VM' ajoute dans le menu Patching.
2026-05-07 20:13:29 +02:00
517b02f602 feat(prepatch): iteration multi-candidats SSH selon priorite SANEF
Probleme: vrexpbtex1 est sur .sanef.groupe (exception a la convention vr*=.sanef-rec.fr).
Le code tentait UN seul target via _resolve (TCP port 22 only) et echouait sans fallback SSH.

Logique de resolution revisee:
1. Convention en 1er: suffixe le plus probable selon prefixe (vr/lr/sr=>.sanef-rec.fr,
   vp/lp/sp=>.sanef.groupe, etc.)
2. servers.fqdn (BDD) en 2e position si renseigne et plausible (commence par hostname.)
3. Autres suffixes du referentiel ensuite

Implementation:
- _candidate_targets(hostname) : nouvelle fonction qui retourne la liste ordonnee
  des FQDN candidats a essayer SSH
- _connect(target, hostname, errors=...) : accepte une list errors optionnelle ou
  les exceptions de chaque tentative (PSMP/cle/password) sont append en clair pour
  diagnostic. Retro-compatible (errors=None par defaut)
- _connect_via_psmp(target, errors=...) : meme pattern
- _fqdn_is_consistent : assoupli, ne verifie plus la convention SANEF (qui rejetait
  les exceptions legitimes), juste que le FQDN commence par hostname.
- run_all_checks: itere _candidate_targets et essaie _connect sur chaque, accumule
  les erreurs de tous les candidats, retourne le 1er qui aboutit

UI:
- check_dns: si target trouve mais client KO, status=warn et liste des candidats tentes
- check_ssh: classification erreur (no route/timeout/refused/permission denied/etc.)
  + liste des candidats tentes + suggestion pour FQDN exception
2026-05-07 19:31:14 +02:00
1747447f82 feat(prepatch_check): message SSH actionnable (capture exception, classifie type erreur)
- run_all_checks: capture l'exception levee par _connect dans ctx['ssh_error']
- check_ssh: utilise l'erreur reelle pour produire un message classifie:
  * 'No route to host' -> reseau injoignable
  * 'Connection timed out' -> port 22 filtre/host down
  * 'Connection refused' -> sshd arrete/bloque
  * 'no matching kex/key exchange' -> algos incompatibles
  * 'host key' -> known_hosts probleme
  * 'permission denied' / 'authentication failed' -> auth refusee
  * 'no authentication methods' -> aucune methode acceptee
  * 'name or service not known' -> DNS KO cote SSH
- details inclut le message d'exception complet pour debug
2026-05-07 11:54:08 +02:00
29f6153370 feat(pct): workflow prevenance PCT (auto-detection + gate confirmation + suffixe Teams)
- Migration migrate_pct_workflow_20260507.sql: ajoute patch_planning_import_rows
  pct_required (boolean default false), pct_confirmed_at (timestamptz),
  pct_confirmed_by_user_id (FK users). Backfill depuis servers.pct_required.
- Auto-detection a l'import (planning_import.py): scan referent_technique +
  mode_operatoire + impacts + commentaire pour pattern \bPCT\b mot entier
  (insensible casse) -> pct_required=true sur la row. Propage egalement vers
  servers.pct_required si pas deja true.
- UI iexec: badge orange '⚠ Prév PCT à faire' sur la cellule asset_name si
  pct_required=true et pas confirme, badge vert ' PCT ok' une fois confirme.
- Gate avant Step 3 (PATCH REEL): scan des serveurs cibles, si certains ont
  pct_required && !pct_confirmed -> 2 confirmations successives + appel
  POST /patching/iexec/confirm-pct qui marque pct_confirmed_at + user_id.
  Ne lance pas le patch si l'operateur annule.
- Endpoint POST /patching/iexec/confirm-pct: marque les rows comme PCT confirmes
  (pct_confirmed_at = now(), pct_confirmed_by_user_id = current user).
- Notif Teams: send_notification accepte planning_row_id optionnel ; si la row
  a pct_required && pct_confirmed, le message debut/fin est suffixe par
  ' (Prévenance PCT ok)' pour informer le responsable que l'amont a ete gere.
2026-05-07 08:19:19 +02:00
060af01db9 feat(teams): fan-out multi-recipient + flag is_database_server + multi-referents
- Migration v2: ajoute teams_channel_rules.match_is_database_server (NULL=any/TRUE=DB only/FALSE=non-DB only),
  servers.is_database_server boolean (default false), table server_additional_referents pour multi-referents
- Service teams_service.py: resolve_channel_for_server -> resolve_channels_for_server (pluriel, retourne LIST)
  * msg_type=reboot: 1 seul canal (canal flagge is_reboot_channel)
  * server.teams_channel_id override: 1 seul canal
  * sinon FAN-OUT: TOUTES les regles actives qui matchent contribuent un canal
  * dynamic_to_email calcule selon nature de la regle (responsable / DBA pool / referents)
- send_notification: boucle sur les canaux resultants, ecrit 1 fichier SP par destination
- UI settings.html: nouveau filtre 'Match serveur DB' dans formulaire regle, badge dans tableau
- Compat: resolve_channel_for_server (singulier) conserve comme wrapper qui retourne le 1er canal

Permet le scenario: serveur DB avec responsable=Delcour -> notif a la fois dans conv Delcour
ET dans conv DBA (Nadine+Cedric), via 2 regles qui matchent en parallele.
2026-05-06 10:33:12 +02:00
edec1f7db5 feat(teams): mode SharePoint sync (calque .exe Sanef Patch Manager) + rules-based routing
- Migration: ajoute sp_route/mode/is_reboot_channel/is_dynamic_dm sur teams_channels,
  cree table teams_channel_rules (match resp/domain/env/msg_type/hostname pattern)
- Service teams_service.py: format texte plat compatible workflows existants,
  write_sharepoint_notification (ecrit fichier .txt dans <sp_base>/<sp_route>/),
  resolve_channel_for_server rules-based avec priorite reboot,
  send_notification orchestre resolution + envoi
- Settings UI: CRUD canaux etendu (mode SP/webhook + flags reboot/dyn_dm),
  CRUD regles avec match conditions, sharepoint_notif_path en secret app,
  bouton Test ecrit fichier .txt en mode SP
- Mode is_dynamic_dm: prefixe le contenu par 'TO: <email>' pour permettre
  un workflow PA unique qui dispatch dynamiquement aux responsables
- Pas d'OAuth requis: PatchCenter ecrit fichiers, Workflows PA cote SharePoint
  (deja en place pour le .exe) declenchent et postent sur Teams

Mode webhook conserve mais inactif tant qu'OAuth Entra ID pas mis en place chez SANEF
2026-05-06 09:57:42 +02:00
6839b3e59d feat(teams): helper resolve_channel_for_server (server > application > default) 2026-05-05 19:13:15 +02:00
1bad243f5e fix(qualys): strip() defensif sur credentials + extraction enrichie de l erreur Qualys (responseCode + errorMessage + errorResolution + RAW fallback si format inconnu) 2026-05-05 18:28:13 +02:00
c77b4b22eb fix(qualys): API 2.0 confirmee (3.0 OTHER_ERROR car endpoint inexistant, 5.0 INVALID_API_VERSION) + body XML + mapping field user-friendly vers nom Qualys (hostname->name, fqdn->dnsHostName, ip->address) - cause racine 401 = mot de passe API expire 2026-05-05 16:56:56 +02:00
cadef89c50 fix(qualys): repasse en API 3.0 (5.0 ne supporte pas l objet hostasset, INVALID_API_VERSION). 12+3+1 endpoints qps/rest revenus en 3.0 2026-05-05 16:48:59 +02:00
5c402e5b63 fix(qualys): extrait responseCode/errorMessage/errorResolution du XML Qualys dans le message d erreur (au lieu de tronquer 200 chars du XML brut) 2026-05-05 16:46:16 +02:00
e7eecf0346 fix(qualys): search_assets_api utilise XML body au lieu de JSON (API 5.0 attend XML, JSON donnait 400). Message d erreur enrichi avec le debut de la reponse 2026-05-05 16:43:22 +02:00
37faba382e fix(qualys): migration API 2.0 EOL -> 5.0 (auth refusee en 2.0 INVALID_CREDENTIALS, OK en 5.0). 12+3+1 endpoints qps/rest mis a jour 2026-05-05 16:40:34 +02:00
785916246f fix(servers): filtre Zone=LAN match aussi zone_id IS NULL (la colonne affiche 'LAN' par defaut quand zone vide) + comparaison case-insensitive sur z.name 2026-05-05 16:05:25 +02:00
4b2a4cb8f2 fix(servers/edit): timeout iTop reduit (3s connect / 10s read au lieu de 30s) + indicateur de chargement htmx visible (bouton change en 'Sauvegarde...' + message en bas du form) 2026-05-05 15:47:12 +02:00
e8f369817e fix(servers): bulk + edit synchronisent aussi les colonnes text legacy s.environnement et s.domaine (sinon liste affiche valeur obsolete) + script SQL re-sync des serveurs deja desyncs 2026-05-05 15:29:34 +02:00
1b82440813 fix(servers): bulk + edit comparaisons domain/env/zone case-insensitive (BD mixte RECETTE/Recette/recette) + fallback bulk env_code si serveur sans domain_env_id + log INFO/WARNING + retour msg=bulk_<n_updated_reel> 2026-05-05 15:19:03 +02:00
5d3c07885d feat(servers): drop colonnes legacy (snapshot_required/pre_patch_script/post_patch_script/satellite_host/need_pct) avec migration donnees + recreation views v_servers / v_patchable / v_conformity_todo + adaptation prereq_service et server_detail.html 2026-05-05 15:11:30 +02:00
0ed564a8ed feat(check satellite): cascade LAN+DMZ avec fallback automatique + migration servers.satellite_url + override BDD prioritaire 2026-05-05 14:34:47 +02:00
7e9cae6758 fix(audit): _resolve verifie la coherence FQDN BDD vs convention prefixe SANEF (vr*=.sanef-rec.fr, vp*=.sanef.groupe) - fallback sur suffixes ordonnes si FQDN incoherent + extension v[tdv] pour recette 2026-05-05 14:09:49 +02:00
075706178e feat(settings/teams M1+M4): UI CRUD canaux Teams + service teams_service.py (Adaptive Card via Incoming Webhook) + bouton Test webhook 2026-05-05 13:58:38 +02:00
ff95424e03 feat(patching/iexec B3.6): bouton 3e Reboot manuel (double confirmation, jamais auto) + 3f Wait reconnexion (poll TCP/22 + SSH uptime, timeout 10min) - shutdown -r +1 avec audit log 2026-05-05 12:06:50 +02:00
19d88f2d53 feat(patching/iexec): detection auto deps problematiques + bouton retry sans paquets KO (multilib, requires, conflicts) - extra_excludes via SSE query param 2026-05-05 11:32:44 +02:00
8cf78dfef3 feat(patching/iexec): terminal live SSE pour dry-run et patch reel - generator yum_stream_lines + endpoint /yum-stream + EventSource cote client + log audit en fin de stream 2026-05-04 17:02:28 +02:00
e29ecff949 feat(patching/iexec B3.4+B3.5): pre-capture services+ports + post-compare avant/apres avec rapport diff (scripts wiki SANEF, push base64) - workflow 3a/3b/3c/3d sequentiel 2026-05-04 16:52:15 +02:00
6c92c71d17 feat(patching/iexec B3): step 3a dry-run (yum update --assumeno) + step 3b real patch (yum update -y) avec excludes effectifs depuis v_servers, validation anti-injection sur excludes, log audit, double confirmation pour patch reel 2026-05-04 16:40:46 +02:00
37e6f0d8f3 chore(snapshot): strip() defensif sur credentials vCenter (copier-coller peut ajouter newline/CR) 2026-05-04 16:29:20 +02:00
a006e3f422 fix(snapshot): message d erreur distingue login KO de VM non trouvee (etait trompeur) 2026-05-04 16:25:10 +02:00
f1baae9c8e fix(snapshot): _find_vm matching tolerant (court + FQDN) + log samples pour debug si VM non trouvee 2026-05-04 16:21:45 +02:00
9996757e4b feat(snapshot): branche prod/hprod via prefixe hostname (vp/sp/lp = prod/metier ; reste = hprod/gestion) + fix matching DR vpsiaavcs1 (etait vpsicavcs1) + tolerance par name 2026-05-04 16:15:46 +02:00
a1476cb3e2 fix(snapshot): fallback secrets vsphere_user/pass (nom Settings UI) en plus de vcenter_user/pass legacy 2026-05-04 16:07:50 +02:00
b07a6816d4 feat(patching/iexec): check espace disque (/ >= 1.5Go, /var/log >= 1Go) + fix detection subscription-manager identity FR/EN via UUID regex 2026-05-04 15:37:12 +02:00
eb2e0dc8ba feat(patching/iexec B1): page wizard step 1 - checks DNS+SSH+Satellite (LAN vpdsiasat2 / DMZ vpdsiasat1 selon domaine), Linux uniquement (Windows skip), sudo -n partout 2026-05-04 15:14:06 +02:00
983552a442 fix(qualys/agents): message d'echec specifique selon cause reelle (DNS/TCP timeout/TCP refused/SSH auth) - plus de 'agent installe? OS supporte?' generique 2026-04-28 02:00:21 +02:00
eecb61c720 fix(qualys/agents): check service multi-format - SysV init francais (en cours d'execution / (pid X)) en plus de systemd active (running) 2026-04-28 01:45:48 +02:00
f0043eb481 ui(qualys/agents): separation RHEL5 (early exit, decom) vs RHEL6 (agent legacy ok, CA bundle a jour) 2026-04-28 01:33:10 +02:00
4db0cf6a56 ui(qualys/agents): si OS EOL (RHEL 5/6) - affiche seule entree 'agent legacy, decom prevu', pas de warnings redondants 2026-04-28 01:31:25 +02:00
b6a602e848 ui(qualys/agents): wording diag prudent (constat/hypothese/proposition vers ticket support, pas affirmer) 2026-04-28 01:27:42 +02:00
67bd3a02d6 ui(qualys/agents): bloc Etat checklist OK/KO en tete (connectivite/disque/service/install) + log systeme 10 lignes 2026-04-28 01:24:57 +02:00
7f8c2c710b ui(qualys/agents): renomme 'Suggestions' en 'Diagnostic' + reformulation orientee constat (pas de cmds shell, oriente vers ticket support) 2026-04-28 01:23:56 +02:00
5abc474805 perf(qualys/agents): combine toutes les cmds en 1 seul channel SSH avec markers - evite Timeout opening channel sur PSMP 2026-04-28 01:18:59 +02:00
d4205fb8f8 fix(qualys/agents): retry avec reconnect SSH si Timeout opening channel (limite channels PSMP) 2026-04-28 01:14:03 +02:00
fc480b4376 ui(qualys/agents): retire bloc Configuration proxy agent (inutile car SANEF prod sort en direct, pas via proxy) 2026-04-28 01:13:18 +02:00
49c700c5d1 fix(qualys/agents): procedure reinstall reelle SANEF (rpm -ivh /root/QualysCloudAgent.rpm) 2026-04-28 00:58:45 +02:00
79cff850d3 feat(qualys/agents): suggestion auto pour install cassee (core dump + package absent RPM/DPKG) 2026-04-28 00:57:06 +02:00
fb448257a1 ui(qualys/agents): connectivite minimale - HTTP code recu = OK, diag detaille seulement si KO 2026-04-28 00:52:17 +02:00
c54ec0ba0c fix(qualys/agents): test connectivite DIRECT vers qagpublic.qg1.apps.qualys.eu (pod EU1 SANEF) - pas de proxy car agent sort en direct 2026-04-28 00:26:29 +02:00
9d312f43a3 feat(qualys/agents): check conf proxy agent (qagent-proxy.conf, drop-in systemd, sysconfig, /etc/environment) + suggestion config proxy 2026-04-28 00:20:56 +02:00
191c167423 fix(qualys/agents): snapshot vCenter (pas LVM) pour rollback avant extend FS 2026-04-28 00:15:12 +02:00
640292c1ce feat(qualys/agents): checks LVM + logrotate + suggestions extend FS / cleanup / fix logrotate avec snapshot LVM obligatoire 2026-04-28 00:11:45 +02:00