refactor: conformité conventions Linux FHS/XDG
- man pages déplacées dans local/share/man/man1/ (man cherche dans man<section>/) - docs déplacées dans local/share/doc/scripts-bash/ (un sous-dossier par package) - old-bin/ supprimé (fichiers obsolètes → historique git) - .config/prep.sh parasite supprimé - 'liste des scripts.base' renommé en 'liste-des-scripts.base' (pas d'espace) - prep.sh et install.sh mis à jour pour les nouveaux chemins
This commit is contained in:
@@ -1,13 +1,11 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
/**
|
||||
* Audit de dérive des configurations PHP
|
||||
* Nettoyeur de surcharge de configuration PHP
|
||||
* Supprime les entrées locales identiques aux originales.
|
||||
* Copyright (C) 2026 Cédric Abonnel
|
||||
* License: GNU Affero General Public License v3
|
||||
*/
|
||||
|
||||
// --- Initialisation & Sécurité ---
|
||||
|
||||
if (posix_getuid() !== 0) {
|
||||
fwrite(STDERR, "Ce script doit être exécuté en root.\n");
|
||||
exit(1);
|
||||
@@ -16,89 +14,76 @@ if (posix_getuid() !== 0) {
|
||||
const CONF_DIR = '/opt/monitoring/conf';
|
||||
|
||||
/**
|
||||
* Extrait les clés d'un fichier de configuration PHP (tableau return [])
|
||||
* sans exécuter le fichier pour éviter les effets de bord, via Regex.
|
||||
* Logique d'affichage
|
||||
*/
|
||||
function extract_keys($file) {
|
||||
$content = file_get_contents($file);
|
||||
// On cherche les patterns : 'KEY' => ou "KEY" =>
|
||||
preg_match_all('/[\'"]([A-Z0-9_]+)[\'"]\s*=>/i', $content, $matches);
|
||||
$keys = $matches[1] ?? [];
|
||||
sort($keys);
|
||||
return array_unique($keys);
|
||||
function log_clean($level, $msg) {
|
||||
$color = ['info' => '34', 'notice' => '32', 'warn' => '33', 'err' => '31'][$level] ?? '37';
|
||||
echo sprintf("\e[%sm[%s]\e[0m %s\n", $color, strtoupper($level), $msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logique de logging
|
||||
* Nettoie un fichier local en comparant ses valeurs avec la base
|
||||
*/
|
||||
function log_audit($level, $event, $msg) {
|
||||
echo sprintf("[%s] %s: %s\n", strtoupper($level), $event, $msg);
|
||||
}
|
||||
function clean_local_config($base_file, $local_file) {
|
||||
// On inclut les fichiers pour récupérer les tableaux de config
|
||||
$base_cfg = include $base_file;
|
||||
$local_cfg = include $local_file;
|
||||
|
||||
function check_config_drift() {
|
||||
$found_issue = false;
|
||||
$reviewed_files = 0;
|
||||
$files_requiring_action = 0;
|
||||
if (!is_array($base_cfg) || !is_array($local_cfg)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
log_audit('info', 'audit_start', "Début de l'audit des configurations PHP");
|
||||
$new_local_cfg = $local_cfg;
|
||||
$removed_keys = [];
|
||||
|
||||
// On cherche les fichiers .php qui ne sont pas des .local.php
|
||||
$base_files = glob(CONF_DIR . '/*.php');
|
||||
$base_files = array_filter($base_files, function($f) {
|
||||
return !str_ends_with($f, '.local.php');
|
||||
});
|
||||
|
||||
foreach ($base_files as $base_conf) {
|
||||
$reviewed_files++;
|
||||
$base_name = basename($base_conf);
|
||||
$local_conf = str_replace('.php', '.local.php', $base_conf);
|
||||
$local_name = basename($local_conf);
|
||||
|
||||
// 1. Si le fichier local n'existe pas
|
||||
if (!file_exists($local_conf)) {
|
||||
if (copy($base_conf, $local_conf)) {
|
||||
chmod($local_conf, 0600);
|
||||
log_audit('notice', 'audit_missing_local', "Le fichier $local_name a été créé par copie de $base_name");
|
||||
} else {
|
||||
log_audit('error', 'audit_create_local_failed', "Impossible de créer $local_name");
|
||||
$found_issue = true;
|
||||
$files_requiring_action++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// 2. Comparaison des clés
|
||||
$keys_base = extract_keys($base_conf);
|
||||
$keys_local = extract_keys($local_conf);
|
||||
|
||||
$missing = array_diff($keys_base, $keys_local); // Présent dans base mais pas local
|
||||
$obsolete = array_diff($keys_local, $keys_base); // Présent dans local mais plus dans base
|
||||
|
||||
if (!empty($missing) || !empty($obsolete)) {
|
||||
$found_issue = true;
|
||||
$files_requiring_action++;
|
||||
|
||||
log_audit('warning', 'audit_file_requires_action', "Vérification requise pour $local_name");
|
||||
|
||||
if (!empty($missing)) {
|
||||
log_audit('warning', 'audit_keys_missing', "Options absentes de $local_name : " . implode(', ', $missing));
|
||||
}
|
||||
|
||||
if (!empty($obsolete)) {
|
||||
log_audit('info', 'audit_keys_obsolete', "Options obsolètes ou personnalisées dans $local_name : " . implode(', ', $obsolete));
|
||||
}
|
||||
} else {
|
||||
log_audit('info', 'audit_file_ok', "Le fichier $local_name est synchronisé avec $base_name");
|
||||
foreach ($local_cfg as $key => $value) {
|
||||
// Si la clé existe en base ET que la valeur est strictement identique
|
||||
if (array_key_exists($key, $base_cfg) && $base_cfg[$key] === $value) {
|
||||
unset($new_local_cfg[$key]);
|
||||
$removed_keys[] = $key;
|
||||
}
|
||||
}
|
||||
|
||||
// Résumé final
|
||||
if (!$found_issue) {
|
||||
log_audit('info', 'audit_success', "Toutes les configurations sont à jour ($reviewed_files fichiers vérifiés)");
|
||||
} else {
|
||||
log_audit('warning', 'audit_requires_action', "Action requise sur $files_requiring_action fichier(s) sur $reviewed_files");
|
||||
if (empty($removed_keys)) {
|
||||
log_clean('info', basename($local_file) . " est déjà optimisé.");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Reconstruction du fichier PHP proprement
|
||||
$content = "<?php\n/**\n * Configuration locale personnalisée\n * Généré par l'audit de nettoyage\n */\n\nreturn [\n";
|
||||
foreach ($new_local_cfg as $key => $value) {
|
||||
$val_export = var_export($value, true);
|
||||
$content .= " '$key' => $val_export,\n";
|
||||
}
|
||||
$content .= "];\n";
|
||||
|
||||
if (file_put_contents($local_file, $content)) {
|
||||
log_clean('notice', basename($local_file) . " nettoyé. Clés supprimées (identiques à la base) : " . implode(', ', $removed_keys));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// --- Main ---
|
||||
check_config_drift();
|
||||
|
||||
log_clean('info', "Début de l'optimisation des configurations locales...");
|
||||
|
||||
$base_files = glob(CONF_DIR . '/*.php');
|
||||
foreach ($base_files as $base_conf) {
|
||||
// On ignore les fichiers .local.php et .conf.local.php
|
||||
if (str_contains($base_conf, '.local.')) continue;
|
||||
|
||||
// Détermination du nom du fichier local correspondant
|
||||
// Gère tes deux formats : monitoring.local.conf.php et alert-engine.conf.local.php
|
||||
$local_conf = str_replace('.conf.php', '.conf.local.php', $base_conf);
|
||||
if (!file_exists($local_conf)) {
|
||||
$local_conf = str_replace('.php', '.local.php', $base_conf);
|
||||
}
|
||||
|
||||
if (file_exists($local_conf)) {
|
||||
clean_local_config($base_conf, $local_conf);
|
||||
}
|
||||
}
|
||||
|
||||
log_clean('info', "Optimisation terminée.");
|
||||
Reference in New Issue
Block a user