%PDF- %PDF-
Direktori : /var/www/projetos/suporte.iigd.com.br/src/Inventory/ |
Current File : /var/www/projetos/suporte.iigd.com.br/src/Inventory/Request.php |
<?php /** * --------------------------------------------------------------------- * * GLPI - Gestionnaire Libre de Parc Informatique * * http://glpi-project.org * * @copyright 2015-2024 Teclib' and contributors. * @copyright 2003-2014 by the INDEPNET Development Team. * @licence https://www.gnu.org/licenses/gpl-3.0.html * * --------------------------------------------------------------------- * * LICENSE * * This file is part of GLPI. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. * * --------------------------------------------------------------------- */ namespace Glpi\Inventory; use Glpi\Agent\Communication\AbstractRequest; use Glpi\Agent\Communication\Headers\Common; use Glpi\Plugin\Hooks; use Plugin; use Unmanaged; /** * Handle inventory request * Both XML (legacy) and JSON inventory formats are supported. * * @see https://github.com/glpi-project/inventory_format/blob/master/inventory.schema.json */ class Request extends AbstractRequest { /** @var Inventory */ private $inventory; /** @var bool */ private bool $is_discovery = false; /** @var string */ private string $network_inventory_mode; protected function initHeaders(): Common { return new Common(); } /** * Handle Query * * @param string $query Query mode (one of self::*_QUERY or self::*_ACTION) * @param mixed $content Contents, optional * * @return boolean */ protected function handleAction($query, $content = null): bool { $this->query = $query; switch ($query) { case self::GET_PARAMS: $this->getParams($content); break; case self::CONTACT_ACTION: $this->contact($content); break; case self::PROLOG_QUERY: $this->prolog($content); break; case self::INVENT_QUERY: case self::INVENT_ACTION: $this->inventory($content); break; case self::NETDISCOVERY_ACTION: $this->networkDiscovery($content); break; case self::SNMP_QUERY: case self::OLD_SNMP_QUERY: case self::NETINV_ACTION: $this->networkInventory($content); break; case self::REGISTER_ACTION: case self::CONFIG_ACTION: case self::ESX_ACTION: case self::COLLECT_ACTION: case self::DEPLOY_ACTION: case self::WOL_ACTION: default: $this->addError("Query '$query' is not supported.", 501); return false; } return true; } /** * Handle Task * * @param string $task Task (one of self::*_TASK) * * @return array */ protected function handleTask($task): array { $params = [ 'options' => [ 'response' => [] ], 'item' => $this->inventory->getAgent(), ]; switch ($task) { case self::INVENT_TASK: return $this->handleInventoryTask($params); case self::NETDISCOVERY_TASK: return $this->handleNetDiscoveryTask($params); case self::NETINV_TASK: return $this->handleNetInventoryTask($params); case self::ESX_TASK: return $this->handleESXTask($params); case self::COLLECT_TASK: return $this->handleCollectTask($params); case self::DEPLOY_TASK: return $this->handleDeployTask($params); case self::WOL_TASK: return $this->handleWakeOnLanTask($params); case self::REMOTEINV_TASK: return $this->handleRemoteInventoryTask($params); default: $this->addError("Task '$task' is not supported.", 400); return []; } } /** * Handle agent GETPARAMS request * * @param mixed $data Inventory input following specs * * @return void */ public function getParams($data) { /** @var array $CFG_GLPI */ global $CFG_GLPI; $this->inventory = new Inventory(); $this->inventory->contact($data); $response = [ 'expiration' => $CFG_GLPI['inventory_frequency'] ?? self::DEFAULT_FREQUENCY, 'status' => 'ok' ]; $params = [ 'options' => [ 'content' => $data, 'response' => $response ], 'item' => $this->inventory->getAgent() ]; $params = Plugin::doHookFunction(Hooks::INVENTORY_GET_PARAMS, $params); $this->addToResponse($params['options']['response']); } /** * Handle agent prolog request * * @param mixed $data Inventory input following specs * * @return void */ public function prolog($data) { /** @var array $CFG_GLPI */ global $CFG_GLPI; if ($this->headers->hasHeader('GLPI-Agent-ID')) { $this->setMode(self::JSON_MODE); $response = [ 'expiration' => $CFG_GLPI['inventory_frequency'] ?? self::DEFAULT_FREQUENCY, 'status' => 'ok' ]; } else { $response = [ 'PROLOG_FREQ' => $CFG_GLPI['inventory_frequency'] ?? self::DEFAULT_FREQUENCY, 'RESPONSE' => 'SEND' ]; } $hook_params = [ 'mode' => $this->getMode(), 'deviceid' => $this->getDeviceID(), 'response' => $response ]; $hook_response = Plugin::doHookFunction( Hooks::PROLOG_RESPONSE, $hook_params ); $response = $hook_response['response']; $this->addToResponse($response); } /** * Handle agent network discovery request * * @param mixed $data Inventory input following specs * * @return void */ public function networkDiscovery($data) { $this->network_inventory_mode = Hooks::NETWORK_DISCOVERY; $this->is_discovery = true; $this->network($data); } /** * Handle agent network inventory request * * @param mixed $data Inventory input following specs * * @return void */ public function networkInventory($data) { $this->network_inventory_mode = Hooks::NETWORK_INVENTORY; $this->network($data); } /** * Handle agent network inventory request * * @param mixed $data Inventory input following specs * * @return void */ public function network($data) { $this->inventory = new Inventory(); $this->inventory ->setDiscovery($this->isDiscovery()) ->setData($data, $this->getMode()); $response = []; $hook_params = [ 'mode' => $this->getMode(), 'inventory' => $this->inventory, 'deviceid' => $this->getDeviceID(), 'response' => $response, 'query' => $this->query ]; $hook_response = Plugin::doHookFunction( $this->network_inventory_mode, $hook_params ); if ($hook_response == $hook_params) { //no hook, use native capabilities $this->inventory($data); } else { //try to use hook response if (isset($hook_response['response']) && count($hook_response['response'])) { $this->addToResponse($response); } else if (isset($hook_response['errors']) && count($hook_response['errors'])) { $this->addError($hook_response['errors'], 400); } else { //nothing expected happens; this is an error $this->addError("Query '" . $this->query . "' is not supported.", 400); } } } /** * Handle agent CONTACT request * * @param mixed $data Inventory input following specs * * @return void */ public function contact($data) { /** @var array $CFG_GLPI */ global $CFG_GLPI; $this->inventory = new Inventory(); $this->inventory->contact($data); $response = [ 'expiration' => $CFG_GLPI['inventory_frequency'] ?? self::DEFAULT_FREQUENCY, 'status' => 'ok' ]; //For the moment it's the Agent who informs us about the active tasks $raw_data = $this->inventory->getRawData(); if ($raw_data !== null && property_exists($raw_data, 'enabled-tasks')) { foreach ($raw_data->{'enabled-tasks'} as $task) { $handle = $this->handleTask($task); if (is_array($handle) && count($handle)) { // Insert related task information under tasks list property $response['tasks'][$task] = $handle; } else { // Task is not supported, disable it and add unsupported message in response $this->addToResponse([ "message" => "$task task not supported", "disabled" => $task ]); } } } $this->addToResponse($response); } /** * Handle agent inventory request * * @param mixed $data Inventory input following specs * * @return void */ public function inventory($data) { /** @var array $CFG_GLPI */ global $CFG_GLPI; if ($this->isDiscovery()) { //force "partial" mode on network discoveries. $data->partial = true; } $this->inventory = new Inventory(); $this->inventory ->setDiscovery($this->isDiscovery()) ->setRequestQuery($this->query) ->setData($data, $this->getMode()); if (!$this->inventory->inError()) { $this->inventory->doInventory($this->test_rules); } if ($this->inventory->inError()) { foreach ($this->inventory->getErrors() as $error) { $error_code = 500; if (str_contains($error, "JSON does not validate")) { $error_code = 400; } $this->addError($error, $error_code); } } else { if ($this->headers->hasHeader('GLPI-Agent-ID')) { $response = [ 'expiration' => $CFG_GLPI['inventory_frequency'] ?? self::DEFAULT_FREQUENCY, 'status' => 'ok' ]; } else { $response = ['RESPONSE' => 'SEND']; } $this->addToResponse($response); } } /** * Handle agent enabled inventory task support on contact request * * @param array $params Required hooks params * * @return array */ public function handleInventoryTask(array $params): array { // Preset response as GLPI supports native inventory by default $params['options']['response'][self::INVENT_TASK] = [ 'server' => 'glpi', 'version' => GLPI_VERSION ]; $params = Plugin::doHookFunction(Hooks::HANDLE_INVENTORY_TASK, $params); // Return inventory task support return $params['options']['response'][self::INVENT_TASK] ?? []; } /** * Handle agent enabled netdiscovery task support on contact request * * @param array $params Required hooks params * * @return array */ public function handleNetDiscoveryTask(array $params): array { $params = Plugin::doHookFunction(Hooks::HANDLE_NETDISCOVERY_TASK, $params); return $params['options']['response'][self::NETDISCOVERY_TASK] ?? []; } /** * Handle agent enabled netinventory task support on contact request * * @param array $params Required hooks params * * @return array */ public function handleNetInventoryTask(array $params): array { $params = Plugin::doHookFunction(Hooks::HANDLE_NETINVENTORY_TASK, $params); return $params['options']['response'][self::NETINV_TASK] ?? []; } /** * Handle agent enabled ESX task support on contact request * * @param array $params Required hooks params * * @return array */ public function handleESXTask(array $params): array { $params = Plugin::doHookFunction(Hooks::HANDLE_ESX_TASK, $params); return $params['options']['response'][self::ESX_TASK] ?? []; } /** * Handle agent enabled collect task support on contact request * * @param array $params Required hooks params * * @return array */ public function handleCollectTask(array $params): array { $params = Plugin::doHookFunction(Hooks::HANDLE_COLLECT_TASK, $params); return $params['options']['response'][self::COLLECT_TASK] ?? []; } /** * Handle agent enabled deploy task support on contact request * * @param array $params Required hooks params * * @return array */ public function handleDeployTask(array $params): array { $params = Plugin::doHookFunction(Hooks::HANDLE_DEPLOY_TASK, $params); return $params['options']['response'][self::DEPLOY_TASK] ?? []; } /** * Handle agent enabled wakeonlan task support on contact request * * @param array $params Required hooks params * * @return array */ public function handleWakeOnLanTask(array $params): array { $params = Plugin::doHookFunction(Hooks::HANDLE_WAKEONLAN_TASK, $params); return $params['options']['response'][self::WOL_TASK] ?? []; } /** * Handle agent enabled remoteinventory task support on contact request * * @param array $params Required hooks params * * @return array */ public function handleRemoteInventoryTask(array $params): array { $params = Plugin::doHookFunction(Hooks::HANDLE_REMOTEINV_TASK, $params); return $params['options']['response'][self::REMOTEINV_TASK] ?? []; } /** * Get inventory request status * * @return array */ public function getInventoryStatus(): array { $items = $this->inventory->getItems(); $status = [ 'metadata' => $this->inventory->getMetadata(), 'items' => $items ]; if (count($items) == 1) { $item = $items[0]; $status += [ 'itemtype' => $item->getType(), 'items_id' => $item->fields['id'] ]; } else if (count($items)) { // Defines 'itemtype' only if all items has same type $itemtype = null; foreach ($items as $item) { if ($itemtype === null && $item->getType() != Unmanaged::class) { $itemtype = $item->getType(); } else if ($itemtype !== $item->getType()) { $itemtype = false; break; } } if ($itemtype) { $status['itemtype'] = $itemtype; } } return $status; } public function getInventory(): Inventory { return $this->inventory; } public function isDiscovery(): bool { return $this->is_discovery; } }