Medulla's XML-RPC API.php

  
 <!-- IMORTANT
- Vérifier connectivité vers le serveur xmlrpc avec par exemple telnet 10.10.0.10 7080
- Vérification du ssl si pas présent l'importer cf procédure qui va venir
1. Récupérer par exemple le ceritifcat de spo ici /var/lib/pulse2/pki/ca-chain.cert.pem
2. Le copié sur le poste client ici /usr/local/share/ca-certificates/ca-certificates.crt
3. L'importer avec la commande sudo update-ca-certificates
-->

<!-- Gestion des appels XML-RPC -->
<?php
// Démarrage de la session
session_start();

// Stockage des données de connexion dans un tableau associatif
// 'scheme' : Protocole utilisé (https)
// 'host' : Adresse du serveur
// 'port' : Port sur lequel le serveur XML-RPC est accessible
// 'login' et 'password' : Identifiants pour l'authentification
$_SESSION["XMLRPC_agent"] = [

   "scheme" => "https",

   "host" => "devdemo.siveo.net",

   // "host" => "127.0.0.1",

   "port" => "7080",

   "login" => "mmc",

   "password" => "s3cr3t",
];

/**

* Exécute une requête XML-RPC.

*

* @param string $method Le nom de la méthode XML-RPC à appeler.

* @param array $params Les paramètres à passer à la méthode.

* @param bool $includeCookie Indique si le cookie de session doit être inclus dans la requête.

* @return array Un tableau contenant les en-têtes HTTP et le corps de la réponse.

* @throws Exception Si une erreur se produit lors de la connexion ou de l'envoi de la requête.

*/
function executeRequest($method, $params, $includeCookie = false) {

   $agentInfo = $_SESSION["XMLRPC_agent"];

   $requestXml = xmlrpc_encode_request($method, $params, ['output_type' => 'php', 'verbosity' => 'pretty', 'encoding' => 'UTF-8']);

   // On définit les en-têtes HTTP

   $url = "/";

   $httpQuery  = "POST " . $url . " HTTP/1.0\r\n";

   $httpQuery .= "User-Agent: MMC web interface\r\n";

   $httpQuery .= "Host: " . $agentInfo["host"] . ":" . $agentInfo["port"] . "\r\n";

   $httpQuery .= "Content-Type: text/xml\r\n";

   $httpQuery .= "Content-Length: " . strlen($requestXml) . "\r\n";

   // On ajoute le cookie si nécessaire

   if ($includeCookie) {

       $httpQuery .= "Cookie: " . $_SESSION['cookie'] . "\r\n";

   }

   $httpQuery .= "Authorization: Basic " . base64_encode($agentInfo["login"] . ":" . $agentInfo["password"]) . "\r\n\r\n";

   $httpQuery .= $requestXml;

   // Configurer le contexte SSL

   // 'allow_self_signed' est défini sur false pour n'accepter que les certificats signés par une autorité de certification reconnue

   // 'verify_peer' est défini sur true pour vérifier le certificat SSL du serveur

   $context = stream_context_create();

   $proto = $agentInfo["scheme"] == "https" ? "ssl://" : "";

   if ($proto) {

       stream_context_set_option($context, "ssl", "allow_self_signed", false);

       stream_context_set_option($context, "ssl", "verify_peer", true);

   }

   // On ouvre la connexion au serveur

   $socket = stream_socket_client($proto . $agentInfo["host"] . ":" . $agentInfo["port"], $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $context);

   if (!$socket) {

       throw new Exception("Unable to connect to XML-RPC server: $errstr ($errno)");

   }

   // On ajoute un délai de 60 secondes pour la lecture

   stream_set_timeout($socket, 60);

   if (!fwrite($socket, $httpQuery)) {

       throw new Exception("Unable to send data to XML-RPC server");

   }

   $responseXml = '';

   while (!feof($socket)) {

       $ret = fgets($socket, 128);

       $responseXml .= $ret;

   }

   fclose($socket);

   // Séparez les en-têtes HTTP du corps de la réponse

   list($headers, $body) = explode("\r\n\r\n", $responseXml, 2);

   return [$headers, $body];
}

/**

* Authentifie l'utilisateur et récupère le cookie de session.

* @param string $method Le nom de la méthode XML-RPC à appeler.

* @param array $params Les paramètres à passer à la méthode.

* @return string Le cookie de session.

* @throws Exception Si une erreur se produit lors de l'authentification.

*/
function authenticateAndGetCookie($method, $params) {

   list($headers, $body) = executeRequest($method, $params);

   // Parsing des en-têtes HTTP pour extraire le cookie de session

   $headers_array = array();

   $header_lines = explode("\r\n", $headers);

   foreach ($header_lines as $header) {

       $parts = explode(': ', $header, 2);

       if (count($parts) == 2) {

           $headers_array[$parts[0]] = $parts[1];

       }

   }

   // Utilisation des en-têtes analysés

   if (isset($headers_array['Set-Cookie'])) {

       $cookie = $headers_array['Set-Cookie'];

       $_SESSION['cookie'] = $cookie;

   } else {

       throw new Exception('Authentication failed, no cookie received');

   }

   return $cookie;
}

/**

* Envoie une requête XML-RPC et retourne la réponse uniquement si authentifié par cookie.

* @param string $method Le nom de la méthode XML-RPC à appeler.

* @param array $params Les paramètres à passer à la méthode.

* @return array La réponse XML-RPC.

* @throws Exception Si une erreur se produit lors de l'envoi de la requête.

*/
function sendXmlRpcRequest($method, $params) {

   list($headers, $body) = executeRequest($method, $params, true);

   $responseXml = substr($body, strpos($body, '<?xml'));

   $response = xmlrpc_decode($responseXml, 'UTF-8');

   if (is_array($response) && xmlrpc_is_fault($response)) {

       throw new Exception("XML-RPC fault: {$response['faultString']} ({$response['faultCode']})");

   }

   return $response;
}

// Authentification et récupération du cookie
$method = "base.ldapAuth";
$params = ['root', 'Sive0DEVDEMO'];

try {

   $responseXml = authenticateAndGetCookie($method, $params);
} catch (Exception $e) {

   echo "Error: " . $e->getMessage();
}

// ✅ Exemple d'utilisation de la méthode pkgs.get_all_packages pour récupérer la liste des paquets
if(isset($_POST['listPackages'])) {

   $method = "pkgs.get_all_packages";

   $params = [

       'root', // login

       false,  // sharing_activated

       0,      // start

       10,      // end

       [

           'filter' => '',

           // 'filter' => 'hostname',

       ] // ctx

   ];

   try {

       $responseXml = sendXmlRpcRequest($method, $params);

       } catch (Exception $e) {

       echo "Error: " . $e->getMessage();

   }
}

// ✅ Exemple d'utilisation de la méthode xmppmaster.get_machines_list pour récupérer la liste des machines
if(isset($_POST['listMachines'])) {

   $method = "xmppmaster.get_machines_list";

   $params = [

       0, // start

       20, // end

       [

           'filter' => '',

           'field' => 'allchamp',

           'computerpresence' => 'presence', // Définir si on veut les machines présentes

           // 'computerpresence' => 'no_presence', // Définir si on veut les machines non présentes

           'location' => "UUID0", // glpi_id - entité

       ] // ctx

   ];

   try {

       $responseXml = sendXmlRpcRequest($method, $params);

   } catch (Exception $e) {

       echo "Error: " . $e->getMessage();

   }
}

// ✅ Exemple d'utilisation de la méthode glpi.getLastMachineInventoryPart pour récupérer les détails d'une machine
if(isset($_POST['detailMachine'])) {

   if (isset($_POST['machineUUID'])) {

       $uuid = $_POST['machineUUID'];

       $method = "glpi.getLastMachineInventoryPart";

       $params = [

           $uuid,

           'Summary',

           0, // minbound

           0, // maxbound

           "", // filter

           [

               "hide_win_updates" => false,

               "history_delta" => false

           ], // options

       ];

       try {

           $responseXml = sendXmlRpcRequest($method, $params);

       } catch (Exception $e) {

           echo "Error: " . $e->getMessage();

       }

   } else {

       echo "Pas d'UUID";

   }
}

// ✅ Exemple d'utilisation de la méthode msc.add_command_api pour lancer un déploiement
if(isset($_POST['deploy'])) {

   $method = "msc.add_command_api";

   $pid = "96982fce-hostname_vq918j7wtnwzm610by"; // pid - paquet_id

   $target = "UUID1"; // target - uuid_machine

   $params = [

       $pid,  // pid - paquet_id

       $target,  // target - uuid_machine

       array(  // params

           "do_reboot" => "",

           "start_script" => "on",

           "clean_on_success" => "on",

           "do_wol" => "",

           "next_connection_delay" => "60",

           "max_connection_attempt" => "3",

           "do_inventory" => "on",

           "issue_halt_to" => array(),

           "maxbw" => "0",

           "name" => "devdemo-win-1",

           "hostname" => "devdemo-win-1",

           "uuid" => $target,

           "pid" => $pid,

           "gid" => NULL,

           // "ltitle" => "TITRE DU DEPLOIEMENT",

           // "deployment_intervals" => "",

           // "from" => "base|computers|msctabs|tablogs",

           // "create_directory" => "on",

           // "tab" => "tablaunch",

       ),

       "push",  // mode

       NULL,  // gid (si vous avez un gid, remplacez NULL par la valeur correspondante)

       array(),  // proxy (si vous avez des informations de proxy, ajoutez-les ici)

       0  // cmd_type (si vous avez un type de commande spécifique, remplacez 0 par la valeur correspondante)

   ];

   try {

       $responseXml = sendXmlRpcRequest($method, $params);

       $commandId = $responseXml; // Récupérer l'ID de la commande

       $method2 = "xmppmaster.addlogincommand";

       $params2 = [

           'root', // login

           $commandId, // commandid

           '', // grpid

           '', // nb_machine_in_grp

           '', // instructions_nb_machine_for_exec

           '', // instructions_datetime_for_exec

           '', // parameterspackage

           0, // rebootrequired

           0, // shutdownrequired

           0, // bandwidth

           0, // syncthing

           [] // params

       ];

       try {

           $responseXml2 = sendXmlRpcRequest($method2, $params2);

       } catch (Exception $e) {

           echo "Error: " . $e->getMessage();

       }

   } catch (Exception $e) {

       echo "Error: " . $e->getMessage();

   }
}

if(isset($_POST['getAllAudit'])) {

   $method = "xmppmaster.get_deploy_by_user_with_interval";

   $params = [

       "root", // login

       "",     // state

       86400,  // intervalsearch

       0,      // start_pagination

       "20",   // end_pagination

       "",     // filt

       "command" // typedeploy

   ];

   try {

       $responseXml = sendXmlRpcRequest($method, $params);

   } catch (Exception $e) {

       echo "Error: " . $e->getMessage();

   }
}

// ✅ Exemple d'utilisation de la méthode xmppmaster.getlinelogssession pour récupérer les logs d'un audit spécifique
if(isset($_POST['getAudit'])) {

   if(isset($_POST['commandID'])) {

       $commandID = $_POST['commandID'];

       $method = "xmppmaster.getlinelogssession";

       $params = [

           $commandID // sessionname

       ];

   }

   try {

       $responseXml = sendXmlRpcRequest($method, $params);

   } catch (Exception $e) {

       echo "Error: " . $e->getMessage();

   }
}
?>

<!-- Affichage WEB -->
<!DOCTYPE html>
<html lang="fr">
<head>

   <meta charset="UTF-8">

   <meta name="viewport" content="width=device-width, initial-scale=1.0">

   <title>Test XML-RPC</title>

   <style>

       table {

           border-collapse: collapse;

           width: 100%;

       }

       th, td {

           border: 1px solid #dddddd;

           text-align: left;

           padding: 8px;

       }

       th {

           background-color: #f2f2f2;

       }

       .container {

           display: flex;

           flex-direction: row;

           justify-content: space-around;

       }

   </style>
</head>
<body>

   <h2>Test XML-RPC</h2>

   <div class="container">

       <!-- Formulaire pour le bouton "Lister les paquets" -->

       <form method="post">

           <button type="submit" name="listPackages">Lister les paquets</button>

       </form>

       <!-- Formulaire pour le bouton "Lister les machines" -->

       <form method="post">

           <button type="submit" name="listMachines">Lister les machines</button>

       </form>

       <!-- Formulaire pour le bouton "Lancer un déploiement" -->

       <form method="post">

           <button type="submit" name="deploy">Déploiement d'un paquet fixe</button>

       </form>

       <!-- Formulaire pour le bouton "Lister tous les audits" -->

       <form method="post">

           <button type="submit" name="getAllAudit">Voir tous les audits</button>

       </form>

       <!-- Formulaire pour le bouton "Voir un audit"

       <form method="post">

           <button type="submit" name="getAudit">Voir Audit</button>

       </form> -->

   </div>

   <!-- Affichage du tableau des paquets -->

   <div id="response">

       <?php

       if(isset($_POST['listPackages'])) {

           echo '<h3>Voilà la liste des paquets</h3>';

           if (isset($responseXml) && is_array($responseXml) && isset($responseXml['datas'])) {

               $datas = $responseXml['datas'];

               echo '<table>';

               echo '<tr>';

               echo '<th>Package</th>';

               echo '<th>Description</th>';

               echo '<th>Version</th>';

               echo '<th>UUID du package</th>';

               echo '</tr>';

               foreach ($datas['name'] as $key => $packageName) {

                   $description = $datas['description'][$key];

                   $version = $datas['version'][$key];

                   $size = number_format($datas['size'][$key] / 1024, 1) . ' kOctets'; // Convertir la taille en kOctets

                   $uuid = $datas['uuid'][$key];

                   echo '<tr>';

                   echo '<td>' . $packageName . '</td>';

                   echo '<td>' . $description . '</td>';

                   echo '<td>' . $version . '</td>';

                   echo '<td>' . $uuid . '</td>';

                   echo '</tr>';

               }

               echo '</table>';

           }

       } elseif(isset($_POST['listMachines'])) {

           echo '<h3>Voilà la liste des machines</h3>';

           if (isset($responseXml) && is_array($responseXml) && isset($responseXml['data'])) {

               $datas = $responseXml['data'];

               $totalMachines = count($datas['id']); // Obtenez le nombre total de machines

               echo '<table border="1">';

               echo '<tr>';

               echo '<th>UUID</th>';

               echo '<th>Nom de la Machine</th>';

               echo '<th>Description</th>';

               echo '<th>Système d\'exploitation</th>';

               echo '<th>Type</th>';

               echo '<th>Dernier Utilisateur</th>';

               echo '<th>Entité</th>';

               echo '<th>Actions</th>';

               echo '</tr>';

               for ($i = 0; $i < $totalMachines; $i++) {

                   // Accédez aux données pertinentes dans le tableau de réponse

                   $uuid = $datas['uuid_inventorymachine'][$i];

                   $machineName = $datas['hostname'][$i];

                   $description = $datas['glpi_description'][$i];

                   $os = $datas['platform'][$i];

                   $type = $datas['model'][$i];

                   $lastUser = $datas['lastuser'][$i];

                   $entity = $datas['entityname'][$i];

                   echo '<tr>';

                   echo '<td>' . $uuid . '</td>';

                   echo '<td>' . $machineName . '</td>';

                   echo '<td>' . $description . '</td>';

                   echo '<td>' . $os . '</td>';

                   echo '<td>' . $type . '</td>';

                   echo '<td>' . $lastUser . '</td>';

                   echo '<td>' . $entity . '</td>';

                   echo '<td>

                           <form method="post">

                               <input type="hidden" name="machineUUID" value="' . $datas['uuid_inventorymachine'][$i] . '">

                               <button type="submit" name="detailMachine">Détail de la machine</button>

                           </form>

                         </td>';

                   echo '</tr>';

               }

               echo '</table>';

           }

       } elseif(isset($_POST['detailMachine'])) {

           echo '<h3>Détails de la Machine</h3>';

           if (isset($responseXml) && is_array($responseXml) && !empty($responseXml)) {

               echo '<table border="1">';

               foreach ($responseXml[0] as $attributeArray) {

                   $attributeName = $attributeArray[0];

                   if (is_array($attributeArray[1])) {

                       $attributeValue = isset($attributeArray[1][2]) ? $attributeArray[1][2] : '';

                   } else {

                       $attributeValue = $attributeArray[1];

                   }

                   echo '<tr>';

                   echo '<td>' . $attributeName . '</td>';

                   echo '<td>' . $attributeValue . '</td>';

                   echo '</tr>';

               }

               echo '</table>';

           }

       } elseif(isset($_POST['getAllAudit'])) {

           echo '<h3>Voilà tous les audits</h3>';

           if (isset($responseXml) && is_array($responseXml) && !empty($responseXml)) {

               $datas = $responseXml['tabdeploy'];

               echo '<table border="1">';

               echo '<tr>';

               echo '<th>Session ID</th>';

               echo '<th>Title</th>';

               echo '<th>State</th>';

               echo '<th>Voir les logs de l\'Audit</th>';

               echo '</tr>';

               foreach (array_keys($datas['sessionid']) as $key) {

                   echo '<tr>';

                   echo '<td>' . $datas['sessionid'][$key] . '</td>';

                   echo '<td>' . $datas['title'][$key] . '</td>';

                   echo '<td>' . $datas['state'][$key] . '</td>';

                   echo '<td>

                           <form method="post">

                               <input type="hidden" name="commandID" value="'.$datas['sessionid'][$key].'">

                               <button type="submit" name="getAudit">Voir les logs</button>

                           </form>

                       </td>';

                   echo '</tr>';

               }

               echo '</table>';

           }

       } elseif(isset($_POST['getAudit'])) {

           echo '<h3>Voilà l\'Audit</h3>';

           if (isset($responseXml) && is_array($responseXml) && !empty($responseXml)) {

               $datas = $responseXml['log'];

               echo '<table border="1">';

               echo '<tr>';

               echo '<th>Commande</th>';

               echo '<th>Date</th>';

               echo '<th>Log</th>';

               echo '</tr>';

               foreach ($datas as $value) {

                   echo '<tr>';

                   echo '<td>' . $value['sessionname'] . '</td>';

                   echo '<td>' . $value['date']->scalar . '</td>';

                   echo '<td>' . $value['text'] . '</td>';

                   echo '</tr>';

               }

               echo '</table>';

           }

       }

       ?>

   </div>

</body>
</html>