- Deleted `test.php` as it was no longer in use. - Enhanced null safety checks in `Inventory.php`, `StdOut-detail.php`, `Backups.php`, and `SwitchsSAN.php` to prevent potential warnings. - Refactored `SwitchsSAN.php` to improve sorting logic for ports based on errors, vFabric, and Port ID. - Added seasonal snow effect script in `all.php` with toggle functionality for user engagement. - Updated navigation bar (`navbar.html`) to include a new VIO page link. - Introduced a new `VIO.php` page to display VIO monitoring details with table export and sorting features.
559 lines
16 KiB
PHP
559 lines
16 KiB
PHP
<?php
|
||
// CONSTANTS //
|
||
$BaseUrl = "http://".$_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_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);
|
||
}
|
||
}
|
||
}
|
||
|
||
//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>
|
||
|
||
<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>
|
||
|
||
|
||
|