commit 18751d75c88a32790a50c1f0a458a2657db6a2ad Author: Guillaume DENIS Date: Sat Jul 4 17:40:39 2026 +0200 Initial commit: CMDB dashboard Serveur Python (http.server + ldap3) servant cmdb.html, la base SQLite partagee avec versioning optimiste, snapshots horodates et recherche AD. Co-Authored-By: Claude Opus 4.8 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..38cea32 --- /dev/null +++ b/.gitignore @@ -0,0 +1,40 @@ +# Database (runtime data) +cmdb.db +cmdb.db.ver +*.db +*.db-journal +*.db-wal +*.db-shm + +# Snapshots (generated backups) +snapshots/ + +# Python +__pycache__/ +*.py[cod] +*.egg-info/ +.eggs/ +build/ +dist/ + +# Virtual environments +.venv/ +venv/ +env/ + +# uv +.uv/ + +# Env / secrets +.env +.env.* +*.secret + +# IDE +.vscode/ +.idea/ +*.swp + +# OS +.DS_Store +Thumbs.db diff --git a/README.md b/README.md new file mode 100644 index 0000000..63526f3 --- /dev/null +++ b/README.md @@ -0,0 +1,76 @@ +
+ Manage OpenLDAP Logo + +

Noctâme

+

CMDB légère : inventaire de parc et recherche Active Directory

+
+ +--- + +## À propos + +Noctâme est une CMDB minimaliste. Un seul serveur Python sert l'interface +(`cmdb.html`), partage une base SQLite entre plusieurs utilisateurs et +interroge l'annuaire Active Directory. + +## Démarrage + +Prérequis : [mise](https://mise.jdx.dev/) (gère la version de Python) et +[uv](https://docs.astral.sh/uv/) (gère les dépendances). + +```bash +mise install # installe Python (>=3.13) +uv sync # installe les dépendances (ldap3) + +uv run cmdb_server.py # http://0.0.0.0:8000 +uv run cmdb_server.py 8080 # port custom +``` + +## Fonctionnalités + +- Inventaire du parc dans une base SQLite partagée (`cmdb.db`) +- Détection de conflit à l'écriture (concurrence optimiste) +- Snapshots automatiques et manuels de la base +- Recherche Active Directory / LDAP intégrée + +--- + +## Annexe + +
+Génération du logo + +
+ +1. **Prompt pour ChatGPT (DALL-E)** : + +``` +A high-quality, original creature inspired by Pokémon style, unevolved stage (basic form). The creature has balanced proportions (can be cute, neutral, or slightly serious), with a clean and memorable silhouette, expressive eyes (not overly exaggerated), and a distinct personality that can range from friendly to calm, mysterious, or determined. + +The creature has a unique elemental theme (choose one: fire, water, electric, grass, ghost, etc.), with subtle and well-integrated visual cues reflecting its type (glowing sparks, leaves, flames, mist, energy patterns, etc.). + +Art style: official Pokémon-style illustration, soft but controlled shading, vibrant yet natural color palette, smooth gradients, clean and precise outlines, slightly stylized but grounded anatomy. + +Pose: simple, confident, and readable, facing slightly toward the viewer, with a composed or expressive stance depending on its personality. + +Background: transparent. + +Lighting: soft studio lighting with gentle contrast to enhance form and details. + +Composition: centered, full body visible, no cropping. + +Aspect ratio: 1:1 + +High resolution, sharp details, no text, no watermark. + +Theme: Astro, Star, Milkyway + +Format d'image : **1:1** +``` + +2. **Supprimer le fond** : [PhotoRoom Background Remover](https://www.photoroom.com/tools/background-remover) + +3. **Size Logo :** 220x200 + +
+ diff --git a/cmdb.html b/cmdb.html new file mode 100644 index 0000000..d2e8c06 --- /dev/null +++ b/cmdb.html @@ -0,0 +1,4055 @@ + + + + + +CMDB — Admin + + + + + + + +
+ +
+

Dashboard

Vue d'ensemble de l'infrastructure

+
+
+

Répartition

+
+
+
Physique / Virtuel
+
+
+
+
Adressage IP
+
+
+
+
+
+

Machines par statut

+
+
+
+

Systèmes d'exploitation

+
+
+
+

Occupation des baies

+
+
+
+ + +
+
+

Réseaux

Cliquez sur un réseau pour voir ses IPs

+ +
+
+
+ + +
+
+

Machines

Cliquez sur un nom pour ouvrir la fiche détaillée

+ +
+
+ + + + + + + +
+
+ Types : +
+
+
+
+ + +
+
+
+ + +
+
+

Informations manquantes

Champs vides ou incomplets détectés dans l'inventaire

+
+
+ + +
+
+
+ + +
+
+

Préférences

Types de machine, catalogue OS et réglages de base

+
+ +
+

Général

+
+
+
+
+
+ +
+
+

Sauvegardes (snapshots)

+ +
+
+
Copies horodatées de la base sur le serveur (dossier snapshots/). + Un snapshot automatique est créé après une modification, au plus une fois par heure. La restauration remplace la base + actuelle et crée d'abord un snapshot de sécurité de l'état courant.
+
+ +
+
+

Import / Export CSV

+
+ + + +
+
+
Exporte l'inventaire (machines, réseaux, IP/MAC, salles/baies) en un fichier CSV — une ligne par IP. + À l'import, les réseaux, salles, baies et machines existants sont mis à jour par correspondance de nom, + les nouveaux sont créés ; les IP d'une machine importée remplacent les siennes. Utile pour sauvegarder ou + migrer les données hors de la base.
+
+ +
+
+

Types de machine

+ +
+
+
« Virtuel » = hébergé sur une autre machine. « Rackable » = peut occuper des U dans une baie. « User » = permet d'assigner un utilisateur (laptop, optiplex…).
+
+ +
+
+

Statuts de machine

+ +
+
+
+ +
+
+

Lien vers ticket

+ +
+
+
Lien + modèle de description à copier pour créer un ticket (ex : changement de configuration switch). {name} est remplacé par le nom de la machine.
+
+ +
+
+

Catalogue OS

+ +
+
+
+ +
+

Active Directory (recherche d'utilisateurs)

+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Recommandé : lancer python3 cmdb_server.py (remplace python -m http.server) — + il sert la page sur http://127.0.0.1:8000 et interroge l'AD directement, aucun connecteur à configurer. + Prérequis : pip install ldap3. Si la page est ouverte en file://, utilisez le connecteur séparé ci-dessous. + Le mot de passe bind est stocké dans la base locale.
+
+ + + +
+
+
+ + +
+
+
+
+
+
+
+
+
+ +
+

Modèles de serveur

+
+ + + +
+
+
+ +
+

CPU

+
+ + + + +
+
+
Sur un serveur : choisir le CPU + nombre de sockets → total de cores calculé automatiquement.
+
+
+
+ +
+ + +
+ +
+ + + + diff --git a/cmdb_server.py b/cmdb_server.py new file mode 100644 index 0000000..245d145 --- /dev/null +++ b/cmdb_server.py @@ -0,0 +1,549 @@ +#!/usr/bin/env python3 +"""Serveur CMDB : sert cmdb.html, la base partagée et la recherche AD. + +Remplace `python -m http.server` ET le connecteur séparé : + pip install ldap3 + python3 cmdb_server.py # http://0.0.0.0:8000 + python3 cmdb_server.py 8080 # port custom + +Endpoints : + GET /db → base SQLite (bytes) + entête X-DB-Version + GET /db/version → {"version": n} (poll léger) + POST /db → écrit la base ; entête X-Base-Version pour la + concurrence optimiste (409 si obsolète) + POST /ldap/search → recherche annuaire (config envoyée par la page) + +La base est un vrai fichier `cmdb.db` partagé : plusieurs personnes +peuvent l'utiliser en même temps, avec détection de conflit. +""" + +import json +import os +import re +import ssl +import sys +import threading +import time +from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer +from urllib.parse import urlparse, parse_qs + +_arg = sys.argv[1].strip() if len(sys.argv) > 1 else "" +PORT = int(_arg) if _arg else int(os.environ.get("PORT", 8000)) + +HERE = os.path.dirname(os.path.abspath(__file__)) +DB_PATH = os.path.join(HERE, "cmdb.db") +VER_PATH = DB_PATH + ".ver" +DB_LOCK = threading.Lock() + + +def db_version(): + try: + with open(VER_PATH) as f: + return int(f.read().strip() or 0) + except (OSError, ValueError): + return 1 if os.path.exists(DB_PATH) else 0 + + +def db_bytes(): + try: + with open(DB_PATH, "rb") as f: + return f.read() + except OSError: + return b"" + + +def db_write(data): + """Écrit la base atomiquement et incrémente la version. Renvoie la version.""" + with DB_LOCK: + ver = db_version() + 1 + tmp = DB_PATH + ".tmp" + with open(tmp, "wb") as f: + f.write(data) + os.replace(tmp, DB_PATH) + with open(VER_PATH, "w") as f: + f.write(str(ver)) + return ver + + +# --------------------------------------------------------------------------- +# Snapshots : copies horodatées de la base dans snapshots/. +# - « auto » : créées après une écriture, au plus 1/heure, rétention 72. +# - « manuel » : créées à la demande (bouton), rétention 100, label libre. +# Restaurer un snapshot crée d'abord un snapshot de sécurité de l'état courant. +# --------------------------------------------------------------------------- +SNAP_DIR = os.path.join(HERE, "snapshots") +# nom : cmdb---v[-