2022-02-11 15:48:06 +01:00

1258 lines
39 KiB
PHP

<?php
/**
* FusionInventory
*
* Copyright (C) 2010-2016 by the FusionInventory Development Team.
*
* http://www.fusioninventory.org/
* https://github.com/fusioninventory/fusioninventory-for-glpi
* http://forge.fusioninventory.org/
*
* ------------------------------------------------------------------------
*
* LICENSE
*
* This file is part of FusionInventory project.
*
* FusionInventory is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FusionInventory 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with FusionInventory. If not, see <http://www.gnu.org/licenses/>.
*
* ------------------------------------------------------------------------
*
* This file is used to manage the agents
*
* ------------------------------------------------------------------------
*
* @package FusionInventory
* @author David Durieux
* @copyright Copyright (c) 2010-2016 FusionInventory team
* @license AGPL License 3.0 or (at your option) any later version
* http://www.gnu.org/licenses/agpl-3.0-standalone.html
* @link http://www.fusioninventory.org/
* @link https://github.com/fusioninventory/fusioninventory-for-glpi
*
*/
if (!defined('GLPI_ROOT')) {
die("Sorry. You can't access directly to this file");
}
/**
* Manage the FusionInventory agents.
*/
class PluginFusioninventoryAgent extends CommonDBTM {
/**
* We activate the history.
*
* @var boolean
*/
public $dohistory = true;
/**
* The right name for this class
*
* @var string
*/
static $rightname = 'plugin_fusioninventory_agent';
/**
* Get name of this type by language of the user connected
*
* @param integer $nb number of elements
* @return string name of this type
*/
static function getTypeName($nb = 0) {
return __('Agent', 'fusioninventory');
}
/**
* Get search function for the class
*
* @return array
*/
function rawSearchOptions() {
$tab = [];
$tab[] = [
'id' => 'common',
'name' => __('Agent', 'fusioninventory')
];
$tab[] = [
'id' => '1',
'table' => $this->getTable(),
'field' => 'name',
'name' => __('Name'),
'datatype' => 'itemlink',
'autocomplete' => true,
];
$tab[] = [
'id' => '2',
'table' => 'glpi_entities',
'field' => 'completename',
'name' => Entity::getTypeName(1),
'datatype' => 'dropdown',
];
$tab[] = [
'id' => '3',
'table' => $this->getTable(),
'field' => 'is_recursive',
'name' => __('Child entities'),
'datatype' => 'bool',
];
$tab[] = [
'id' => '4',
'table' => $this->getTable(),
'field' => 'last_contact',
'name' => __('Last contact', 'fusioninventory'),
'datatype' => 'datetime',
];
$tab[] = [
'id' => '5',
'table' => $this->getTable(),
'field' => 'lock',
'name' => __('locked', 'fusioninventory'),
'datatype' => 'bool',
];
$tab[] = [
'id' => '6',
'table' => $this->getTable(),
'field' => 'device_id',
'name' => __('Device_id', 'fusioninventory'),
'datatype' => 'text',
'massiveaction' => false,
];
$tab[] = [
'id' => '7',
'table' => 'glpi_computers',
'field' => 'name',
'name' => __('Computer link', 'fusioninventory'),
'datatype' => 'itemlink',
'itemlink_type' => 'Computer',
'massiveaction' => false,
];
$tab[] = [
'id' => '8',
'table' => $this->getTable(),
'field' => 'version',
'name' => _n('Version', 'Versions', 1),
'datatype' => 'text',
'massiveaction' => false,
];
$tab[] = [
'id' => '9',
'table' => $this->getTable(),
'field' => 'token',
'name' => __('Token'),
'datatype' => 'text',
'massiveaction' => false,
];
$tab[] = [
'id' => '10',
'table' => $this->getTable(),
'field' => 'useragent',
'name' => __('Useragent', 'fusioninventory'),
'datatype' => 'text',
'massiveaction' => false,
];
$tab[] = [
'id' => '11',
'table' => $this->getTable(),
'field' => 'tag',
'name' => __('FusionInventory tag', 'fusioninventory'),
'datatype' => 'text',
'massiveaction' => false,
];
$tab[] = [
'id' => '12',
'table' => $this->getTable(),
'field' => 'threads_networkdiscovery',
'name' => __('Threads number', 'fusioninventory') . "&nbsp;(" .
strtolower(__('Network discovery', 'fusioninventory')) .
")",
'datatype' => 'integer',
];
$tab[] = [
'id' => '13',
'table' => $this->getTable(),
'field' => 'threads_networkinventory',
'name' => __('Threads number', 'fusioninventory') . "&nbsp;(" .
strtolower(__('Network inventory (SNMP)', 'fusioninventory')) .
")",
'datatype' => 'integer',
];
$tab[] = [
'id' => '14',
'table' => $this->getTable(),
'field' => 'agent_port',
'name' => __('Agent port', 'fusioninventory'),
'datatype' => 'integer',
];
$i = 20;
$pfAgentmodule = new PluginFusioninventoryAgentmodule();
$a_modules = $pfAgentmodule->find();
foreach ($a_modules as $data) {
$tab[] = [
'id' => $i,
'table' => $pfAgentmodule->getTable(),
'field' => $data["modulename"],
'linkfield' => $data["modulename"],
'name' => __('Module', 'fusioninventory') . " - " . $data["modulename"],
'datatype' => 'bool',
'massiveaction' => false,
];
$i++;
}
return $tab;
}
/**
* Define tabs to display on form page
*
* @param array $options
* @return array containing the tabs name
*/
function defineTabs($options = []) {
$ong = [];
$this->addDefaultFormTab($ong);
$this->addStandardTab('PluginFusioninventoryAgentmodule', $ong, $options);
$this->addStandardTab('Log', $ong, $options);
return $ong;
}
/**
* Get comments of the object
*
* @return string comments in HTML format
*/
function getComments() {
$comment = __('Useragent', 'fusioninventory').' : '.$this->fields['useragent'].'<br/>'.
__('Last contact', 'fusioninventory').' : '.
Html::convDateTime($this->fields['last_contact']).' minutes';
if (!empty($comment)) {
return Html::showToolTip($comment, ['display' => false]);
}
return $comment;
}
/**
* Get the massive actions for this object
*
* @param object|null $checkitem
* @return array list of actions
*/
function getSpecificMassiveActions($checkitem = null) {
$actions = [];
if (Session::haveRight("plugin_fusioninventory_agent", UPDATE)) {
$pfAgentmodule = new PluginFusioninventoryAgentmodule();
$a_modules = $pfAgentmodule->find();
foreach ($a_modules as $data) {
$actions[__CLASS__.MassiveAction::CLASS_ACTION_SEPARATOR.$data["modulename"]] =
__('Module', 'fusioninventory')." - ".$data['modulename'];
}
$actions[__CLASS__.MassiveAction::CLASS_ACTION_SEPARATOR.'transfert'] = __('Transfer');
}
return $actions;
}
/**
* Display form related to the massive action selected
*
* @param object $ma MassiveAction instance
* @return boolean
*/
static function showMassiveActionsSubForm(MassiveAction $ma) {
if ($ma->getAction() == 'transfert') {
Dropdown::show('Entity');
echo "<br><br>".Html::submit(__('Post'),
['name' => 'massiveaction']);
return true;
}
$pfAgentmodule = new PluginFusioninventoryAgentmodule();
$a_modules = $pfAgentmodule->find();
foreach ($a_modules as $data) {
if ($ma->getAction() == $data['modulename']) {
Dropdown::showYesNo($ma->getAction());
echo "<br><br>".Html::submit(__('Post'),
['name' => 'massiveaction']);
return true;
}
}
return parent::showMassiveActionsSubForm($ma);
}
/**
* Execution code for massive action
*
* @param object $ma MassiveAction instance
* @param object $item item on which execute the code
* @param array $ids list of ID on which execute the code
*/
static function processMassiveActionsForOneItemtype(MassiveAction $ma, CommonDBTM $item,
array $ids) {
$pfAgent = new self();
switch ($ma->getAction()) {
case 'transfert' :
foreach ($ids as $key) {
if ($pfAgent->getFromDB($key)) {
$input = [];
$input['id'] = $key;
$input['entities_id'] = filter_input(INPUT_POST, "entities_id");
if ($pfAgent->update($input)) {
//set action massive ok for this item
$ma->itemDone($item->getType(), $key, MassiveAction::ACTION_OK);
} else {
// KO
$ma->itemDone($item->getType(), $key, MassiveAction::ACTION_KO);
}
}
}
return;
}
$pfAgentmodule = new PluginFusioninventoryAgentmodule();
$a_modules = $pfAgentmodule->find();
foreach ($a_modules as $data2) {
if ($ma->getAction() == $data2['modulename']) {
foreach ($ids as $key) {
if ($ma->POST[$data2['modulename']] == $data2['is_active']) {
// Remove from exceptions
$a_exceptions = importArrayFromDB($data2['exceptions']);
if (in_array($key, $a_exceptions)) {
foreach ($a_exceptions as $key2=>$value2) {
if ($value2 == $key) {
unset($a_exceptions[$key2]);
}
}
}
$data2['exceptions'] = exportArrayToDB($a_exceptions);
} else {
// Add to exceptions
$a_exceptions = importArrayFromDB($data2['exceptions']);
if (!in_array($key, $a_exceptions)) {
$a_exceptions[] = (string)$key;
}
$data2['exceptions'] = exportArrayToDB($a_exceptions);
}
$ma->itemDone($item->getType(), $key, MassiveAction::ACTION_OK);
}
$pfAgentmodule->update($data2);
}
}
return;
}
/**
* Display form for agent configuration
*
* @param integer $agents_id ID of the agent
* @param array $options
* @return boolean
*/
function showForm($agents_id, $options = []) {
global $CFG_GLPI;
if ($agents_id!='') {
$this->getFromDB($agents_id);
} else {
$this->getEmpty();
$pfConfig = new PluginFusioninventoryConfig();
unset($this->fields['id']);
$this->fields['threads_networkdiscovery'] =
$pfConfig->getValue('threads_networkdiscovery');
$this->fields['timeout_networkdiscovery'] =
$pfConfig->getValue('timeout_networkdiscovery');
$this->fields['threads_networkinventory'] =
$pfConfig->getValue('threads_networkinventory');
$this->fields['timeout_networkinventory'] =
$pfConfig->getValue('timeout_networkinventory');
$this->fields['senddico'] = 0;
}
$this->initForm($agents_id, $options);
$this->showFormHeader($options);
echo "<tr class='tab_bg_1'>";
echo "<td>".__('Name')." :</td>";
echo "<td align='center'>";
Html::autocompletionTextField($this, 'name', ['size' => 40]);
echo "</td>";
echo "<td>".__('Device_id', 'fusioninventory')."&nbsp;:</td>";
echo "<td align='center'>";
echo $this->fields["device_id"];
echo "</td>";
echo "</tr>";
echo "<tr class='tab_bg_1'>";
echo "<td>".__('Computer link', 'fusioninventory')."&nbsp:</td>";
echo "<td align='center'>";
if (!empty($this->fields["computers_id"])) {
$oComputer = new Computer();
$oComputer->getFromDB($this->fields["computers_id"]);
echo $oComputer->getLink(1);
echo Html::hidden('computers_id',
['value' => $this->fields["computers_id"]]);
echo "&nbsp;<a class='pointer' onclick='submitGetLink(\"".
Plugin::getWebDir('fusioninventory')."/front/agent.form.php\", ".
"{\"disconnect\": \"disconnect\",
\"computers_id\": ".$this->fields['computers_id'].",
\"id\": ".$this->fields['id'].",
\"_glpi_csrf_token\": \"".Session::getNewCSRFToken()."\"});'>".
"<img src='".$CFG_GLPI['root_doc']."/pics/delete.png' /></a>";
} else {
Computer_Item::dropdownConnect("Computer", "Computer", 'computers_id',
$this->fields['entities_id']);
}
echo "</td>";
echo "<td>".__('Token')."&nbsp:</td>";
echo "<td align='center'>";
echo $this->fields["token"];
echo "</td>";
echo "</tr>";
echo "<tr class='tab_bg_1'>";
echo "<td>".__('locked', 'fusioninventory')."&nbsp:</td>";
echo "<td align='center'>";
Dropdown::showYesNo('lock', $this->fields["lock"]);
echo "</td>";
echo "<td>"._n('Version', 'Versions', 1)."&nbsp:</td>";
echo "<td align='center'>";
$a_versions = importArrayFromDB($this->fields["version"]);
foreach ($a_versions as $module => $version) {
echo "<strong>".$module. "</strong>: ".$version."<br/>";
}
echo "</td>";
echo "</tr>";
echo "<tr class='tab_bg_1'>";
echo "<td>".__('Threads number', 'fusioninventory')."&nbsp;".
"(".strtolower(__('Network discovery', 'fusioninventory')).")&nbsp;:</td>";
echo "<td align='center'>";
Dropdown::showNumber("threads_networkdiscovery", [
'value' => $this->fields["threads_networkdiscovery"],
'toadd' => [ __('General setup') ],
'min' => 1,
'max' => 400]
);
echo "</td>";
echo "<td>".__('Useragent', 'fusioninventory')."&nbsp:</td>";
echo "<td align='center'>";
echo $this->fields["useragent"];
echo "</td>";
echo "</tr>";
echo "<tr class='tab_bg_1'>";
echo "<td>".__('SNMP timeout', 'fusioninventory')."&nbsp;".
"(".strtolower(__('Network discovery', 'fusioninventory')).")&nbsp;:</td>";
echo "<td align='center'>";
Dropdown::showNumber("timeout_networkdiscovery", [
'value' => $this->fields["timeout_networkdiscovery"],
'toadd' => [ __('General setup') ],
'min' => 1,
'max' => 60]
);
echo "</td>";
echo "<td>".__('Last contact', 'fusioninventory')."&nbsp:</td>";
echo "<td align='center'>";
echo Html::convDateTime($this->fields["last_contact"]);
echo "</td>";
echo "</tr>";
echo "<tr class='tab_bg_1'>";
echo "<td>".__('Threads number', 'fusioninventory')."&nbsp;".
"(".strtolower(__('Network inventory (SNMP)', 'fusioninventory')).")&nbsp;:</td>";
echo "<td align='center'>";
Dropdown::showNumber("threads_networkinventory", [
'value' => $this->fields["threads_networkinventory"],
'toadd' => [ __('General setup') ],
'min' => 1,
'max' => 400]
);
echo "</td>";
echo "<td>".__('FusionInventory tag', 'fusioninventory')."&nbsp:</td>";
echo "<td align='center'>";
echo $this->fields["tag"];
echo "</td>";
echo "</tr>";
echo "<td>".__('SNMP timeout', 'fusioninventory')."&nbsp;".
"(".strtolower(__('Network inventory (SNMP)', 'fusioninventory')).")&nbsp;:</td>";
echo "<td align='center'>";
Dropdown::showNumber("timeout_networkinventory", [
'value' => $this->fields["timeout_networkinventory"],
'toadd' => [ __('General setup') ],
'min' => 1,
'max' => 60]
);
echo "</td>";
echo "<td colspan='2'>";
echo "</td>";
echo "</tr>";
echo "<tr class='tab_bg_1'>";
$pfConfig = new PluginFusioninventoryConfig();
echo "<td>".__('Agent port', 'fusioninventory')." (".
__('if empty use port configured in general options', 'fusioninventory')
." <i>".$pfConfig->getValue('agent_port')."</i>)&nbsp:</td>";
echo "<td align='center'>";
echo "<input type='text' name='agent_port' value='".$this->fields['agent_port']."'/>";
echo "</td>";
echo "<td colspan='2'>";
echo "</td>";
echo "</tr>";
$this->showFormButtons($options);
return true;
}
/**
* Disconnect an agent from a computer
* @params POST parameters
* @return void
*/
function disconnect($params) {
if (isset($params['computers_id']) && isset($params['id'])) {
$pfComputer = new PluginFusioninventoryInventoryComputerComputer();
$pfComputer->deleteByCriteria(['computers_id' => $params['computers_id']]);
$this->update(['id' => $params['id'], 'computers_id' => 0]);
}
}
/**
* Get agent information by device_id
*
* @global object $DB
* @param string $device_id
* @return array all data of agent from database
*/
function infoByKey($device_id) {
global $DB;
$iterator = $DB->request([
'FROM' => $this->getTable(),
'WHERE' => ['device_id' => $device_id],
'START' => 0,
'LIMIT' => 1
]);
$agent = [];
if (count($iterator)) {
$agent = $iterator->next();
}
return $agent;
}
/**
* Import token: create of update it in database
*
* @param array $arrayinventory
* @return integer id of the agent from database
*/
function importToken($arrayinventory) {
if (isset($arrayinventory['DEVICEID'])) {
$a_agent = $this->find(['device_id' => $arrayinventory['DEVICEID']], [], 1);
if (empty($a_agent)) {
$a_input = [];
if (isset($arrayinventory['TOKEN'])) {
$a_input['token'] = $arrayinventory['TOKEN'];
}
$a_input['name'] = $arrayinventory['DEVICEID'];
$a_input['device_id'] = $arrayinventory['DEVICEID'];
$a_input['entities_id'] = 0;
$a_input['last_contact'] = date("Y-m-d H:i:s");
$a_input['useragent'] = filter_input(INPUT_SERVER, "HTTP_USER_AGENT");
// Set default number of threads for network tasks to 0 to follow general setup
$a_input['threads_networkdiscovery'] = 0;
$a_input['threads_networkinventory'] = 0;
$agents_id = $this->add($a_input);
if ($agents_id) {
return $agents_id;
}
} else {
foreach ($a_agent as $data) {
$input = [];
$input['id'] = $data['id'];
if (isset($arrayinventory['TOKEN'])) {
$input['token'] = $arrayinventory['TOKEN'];
}
$input['last_contact'] = date("Y-m-d H:i:s");
$input['useragent'] = filter_input(INPUT_SERVER, "HTTP_USER_AGENT");
$this->update($input);
return $data['id'];
}
}
}
return 0;
}
/**
* Get all IP of the computer linked with this agent
*
* @return array list of IP
*/
function getIPs() {
if (!isset($this->fields['computers_id'])
|| $this->fields['computers_id'] == 0) {
trigger_error('Agent must be initialized');
}
$ip_addresses = PluginFusioninventoryToolbox::getIPforDevice('Computer', $this->fields['computers_id']);
return $ip_addresses;
}
/**
* Get the agent id linked to this computer id
*
* @param integer $computers_id id of the agent
* @return integer|false integer if found agent id, otherwise false
*/
function getAgentWithComputerid($computers_id) {
$agent = $this->find(['computers_id' => $computers_id], [], 1);
if (count($agent) == 1) {
$data = current($agent);
$this->getFromDB($data['id']);
return $data['id'];
}
return false;
}
/**
* Get the agents id of a list of computers id
*
* @param array $computer_ids list of id of computers
* @return array list of agents [id] => information of agent
*/
function getAgentsFromComputers($computer_ids = []) {
if (count($computer_ids) == 0) {
return [];
}
$agents = $this->find(['computers_id' => $computer_ids]);
return $agents;
}
/**
* Get the computer linked with this agent
*
* @return object|false return Computer object if exist, otherwise false
*/
function getAssociatedComputer() {
$computer = new Computer();
if (!isset($this->fields['id'])) {
trigger_error("Agent must be initialized!");
return false;
}
$computer->getFromDB($this->fields['computers_id']);
return $computer;
}
/**
* Link a computer with an agent
*
* @param integer $computers_id id of the computer
* @param string $device_id devide_id of the agent
* @param integer $entities_id id of the entity
* @return boolean true if successfully linked
*/
function setAgentWithComputerid($computers_id, $device_id, $entities_id) {
$a_agent = $this->find(['computers_id' => $computers_id], [], 1);
// Is this computer already linked to an agent?
$agent = array_shift($a_agent);
if (is_array($agent)) {
// relation
if ($agent['device_id'] != $device_id
|| $agent['entities_id'] != $entities_id) {
$input = [];
$input['id'] = $agent['id'];
$input['device_id'] = $device_id;
$input['entities_id'] = $entities_id;
$this->update($input);
}
// // Clean up the agent list
// $oldAgent_deviceids = $this->find(
// // computer linked to the wrong agent
// "(`computers_id`='".$computers_id."' AND `device_id` <> '".$device_id."')");
// foreach ($oldAgent_deviceids as $oldAgent) {
// $this->delete($oldAgent);
// }
$oldAgents = $this->find(
// the same device_id but linked on the wrong computer
['device_id' => $device_id, 'computers_id' => ['!=', $computers_id]]);
foreach ($oldAgents as $oldAgent) {
$input = [];
$input['id'] = $agent['id'];
$input['last_contact'] = $oldAgent['last_contact'];
$input['version'] = $oldAgent['version'];
$input['name'] = $oldAgent['name'];
$input['useragent'] = $oldAgent['useragent'];
$input['token'] = $oldAgent['token'];
$input['tag'] = $oldAgent['tag'];
$input['entities_id'] = $entities_id;
$this->update($input);
$this->delete($oldAgent);
}
return true;
} else { // This is a new computer
// Link agent with computer
$agent = $this->infoByKey($device_id);
if (isset($agent['id'])) {
$agent['computers_id'] = $computers_id;
$agent['entities_id'] = $entities_id;
$this->update($agent);
return true;
}
}
return false;
}
/**
* Display form with the remotely status of agent (available, not available,
* waiting, running...)
*
* @global array $CFG_GLPI
* @param object $computer Computer object
*/
function showRemoteStatus($computer = null) {
global $CFG_GLPI;
/**
* Check for initialized agent
*/
if (!isset($this->fields['id'])) {
return;
}
/**
* Check for initialized $computer
*/
if (is_null($computer) || !isset($computer->fields['id'])) {
return;
}
$agent_id = $this->fields['id'];
$fi_path = Plugin::getWebDir('fusioninventory');
echo "<tr class='tab_bg_1'>";
echo "<td>";
echo __('Status')."&nbsp;:";
echo "</td>";
echo "<td>";
$load_anim = '<i class="fas fa-sync fa-spin fa-fw"></i>';
echo Html::scriptBlock("$(function() {
var waiting = false;
var refresh_status = function(display_refresh) {
var display_refresh = (typeof display_refresh !== 'undefined') ? display_refresh : true;
$('#agent_status').html('$load_anim');
$('#refresh_status').hide();
$('#force_inventory_button').hide();
$.get('$fi_path/ajax/remote_status.php', {
id: $agent_id,
action: 'get_status'
}, function(answer) {
if (typeof answer.waiting != 'undefined'
&& answer.waiting == true) {
$('#force_inventory_button').show();
waiting = true;
}
$('#agent_status').html(answer.message);
if (display_refresh) {
$('#refresh_status').show();
}
});
};
var force_inventory = function() {
$('#agent_status').html('$load_anim');
$('#refresh_status').hide();
waiting = false;
$('#force_inventory_button').hide();
$.get('$fi_path/ajax/remote_status.php', {
id: $agent_id,
action: 'start_agent'
}, function(answer) {
refresh_status(false);
displayAjaxMessageAfterRedirect();
// add a loop for checking status (set a max iterations to avoid infinite looping)
var loop_index = 0;
var myloop = setInterval(function() {
if (loop_index > 30 || waiting) {
clearInterval(myloop);
$('#refresh_status').show();
return;
}
refresh_status(false);
loop_index++;
}, 2000);
});
};
$(document)
.on('click', '#refresh_status', function() {
refresh_status();
})
.on('click', '#force_inventory_button', function() {
force_inventory();
});
});");
echo "<span id='agent_status'>".
__("not yet requested, refresh?", 'fusioninventory').
"</span>";
echo "<span id='refresh_status'><i class='fas fa-sync'></i></span>";
echo "</td>";
echo "<td colspan='2'>";
echo "<span id='force_inventory_button'>".
__('Force inventory', 'fusioninventory').
"</span>";
echo "</td>";
echo "</tr>";
}
/**
* Get the remotely status of the agent (available, not available, waiting,
* running...)
*
* @return array
*/
function getStatus() {
$url_addresses = $this->getAgentStatusURLs();
PluginFusioninventoryDisplay::disableDebug();
ob_start();
ini_set("allow_url_fopen", "1");
$ctx = stream_context_create([
'http' => [
'timeout' => 1
]
]
);
$contents="";
$url_ok = null;
$url_headers=[];
foreach ($url_addresses as $url) {
$stream = fopen($url, 'r', false, $ctx);
if ($stream) {
//$result = file_get_contents($url, FALSE, $ctx);
$contents = stream_get_contents($stream);
$url_headers[$url] = stream_get_meta_data($stream);
fclose($stream);
if ($contents !== false) {
$url_ok = $url;
break;
}
}
}
$error = ob_get_contents();
ob_end_clean();
PluginFusioninventoryDisplay::reenableusemode();
$status = [
"url_ok" => $url_ok,
"message" => ""
];
if ($contents !== "") {
$status['message'] = preg_replace("/^status: /", "", $contents);
}
if ($contents == '' AND !strstr($error, "failed to open stream: Permission denied")) {
$status['message'] = "noanswer";
}
return $status;
}
/**
* Send a request to the remotely agent to run now
*
* @return boolean true if send successfully, otherwise false
*/
function wakeUp() {
$ret = false;
PluginFusioninventoryDisplay::disableDebug();
$urls = $this->getAgentRunURLs();
$ctx = stream_context_create(['http' => ['timeout' => 2]]);
foreach ($urls as $url) {
if (!$ret) {
if (@file_get_contents($url, 0, $ctx) !== false) {
$ret = true;
break;
}
}
}
PluginFusioninventoryDisplay::reenableusemode();
return $ret;
}
/**
* Store version of each module of agent
*
* @param integer $agent_id id of the agent
* @param string $module name of the module (inventory, deploy...)
* @param string $version version of the module
*/
function setAgentVersions($agent_id, $module, $version) {
$this->getFromDB($agent_id);
$a_version = importArrayFromDB($this->fields['version']);
if (!is_array($a_version)) {
$versionTmp = $a_version;
$a_version = [];
$a_version["INVENTORY"] = $versionTmp;
}
$a_version[$module] = $version;
$input = [];
$input['id'] = $this->fields['id'];
$input['version'] = exportArrayToDB($a_version);
$this->update($input);
}
/**
* Get the version of agent (it's the same number as inventory module)
*
* @param integer $agent_id id of the agent
* @return string version of agent
*/
function getAgentVersion($agent_id) {
$this->getFromDB($agent_id);
$a_version = importArrayFromDB($this->fields['version']);
if (isset($a_version['INVENTORY'])) {
return str_replace('v', '', $a_version['INVENTORY']);
}
return '0';
}
/**
* get the agent by the device_id
*
* @param string $device_id the device_id sent by the agent
* @return array|false agent information if found, otherwise false
*/
static function getByDeviceID($device_id) {
$agents = getAllDataFromTable(
'glpi_plugin_fusioninventory_agents',
[
'device_id' => $device_id,
'lock' => 0
]
);
if (!empty($agents)) {
return array_pop($agents);
} else {
return false;
}
}
/**
* Get / generate the URLs to communicate with current agent
*
* @return array list of HTTP URL used to contact the agent
*/
public function getAgentBaseURLs() {
$config = new PluginFusioninventoryConfig();
$port = $config->getValue('agent_port');
$url_addresses = [];
if (isset($this->fields['id'])) {
$computer = $this->getAssociatedComputer();
if ($this->fields['agent_port'] != ''
&& is_numeric($this->fields['agent_port'])) {
$port = $this->fields['agent_port'];
}
if ($computer->fields["name"] && $computer->fields["name"] != "localhost") {
array_push($url_addresses, "http://".$computer->fields["name"].
":".$port);
$ditem = new Domain_Item();
if ($ditem->getFromDBByCrit(['itemtype' => 'Computer', 'items_id' => $computer->fields['id']])) {
$domain = new Domain();
$domain->getFromDB($ditem->fields['domains_id']);
array_push($url_addresses, "http://".
$computer->fields["name"].'.'.
$domain->fields["name"].
":".$port);
}
}
}
// Guess the machine name from the DEVICEID,
// useful when Windows domain != DNS domain
$stack = [];
if (preg_match('/(\S+)-\d{4}-\d{2}-\d{2}-\d{2}-\d{2}-\d{2}$/',
$this->fields['name'],
$stack)) {
array_push($url_addresses, "http://".$stack[1].":".$port);
}
$ip_addresses = $this->getIPs();
foreach ($ip_addresses as $ip_address) {
if ($ip_address != '') {
array_push($url_addresses, "http://".$ip_address.":".$port);
}
}
return $url_addresses;
}
/**
* Get the URLs used to get the status of the agent
*
* @return array list of HTTP URL to get the agent's state
*/
public function getAgentStatusURLs() {
$ret = [];
foreach ($this->getAgentBaseURLs() as $url) {
array_push($ret, $url."/status");
}
return $ret;
}
/**
* Get the URLs used to wake up the agent
*
* @return array liste of HTTP URL to ask the agent to wake up
*/
public function getAgentRunURLs() {
$ret = [];
foreach ($this->getAgentBaseURLs() as $url) {
array_push($ret, $url."/now/".$this->fields['token']);
}
return $ret;
}
/**
* Display configuration form of agent
*/
static function showConfig() {
echo "<table width='950' class='tab_cadre_fixe'>";
echo "<tr>";
echo "<th colspan='2'>";
echo __('Informations for agent configuration', 'fusioninventory');
echo "</th>";
echo "</tr>";
echo "<tr class='tab_bg_1'>";
echo "<td width='50%'>";
$array = explode("/", filter_input(INPUT_SERVER, "HTTP_REFERER"));
$create_url = $array[0]."//".$array[2].
str_replace("front/wizard.php", "", filter_input(INPUT_SERVER, "PHP_SELF"));
echo __('Communication url of the server', 'fusioninventory')."&nbsp;:";
echo "</td>";
echo "<td>";
echo "<strong>".$create_url."</strong>";
echo "</td>";
echo "</tr>";
echo "</table>";
}
/**
* Disable data to put in glpi_logs because don't want to write all these
* very often changes
*/
function pre_updateInDB() {
if (isset($this->oldvalues['version'])
AND $this->input['version'] == $this->oldvalues['version']) {
$key = array_search('version', $this->updates);
unset($this->oldvalues['version']);
}
if (isset($this->oldvalues['last_contact'])) {
$key = array_search('last_contact', $this->updates);
unset($this->oldvalues['last_contact']);
}
if (isset($this->oldvalues['token'])) {
$key = array_search('token', $this->updates);
unset($this->oldvalues['token']);
}
}
/**
* Display agent information for a computer
*
* @param Computer the computer
* @param integer $colspan the number of columns of the form (2 by default)
*/
function showInfoForComputer(Computer $computer, $colspan = 2) {
if ($this->getAgentWithComputerid($computer->getID())) {
echo '<tr class="tab_bg_1">';
echo '<td>'.__('Agent', 'fusioninventory').'</td>';
echo '<td>'.$this->getLink(1).'</td>';
if ($colspan == 2) {
echo '</tr>';
echo '<tr class="tab_bg_1">';
}
echo '<td>'.__('Useragent', 'fusioninventory').'</td>';
echo '<td>'.$this->fields['useragent'].'</td>';
echo '</tr>';
$this->showRemoteStatus($computer);
echo '<tr class="tab_bg_1">';
echo '<td>'.__('FusionInventory tag', 'fusioninventory').'</td>';
echo '<td>'.$this->fields['tag'].'</td>';
if ($colspan == 2) {
echo '</tr>';
echo '<tr class="tab_bg_1">';
}
echo '<td>';
echo __('Last contact', 'fusioninventory');
echo '</td>';
echo '<td>';
echo Html::convDateTime($this->fields['last_contact']);
echo '</td>';
echo '</tr>';
}
}
/**
* Cron task: clean or do defined action when agent not have been contacted
* the server since xx days
*
* @global object $DB
* @param object $task
* @return boolean true if successful, otherwise false
*/
static function cronCleanoldagents($task = null) {
global $DB;
$pfConfig = new PluginFusioninventoryConfig();
$pfAgent = new PluginFusioninventoryAgent();
$retentiontime = $pfConfig->getValue('agents_old_days');
if ($retentiontime == 0) {
return true;
}
$iterator = $DB->request([
'FROM' => 'glpi_plugin_fusioninventory_agents',
'WHERE' => [
'last_contact' => ['<', new QueryExpression("date_add(now(), interval -".$retentiontime." day)")]
]
]);
if (count($iterator)) {
$cron_status = false;
$action = $pfConfig->getValue('agents_action');
if ($action == PluginFusioninventoryConfig::ACTION_CLEAN) {
//delete agents
while ($data = $iterator->next()) {
$pfAgent->delete($data);
$task->addVolume(1);
$cron_status = true;
}
} else {
//change status of agents
while ($data = $iterator->next()) {
$computer = new Computer();
if ($computer->getFromDB($data['computers_id'])) {
$computer->update([
'id' => $data['computers_id'],
'states_id' => $pfConfig->getValue('agents_status')]);
$task->addVolume(1);
$cron_status = true;
}
}
}
}
return $cron_status;
}
}