Files
Web-Infra-Reports-IT/include/all.php
sva-e025532 c185d099d6 Add VIO FC Status monitoring page and enhance server inventory filtering
- Introduced `Storage/VIO.php` for monitoring VIO Fibre Channel status with client balancing checks and table sorting.
- Updated `/include/en.php` and `/include/fr.php` to include new translations for ServiceNow and VIO-related navigation elements.
- Improved SQL query and filtering logic in `/X/Inventory.php` to exclude VIO entries and add XenSam version data.
- Enhanced `/reports/heartbeat.php` with a new mechanism for handling server heartbeat status, allowing better granularity and readability.
2026-09-14 10:32:15 +02:00

661 lines
19 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
// LANGUAGE MANAGEMENT
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
$lang = $_GET['lang'] ?? $_SESSION['lang'] ?? 'fr'; // "en" as default
$allowed_langs = ['en', 'fr'];
if (!in_array($lang, $allowed_langs)) {
$lang = 'fr'; // DEFAULT failback
}
$_SESSION['lang'] = $lang;
include $_SERVER['DOCUMENT_ROOT'] . "/include/" . $lang . ".php";
// CONSTANTS //
$BaseUrl = "https://".$_SERVER['SERVER_NAME'];
$root = $_SERVER['DOCUMENT_ROOT'];
$bdnuss = "http://web-bdnuss-sys-dev.appliarmony.net";
$opwsinf = "https://wsopinf.appliarmony.net";
// FUNCTIONS //
//tools//
function decypher(string $name): ?string {
$openssl = 'C:\Program Files\FireDaemon OpenSSL 3\bin\openssl.exe';
$cmsFile = "F:\\Include\\dat\\$name.p7m";
$certPem = "F:\\Include\\certs\\cert_only.pem";
$keyPem = "F:\\Include\\certs\\key_only.pem";
foreach ([$openssl,$cmsFile,$certPem,$keyPem] as $p) {
if (!is_file($p)) { error_log("Missing file: $p"); return null; }
}
$cmd = '"' . $openssl . '" cms -decrypt -inform PEM'
. ' -in ' . escapeshellarg($cmsFile)
. ' -recip ' . escapeshellarg($certPem)
. ' -inkey ' . escapeshellarg($keyPem)
. ' -out -';
$spec = [
0 => ['pipe','r'], // stdin (unused)
1 => ['pipe','w'], // stdout -> texte déchiffré
2 => ['pipe','w'], // stderr -> erreurs OpenSSL
];
$proc = proc_open($cmd, $spec, $pipes);
if (!is_resource($proc)) { error_log('proc_open failed'); return null; }
fclose($pipes[0]); // rien à envoyer en stdin
$stdout = stream_get_contents($pipes[1]); fclose($pipes[1]);
$stderr = stream_get_contents($pipes[2]); fclose($pipes[2]);
$code = proc_close($proc);
if ($code !== 0) {
error_log("OpenSSL failed (code $code): $stderr");
return null;
}
return $stdout;
}
function PostJson($url, $content){
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-type: application/json"));
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $content);
$retour = curl_exec($curl);
curl_close($curl);
return $retour;
}
//invoke//
function Invoke_Infra($request)
{
error_reporting(E_ALL ^ E_WARNING);
$user = "INFRA_dbo";
$pwd = decypher("infra");
$server = "DUN-PRD-R1MSSQL.armony.net\PRD";
$database = "INFRA";
$conn = odbc_connect("Driver={SQL Server};Server=$server;Database=$database;", $user, $pwd);
if (!($conn)) {
echo "Pas de connexion";
}
$rs = odbc_exec($conn, $request);
if (str_contains(strtoupper($request), "SELECT")) {
while ($row = odbc_fetch_array($rs)) {
$answer[] = $row;
}
}
if (isset($answer)) {
return $answer;
} else {
if ($rs) {
return "OK";
} else {
error_reporting(E_ALL);
return "ERROR : " . odbc_errormsg($conn);
}
}
}
function Invoke_Infra_long($request)
{
error_reporting(E_ALL ^ E_WARNING);
$user = "INFRA_dbo";
$pwd = decypher("infra");
$server = "DUN-PRD-R1MSSQL.armony.net\PRD";
$database = "INFRA";
$conn = odbc_connect("Driver={ODBC Driver 18 for SQL Server};Server=$server;Database=$database;TrustServerCertificate=yes;", $user, $pwd);
if (!($conn)) {
echo "Pas de connexion";
}
$rs = odbc_exec($conn, $request);
odbc_longreadlen($rs, 1048576); // 1 Mo, large devant tes 289 Ko max
if (str_contains(strtoupper($request), "SELECT")) {
while ($row = odbc_fetch_array($rs)) {
$answer[] = $row;
}
}
if (isset($answer)) {
return $answer;
} else {
if ($rs) {
return "OK";
} else {
error_reporting(E_ALL);
return "ERROR : " . odbc_errormsg($conn);
}
}
}
function Invoke_WebSelfInfra($request)
{
$user = "Scom-Write";
$pwd = decypher("web-self-infra");
$server = "DUN-PRD-R1SCOM.armony.net\OPS";
$database = "web-self-infra";
$conn = odbc_connect("Driver={SQL Server};Server=$server;Database=$database;", $user, $pwd);
if (!($conn)) {
echo "Pas de connexion";
}
$rs = odbc_exec($conn, $request);
if (str_contains(strtoupper($request), "SELECT")) {
while ($row = odbc_fetch_array($rs)) {
$answer[] = $row;
}
}
return $answer ?? null;
}
function Invoke_WebInfraReports($request)
{
$user = "admin";
$pwd = decypher("web-infra-reports");
$server = "dun-sup-s2entry.armony.net:3306";
$database = "web-infra-reports";
$conn = new mysqli($server, $user, $pwd, $database);
$rs = $conn->query($request);
while ($row = mysqli_fetch_array($rs)) {
$answer[] = $row;
}
return $answer ?? null;
}
function Invoke_SCOMInfra($request)
{
$user = "Scom-Write";
$pwd = decypher("ScomInfra");
$server = "DUN-PRD-R1SCOM.armony.net\OPS";
$database = "infra";
$conn = odbc_connect("Driver={SQL Server};Server=$server;Database=$database;", $user, $pwd);
if (!($conn)) {
echo "Pas de connexion";
}
$rs = odbc_exec($conn, $request);
if (str_contains(strtoupper($request), "SELECT")) {
while ($row = odbc_fetch_array($rs)) {
$answer[] = $row;
}
}
return $answer ?? null;
}
function Invoke_Entry01($request)
{
$user = "infra";
$pwd = decypher("entry01");
$server = "dun-sup-entry01:3306";
$database = "infra";
$conn = new mysqli($server, $user, $pwd, $database);
$rs = $conn->query($request);
while ($row = mysqli_fetch_array($rs)) {
$answer[] = $row;
}
return $answer ?? null;
}
function Invoke_WebInfraTools($request)
{
$user = "admin";
$pwd = decypher("web-infra-tools");
$server = "dun-sup-s2entry.armony.net:3306";
$database = "webinfratools";
$conn = new mysqli($server, $user, $pwd, $database);
$rs = $conn->query($request);
while ($row = mysqli_fetch_array($rs)) {
$answer[] = $row;
}
return $answer ?? null;
}
function Invoke_GLPI($request)
{
$user="glpi_lect_seule";
$pwd=decypher("glpi");
$server="mys_glpi_prod.appliarmony.net";
$database="glpi";
$conn = new mysqli($server, $user, $pwd, $database);
$rs = $conn->query($request);
while ($row = mysqli_fetch_array($rs)) {
$answer[] = $row;
}
return $answer ?? null;
}
function Invoke_aixcmdb($request)
{
$conn_string = "DRIVER={IBM DB2 ODBC DRIVER - F_DB2_clidriver};" .
"DATABASE=AIXCMDB; " .
"HOSTNAME=db2_aixcmdb.appliarmony.net;" .
"PORT=50000; " .
"PROTOCOL=TCPIP; " .
"UID=aixcmdb;" .
"AUTHENTICATION=SERVER;" .
"PWD=".decypher('aixcmdb').";";
$conn = odbc_connect($conn_string, "", "");
if (!$conn) {
$error_message = "ODBC Connect Error: " . odbc_errormsg() . " (" . odbc_error() . ")";
echo "Pas de connexion : " . $error_message . "<br>";
return "ERROR: Could not connect to DB2. Check connection string and ODBC setup.";
}
$rs = odbc_exec($conn, $request);
if (str_contains(strtoupper($request), "SELECT")) {
$answer = [];
while ($row = odbc_fetch_array($rs)) {
$answer[] = $row;
}
}
if (isset($answer)) {
return $answer;
} else {
if ($rs) {
return "OK";
} else {
error_reporting(E_ALL);
return "ERROR : " . odbc_errormsg($conn);
}
}
}
function Invoke_Arrets($request)
{
error_reporting(E_ALL ^ E_WARNING);
$user = "kpiamf_arrets_view";
$pwd = decypher("arrets");
$server = "SQL_DW_PRD_KPIAMF.appliarmony.net";
$database = "KPIAMF";
$conn = odbc_connect("Driver={SQL Server};Server=$server;Database=$database;", $user, $pwd);
if (!($conn)) {
echo "Pas de connexion";
}
$rs = odbc_exec($conn, $request);
if (str_contains(strtoupper($request), "SELECT")) {
while ($row = odbc_fetch_array($rs)) {
$answer[] = $row;
}
}
if (isset($answer)) {
return $answer;
} else {
if ($rs) {
return "OK";
} else {
error_reporting(E_ALL);
return "ERROR : " . odbc_errormsg($conn);
}
}
}
function Invoke_RH($request)
{
error_reporting(E_ALL ^ E_WARNING);
$user = "hrdata_mgr_view";
$pwd = decypher("rh");
$server = "SQL_DW_PRD_HRDATA.appliarmony.net";
$database = "HRDATA";
$conn = odbc_connect("Driver={SQL Server};Server=$server;Database=$database;", $user, $pwd);
if (!($conn)) {
echo "Pas de connexion";
}
$rs = odbc_exec($conn, $request);
if (str_contains(strtoupper($request), "SELECT")) {
while ($row = odbc_fetch_array($rs)) {
$answer[] = $row;
}
}
if (isset($answer)) {
return $answer;
} else {
if ($rs) {
return "OK";
} else {
error_reporting(E_ALL);
return "ERROR : " . odbc_errormsg($conn);
}
}
}
//DB Conn//
function DB_SCCM(){
$user = "infra";
$pwd = decypher("SCCM");
$conn = odbc_connect("Driver={SQL Server};Server=DUN-SMS-SRV01;Database=CM_SV1;", $user, $pwd);
return $conn;
}
function DB_GLPI() {
$username="glpi_lect_seule";
$password=decypher( "glpi");
$dbserver="mys_glpi_prod.appliarmony.net";
$database="glpi";
$conn = new mysqli($dbserver,$username,$password,$database);
return $conn;
}
function DB_ENTRY01() {
$username="infra";
$password=decypher("entry01");
$dbserver="dun-sup-entry01.armony.net";
$database="infra";
$conn = new mysqli($dbserver,$username,$password,$database);
return $conn;
}
function DB_ENTRY02() {
$username="admin";
$password=decypher("web-infra-reports");
$dbserver="dun-sup-s2entry.armony.net";
$database="web-infra-reports";
$conn = new mysqli($dbserver,$username,$password,$database);
return $conn ;
}
function DB_INFRA() {
$user="INFRA_dbo";
$pwd=decypher("infra");
$server="DUN-PRD-R1MSSQL.armony.net\PRD";
$database="INFRA";
$conn = odbc_connect("Driver={SQL Server};Server=$server;Database=$database;", $user, $pwd);
return $conn ;
}
function DB_ZABBIX()
{
$host = 'aztprdzabbix52.armony.net';
$dbname = 'zabbix';
$user = 'patrick';
$pass = decypher( 'zabbix');
$pdo = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
return $pdo;
}
//Cookie//
function Set_Cookie() {
// --- paramètres ---
$cookieName = 'UserInfo';
$cookieLife = 86400 * 365; // 1 an
$cookieDomain = '.appliarmony.net';
$secureFlag = true;
$httpOnly = true;
$sameSite = 'Lax';
// --- helpers ---
$now = date('Y-m-d H:i:s');
// IP client: XFF (première IP) -> fallback REMOTE_ADDR
$ip = '';
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$parts = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
$cand = trim($parts[0]);
if (filter_var($cand, FILTER_VALIDATE_IP)) $ip = $cand;
}
if (!$ip && !empty($_SERVER['REMOTE_ADDR'])) $ip = $_SERVER['REMOTE_ADDR'];
// User Windows (SSO)
$user = $_SERVER['REMOTE_USER'] ?? null;
$hasUser = !empty($user);
// --- lecture éventuelle du cookie existant ---
$cookie = [];
if (!empty($_COOKIE[$cookieName])) {
$decoded = json_decode($_COOKIE[$cookieName], true);
if (is_array($decoded)) $cookie = $decoded;
}
// --- écriture/MAJ SEULEMENT si on a un REMOTE_USER ---
if ($hasUser) {
if (empty($cookie) || ($cookie['user'] ?? null) !== $user) {
// Nouveau cookie ou changement d’utilisateur → reset
$cookie = [
'user' => $user,
'ip' => $ip,
'created' => $now,
'last' => $now
];
} else {
// Même user → on rafraîchit last + IP
$cookie['ip'] = $ip ?: ($cookie['ip'] ?? '');
$cookie['last'] = $now;
}
// Écrire le cookie (évite d’écrire si headers déjà envoyés)
if (!headers_sent()) {
setcookie($cookieName, json_encode($cookie), [
'expires' => time() + $cookieLife,
'path' => '/',
'domain' => $cookieDomain,
'secure' => $secureFlag,
'httponly' => $httpOnly,
'samesite' => $sameSite
]);
}
}
// --- exposer des constantes pour le reste du code ---
// Priorité: si on a REMOTE_USER, on l’utilise; sinon on retombe sur le cookie existant; sinon vide/anonyme.
$currentUser = $hasUser ? $user : ($cookie['user'] ?? 'Anonymous');
$currentIp = $hasUser ? $ip : ($cookie['ip'] ?? ($_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'] ?? ''));
if (!defined('CURRENT_USER')) define('CURRENT_USER', $currentUser);
if (!defined('CURRENT_IP')) define('CURRENT_IP', $currentIp);
if (!defined('COOKIE_INFO')) define('COOKIE_INFO', $cookie);
}
Set_Cookie();
?>
<style>
/* 1. CONFIGURATION DES COULEURS */
:root {
/* Par défaut (Mode Clair / bg-light) : Gris visible sur blanc */
--snow-color: rgba(160, 160, 160, 0.9);
}
/* 2. DÉTECTION DU MODE SOMBRE BASÉE SUR TON SCRIPT */
/* Ton script ajoute la classe 'bg-dark' au body, on s'en sert ici */
body.bg-dark {
--snow-color: rgba(255, 255, 255, 0.9) !important;
}
/* Gestion des préférences système (OS) au cas où le script JS n'a pas encore chargé */
@media (prefers-color-scheme: dark) {
body:not(.bg-light) { /* Sauf si l'utilisateur a forcé le mode clair */
--snow-color: rgba(255, 255, 255, 0.9);
}
}
/* 3. STYLES DU CANVAS ET DU BOUTON */
#snow-canvas {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 9999; /* Au-dessus de tout */
pointer-events: none; /* LAISSE PASSER LES CLICS (Vital !) */
}
#snow-toggle-btn {
position: fixed;
/* Positionné un peu au-dessus du bas pour ne pas gêner d'autres footers */
bottom: 20px;
right: 20px;
z-index: 10000;
background: transparent;
color: var(--snow-color); /* Le bouton prend aussi la couleur du thème */
border: 1px solid var(--snow-color);
border-radius: 50%;
width: 35px;
height: 35px;
cursor: pointer;
font-size: 18px;
transition: all 0.3s;
display: flex;
align-items: center;
justify-content: center;
opacity: 0.5; /* Discret par défaut */
}
#snow-toggle-btn:hover {
opacity: 1;
background: rgba(128, 128, 128, 0.2);
}
</style>
<!-- // SNOWFLAKES -->
<canvas id="snow-canvas"></canvas>
<button id="snow-toggle-btn" title="Activer/Désactiver la neige">❄️</button>
<script>
(function() {
// --- 1. GESTION DES DATES (15 Déc au 5 Jan) ---
const now = new Date();
const month = now.getMonth() + 1; // JS compte les mois de 0 à 11, donc on ajoute 1
const day = now.getDate();
// La condition : (Mois = 12 ET Jour >= 15) OU (Mois = 1 ET Jour ≤ 5)
const isSeason = (month === 12 && day >= 15) || (month === 1 && day <= 5);
const canvas = document.getElementById('snow-canvas');
const toggleBtn = document.getElementById('snow-toggle-btn');
// Si on n'est pas dans la période, on cache tout et on arrête le script.
if (!isSeason) {
if (canvas) canvas.style.display = 'none';
if (toggleBtn) toggleBtn.style.display = 'none';
return; // Arrêt immédiat du script
}
// --- 2. CONFIGURATION ---
const ctx = canvas.getContext('2d');
let width = window.innerWidth;
let height = window.innerHeight;
const maxFlakes = 80;
let flakes = [];
let animationId;
let isSnowing = false;
// Gestion du redimensionnement
canvas.width = width;
canvas.height = height;
window.addEventListener('resize', () => {
width = window.innerWidth;
height = window.innerHeight;
canvas.width = width;
canvas.height = height;
});
// --- 3. CLASSE FLOCON ---
class Snowflake {
constructor() {
this.reset(true);
}
reset(initial = false) {
this.x = Math.random() * width;
this.y = initial ? Math.random() * height : -10;
this.radius = Math.random() * 3 + 1;
this.speed = Math.random() * 1.5 + 0.5;
this.drift = Math.random() * 2 - 1;
}
update() {
this.y += this.speed;
this.x += this.drift;
if (this.y > height || this.x > width || this.x < 0) {
this.reset();
}
}
draw(color) {
ctx.beginPath();
ctx.fillStyle = color;
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true);
ctx.fill();
}
}
// --- 4. ANIMATION ---
function initFlakes() {
flakes = [];
for (let i = 0; i < maxFlakes; i++) {
flakes.push(new Snowflake());
}
}
function animate() {
if (!isSnowing) {
ctx.clearRect(0, 0, width, height);
return;
}
ctx.clearRect(0, 0, width, height);
// Récupération dynamique de la couleur (compatible avec ton script Light Switch)
const style = getComputedStyle(document.body);
const currentColor = style.getPropertyValue('--snow-color').trim();
flakes.forEach(flake => {
flake.update();
flake.draw(currentColor);
});
animationId = requestAnimationFrame(animate);
}
// --- 5. BOUTON & INIT ---
function toggleSnow() {
isSnowing = !isSnowing;
updateButtonState();
if (isSnowing) {
initFlakes();
animate();
localStorage.setItem('snow-preference', 'on');
} else {
cancelAnimationFrame(animationId);
ctx.clearRect(0, 0, width, height);
localStorage.setItem('snow-preference', 'off');
}
}
function updateButtonState() {
if(isSnowing) {
toggleBtn.style.opacity = "1";
toggleBtn.style.background = "rgba(128, 128, 128, 0.3)";
} else {
toggleBtn.style.opacity = "0.5";
toggleBtn.style.background = "transparent";
}
}
toggleBtn.addEventListener('click', toggleSnow);
const savedPref = localStorage.getItem('snow-preference');
if (savedPref !== 'off') {
isSnowing = true;
initFlakes();
animate();
updateButtonState();
}
})();
</script>
<!-- MODAL WAIT -->
<div class="modal fade bs-example-modal-sm" id="wait" tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="static" style="padding-top: 15%;">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title mb-1 text-dark text-uppercase">
<span class="text-center"><i class="bi bi-hourglass-split"></i><br> Work in progress ...</span>
</h4>
</div>
<div class="modal-body">
<div class="progress">
<div class="progress-bar progress-bar-secondary progress-bar-striped progress-bar-animated" style="width: 100%"></div>
</div>
</div>
</div>
</div>
</div>