From daa932a0ed660d1781524ee0b6b50b59d33e9cf3 Mon Sep 17 00:00:00 2001 From: syoul Date: Thu, 25 Dec 2025 15:20:50 +0100 Subject: [PATCH] Initial commit: Script MD to Print avec Docker --- .dockerignore | 49 ++ .gitignore | 38 ++ CHANGELOG.md | 48 ++ Dockerfile | 58 ++ Makefile | 110 ++++ README.md | 360 +++++++++++ config.example.conf | 48 ++ docker-compose.yml | 32 + docker_run.sh | 130 ++++ documents/PLAN_DEPLOIEMENT_ORDRE.md | 885 ++++++++++++++++++++++++++++ documents/PROCHAINES_ETAPES.md | 326 ++++++++++ md_to_print.sh | 670 +++++++++++++++++++++ 12 files changed, 2754 insertions(+) create mode 100644 .dockerignore create mode 100644 .gitignore create mode 100644 CHANGELOG.md create mode 100644 Dockerfile create mode 100644 Makefile create mode 100644 README.md create mode 100644 config.example.conf create mode 100644 docker-compose.yml create mode 100755 docker_run.sh create mode 100644 documents/PLAN_DEPLOIEMENT_ORDRE.md create mode 100644 documents/PROCHAINES_ETAPES.md create mode 100755 md_to_print.sh diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..034e9d4 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,49 @@ +# Répertoires de sortie +output/ +logs/ + +# Fichiers Git +.git/ +.gitignore +.gitattributes + +# Documentation (optionnel, décommenter si vous voulez réduire la taille) +# README.md +# CHANGELOG.md + +# Fichiers de configuration personnalisés +config.conf + +# Fichiers temporaires +*.tmp +*.swp +*.swo +*~ + +# Fichiers PDF générés +*.pdf + +# Fichiers de log +*.log + +# Fichiers de sauvegarde +*.bak +*.backup + +# Fichiers système +.DS_Store +Thumbs.db + +# Fichiers IDE +.vscode/ +.idea/ +*.code-workspace + +# Fichiers Docker +docker-compose.yml +docker_run.sh +.docker/ + +# Fichiers de test +documents/test.md + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e3cbd80 --- /dev/null +++ b/.gitignore @@ -0,0 +1,38 @@ +# Fichiers de configuration personnalisés +config.conf + +# Répertoires de sortie +output/ +logs/ + +# Fichiers temporaires +*.tmp +*.swp +*.swo +*~ + +# Fichiers PDF générés (optionnel, décommenter si nécessaire) +# *.pdf + +# Fichiers de log +*.log + +# Fichiers de sauvegarde +*.bak +*.backup + +# Fichiers système +.DS_Store +Thumbs.db + +# Fichiers IDE +.vscode/ +.idea/ +*.code-workspace + +# Fichiers Docker +.docker/ + +# Fichiers de test +documents/test.md + diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..57dd3c1 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,48 @@ +# Changelog + +Tous les changements notables de ce projet seront documentés dans ce fichier. + +Le format est basé sur [Keep a Changelog](https://keepachangelog.com/fr/1.0.0/), +et ce projet adhère à [Semantic Versioning](https://semver.org/lang/fr/). + +## [1.0.0] - 2024-01-XX + +### Ajouté +- Script principal `md_to_print.sh` avec toutes les fonctionnalités de base +- Conversion automatique Markdown → PDF avec Pandoc +- Prévisualisation PDF avant impression (evince/okular/xdg-open) +- Options d'impression avancées: + - Sélection d'imprimante + - Nombre de copies + - Sélection de pages + - Orientation (portrait/paysage) + - Taille de papier + - Qualité d'impression + - Impression couleur/monochrome + - Mode recto-verso +- Fichier de configuration optionnel (format INI) +- Installation automatique des dépendances +- Support Docker complet: + - Dockerfile optimisé + - docker-compose.yml + - Script wrapper docker_run.sh +- Système de logging détaillé avec niveaux (DEBUG, INFO, WARN, ERROR) +- Gestion d'erreurs complète avec codes de retour appropriés +- Makefile avec commandes utiles (build, test, clean, install, uninstall) +- Documentation complète (README.md) +- Fichiers de support (.gitignore, .dockerignore) + +### Sécurité +- Utilisateur non-root dans Docker +- Validation des chemins de fichiers +- Protection contre l'injection de commandes +- Validation des entrées utilisateur + +### Documentation +- README.md complet avec exemples +- CHANGELOG.md pour le suivi des versions +- Commentaires dans le code +- Messages d'aide détaillés + +[1.0.0]: https://github.com/yourusername/MD_to_print/releases/tag/v1.0.0 + diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a3becf2 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,58 @@ +FROM debian:bookworm-slim + +# Métadonnées +LABEL maintainer="MD_to_Print" +LABEL description="Script automatique Markdown vers PDF et impression" +LABEL version="1.0.0" + +# Variables d'environnement +ENV DEBIAN_FRONTEND=noninteractive \ + TZ=Europe/Paris \ + LANG=fr_FR.UTF-8 \ + LC_ALL=fr_FR.UTF-8 + +# Installation des dépendances système et locales +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + locales \ + && sed -i '/fr_FR.UTF-8/s/^# //g' /etc/locale.gen && \ + locale-gen fr_FR.UTF-8 && \ + apt-get install -y --no-install-recommends \ + pandoc \ + texlive-latex-base \ + texlive-xetex \ + texlive-fonts-recommended \ + texlive-latex-extra \ + texlive-lang-french \ + fonts-dejavu \ + cups \ + cups-client \ + evince \ + curl \ + ca-certificates \ + make \ + && rm -rf /var/lib/apt/lists/* \ + && apt-get clean + +# Création d'un utilisateur non-root pour sécurité +RUN useradd -m -u 1000 -s /bin/bash mdprint && \ + mkdir -p /workspace/documents /workspace/output /workspace/logs && \ + chown -R mdprint:mdprint /workspace + +# Répertoire de travail +WORKDIR /workspace + +# Copie du script principal +COPY md_to_print.sh /usr/local/bin/md_to_print.sh +RUN chmod +x /usr/local/bin/md_to_print.sh + +# Copie du fichier de configuration exemple +COPY config.example.conf /workspace/config.example.conf + +# Basculer vers l'utilisateur non-root +USER mdprint + +# Point d'entrée +ENTRYPOINT ["/usr/local/bin/md_to_print.sh"] +CMD ["--help"] + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..28833a6 --- /dev/null +++ b/Makefile @@ -0,0 +1,110 @@ +.PHONY: build run shell test clean install uninstall help + +# Variables +IMAGE_NAME=md-to-print +IMAGE_TAG=latest +SCRIPT_NAME=md_to_print.sh +INSTALL_DIR=/usr/local/bin +CONFIG_DIR=/etc/md-to-print + +# Couleurs +GREEN=\033[0;32m +YELLOW=\033[1;33m +NC=\033[0m + +help: + @echo "Commandes disponibles:" + @echo " make build - Construire l'image Docker" + @echo " make shell - Ouvrir un shell interactif dans le conteneur" + @echo " make test - Tester avec un fichier markdown exemple" + @echo " make clean - Nettoyer les fichiers générés (PDFs, logs)" + @echo " make install - Installer le script localement" + @echo " make uninstall - Désinstaller le script" + @echo " make help - Afficher cette aide" + +# Construction de l'image Docker +build: + @echo "$(GREEN)Construction de l'image Docker...$(NC)" + docker build -t $(IMAGE_NAME):$(IMAGE_TAG) . + @echo "$(GREEN)Image construite avec succès$(NC)" + +# Exécution interactive avec shell +shell: build + @echo "$(GREEN)Ouverture d'un shell dans le conteneur...$(NC)" + docker run --rm -it \ + -v $(PWD)/documents:/workspace/documents:ro \ + -v $(PWD)/output:/workspace/output \ + -v $(PWD)/logs:/workspace/logs \ + --network host \ + $(IMAGE_NAME):$(IMAGE_TAG) \ + /bin/bash + +# Test avec un fichier exemple +test: build + @echo "$(GREEN)Création d'un fichier markdown de test...$(NC)" + @mkdir -p documents output logs + @cat > documents/test.md << 'EOF' +# Test Markdown + +Ceci est un test de conversion Markdown vers PDF. + +## Fonctionnalités + +- Conversion automatique +- Impression +- Prévisualisation +- Options avancées + +## Exemple de code + +\`\`\`bash +echo "Hello World" +\`\`\` + +## Liste numérotée + +1. Premier élément +2. Deuxième élément +3. Troisième élément + +**Texte en gras** et *texte en italique*. +EOF + @echo "$(GREEN)Exécution du test...$(NC)" + docker run --rm -it \ + -v $(PWD)/documents:/workspace/documents:ro \ + -v $(PWD)/output:/workspace/output \ + -v $(PWD)/logs:/workspace/logs \ + --network host \ + $(IMAGE_NAME):$(IMAGE_TAG) \ + /workspace/documents/test.md --preview --keep-pdf --verbose + @echo "$(GREEN)Test terminé. Vérifiez le fichier output/test.pdf$(NC)" + +# Nettoyage +clean: + @echo "$(YELLOW)Nettoyage des fichiers générés...$(NC)" + @rm -rf output/*.pdf logs/*.log 2>/dev/null || true + @rm -f documents/test.md 2>/dev/null || true + @echo "$(GREEN)Nettoyage terminé$(NC)" + +# Installation locale +install: + @echo "$(GREEN)Installation du script...$(NC)" + @if [ ! -f "$(SCRIPT_NAME)" ]; then \ + echo "Erreur: $(SCRIPT_NAME) introuvable"; \ + exit 1; \ + fi + @sudo mkdir -p $(INSTALL_DIR) $(CONFIG_DIR) + @sudo cp $(SCRIPT_NAME) $(INSTALL_DIR)/$(SCRIPT_NAME) + @sudo chmod +x $(INSTALL_DIR)/$(SCRIPT_NAME) + @sudo cp config.example.conf $(CONFIG_DIR)/config.example.conf + @echo "$(GREEN)Script installé dans $(INSTALL_DIR)/$(SCRIPT_NAME)$(NC)" + @echo "$(GREEN)Configuration exemple dans $(CONFIG_DIR)/config.example.conf$(NC)" + @echo "$(YELLOW)Créez $(CONFIG_DIR)/config.conf pour personnaliser la configuration$(NC)" + +# Désinstallation +uninstall: + @echo "$(YELLOW)Désinstallation du script...$(NC)" + @sudo rm -f $(INSTALL_DIR)/$(SCRIPT_NAME) + @sudo rm -rf $(CONFIG_DIR) + @echo "$(GREEN)Désinstallation terminée$(NC)" + diff --git a/README.md b/README.md new file mode 100644 index 0000000..b74e73e --- /dev/null +++ b/README.md @@ -0,0 +1,360 @@ +# MD_to_Print - Script automatique Markdown → PDF → Impression + +Application CLI complète pour convertir des fichiers Markdown en PDF et les imprimer automatiquement sur Debian/Linux, avec support Docker, prévisualisation, options d'impression avancées, et gestion d'erreurs robuste. + +## Fonctionnalités + +- **Conversion automatique** Markdown → PDF avec Pandoc +- **Prévisualisation** avant impression (evince/okular/xdg-open) +- **Options d'impression avancées** (copies, pages, orientation, qualité, couleur, recto-verso) +- **Fichier de configuration** optionnel (format INI) +- **Installation automatique** des dépendances +- **Support Docker** pour isolation et portabilité +- **Gestion d'erreurs** complète avec codes de retour appropriés +- **Système de logging** détaillé avec niveaux (DEBUG, INFO, WARN, ERROR) +- **Interface en ligne de commande** avec options complètes + +## Installation + +### Installation locale + +1. Cloner ou télécharger le projet: +```bash +cd MD_to_print +chmod +x md_to_print.sh +``` + +2. Installer les dépendances manuellement ou automatiquement: +```bash +# Installation automatique +./md_to_print.sh --install-deps + +# Ou installation manuelle +sudo apt-get update +sudo apt-get install -y pandoc texlive-latex-base texlive-fonts-recommended \ + texlive-latex-extra texlive-lang-french cups +``` + +3. (Optionnel) Installation système: +```bash +make install +``` + +### Installation avec Docker + +1. Construire l'image Docker: +```bash +make build +# ou +docker build -t md-to-print:latest . +``` + +2. Créer les répertoires nécessaires: +```bash +mkdir -p documents output logs +``` + +## Utilisation + +### Utilisation locale + +#### Commande de base +```bash +./md_to_print.sh document.md +``` + +#### Avec prévisualisation +```bash +./md_to_print.sh document.md --preview +``` + +#### Options avancées +```bash +./md_to_print.sh document.md \ + --printer HP_LaserJet \ + --copies 2 \ + --color \ + --duplex duplex \ + --quality high \ + --pages 1-5 \ + --orientation landscape \ + --keep-pdf +``` + +#### Avec fichier de configuration +```bash +# Créer votre configuration +cp config.example.conf config.conf +# Éditer config.conf selon vos besoins + +# Utiliser la configuration +./md_to_print.sh document.md --config config.conf +``` + +### Utilisation avec Docker + +#### Via le wrapper script +```bash +chmod +x docker_run.sh +./docker_run.sh documents/mon_fichier.md --preview +``` + +#### Directement avec docker +```bash +docker run --rm -it \ + -v $(pwd)/documents:/workspace/documents:ro \ + -v $(pwd)/output:/workspace/output \ + -v $(pwd)/logs:/workspace/logs \ + --network host \ + md-to-print:latest \ + /workspace/documents/document.md --preview +``` + +#### Via Docker Compose +```bash +# Modifier docker-compose.yml si nécessaire +docker-compose run --rm md-to-print \ + /workspace/documents/document.md --preview +``` + +### Via Makefile + +```bash +# Construire l'image +make build + +# Tester avec fichier exemple +make test + +# Ouvrir un shell dans le conteneur +make shell + +# Nettoyer les fichiers générés +make clean +``` + +## Options disponibles + +| Option | Description | Défaut | +|--------|-------------|--------| +| `-p, --preview` | Prévisualiser le PDF avant impression | false | +| `-P, --printer NOM` | Spécifier l'imprimante | Imprimante système | +| `-c, --copies N` | Nombre de copies | 1 | +| `-r, --pages RANGE` | Pages à imprimer (ex: 1-3,5,7-9) | Toutes | +| `-o, --orientation DIR` | Orientation (portrait/landscape) | portrait | +| `-s, --size SIZE` | Taille du papier (A4, A3, Letter, etc.) | A4 | +| `-q, --quality QUALITY` | Qualité (draft, normal, high) | normal | +| `-C, --color` | Impression en couleur | false | +| `-d, --duplex MODE` | Mode recto-verso (none, simplex, duplex) | none | +| `-i, --install-deps` | Installer les dépendances automatiquement | false | +| `-k, --keep-pdf` | Conserver le fichier PDF après impression | false | +| `--config FILE` | Fichier de configuration | Aucun | +| `-v, --verbose` | Mode verbeux (logging DEBUG) | false | +| `-l, --log FILE` | Fichier de log | Aucun | +| `-h, --help` | Afficher l'aide | - | +| `--version` | Afficher la version | - | + +## Configuration + +Le fichier de configuration utilise le format INI avec trois sections: + +### Section `[default]` +Options d'impression par défaut (printer, copies, orientation, size, quality, color, duplex, preview, keep_pdf) + +### Section `[paths]` +Chemins des répertoires (output_dir, log_dir) + +### Section `[logging]` +Paramètres de logging (level, file, verbose) + +Exemple de fichier `config.conf`: +```ini +[default] +printer=HP_LaserJet +copies=1 +orientation=portrait +size=A4 +quality=normal +color=false +duplex=none +preview=false +keep_pdf=false + +[paths] +output_dir=./output +log_dir=./logs + +[logging] +level=INFO +file=md_to_print.log +verbose=false +``` + +## Structure du projet + +``` +MD_to_print/ +├── md_to_print.sh # Script principal +├── config.example.conf # Fichier de configuration exemple +├── Dockerfile # Configuration Docker +├── docker-compose.yml # Configuration Docker Compose +├── docker_run.sh # Wrapper Docker +├── Makefile # Commandes Make +├── .dockerignore # Fichiers à exclure du build Docker +├── .gitignore # Fichiers à ignorer dans Git +├── README.md # Documentation (ce fichier) +├── CHANGELOG.md # Historique des versions +├── documents/ # Fichiers Markdown sources +├── output/ # PDFs générés +└── logs/ # Fichiers de logs +``` + +## Exemples d'utilisation + +### Impression simple +```bash +./md_to_print.sh rapport.md +``` + +### Impression avec prévisualisation +```bash +./md_to_print.sh rapport.md --preview +``` + +### Impression recto-verso en couleur +```bash +./md_to_print.sh rapport.md --duplex duplex --color --copies 2 +``` + +### Impression de pages spécifiques +```bash +./md_to_print.sh rapport.md --pages 1-10,15,20-25 +``` + +### Impression paysage haute qualité +```bash +./md_to_print.sh presentation.md --orientation landscape --quality high +``` + +### Avec logging détaillé +```bash +./md_to_print.sh document.md --verbose --log mon_log.txt +``` + +## Codes de retour + +| Code | Signification | +|------|---------------| +| 0 | Succès | +| 1 | Erreur générale | +| 2 | Fichier introuvable | +| 3 | Dépendances manquantes | +| 4 | Erreur conversion PDF | +| 5 | Erreur impression | +| 6 | Erreur configuration | +| 7 | Erreur Docker | +| 8 | Permissions insuffisantes | +| 9 | Argument invalide | +| 10 | Imprimante non disponible | + +## Configuration de l'impression dans Docker + +Pour que l'impression fonctionne depuis Docker, vous devez configurer l'accès à CUPS: + +1. Installer CUPS sur l'hôte: +```bash +sudo apt-get install cups +``` + +2. Configurer le partage réseau dans `/etc/cups/cupsd.conf`: +``` +Listen localhost:631 +Port 631 +``` + +3. Redémarrer CUPS: +```bash +sudo systemctl restart cups +``` + +4. Le socket CUPS sera monté automatiquement via docker-compose.yml ou docker_run.sh + +## Dépannage + +### Erreur: "pandoc n'est pas installé" +```bash +./md_to_print.sh document.md --install-deps +``` + +### Erreur: "Imprimante non disponible" +```bash +# Lister les imprimantes disponibles +lpstat -p + +# Utiliser l'imprimante par défaut +./md_to_print.sh document.md +``` + +### Erreur: "Permission de lecture refusée" +```bash +# Vérifier les permissions du fichier +ls -l document.md + +# Donner les permissions de lecture +chmod +r document.md +``` + +### Erreur Docker: "Cannot connect to the Docker daemon" +```bash +# Vérifier que Docker est démarré +sudo systemctl status docker + +# Démarrer Docker si nécessaire +sudo systemctl start docker + +# Ajouter votre utilisateur au groupe docker +sudo usermod -aG docker $USER +# Déconnexion/reconnexion nécessaire +``` + +### Prévisualisation ne fonctionne pas dans Docker +La prévisualisation graphique nécessite l'accès X11. Assurez-vous que: +- `DISPLAY` est défini dans votre environnement +- `/tmp/.X11-unix` est accessible +- Les permissions X11 sont correctes: +```bash +xhost +local:docker +``` + +## Dépendances + +### Dépendances système +- pandoc +- texlive-latex-base +- texlive-fonts-recommended +- texlive-latex-extra +- texlive-lang-french (support français) +- cups (pour l'impression) +- evince ou okular (pour la prévisualisation, optionnel) + +Toutes les dépendances sont installées automatiquement avec l'option `--install-deps` ou dans l'image Docker. + +## Contribution + +Les contributions sont les bienvenues! N'hésitez pas à: +- Signaler des bugs +- Proposer des améliorations +- Soumettre des pull requests + +## Licence + +Ce projet est fourni tel quel, sans garantie. + +## Auteur + +MD_to_Print - Script automatique Markdown → PDF → Impression + +## Historique + +Voir [CHANGELOG.md](CHANGELOG.md) pour l'historique des versions. + diff --git a/config.example.conf b/config.example.conf new file mode 100644 index 0000000..07751e0 --- /dev/null +++ b/config.example.conf @@ -0,0 +1,48 @@ +# Configuration exemple pour MD_to_Print +# Copiez ce fichier vers config.conf et modifiez selon vos besoins + +[default] +# Imprimante par défaut (laisser vide pour utiliser l'imprimante système) +printer= + +# Nombre de copies par défaut +copies=1 + +# Orientation: portrait ou landscape +orientation=portrait + +# Taille du papier: A4, A3, Letter, Legal, etc. +size=A4 + +# Qualité d'impression: draft, normal, high +quality=normal + +# Impression en couleur (true/false) +color=false + +# Mode recto-verso: none, simplex, duplex +duplex=none + +# Prévisualiser le PDF avant impression (true/false) +preview=false + +# Conserver le fichier PDF après impression (true/false) +keep_pdf=false + +[paths] +# Répertoire de sortie pour les PDFs générés +output_dir=./output + +# Répertoire pour les fichiers de log +log_dir=./logs + +[logging] +# Niveau de log: DEBUG, INFO, WARN, ERROR +level=INFO + +# Nom du fichier de log (sera placé dans log_dir) +file=md_to_print.log + +# Mode verbeux (true/false) +verbose=false + diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..20c27d0 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,32 @@ +version: '3.8' + +services: + md-to-print: + build: + context: . + dockerfile: Dockerfile + image: md-to-print:latest + container_name: md-to-print + volumes: + # Monter le répertoire contenant les fichiers markdown (lecture seule) + - ./documents:/workspace/documents:ro + # Monter le répertoire de sortie pour les PDFs + - ./output:/workspace/output + # Monter le répertoire de logs + - ./logs:/workspace/logs + # Accès à l'imprimante via CUPS (nécessite configuration CUPS) + - /var/run/cups:/var/run/cups:ro + # Optionnel: pour la prévisualisation graphique (décommenter si nécessaire) + # - /tmp/.X11-unix:/tmp/.X11-unix:ro + environment: + - TZ=Europe/Paris + - DISPLAY=${DISPLAY:-} + network_mode: host + # Pour l'accès à l'affichage (prévisualisation) + # Décommenter les lignes suivantes si vous avez besoin de la prévisualisation graphique: + # stdin_open: true + # tty: true + # devices: + # - /dev/dri:/dev/dri + restart: "no" + diff --git a/docker_run.sh b/docker_run.sh new file mode 100755 index 0000000..be1fbe5 --- /dev/null +++ b/docker_run.sh @@ -0,0 +1,130 @@ +#!/bin/bash + +# Wrapper pour exécuter le script MD_to_Print dans Docker +# Usage: ./docker_run.sh fichier.md [options...] + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +MD_FILE="${1:-}" + +# Couleurs +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +# Fonction d'aide +show_help() { + cat << EOF +Wrapper Docker pour MD_to_Print + +Usage: $0 fichier.md [options...] + +Ce script simplifie l'exécution de MD_to_Print dans Docker en gérant: +- Les chemins absolus des fichiers +- Le montage des volumes +- Le passage des arguments +- La gestion des erreurs Docker + +EXEMPLES: + $0 documents/rapport.md --preview + $0 documents/rapport.md --printer HP_LaserJet --copies 2 + $0 documents/rapport.md --config config.conf --verbose + +OPTIONS: + Toutes les options de md_to_print.sh sont supportées. + Utilisez: docker run --rm md-to-print:latest --help + pour voir toutes les options disponibles. +EOF +} + +# Vérification des arguments +if [ -z "$MD_FILE" ] || [ "$MD_FILE" = "-h" ] || [ "$MD_FILE" = "--help" ]; then + show_help + exit 0 +fi + +# Vérifier que Docker est disponible +if ! command -v docker &> /dev/null; then + echo -e "${RED}Erreur: Docker n'est pas installé ou non disponible dans le PATH${NC}" + exit 1 +fi + +# Vérifier que le fichier existe +if [ ! -f "$MD_FILE" ]; then + echo -e "${RED}Erreur: Le fichier '$MD_FILE' n'existe pas${NC}" + exit 2 +fi + +# Obtenir le chemin absolu du fichier +MD_FILE_ABS="$(realpath "$MD_FILE")" +MD_DIR="$(dirname "$MD_FILE_ABS")" +MD_NAME="$(basename "$MD_FILE_ABS")" + +# Vérifier que le fichier est dans le répertoire documents ou un sous-répertoire +if [[ ! "$MD_DIR" =~ ^"$SCRIPT_DIR"/documents ]]; then + echo -e "${YELLOW}Attention: Le fichier n'est pas dans le répertoire documents/${NC}" + echo -e "${BLUE}Le fichier sera accessible via le montage du répertoire parent${NC}" + MD_REL_PATH="$(realpath --relative-to="$SCRIPT_DIR" "$MD_FILE_ABS")" + MD_DIR="$SCRIPT_DIR" + MD_NAME="$MD_REL_PATH" +fi + +# Créer les répertoires nécessaires +mkdir -p "$SCRIPT_DIR/documents" "$SCRIPT_DIR/output" "$SCRIPT_DIR/logs" + +# Vérifier si l'image Docker existe +if ! docker images md-to-print:latest --format "{{.Repository}}:{{.Tag}}" | grep -q "md-to-print:latest"; then + echo -e "${YELLOW}Image Docker non trouvée. Construction de l'image...${NC}" + cd "$SCRIPT_DIR" + docker build -t md-to-print:latest . +fi + +# Construire la commande Docker +DOCKER_CMD=( + docker run + --rm + -it + -v "$SCRIPT_DIR/documents:/workspace/documents:ro" + -v "$SCRIPT_DIR/output:/workspace/output" + -v "$SCRIPT_DIR/logs:/workspace/logs" + --network host +) + +# Ajouter le support X11 si DISPLAY est défini (pour prévisualisation) +if [ -n "${DISPLAY:-}" ]; then + DOCKER_CMD+=( + -e DISPLAY="$DISPLAY" + -v /tmp/.X11-unix:/tmp/.X11-unix:ro + ) +fi + +# Ajouter l'accès CUPS si disponible +if [ -d "/var/run/cups" ]; then + DOCKER_CMD+=(-v /var/run/cups:/var/run/cups:ro) +fi + +DOCKER_CMD+=(md-to-print:latest) + +# Ajouter le fichier markdown et les options +if [[ "$MD_DIR" == "$SCRIPT_DIR" ]]; then + DOCKER_CMD+=("/workspace/$MD_NAME") +else + DOCKER_CMD+=("/workspace/documents/$MD_NAME") +fi + +# Ajouter les options restantes +shift +for arg in "$@"; do + DOCKER_CMD+=("$arg") +done + +# Exécuter +echo -e "${GREEN}Exécution dans Docker...${NC}" +echo -e "${BLUE}Commande: ${DOCKER_CMD[*]}${NC}" +echo "" + +exec "${DOCKER_CMD[@]}" + diff --git a/documents/PLAN_DEPLOIEMENT_ORDRE.md b/documents/PLAN_DEPLOIEMENT_ORDRE.md new file mode 100644 index 0000000..0ed73e7 --- /dev/null +++ b/documents/PLAN_DEPLOIEMENT_ORDRE.md @@ -0,0 +1,885 @@ +# Plan de Déploiement - Ordre Logique - Smart-Motions + +**Date** : Novembre 2025 +**Version** : 1.0 +**Contexte** : Plan complet de déploiement et configuration de l'infrastructure Smart-Motions + +--- + +## 📋 Table des matières + +1. [Vue d'ensemble](#vue-densemble) +2. [Phases de déploiement](#phases-de-déploiement) +3. [Phase 1 : Préparation et Infrastructure de base](#phase-1--préparation-et-infrastructure-de-base) +4. [Phase 2 : Réseau et Sécurité](#phase-2--réseau-et-sécurité) +5. [Phase 3 : Active Directory et Services de base](#phase-3--active-directory-et-services-de-base) +6. [Phase 4 : Services Windows](#phase-4--services-windows) +7. [Phase 5 : Services Infrastructure](#phase-5--services-infrastructure) +8. [Phase 6 : Services applicatifs](#phase-6--services-applicatifs) +7. [Phase 7 : Postes clients et finalisation](#phase-7--postes-clients-et-finalisation) +8. [Checklist complète](#checklist-complète) +9. [Dépendances entre services](#dépendances-entre-services) + +--- + +## Vue d'ensemble + +### Objectif + +Ce document définit l'ordre logique de déploiement et de configuration de toute l'infrastructure Smart-Motions, en tenant compte des dépendances entre les services. + +### Principes + +1. **Infrastructure d'abord** : Réseau, virtualisation, stockage +2. **Services de base** : AD, DNS, DHCP +3. **Services dépendants** : Services qui nécessitent AD +4. **Services applicatifs** : Applications métier +5. **Postes clients** : Déploiement des postes utilisateurs +6. **Finalisation** : Tests, sécurité, documentation + +### Durée estimée + +- **Phase 1-2** : 2-3 jours +- **Phase 3** : 2-3 jours +- **Phase 4** : 3-4 jours +- **Phase 5** : 2-3 jours +- **Phase 6** : 2-3 jours +- **Phase 7** : 2-3 jours +- **Total** : 13-19 jours (environ 3-4 semaines) + +--- + +## Phases de déploiement + +``` +┌─────────────────────────────────────────────────────────┐ +│ PHASE 1 : Préparation et Infrastructure de base │ +│ - Proxmox, Templates, Réseau │ +└─────────────────────────────────────────────────────────┘ + ↓ +┌─────────────────────────────────────────────────────────┐ +│ PHASE 2 : Réseau et Sécurité │ +│ - pfSense, VPN Site-to-Site, DMZ │ +└─────────────────────────────────────────────────────────┘ + ↓ +┌─────────────────────────────────────────────────────────┐ +│ PHASE 3 : Active Directory et Services de base │ +│ - AD, DNS, DHCP, LAPS │ +└─────────────────────────────────────────────────────────┘ + ↓ +┌─────────────────────────────────────────────────────────┐ +│ PHASE 4 : Services Windows │ +│ - Serveur fichiers, RDS, Veeam, GPO │ +└─────────────────────────────────────────────────────────┘ + ↓ +┌─────────────────────────────────────────────────────────┐ +│ PHASE 5 : Services Infrastructure │ +│ - GLPI, Zabbix, DNS Split, Déploiement │ +└─────────────────────────────────────────────────────────┘ + ↓ +┌─────────────────────────────────────────────────────────┐ +│ PHASE 6 : Services applicatifs │ +│ - Messagerie, Nextcloud, DMZ (FTP/Extranet) │ +└─────────────────────────────────────────────────────────┘ + ↓ +┌─────────────────────────────────────────────────────────┐ +│ PHASE 7 : Postes clients et finalisation │ +│ - Déploiement postes, Tests, Pentest, Documentation │ +└─────────────────────────────────────────────────────────┘ +``` + +--- + +## Phase 1 : Préparation et Infrastructure de base + +### Objectif + +Préparer l'infrastructure de virtualisation et créer les templates nécessaires. + +### Étapes + +#### 1.1 Installation et configuration Proxmox + +- [ ] **Installer Proxmox** sur les serveurs physiques (Paris et Lyon) +- [ ] **Configurer les bridges réseau** : + - `vmbr0` : Management (192.168.42.0/24) + - `vmbr1` : WAN (selon configuration) + - `vmbr2` : LAN (10.0.0.0/24 pour Paris, 10.1.0.0/24 pour Lyon) +- [ ] **Configurer le stockage** : Disques locaux ou partagés +- [ ] **Créer les pools de ressources** : Paris, Lyon + +**Documentation** : `docs/proxmox/PROXMOX_NETWORK_CONFIG.md` + +#### 1.2 Création des templates Proxmox + +- [ ] **Template Windows Server 2022** : + - Installer Windows Server 2022 + - Configurer sysprep + - Créer le template +- [ ] **Template Debian 12** : + - Installer Debian 12 + - Configurer cloud-init + - Créer le template +- [ ] **Template Ubuntu 22.04** : + - Installer Ubuntu 22.04 + - Configurer cloud-init + - Créer le template +- [ ] **Template pfSense** : + - Installer pfSense + - Configuration de base + - Créer le template + +**Documentation** : +- `docs/proxmox/PROXMOX_TEMPLATES.md` +- `docs/pfsense/PFSENSE_TEMPLATE.md` + +#### 1.3 Vérification de l'infrastructure + +- [ ] **Tester la connectivité réseau** entre les serveurs Proxmox +- [ ] **Vérifier l'accès aux templates** créés +- [ ] **Valider les ressources** (CPU, RAM, stockage) + +**Durée estimée** : 1-2 jours + +--- + +## Phase 2 : Réseau et Sécurité + +### Objectif + +Déployer et configurer les firewalls pfSense et établir la connectivité entre les sites. + +### Étapes + +#### 2.1 Déploiement des firewalls pfSense + +- [ ] **Déployer PAR-FW1** (10.0.0.1) : + - Créer la VM depuis le template pfSense + - Configurer les interfaces réseau (WAN, LAN, OPT1 pour DMZ) + - Configuration initiale via console +- [ ] **Déployer LYO-FW1** (10.1.0.1) : + - Créer la VM depuis le template pfSense + - Configurer les interfaces réseau + - Configuration initiale via console + +**Documentation** : `docs/pfsense/PFSENSE_INITIAL_CONFIG.md` + +#### 2.2 Configuration manuelle initiale pfSense + +**Pour chaque firewall** : + +- [ ] **Configuration de base** : + - Changer le mot de passe admin + - Configurer l'interface WAN (IP statique ou DHCP) + - Configurer l'interface LAN (10.0.0.1 pour Paris, 10.1.0.1 pour Lyon) + - Activer SSH (optionnel, pour Ansible) +- [ ] **Règles firewall de base** : + - Autoriser le trafic LAN → WAN + - Bloquer le trafic WAN → LAN (sauf exceptions) + - Configurer les règles de base + +**Documentation** : `docs/pfsense/PFSENSE_INITIAL_CONFIG.md` + +#### 2.3 Configuration VPN Site-to-Site + +- [ ] **Configurer IPsec VPN** entre PAR-FW1 et LYO-FW1 : + - Phase 1 (IKE) : Chiffrement, authentification + - Phase 2 (IPsec) : Réseaux à connecter + - Routes statiques +- [ ] **Tester la connectivité** : + - Ping entre les sites + - Vérifier la réplication AD (une fois AD déployé) + +**Documentation** : `docs/pfsense/PFSENSE_SETUP.md` + +#### 2.4 Configuration DMZ + +- [ ] **Créer l'interface DMZ** sur PAR-FW1 (OPT1) +- [ ] **Configurer le réseau DMZ** : 10.0.0.100/24 +- [ ] **Règles firewall DMZ** : + - WAN → DMZ (ports spécifiques) + - DMZ → WAN (accès Internet) + - DMZ → LAN (bloqué par défaut) + +**Documentation** : `docs/pfsense/PFSENSE_SETUP.md` + +#### 2.5 Configuration automatisée pfSense (Ansible) + +- [ ] **Déployer les VMs admin jump hosts** : + - PAR-ADMIN1 (10.0.0.151) + - LYO-ADMIN1 (10.1.0.151) +- [ ] **Configurer les jump hosts** : + - Interfaces réseau (Management + LAN) + - Installation Ansible et collections +- [ ] **Automatiser la configuration pfSense** : + - Règles firewall avancées + - Proxy et filtrage web + - VPN Client (OpenVPN) + - Filtrage géographique (PFBlockerNG) + +**Documentation** : +- `docs/pfsense/PFSENSE_ANSIBLE.md` +- `docs/pfsense/PFSENSE_DEPLOYMENT_ORDER.md` + +**Durée estimée** : 1-2 jours + +--- + +## Phase 3 : Active Directory et Services de base + +### Objectif + +Déployer Active Directory, DNS, DHCP et sécuriser les comptes administrateurs. + +### Étapes + +#### 3.1 Déploiement du premier contrôleur de domaine (PAR-DC1) + +- [ ] **Créer la VM PAR-DC1** (10.0.0.11) : + - 4 cores, 8 Go RAM, 100 Go disque + - Interface LAN (vmbr2) +- [ ] **Installer Windows Server 2022** +- [ ] **Configurer le réseau** : + - IP statique : 10.0.0.11/24 + - DNS : 127.0.0.1 (lui-même) + - Passerelle : 10.0.0.1 (pfSense) +- [ ] **Promouvoir en contrôleur de domaine** : + - Créer la forêt : `smartmotion.ovh` + - Installer les rôles : AD DS, DNS + - Configurer DNS intégré +- [ ] **Vérifier la réplication DNS** : Automatique avec AD + +**Documentation** : `docs/active-directory/ANALYSE_AD_VS_LDAP.md` + +#### 3.2 Déploiement du second contrôleur de domaine (PAR-DC2) + +- [ ] **Créer la VM PAR-DC2** (10.0.0.12) : + - 4 cores, 8 Go RAM, 100 Go disque +- [ ] **Installer Windows Server 2022** +- [ ] **Configurer le réseau** : + - IP statique : 10.0.0.12/24 + - DNS : 10.0.0.11 (PAR-DC1) +- [ ] **Promouvoir en contrôleur de domaine** : + - Joindre le domaine existant : `smartmotion.ovh` + - Installer les rôles : AD DS, DNS +- [ ] **Vérifier la réplication AD** : Automatique +- [ ] **Configurer les forwarders DNS** : 1.1.1.1, 8.8.8.8 + +#### 3.3 Configuration DNS interne + +- [ ] **Créer les enregistrements DNS internes** : + - `dc1.smartmotion.ovh` → 10.0.0.11 + - `dc2.smartmotion.ovh` → 10.0.0.12 + - Enregistrements pour les futurs serveurs +- [ ] **Configurer les zones DNS** : + - Zone `smartmotion.ovh` (intégrée AD) + - Zones de recherche inversée + +**Documentation** : `docs/services/DNS_SPLIT.md` + +#### 3.4 Configuration DHCP + +- [ ] **Installer le rôle DHCP** sur PAR-DC1 +- [ ] **Créer une étendue DHCP** : + - Plage : 10.0.0.100 - 10.0.0.200 + - Passerelle : 10.0.0.1 + - DNS : 10.0.0.11, 10.0.0.12 + - Domaine : `smartmotion.ovh` +- [ ] **Autoriser le serveur DHCP** dans AD +- [ ] **Réservations IP** pour les serveurs fixes + +#### 3.5 Déploiement RODC Lyon (LYO-RODC1) + +- [ ] **Créer la VM LYO-RODC1** (10.1.0.10) : + - 2 cores, 4 Go RAM, 50 Go disque +- [ ] **Installer Windows Server 2022** +- [ ] **Configurer le réseau** : + - IP statique : 10.1.0.10/24 + - DNS : 10.0.0.11 (via VPN) +- [ ] **Promouvoir en RODC** : + - Read-Only Domain Controller + - Pas de modifications AD possibles +- [ ] **Installer DHCP** sur LYO-RODC1 : + - Plage : 10.1.0.100 - 10.1.0.200 + - Passerelle : 10.1.0.1 + +#### 3.6 Configuration Microsoft LAPS + +- [ ] **Installer LAPS** sur PAR-DC1 et PAR-DC2 +- [ ] **Extension du schéma AD** : Automatique +- [ ] **Créer une GPO** pour LAPS : + - Activer la gestion des mots de passe admin locaux + - Configurer les paramètres (longueur, complexité) +- [ ] **Lier la GPO** aux OUs des postes clients +- [ ] **Tester** : Vérifier la rotation des mots de passe + +**Documentation** : `docs/windows/LAPS.md` + +#### 3.7 Création des utilisateurs et groupes AD + +- [ ] **Créer les OUs** : + - `Departements/Direction` + - `Departements/Commercial` + - `Departements/Technique` + - `Departements/Support` + - `Servers/Paris` + - `Servers/Lyon` + - `Clients/Paris` + - `Clients/Lyon` +- [ ] **Créer les groupes de sécurité** : + - `Direction`, `Commercial`, `Technique`, `Support` + - `Chefs-Services` (pour administrateurs locaux) + - `VPN-Users` (pour VPN client) +- [ ] **Créer les comptes utilisateurs** (50 utilisateurs) +- [ ] **Créer les comptes de service** : + - `svc-nextcloud` (pour Nextcloud LDAP) + - `svc-glpi` (pour GLPI LDAP) + - `svc-veeam` (pour Veeam) + +**Durée estimée** : 2-3 jours + +--- + +## Phase 4 : Services Windows + +### Objectif + +Déployer les services Windows : fichiers, RDS, sauvegardes, GPO. + +### Étapes + +#### 4.1 Serveur de fichiers Paris (PAR-FILE1) + +- [ ] **Créer la VM PAR-FILE1** (10.0.0.20) : + - 4 cores, 8 Go RAM, 2 To disque +- [ ] **Installer Windows Server 2022** +- [ ] **Joindre au domaine** : `smartmotion.ovh` +- [ ] **Installer le rôle File Server** +- [ ] **Créer les partages** : + - `\\PAR-FILE1\Departements\` + - `\\PAR-FILE1\Public\` + - `\\PAR-FILE1\Applications\` + - `\\PAR-FILE1\Users\` (pour redirection profils) +- [ ] **Configurer FSRM** : + - Quotas par utilisateur (10 Go standard, 20 Go direction) + - Filtrage de fichiers (bloquer multimédia) +- [ ] **Activer la déduplication** : + - Volume D:\ + - Type : General purpose file server +- [ ] **Activer Shadow Copies** : + - Volume D:\ + - Fréquence : 2 fois par jour +- [ ] **Configurer les permissions** : Par groupes AD + +**Documentation** : `docs/windows/SERVEUR_FICHIERS.md` + +#### 4.2 Serveur de fichiers Lyon (LYO-FILE1) + +- [ ] **Créer la VM LYO-FILE1** (10.1.0.20) : + - 2 cores, 4 Go RAM, 1 To disque +- [ ] **Installer Windows Server 2022** +- [ ] **Joindre au domaine** +- [ ] **Installer le rôle File Server** +- [ ] **Créer les partages locaux** +- [ ] **Configurer FSRM** (quotas) + +#### 4.3 Configuration DFS-R (Réplication) + +- [ ] **Installer DFS Replication** sur PAR-FILE1 et LYO-FILE1 +- [ ] **Créer un groupe de réplication** : + - Nom : `Sylvestre-Replication` +- [ ] **Ajouter les membres** : PAR-FILE1, LYO-FILE1 +- [ ] **Créer un dossier répliqué** : + - `Documents` : Réplication bidirectionnelle +- [ ] **Configurer la topologie** : Hub (Paris) - Spoke (Lyon) +- [ ] **Tester la réplication** : Vérifier la synchronisation + +**Documentation** : `docs/windows/SERVEUR_FICHIERS.md` + +#### 4.4 Remote Desktop Services (PAR-RDS1) + +- [ ] **Créer la VM PAR-RDS1** (10.0.0.60) : + - 8 cores, 16 Go RAM, 100 Go disque +- [ ] **Installer Windows Server 2022** +- [ ] **Joindre au domaine** +- [ ] **Installer les rôles RDS** : + - RD Session Host + - RD Web Access + - RD Gateway + - RD Licensing +- [ ] **Configurer le déploiement RDS** : + - RD Connection Broker : PAR-RDS1 + - RD Session Host : PAR-RDS1 + - RD Web Access : PAR-RDS1 +- [ ] **Publier des applications RemoteApp** : + - Microsoft Office + - Applications métier +- [ ] **Configurer TLS** : Certificat SSL +- [ ] **Tester l'accès** : Via navigateur web + +**Documentation** : `docs/windows/RDS_REMOTE_DESKTOP.md` + +#### 4.5 Veeam Backup & Replication (PAR-VEEAM1) + +- [ ] **Créer la VM PAR-VEEAM1** (10.0.0.50) : + - 4 cores, 8 Go RAM, 5 To disque +- [ ] **Installer Windows Server 2022** +- [ ] **Joindre au domaine** +- [ ] **Installer Veeam Backup & Replication** +- [ ] **Configurer le repository** : + - Chemin : `D:\Backups` + - Espace : 5 To +- [ ] **Créer les jobs de sauvegarde** : + - PAR-DC1, PAR-DC2 : Quotidien + - PAR-FILE1, LYO-FILE1 : Quotidien + - PAR-RDS1 : Quotidien + - Autres serveurs : Hebdomadaire +- [ ] **Configurer la rétention** : 30 jours +- [ ] **Tester une restauration** : Fichier individuel + +**Documentation** : `docs/windows/VEEAM_SAUVEGARDE.md` + +#### 4.6 Group Policy Objects (GPO) + +- [ ] **Créer les GPO de base** : + - `GPO-Departement-Direction` + - `GPO-Departement-Commercial` + - `GPO-Departement-Technique` + - `GPO-Postes-Clients` + - `GPO-Chefs-Services` (administrateurs locaux) +- [ ] **Configurer le déploiement automatique** : + - Imprimantes par département + - Lecteurs réseau mappés + - Redirection de profils (Documents, Desktop, AppData) +- [ ] **Configurer les administrateurs locaux** : + - Groupe `Chefs-Services` → Administrateurs locaux +- [ ] **Tester les GPO** : Sur un poste de test + +**Documentation** : `docs/windows/GPO_GROUP_POLICY.md` + +**Durée estimée** : 3-4 jours + +--- + +## Phase 5 : Services Infrastructure + +### Objectif + +Déployer les services d'infrastructure : GLPI, Zabbix, DNS Split, déploiement. + +### Étapes + +#### 5.1 GLPI - Gestion de parc (PAR-GLPI1) + +- [ ] **Créer la VM PAR-GLPI1** (10.0.0.30) : + - 2 cores, 4 Go RAM, 100 Go disque +- [ ] **Installer Debian 12** +- [ ] **Installer GLPI** : + - Apache, PHP, MariaDB + - GLPI 10.0.7 +- [ ] **Configurer l'intégration AD** : + - LDAP : 10.0.0.11 + - Compte de service : `svc-glpi` + - Synchronisation automatique +- [ ] **Installer OCS Inventory** : + - Serveur OCS + - Agents sur les postes clients +- [ ] **Configurer GLPI + OCS** : + - Plugin OCS dans GLPI + - Synchronisation inventaire +- [ ] **Créer les catégories d'incidents** +- [ ] **Tester la création de tickets** + +**Documentation** : `docs/services/GLPI_GESTION_PARC.md` + +#### 5.2 Zabbix - Supervision (PAR-ZABBIX1) + +- [ ] **Créer la VM PAR-ZABBIX1** (10.0.0.40) : + - 4 cores, 8 Go RAM, 200 Go disque +- [ ] **Installer Ubuntu 22.04** +- [ ] **Installer Zabbix Server** : + - Zabbix 6.0 + - PostgreSQL + - Nginx +- [ ] **Configurer les hôtes** : + - Serveurs Windows (via Zabbix Agent) + - Serveurs Linux (via Zabbix Agent) + - Équipements réseau (via SNMP si supporté) +- [ ] **Créer des tableaux de bord** : + - Dashboard Infrastructure + - Dashboard Réseau + - Dashboard Services +- [ ] **Configurer les alertes** : + - Notifications email + - Seuils d'alerte +- [ ] **Tester les alertes** : Simulation d'incident + +**Documentation** : `docs/services/ZABBIX_SUPERVISION.md` + +#### 5.3 DNS Split (Interne/Externe) + +- [ ] **Acheter un nom de domaine** : + - `smartmotion.ovh` (ou autre) + - Registrar : OVH, Gandi, Online, etc. +- [ ] **Configurer DNS interne (AD)** : + - Enregistrements A pour tous les services + - `www.smartmotion.ovh` → 10.0.0.30 (GLPI) + - `mail.smartmotion.ovh` → 10.0.0.XX (Zimbra) + - `zabbix.smartmotion.ovh` → 10.0.0.40 + - etc. +- [ ] **Configurer DNS externe (Hébergeur)** : + - Enregistrements A pour services exposés + - `www.smartmotion.ovh` → IP publique + - `ftp.smartmotion.ovh` → IP publique DMZ + - Enregistrements MX pour email +- [ ] **Configurer les forwarders DNS** : 1.1.1.1, 8.8.8.8 +- [ ] **Tester la résolution** : + - Interne : `nslookup www.smartmotion.ovh 10.0.0.11` + - Externe : `nslookup www.smartmotion.ovh 8.8.8.8` + +**Documentation** : `docs/services/DNS_SPLIT.md` + +#### 5.4 Solution de déploiement des postes + +- [ ] **Créer la VM PAR-DEPLOY1** (10.0.0.80) : + - 4 cores, 8 Go RAM, 500 Go disque +- [ ] **Installer Windows Server 2022** +- [ ] **Joindre au domaine** +- [ ] **Installer WDS + MDT** : + - Windows Deployment Services + - Microsoft Deployment Toolkit + - Windows ADK +- [ ] **Créer les images de référence** : + - Windows 11 Pro - PC fixes + - Windows 11 Pro - Portables +- [ ] **Configurer les Task Sequences** : + - Installation Windows 11 + - Applications pré-installées + - Jointure au domaine +- [ ] **Tester le déploiement** : Sur un poste de test + +**Documentation** : `docs/services/DEPLOIEMENT_POSTES.md` + +**Durée estimée** : 2-3 jours + +--- + +## Phase 6 : Services applicatifs + +### Objectif + +Déployer les services applicatifs : messagerie, Nextcloud, DMZ. + +### Étapes + +#### 6.1 Service de messagerie (Zimbra ou M365) + +**Option A : Zimbra (hébergé localement)** + +- [ ] **Créer la VM PAR-MAIL1** (10.0.0.XX) : + - 4 cores, 8 Go RAM, 200 Go disque +- [ ] **Installer Zimbra** : + - Debian 12 + - Zimbra Open Source ou Network Edition +- [ ] **Configurer le domaine** : `smartmotion.ovh` +- [ ] **Créer les boîtes mail** : 50 utilisateurs +- [ ] **Configurer l'intégration AD** : LDAP +- [ ] **Configurer les enregistrements DNS** : + - MX : `mail.smartmotion.ovh` + - SPF, DKIM, DMARC + +**Option B : Microsoft 365 (SaaS)** + +- [ ] **Souscrire à Microsoft 365** : + - Plan Business Standard ou Premium + - 50 licences utilisateur +- [ ] **Configurer le domaine** : `smartmotion.ovh` + - Vérification du domaine + - Enregistrements DNS (MX, SPF, etc.) +- [ ] **Synchroniser avec AD** : Azure AD Connect (optionnel) +- [ ] **Créer les boîtes mail** : 50 utilisateurs + +**Documentation** : `docs/messagerie/COMPARAISON_ZIMBRA_M365.md` + +#### 6.2 Nextcloud + +- [ ] **Créer la VM PAR-NEXTCLOUD1** (10.0.0.XX) : + - 2 cores, 4 Go RAM, 500 Go disque +- [ ] **Installer Nextcloud** : + - Debian 12 + - Nextcloud 28+ + - Apache, PHP, MariaDB +- [ ] **Configurer l'intégration AD** : + - LDAP : 10.0.0.11 + - Compte de service : `svc-nextcloud` + - Synchronisation automatique +- [ ] **Configurer les partages** : + - Intégration avec serveur de fichiers + - Quotas par utilisateur +- [ ] **Tester l'accès** : Via navigateur web + +**Documentation** : `docs/active-directory/NEXTCLOUD_LDAP_AD.md` + +#### 6.3 DMZ - FTP et Extranet (PAR-FTP1) + +- [ ] **Créer la VM PAR-FTP1** (10.0.0.70) : + - 2 cores, 2 Go RAM, 100 Go disque + - Interface DMZ (10.0.0.100/24) +- [ ] **Installer Debian 12** +- [ ] **Installer vsftpd** : + - Configuration FTP sécurisé + - Utilisateurs virtuels +- [ ] **Installer Apache** : + - Extranet web + - PHP, base de données +- [ ] **Configurer les règles firewall** : + - WAN → DMZ (ports FTP et HTTP/HTTPS) + - DMZ → LAN (bloqué) +- [ ] **Tester l'accès** : + - FTP depuis Internet + - Extranet depuis Internet + +**Documentation** : `docs/services/DMZ_FTP_EXTRANET.md` + +#### 6.4 VPN Client avec authentification RADIUS + +- [ ] **Configurer NPS (Network Policy Server)** sur PAR-DC1 : + - Installer le rôle NPS + - Créer un RADIUS client (pfSense) + - Créer une Network Policy (groupe VPN-Users) +- [ ] **Configurer OpenVPN sur pfSense** : + - Serveur OpenVPN + - Authentification RADIUS + - Certificats SSL +- [ ] **Créer les profils VPN** : + - Fichiers .ovpn pour les clients +- [ ] **Tester la connexion VPN** : + - Depuis un poste externe + - Authentification avec compte AD + +**Documentation** : `docs/services/VPN_CLIENT_RADIUS.md` + +**Durée estimée** : 2-3 jours + +--- + +## Phase 7 : Postes clients et finalisation + +### Objectif + +Déployer les postes clients, effectuer les tests et finaliser la documentation. + +### Étapes + +#### 7.1 Déploiement des postes clients + +- [ ] **Déployer les 40 PC fixes (Paris)** : + - Via WDS + MDT + - Windows 11 Pro + - Applications pré-installées + - Jointure au domaine +- [ ] **Déployer les 5 portables (Paris)** : + - Via WDS + MDT + - Windows 11 Pro + - Configuration portable +- [ ] **Déployer les 5 portables (Lyon)** : + - Via WDS + MDT (depuis Paris via VPN) + - Windows 11 Pro +- [ ] **Vérifier les GPO** : + - Imprimantes déployées + - Lecteurs réseau mappés + - Redirection de profils active +- [ ] **Vérifier LAPS** : + - Mots de passe admin locaux gérés + - Rotation automatique + +**Documentation** : `docs/services/DEPLOIEMENT_POSTES.md` + +#### 7.2 Tests fonctionnels + +- [ ] **Tests de connectivité** : + - Ping entre tous les serveurs + - Accès aux partages réseau + - Résolution DNS (interne et externe) +- [ ] **Tests de services** : + - Accès GLPI (gestion de parc) + - Accès Zabbix (supervision) + - Accès RDS (bureaux à distance) + - Accès Nextcloud + - Accès messagerie +- [ ] **Tests de réplication** : + - Réplication AD (Paris ↔ Lyon) + - Réplication DFS-R (fichiers) +- [ ] **Tests de sauvegarde** : + - Jobs Veeam fonctionnels + - Restauration test (fichier individuel) + - Shadow Copies accessibles +- [ ] **Tests VPN** : + - VPN Site-to-Site (Paris ↔ Lyon) + - VPN Client (depuis Internet) + +#### 7.3 Tests de sécurité (Pentest) + +- [ ] **Installation des outils** : + - Nmap + - Nessus (Community Edition ou commercial) +- [ ] **Scan réseau avec Nmap** : + - Scan de tous les réseaux (10.0.0.0/24, 10.1.0.0/24) + - Détection des ports ouverts + - Identification des services +- [ ] **Scan de vulnérabilités avec Nessus** : + - Scan de tous les serveurs + - Identification des vulnérabilités + - Classification (Critique, Haute, Moyenne, Faible) +- [ ] **Correction des vulnérabilités** : + - Mises à jour système + - Fermeture de ports inutiles + - Renforcement de la configuration +- [ ] **Nouveau scan de validation** : + - Vérifier que les vulnérabilités sont corrigées +- [ ] **Rapport de pentest** : + - Documenter les résultats + - Liste des vulnérabilités corrigées + - Recommandations + +**Documentation** : `docs/security/PENTEST_NMAP_NESSUS.md` + +#### 7.4 Documentation finale + +- [ ] **Vérifier la documentation** : + - Tous les documents à jour + - Procédures complètes + - Schémas réseau +- [ ] **Créer un guide utilisateur** : + - Accès aux services + - Utilisation de Nextcloud + - Utilisation de la messagerie + - Accès VPN +- [ ] **Créer un guide administrateur** : + - Procédures de maintenance + - Procédures de sauvegarde/restauration + - Procédures de dépannage +- [ ] **Documenter les mots de passe** : + - Stockage sécurisé (Vault) + - Liste des comptes de service + - Accès aux équipements + +**Durée estimée** : 2-3 jours + +--- + +## Checklist complète + +### Phase 1 : Préparation +- [ ] Proxmox installé et configuré +- [ ] Templates créés (Windows, Debian, Ubuntu, pfSense) +- [ ] Réseau configuré (bridges, VLAN) + +### Phase 2 : Réseau et Sécurité +- [ ] pfSense déployé (Paris et Lyon) +- [ ] Configuration manuelle initiale +- [ ] VPN Site-to-Site configuré +- [ ] DMZ configurée +- [ ] Configuration automatisée (Ansible) + +### Phase 3 : Active Directory +- [ ] PAR-DC1 déployé et promu +- [ ] PAR-DC2 déployé et promu +- [ ] LYO-RODC1 déployé et promu +- [ ] DNS interne configuré +- [ ] DHCP configuré (Paris et Lyon) +- [ ] LAPS installé et configuré +- [ ] Utilisateurs et groupes créés + +### Phase 4 : Services Windows +- [ ] PAR-FILE1 déployé et configuré +- [ ] LYO-FILE1 déployé et configuré +- [ ] DFS-R configuré +- [ ] PAR-RDS1 déployé et configuré +- [ ] PAR-VEEAM1 déployé et configuré +- [ ] GPO créées et configurées + +### Phase 5 : Services Infrastructure +- [ ] PAR-GLPI1 déployé et configuré +- [ ] PAR-ZABBIX1 déployé et configuré +- [ ] DNS Split configuré +- [ ] Solution de déploiement configurée + +### Phase 6 : Services applicatifs +- [ ] Messagerie déployée (Zimbra ou M365) +- [ ] Nextcloud déployé et configuré +- [ ] DMZ (FTP/Extranet) déployée +- [ ] VPN Client configuré + +### Phase 7 : Finalisation +- [ ] Postes clients déployés (50 postes) +- [ ] Tests fonctionnels réussis +- [ ] Pentest effectué et vulnérabilités corrigées +- [ ] Documentation complète + +--- + +## Dépendances entre services + +### Graphique des dépendances + +``` +Proxmox + ↓ +pfSense (VPN Site-to-Site) + ↓ +Active Directory (PAR-DC1, PAR-DC2) + ├─→ DNS interne + ├─→ DHCP + ├─→ LAPS + └─→ Utilisateurs/Groups + ↓ + ├─→ GPO + ├─→ Serveur fichiers (FSRM, DFS-R) + ├─→ RDS + ├─→ Veeam + ├─→ GLPI (LDAP) + ├─→ Nextcloud (LDAP) + ├─→ VPN Client (RADIUS/NPS) + └─→ Déploiement postes (jointure domaine) + ↓ + Postes clients +``` + +### Ordre critique + +1. **Proxmox** : Nécessaire pour tout le reste +2. **pfSense** : Nécessaire pour la connectivité réseau +3. **Active Directory** : Nécessaire pour tous les services Windows et authentification +4. **DNS** : Nécessaire pour la résolution de noms +5. **DHCP** : Nécessaire pour l'attribution d'IPs automatiques +6. **Services dépendants** : Tous les autres services + +### Points d'attention + +- ⚠️ **Ne pas déployer de services avant AD** : Tous les services Windows nécessitent AD +- ⚠️ **VPN Site-to-Site avant RODC Lyon** : Le RODC doit pouvoir communiquer avec les DC Paris +- ⚠️ **DNS avant autres services** : La résolution de noms est critique +- ⚠️ **GPO avant déploiement postes** : Les postes doivent être configurés dès le déploiement + +--- + +## Durée totale estimée + +| Phase | Durée | Description | +|-------|-------|-------------| +| **Phase 1** | 1-2 jours | Préparation infrastructure | +| **Phase 2** | 1-2 jours | Réseau et sécurité | +| **Phase 3** | 2-3 jours | Active Directory | +| **Phase 4** | 3-4 jours | Services Windows | +| **Phase 5** | 2-3 jours | Services Infrastructure | +| **Phase 6** | 2-3 jours | Services applicatifs | +| **Phase 7** | 2-3 jours | Postes clients et finalisation | +| **TOTAL** | **13-19 jours** | **3-4 semaines** | + +--- + +*Document créé le : Novembre 2025* +*Version : 1.0* +*Projet : Smart-Motions - Plan de déploiement* + diff --git a/documents/PROCHAINES_ETAPES.md b/documents/PROCHAINES_ETAPES.md new file mode 100644 index 0000000..6550c54 --- /dev/null +++ b/documents/PROCHAINES_ETAPES.md @@ -0,0 +1,326 @@ +# Prochaines Etapes - Deploiement Smart-Motions + +**Date** : Decembre 2025 +**Statut** : En cours - Phase 2 (Reseau et Securite) + +--- + +## Etat actuel de l'infrastructure + +### Ce qui est deploye et operationnel + +| Composant | IP | Statut | Notes | +|-----------|-----|--------|-------| +| Proxmox Paris | 192.168.42.231 | OK | Bridges vmbr0-3 configures | +| PAR-FW1 (pfSense) | WAN: 192.168.254.10, LAN: 10.0.0.1, DMZ: 10.0.10.1 | OK | Config initiale terminee | +| PAR-ADMIN1 (Jump Host) | 192.168.42.225 + 10.0.0.151 | OK | Acces SSH operationnel | + +### Configuration pfSense terminee + +- Hostname et DNS publics (8.8.8.8, 1.1.1.1) - temporaire +- DHCP sur LAN (10.0.0.100-199) +- Regles firewall LAN (Internet, Lyon, DMZ) +- Regles firewall WAN (OpenVPN, NAT vers DMZ) +- Regles firewall DMZ (Internet, Block vers LAN) +- NAT Port Forwards (FTP, HTTP, HTTPS vers DMZ) +- CA "SmartMotions-CA" cree manuellement + +--- + +## Prochaines etapes par priorite + +### ETAPE 0 : Configuration DNS OVH + Cloudflare (OPTIONNEL MAIS RECOMMANDE) + +**Objectif** : Deleguer le DNS vers Cloudflare pendant que la propagation se fait (24-48h) + +**Pourquoi maintenant ?** +- La propagation prend du temps, autant la lancer tot +- Permet de tester le VPN avec un nom de domaine (`vpn.smartmotion.ovh`) +- Aucune dependance avec les autres etapes + +#### 0.1 Creer un compte Cloudflare + +1. Aller sur [dash.cloudflare.com](https://dash.cloudflare.com) +2. Creer un compte (plan Free) +3. Ajouter le site `smartmotion.ovh` +4. Noter les nameservers Cloudflare (ex: `alex.ns.cloudflare.com`, `vera.ns.cloudflare.com`) + +#### 0.2 Modifier les DNS chez OVH + +1. Aller sur [manager.ovh.com](https://www.ovh.com/manager/) +2. Web Cloud > Noms de domaine > `smartmotion.ovh` > Serveurs DNS +3. Remplacer les serveurs OVH par les serveurs Cloudflare +4. Sauvegarder + +#### 0.3 Creer les enregistrements de base dans Cloudflare + +| Type | Name | Content | Proxy | +|------|------|---------|-------| +| A | @ | 45.80.22.46 | ON | +| A | www | 45.80.22.46 | ON | +| A | vpn | 45.80.22.46 | OFF | + +**Duree** : 1-2h de configuration + 24-48h de propagation + +**Documentation complete** : `docs/services/DNS_OVH_CLOUDFLARE_SETUP.md` + +--- + +### ETAPE 1 : VPN Site-to-Site Paris-Lyon (Prerequis pour Lyon) + +**Objectif** : Etablir la connectivite entre les deux sites avant de deployer quoi que ce soit a Lyon. + +#### 1.1 Creer le certificat serveur OpenVPN (sur PAR-FW1) + +1. Aller dans **System > Cert Manager > Certificates** +2. Cliquer **+ Add/Sign** +3. Remplir : + - **Method** : Create an internal Certificate + - **Descriptive Name** : `PAR-FW1-OpenVPN-Server` + - **Certificate Authority** : SmartMotions-CA + - **Certificate Type** : Server Certificate + - **Key Length** : 2048 + - **Common Name** : `par-fw1.smartmotion.ovh` + - **Alternative Names** : `192.168.254.10` +4. **Save** + +#### 1.2 Configurer le serveur OpenVPN (sur PAR-FW1) + +1. Aller dans **VPN > OpenVPN > Servers** +2. Cliquer **+ Add** +3. Configuration : + - **Server mode** : Peer to Peer (SSL/TLS) + - **Protocol** : UDP on IPv4 only + - **Device mode** : tun + - **Interface** : WAN + - **Local port** : 1194 + - **TLS Configuration** : Activer, generer une cle TLS + - **Peer Certificate Authority** : SmartMotions-CA + - **Server Certificate** : PAR-FW1-OpenVPN-Server + - **Encryption Algorithm** : AES-256-GCM + - **IPv4 Tunnel Network** : `10.10.0.0/30` (petit reseau pour P2P) + - **IPv4 Remote Network(s)** : `10.1.0.0/24` (LAN Lyon) + - **Compression** : Omit +4. **Save** + +#### 1.3 Exporter la configuration pour Lyon + +1. Aller dans **System > Cert Manager > CAs** +2. Exporter le CA (icone export) - sauvegarder le fichier +3. Creer un certificat client pour LYO-FW1 : + - **System > Cert Manager > Certificates > Add** + - **Descriptive Name** : `LYO-FW1-OpenVPN-Client` + - **Certificate Type** : User Certificate +4. Noter la cle TLS partagee + +--- + +### ETAPE 2 : Deployer Lyon (LYO-FW1) + +**Prerequis** : VPN configure cote Paris + +#### 2.1 Deployer la VM LYO-FW1 avec Terraform + +```bash +cd "/home/syoul/IPSSI SMARTMOTION/terraform/environments/lyon" +tofu init +tofu plan +tofu apply +``` + +#### 2.2 Configuration manuelle initiale LYO-FW1 + +Via la console Proxmox : +1. Assigner les interfaces : + - vtnet0 = WAN (192.168.254.11/24, GW: 192.168.254.254) + - vtnet1 = LAN (10.1.0.1/24) +2. Activer SSH +3. Changer le mot de passe admin + +#### 2.3 Configurer le client OpenVPN (sur LYO-FW1) + +1. Importer le CA SmartMotions-CA +2. Importer le certificat LYO-FW1-OpenVPN-Client +3. Configurer le client OpenVPN vers 192.168.254.10:1194 +4. Verifier la connectivite : `ping 10.0.0.1` depuis LYO-FW1 + +--- + +### ETAPE 3 : Deployer les Domain Controllers Paris + +**Prerequis** : pfSense Paris operationnel + +#### 3.1 Deployer PAR-DC1 (10.0.0.11) + +```bash +# Ajouter au main.tf de Paris si pas deja fait +cd "/home/syoul/IPSSI SMARTMOTION/terraform/environments/paris" +tofu plan +tofu apply +``` + +Configuration Windows Server : +1. IP statique : 10.0.0.11/24, GW: 10.0.0.1, DNS: 127.0.0.1 +2. Installer le role AD DS +3. Promouvoir en DC : nouvelle foret `smartmotion.ovh` +4. Configurer DNS integre + +#### 3.2 Deployer PAR-DC2 (10.0.0.12) + +1. IP statique : 10.0.0.12/24, GW: 10.0.0.1, DNS: 10.0.0.11 +2. Joindre le domaine `smartmotion.ovh` +3. Promouvoir en DC additionnel + +#### 3.3 Mettre a jour DNS pfSense + +Une fois les DC operationnels : + +```bash +cd "/home/syoul/IPSSI SMARTMOTION/ansible" +ansible-playbook -i inventories/paris.yml playbooks/04b-configure-pfsense-paris-dns.yml +``` + +--- + +### ETAPE 4 : Deployer le serveur DMZ (PAR-FTP1) + +**Prerequis** : pfSense et NAT configures + +#### 4.1 Deployer PAR-FTP1 (10.0.10.70) + +```bash +cd "/home/syoul/IPSSI SMARTMOTION/terraform/environments/paris" +tofu plan +tofu apply +``` + +#### 4.2 Configurer le serveur + +1. IP statique : 10.0.10.70/24, GW: 10.0.10.1, DNS: 8.8.8.8 +2. Installer vsftpd (FTP) +3. Installer Apache/Nginx (Extranet) +4. Tester l'acces depuis Internet via NAT + +--- + +## Ordre de deploiement recommande + +``` +Phase actuelle : Phase 2 (Reseau) - EN COURS + | + v ++--------------------------------------------------+ +| ETAPE 1 : VPN Site-to-Site | +| - Certificat serveur OpenVPN | +| - Serveur OpenVPN sur PAR-FW1 | +| Duree estimee : 1-2 heures | ++--------------------------------------------------+ + | + v ++--------------------------------------------------+ +| ETAPE 2 : Deploiement Lyon | +| - Terraform LYO-FW1 | +| - Config manuelle + Client OpenVPN | +| - Test connectivite VPN | +| Duree estimee : 2-3 heures | ++--------------------------------------------------+ + | + v ++--------------------------------------------------+ +| ETAPE 3 : Domain Controllers Paris | +| - PAR-DC1 (DC primaire, DNS, DHCP) | +| - PAR-DC2 (DC secondaire) | +| - Mise a jour DNS pfSense | +| Duree estimee : 1 jour | ++--------------------------------------------------+ + | + v ++--------------------------------------------------+ +| ETAPE 4 : Serveur DMZ | +| - PAR-FTP1 (FTP + Extranet) | +| - Tests NAT depuis Internet | +| Duree estimee : 2-3 heures | ++--------------------------------------------------+ + | + v ++--------------------------------------------------+ +| ETAPE 5 : RODC Lyon (apres VPN + DC) | +| - LYO-RODC1 (RODC + DNS cache + DHCP) | +| Duree estimee : 3-4 heures | ++--------------------------------------------------+ + | + v + [Suite Phase 4 : Services Windows] +``` + +--- + +## Commandes utiles + +### Acces SSH aux VMs + +```bash +# Via le jump host PAR-ADMIN1 +ssh -J debian@192.168.42.225 admin@10.0.0.1 # pfSense Paris +ssh -J debian@192.168.42.225 debian@10.0.10.70 # PAR-FTP1 (DMZ) +``` + +### Terraform + +```bash +cd "/home/syoul/IPSSI SMARTMOTION/terraform/environments/paris" +tofu plan # Voir les changements +tofu apply # Appliquer +tofu destroy # Supprimer (attention!) +``` + +### Ansible + +```bash +cd "/home/syoul/IPSSI SMARTMOTION/ansible" + +# Installer les collections +ansible-galaxy collection install -r requirements.yml -p ./collections + +# Lancer un playbook +ansible-playbook -i inventories/paris.yml playbooks/04a-configure-pfsense-paris-initial.yml + +# Tester la connectivite +ansible -i inventories/paris.yml paris_firewalls -m ping +``` + +--- + +## Points d'attention + +### VPN Site-to-Site +- Le tunnel doit etre etabli AVANT de deployer quoi que ce soit a Lyon +- Les routes doivent etre configurees des deux cotes +- Tester avec un ping avant de continuer + +### Domain Controllers +- PAR-DC1 doit etre operationnel avant PAR-DC2 +- Attendre la replication AD avant de deployer le RODC +- Ne pas oublier de mettre a jour les DNS sur pfSense + +### DMZ +- Le serveur DMZ ne doit PAS avoir acces au LAN +- Tester le blocage : depuis PAR-FTP1, `ping 10.0.0.11` doit echouer +- Tester le NAT depuis une IP externe + +--- + +## Ressources + +- Architecture : `docs/architecture/architecture.md` +- Plan complet : `docs/deployment/PLAN_DEPLOIEMENT_ORDRE.md` +- Config pfSense : `docs/pfsense/PFSENSE_SETUP.md` +- Config VPN : `docs/services/VPN_CLIENT_RADIUS.md` +- DMZ : `docs/services/DMZ_FTP_EXTRANET.md` +- **DNS OVH + Cloudflare** : `docs/services/DNS_OVH_CLOUDFLARE_SETUP.md` +- **NAT Freebox + OpenWRT** : `docs/network/NAT_FREEBOX_OPENWRT.md` + +--- + +*Document cree le : Decembre 2025* +*Derniere mise a jour : 13 Decembre 2025* diff --git a/md_to_print.sh b/md_to_print.sh new file mode 100755 index 0000000..ded9efd --- /dev/null +++ b/md_to_print.sh @@ -0,0 +1,670 @@ +#!/bin/bash + +# Script automatique : Markdown → PDF → Prévisualisation → Impression +# Usage: ./md_to_print.sh fichier.md [options] + +set -euo pipefail + +# Version +VERSION="1.0.0" + +# Codes de retour +EXIT_SUCCESS=0 +EXIT_GENERAL=1 +EXIT_FILE_NOT_FOUND=2 +EXIT_DEPS_MISSING=3 +EXIT_PDF_CONVERSION=4 +EXIT_PRINT_ERROR=5 +EXIT_CONFIG_ERROR=6 +EXIT_DOCKER_ERROR=7 +EXIT_PERMISSIONS=8 +EXIT_INVALID_ARG=9 +EXIT_PRINTER_UNAVAILABLE=10 + +# Couleurs pour les messages +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +# Variables par défaut +PREVIEW=false +PRINTER="" +COPIES=1 +PAGES="" +ORIENTATION="portrait" +SIZE="A4" +QUALITY="normal" +COLOR=false +DUPLEX="none" +INSTALL_DEPS=false +KEEP_PDF=false +CONFIG_FILE="" +VERBOSE=false +LOG_FILE="" +LOG_LEVEL="INFO" + +# Répertoires +OUTPUT_DIR="./output" +LOG_DIR="./logs" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# Fonction de logging +log() { + local level="$1" + shift + local message="$*" + local timestamp=$(date '+%Y-%m-%d %H:%M:%S') + local log_entry="[${timestamp}] [${level}] ${message}" + + case "$level" in + DEBUG) + if [ "$VERBOSE" = true ] || [ "$LOG_LEVEL" = "DEBUG" ]; then + echo -e "${BLUE}${log_entry}${NC}" >&2 + fi + ;; + INFO) + echo -e "${GREEN}${log_entry}${NC}" >&2 + ;; + WARN) + echo -e "${YELLOW}${log_entry}${NC}" >&2 + ;; + ERROR) + echo -e "${RED}${log_entry}${NC}" >&2 + ;; + esac + + if [ -n "$LOG_FILE" ] && [ -f "$LOG_FILE" ]; then + echo "${log_entry}" >> "$LOG_FILE" + fi +} + +# Fonction d'aide +show_help() { + cat << EOF +MD_to_Print v${VERSION} - Conversion Markdown → PDF → Impression + +Usage: $0 fichier.md [OPTIONS] + +OPTIONS: + -p, --preview Prévisualiser le PDF avant impression + -P, --printer NOM Spécifier l'imprimante + -c, --copies N Nombre de copies (défaut: 1) + -r, --pages RANGE Pages à imprimer (ex: 1-3,5,7-9) + -o, --orientation DIR Orientation: portrait ou landscape (défaut: portrait) + -s, --size SIZE Taille: A4, A3, Letter, etc. (défaut: A4) + -q, --quality QUALITY Qualité: draft, normal, high (défaut: normal) + -C, --color Impression en couleur + -d, --duplex MODE Mode recto-verso: none, simplex, duplex (défaut: none) + -i, --install-deps Installer les dépendances automatiquement + -k, --keep-pdf Conserver le fichier PDF après impression + --config FILE Fichier de configuration + -v, --verbose Mode verbeux (logging DEBUG) + -l, --log FILE Fichier de log + -h, --help Afficher cette aide + --version Afficher la version + +EXEMPLES: + $0 document.md --preview + $0 document.md --printer HP_LaserJet --copies 2 --color + $0 document.md --pages 1-5 --orientation landscape + $0 document.md --duplex duplex --quality high --config myconfig.conf + +CONFIGURATION: + Le fichier de configuration utilise le format INI avec les sections: + [default], [paths], [logging] + Voir config.example.conf pour un exemple. + +CODES DE RETOUR: + 0 : Succès + 1 : Erreur générale + 2 : Fichier introuvable + 3 : Dépendances manquantes + 4 : Erreur conversion PDF + 5 : Erreur impression + 6 : Erreur configuration + 7 : Erreur Docker + 8 : Permissions insuffisantes + 9 : Argument invalide + 10 : Imprimante non disponible +EOF +} + +# Fonction de chargement de configuration +load_config() { + local config_path="$1" + + if [ ! -f "$config_path" ]; then + log ERROR "Fichier de configuration introuvable: $config_path" + return $EXIT_CONFIG_ERROR + fi + + log INFO "Chargement de la configuration depuis: $config_path" + + while IFS='=' read -r key value || [ -n "$key" ]; do + # Ignorer les commentaires et lignes vides + [[ "$key" =~ ^[[:space:]]*# ]] && continue + [[ -z "${key// }" ]] && continue + + # Supprimer les espaces + key=$(echo "$key" | tr -d '[:space:]') + value=$(echo "$value" | tr -d '[:space:]') + + case "$key" in + printer) + [ -z "$PRINTER" ] && PRINTER="$value" + ;; + copies) + [ "$COPIES" = 1 ] && COPIES="$value" + ;; + orientation) + [ "$ORIENTATION" = "portrait" ] && ORIENTATION="$value" + ;; + size) + [ "$SIZE" = "A4" ] && SIZE="$value" + ;; + quality) + [ "$QUALITY" = "normal" ] && QUALITY="$value" + ;; + color) + [ "$COLOR" = false ] && COLOR=$( [ "$value" = "true" ] && echo true || echo false ) + ;; + duplex) + [ "$DUPLEX" = "none" ] && DUPLEX="$value" + ;; + preview) + [ "$PREVIEW" = false ] && PREVIEW=$( [ "$value" = "true" ] && echo true || echo false ) + ;; + keep_pdf) + [ "$KEEP_PDF" = false ] && KEEP_PDF=$( [ "$value" = "true" ] && echo true || echo false ) + ;; + output_dir) + OUTPUT_DIR="$value" + ;; + log_dir) + LOG_DIR="$value" + ;; + level) + LOG_LEVEL="$value" + ;; + file) + [ -z "$LOG_FILE" ] && LOG_FILE="$LOG_DIR/$value" + ;; + verbose) + [ "$VERBOSE" = false ] && VERBOSE=$( [ "$value" = "true" ] && echo true || echo false ) + ;; + esac + done < <(grep -v '^\[' "$config_path" | grep -v '^[[:space:]]*$') + + log INFO "Configuration chargée avec succès" + return $EXIT_SUCCESS +} + +# Fonction d'installation des dépendances +install_dependencies() { + log INFO "Vérification et installation des dépendances..." + + if ! command -v apt-get &> /dev/null; then + log ERROR "apt-get non disponible. Installation manuelle requise." + return $EXIT_DEPS_MISSING + fi + + log INFO "Mise à jour de la liste des paquets..." + if ! sudo apt-get update -qq; then + log ERROR "Échec de la mise à jour des paquets" + return $EXIT_DEPS_MISSING + fi + + local deps_to_install=() + + if ! command -v pandoc &> /dev/null; then + deps_to_install+=("pandoc") + fi + + if ! command -v pdflatex &> /dev/null; then + deps_to_install+=("texlive-latex-base" "texlive-fonts-recommended" "texlive-latex-extra") + fi + + if ! command -v lp &> /dev/null; then + deps_to_install+=("cups") + fi + + if [ ${#deps_to_install[@]} -gt 0 ]; then + log INFO "Installation: ${deps_to_install[*]}" + if ! sudo apt-get install -y "${deps_to_install[@]}"; then + log ERROR "Échec de l'installation des dépendances" + return $EXIT_DEPS_MISSING + fi + log INFO "Dépendances installées avec succès" + else + log INFO "Toutes les dépendances sont déjà installées" + fi + + return $EXIT_SUCCESS +} + +# Fonction de vérification des dépendances +check_dependencies() { + local missing_deps=() + + if ! command -v pandoc &> /dev/null; then + missing_deps+=("pandoc") + fi + + if ! command -v pdflatex &> /dev/null; then + missing_deps+=("texlive-latex-base") + fi + + if ! command -v lp &> /dev/null; then + missing_deps+=("cups") + fi + + if [ ${#missing_deps[@]} -gt 0 ]; then + log ERROR "Dépendances manquantes: ${missing_deps[*]}" + log INFO "Utilisez l'option --install-deps pour installer automatiquement" + return $EXIT_DEPS_MISSING + fi + + return $EXIT_SUCCESS +} + +# Fonction de prévisualisation +preview_pdf() { + local pdf_file="$1" + + if [ ! -f "$pdf_file" ]; then + log ERROR "Fichier PDF introuvable pour prévisualisation: $pdf_file" + return $EXIT_FILE_NOT_FOUND + fi + + log INFO "Ouverture de la prévisualisation..." + + if command -v evince &> /dev/null; then + evince "$pdf_file" 2>/dev/null & + log DEBUG "Utilisation de evince pour la prévisualisation" + elif command -v okular &> /dev/null; then + okular "$pdf_file" 2>/dev/null & + log DEBUG "Utilisation de okular pour la prévisualisation" + elif command -v xdg-open &> /dev/null; then + xdg-open "$pdf_file" 2>/dev/null & + log DEBUG "Utilisation de xdg-open pour la prévisualisation" + else + log WARN "Aucun visualiseur PDF trouvé. Installation recommandée: evince ou okular" + return $EXIT_DEPS_MISSING + fi + + log INFO "Appuyez sur Entrée pour continuer avec l'impression..." + read -r + return $EXIT_SUCCESS +} + +# Fonction de liste des imprimantes +list_printers() { + log INFO "Imprimantes disponibles:" + if command -v lpstat &> /dev/null; then + lpstat -p 2>/dev/null | grep -E "^printer" | awk '{print " - " $2}' || log WARN "Aucune imprimante trouvée" + else + log WARN "lpstat non disponible, impossible de lister les imprimantes" + fi +} + +# Fonction de validation de l'imprimante +check_printer() { + local printer_name="$1" + + if [ -z "$printer_name" ]; then + return $EXIT_SUCCESS + fi + + if ! command -v lpstat &> /dev/null; then + log WARN "lpstat non disponible, impossible de vérifier l'imprimante" + return $EXIT_SUCCESS + fi + + if lpstat -p "$printer_name" &>/dev/null; then + log DEBUG "Imprimante '$printer_name' disponible" + return $EXIT_SUCCESS + else + log WARN "Imprimante '$printer_name' non disponible" + list_printers + return $EXIT_PRINTER_UNAVAILABLE + fi +} + +# Parsing des arguments +MD_FILE="" +ARGS=("$@") + +while [[ $# -gt 0 ]]; do + case $1 in + -p|--preview) + PREVIEW=true + shift + ;; + -P|--printer) + if [ -z "${2:-}" ]; then + log ERROR "Option --printer nécessite un argument" + exit $EXIT_INVALID_ARG + fi + PRINTER="$2" + shift 2 + ;; + -c|--copies) + if [ -z "${2:-}" ]; then + log ERROR "Option --copies nécessite un argument" + exit $EXIT_INVALID_ARG + fi + COPIES="$2" + shift 2 + ;; + -r|--pages) + if [ -z "${2:-}" ]; then + log ERROR "Option --pages nécessite un argument" + exit $EXIT_INVALID_ARG + fi + PAGES="$2" + shift 2 + ;; + -o|--orientation) + if [ -z "${2:-}" ]; then + log ERROR "Option --orientation nécessite un argument" + exit $EXIT_INVALID_ARG + fi + ORIENTATION="$2" + shift 2 + ;; + -s|--size) + if [ -z "${2:-}" ]; then + log ERROR "Option --size nécessite un argument" + exit $EXIT_INVALID_ARG + fi + SIZE="$2" + shift 2 + ;; + -q|--quality) + if [ -z "${2:-}" ]; then + log ERROR "Option --quality nécessite un argument" + exit $EXIT_INVALID_ARG + fi + QUALITY="$2" + shift 2 + ;; + -C|--color) + COLOR=true + shift + ;; + -d|--duplex) + if [ -z "${2:-}" ]; then + log ERROR "Option --duplex nécessite un argument" + exit $EXIT_INVALID_ARG + fi + DUPLEX="$2" + shift 2 + ;; + -i|--install-deps) + INSTALL_DEPS=true + shift + ;; + -k|--keep-pdf) + KEEP_PDF=true + shift + ;; + --config) + if [ -z "${2:-}" ]; then + log ERROR "Option --config nécessite un argument" + exit $EXIT_INVALID_ARG + fi + CONFIG_FILE="$2" + shift 2 + ;; + -v|--verbose) + VERBOSE=true + LOG_LEVEL="DEBUG" + shift + ;; + -l|--log) + if [ -z "${2:-}" ]; then + log ERROR "Option --log nécessite un argument" + exit $EXIT_INVALID_ARG + fi + LOG_FILE="$2" + shift 2 + ;; + -h|--help) + show_help + exit $EXIT_SUCCESS + ;; + --version) + echo "MD_to_Print v${VERSION}" + exit $EXIT_SUCCESS + ;; + -*) + log ERROR "Option inconnue: $1" + show_help + exit $EXIT_INVALID_ARG + ;; + *) + if [ -z "$MD_FILE" ]; then + MD_FILE="$1" + else + log ERROR "Trop de fichiers spécifiés: $MD_FILE et $1" + exit $EXIT_INVALID_ARG + fi + shift + ;; + esac +done + +# Vérification du fichier markdown +if [ -z "$MD_FILE" ]; then + log ERROR "Aucun fichier markdown spécifié" + show_help + exit $EXIT_INVALID_ARG +fi + +# Résolution du chemin absolu +if [[ "$MD_FILE" != /* ]]; then + MD_FILE="$(realpath "$MD_FILE" 2>/dev/null || echo "$MD_FILE")" +fi + +if [ ! -f "$MD_FILE" ]; then + log ERROR "Le fichier '$MD_FILE' n'existe pas" + exit $EXIT_FILE_NOT_FOUND +fi + +# Vérification des permissions de lecture +if [ ! -r "$MD_FILE" ]; then + log ERROR "Permission de lecture refusée pour '$MD_FILE'" + exit $EXIT_PERMISSIONS +fi + +# Création des répertoires nécessaires +mkdir -p "$OUTPUT_DIR" "$LOG_DIR" + +# Initialisation du fichier de log si spécifié +if [ -n "$LOG_FILE" ]; then + mkdir -p "$(dirname "$LOG_FILE")" + touch "$LOG_FILE" +fi + +# Chargement de la configuration si spécifiée +if [ -n "$CONFIG_FILE" ]; then + if ! load_config "$CONFIG_FILE"; then + exit $EXIT_CONFIG_ERROR + fi +elif [ -f "$SCRIPT_DIR/config.conf" ]; then + log DEBUG "Chargement de la configuration par défaut: $SCRIPT_DIR/config.conf" + load_config "$SCRIPT_DIR/config.conf" || true +fi + +# Installation des dépendances si demandée +if [ "$INSTALL_DEPS" = true ]; then + if ! install_dependencies; then + exit $EXIT_DEPS_MISSING + fi +fi + +# Vérification des dépendances +if ! check_dependencies; then + exit $EXIT_DEPS_MISSING +fi + +# Génération du nom du fichier PDF +MD_BASENAME=$(basename "$MD_FILE" .md) +PDF_FILE="$OUTPUT_DIR/${MD_BASENAME}.pdf" + +log INFO "=== Conversion Markdown → PDF ===" +log INFO "Fichier source: $MD_FILE" +log INFO "Fichier PDF: $PDF_FILE" + +# Conversion Markdown → PDF avec options +# Détection du moteur PDF disponible (xelatex gère mieux Unicode) +PDF_ENGINE="pdflatex" +if command -v xelatex &> /dev/null; then + PDF_ENGINE="xelatex" + log DEBUG "Utilisation de xelatex pour meilleure gestion Unicode" +fi + +PANDOC_OPTS=( + "$MD_FILE" + -o "$PDF_FILE" + --pdf-engine="$PDF_ENGINE" + -V geometry:margin=2cm + -V fontsize=11pt + -V documentclass=article + -V papersize="$SIZE" +) + +# Options spécifiques pour xelatex (meilleure gestion Unicode) +if [ "$PDF_ENGINE" = "xelatex" ]; then + PANDOC_OPTS+=( + -V mainfont="DejaVu Sans" + -V monofont="DejaVu Sans Mono" + ) +fi + +if [ "$ORIENTATION" = "landscape" ]; then + PANDOC_OPTS+=(-V geometry:landscape) +fi + +log DEBUG "Exécution: pandoc ${PANDOC_OPTS[*]}" + +if ! pandoc "${PANDOC_OPTS[@]}" 2>&1 | while IFS= read -r line; do log DEBUG "$line"; done; then + log ERROR "Erreur lors de la conversion en PDF" + exit $EXIT_PDF_CONVERSION +fi + +if [ ! -f "$PDF_FILE" ]; then + log ERROR "Le fichier PDF n'a pas été créé" + exit $EXIT_PDF_CONVERSION +fi + +log INFO "PDF créé avec succès: $PDF_FILE" + +# Vérification de l'imprimante si spécifiée +if [ -n "$PRINTER" ]; then + if ! check_printer "$PRINTER"; then + log WARN "Tentative d'utilisation de l'imprimante par défaut" + PRINTER="" + fi +fi + +# Prévisualisation si demandée +if [ "$PREVIEW" = true ]; then + if ! preview_pdf "$PDF_FILE"; then + log WARN "Échec de la prévisualisation, continuation avec l'impression" + fi +fi + +# Préparation des options d'impression +LP_OPTS=() + +if [ -n "$PRINTER" ]; then + LP_OPTS+=(-d "$PRINTER") +else + log INFO "Utilisation de l'imprimante par défaut" + list_printers +fi + +LP_OPTS+=(-n "$COPIES") + +if [ -n "$PAGES" ]; then + LP_OPTS+=(-o page-ranges="$PAGES") +fi + +if [ "$ORIENTATION" = "landscape" ]; then + LP_OPTS+=(-o orientation-requested=4) +fi + +LP_OPTS+=(-o media="$SIZE") + +case "$QUALITY" in + draft) + LP_OPTS+=(-o print-quality=3) + ;; + high) + LP_OPTS+=(-o print-quality=5) + ;; + *) + LP_OPTS+=(-o print-quality=4) + ;; +esac + +if [ "$COLOR" = true ]; then + LP_OPTS+=(-o ColorMode=Color) +else + LP_OPTS+=(-o ColorMode=Monochrome) +fi + +case "$DUPLEX" in + simplex) + LP_OPTS+=(-o sides=one-sided) + ;; + duplex) + LP_OPTS+=(-o sides=two-sided-long-edge) + ;; + *) + LP_OPTS+=(-o sides=one-sided) + ;; +esac + +# Impression +log INFO "=== Impression ===" +log INFO "Options:" +log INFO " - Copies: $COPIES" +log INFO " - Taille: $SIZE" +log INFO " - Orientation: $ORIENTATION" +log INFO " - Qualité: $QUALITY" +log INFO " - Couleur: $([ "$COLOR" = true ] && echo "Oui" || echo "Non")" +log INFO " - Recto-verso: $DUPLEX" +[ -n "$PAGES" ] && log INFO " - Pages: $PAGES" +[ -n "$PRINTER" ] && log INFO " - Imprimante: $PRINTER" + +log DEBUG "Exécution: lp ${LP_OPTS[*]} $PDF_FILE" + +if ! lp "${LP_OPTS[@]}" "$PDF_FILE" 2>&1 | while IFS= read -r line; do log DEBUG "$line"; done; then + log ERROR "Erreur lors de l'impression" + log INFO "Le fichier PDF a été conservé: $PDF_FILE" + exit $EXIT_PRINT_ERROR +fi + +log INFO "Impression lancée avec succès!" + +# Gestion du fichier PDF +if [ "$KEEP_PDF" = false ]; then + read -p "Supprimer le fichier PDF temporaire? (o/N): " -n 1 -r + echo + if [[ $REPLY =~ ^[Oo]$ ]]; then + rm "$PDF_FILE" + log INFO "Fichier PDF supprimé" + else + log INFO "Fichier PDF conservé: $PDF_FILE" + fi +else + log INFO "Fichier PDF conservé: $PDF_FILE" +fi + +log INFO "=== Opération terminée avec succès ===" +exit $EXIT_SUCCESS +