1<?php 2 3/* 4 ------------------------------------------------------------------------ 5 FusionInventory 6 Copyright (C) 2010-2016 by the FusionInventory Development Team. 7 8 http://www.fusioninventory.org/ http://forge.fusioninventory.org/ 9 ------------------------------------------------------------------------ 10 11 LICENSE 12 13 This file is part of FusionInventory project. 14 15 FusionInventory is free software: you can redistribute it and/or modify 16 it under the terms of the GNU Affero General Public License as published by 17 the Free Software Foundation, either version 3 of the License, or 18 (at your option) any later version. 19 20 FusionInventory is distributed in the hope that it will be useful, 21 but WITHOUT ANY WARRANTY; without even the implied warranty of 22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 GNU Affero General Public License for more details. 24 25 You should have received a copy of the GNU Affero General Public License 26 along with FusionInventory. If not, see <http://www.gnu.org/licenses/>. 27 28 ------------------------------------------------------------------------ 29 30 @package FusionInventory 31 @author David Durieux 32 @co-author 33 @copyright Copyright (c) 2010-2016 FusionInventory team 34 @license AGPL License 3.0 or (at your option) any later version 35 http://www.gnu.org/licenses/agpl-3.0-standalone.html 36 @link http://www.fusioninventory.org/ 37 @link http://forge.fusioninventory.org/projects/fusioninventory-for-glpi/ 38 @since 2010 39 40 ------------------------------------------------------------------------ 41 */ 42 43if (!defined('GLPI_ROOT')) { 44 die("Sorry. You can't access directly to this file"); 45} 46 47class PluginFusioninventoryAgent extends CommonDBTM { 48 49 public $dohistory = TRUE; 50 51 static $rightname = 'plugin_fusioninventory_agent'; 52 53 /** 54 * Get name of this type 55 * 56 * @return text name of this type by language of the user connected 57 * 58 **/ 59 static function getTypeName($nb=0) { 60 return __('Agent', 'fusioninventory'); 61 } 62 63 64 65 function getSearchOptions() { 66 67 $tab = array(); 68 69 $tab['common'] = __('Agent', 'fusioninventory'); 70 71 $tab[1]['table'] = $this->getTable(); 72 $tab[1]['field'] = 'name'; 73 $tab[1]['linkfield'] = 'name'; 74 $tab[1]['name'] = __('Name'); 75 $tab[1]['datatype'] = 'itemlink'; 76 77 $tab[2]['table'] = 'glpi_entities'; 78 $tab[2]['field'] = 'completename'; 79 $tab[2]['name'] = __('Entity'); 80 $tab[2]['datatype'] = 'dropdown'; 81 82 $tab[3]['table'] = $this->getTable(); 83 $tab[3]['field'] = 'is_recursive'; 84 $tab[3]['linkfield'] = 'is_recursive'; 85 $tab[3]['name'] = __('Child entities'); 86 $tab[3]['datatype'] = 'bool'; 87 88 $tab[4]['table'] = $this->getTable(); 89 $tab[4]['field'] = 'last_contact'; 90 $tab[4]['linkfield'] = ''; 91 $tab[4]['name'] = __('Last contact', 'fusioninventory'); 92 $tab[4]['datatype'] = 'datetime'; 93 94 $tab[5]['table'] = $this->getTable(); 95 $tab[5]['field'] = 'lock'; 96 $tab[5]['linkfield'] = 'lock'; 97 $tab[5]['name'] = __('locked', 'fusioninventory'); 98 $tab[5]['datatype'] = 'bool'; 99 100 $tab[6]['table'] = $this->getTable(); 101 $tab[6]['field'] = 'device_id'; 102 $tab[6]['linkfield'] = 'device_id'; 103 $tab[6]['name'] = __('Device_id', 'fusioninventory'); 104 $tab[6]['datatype'] = 'text'; 105 $tab[6]['massiveaction'] = FALSE; 106 107 $tab[7]['table'] = 'glpi_computers'; 108 $tab[7]['field'] = 'name'; 109 $tab[7]['name'] = __('Computer link', 'fusioninventory'); 110 $tab[7]['datatype'] = 'itemlink'; 111 $tab[7]['itemlink_type'] = 'Computer'; 112 $tab[7]['massiveaction'] = FALSE; 113 114 $tab[8]['table'] = $this->getTable(); 115 $tab[8]['field'] = 'version'; 116 $tab[8]['linkfield'] = 'version'; 117 $tab[8]['name'] = __('Version'); 118 $tab[8]['datatype'] = 'text'; 119 $tab[8]['massiveaction'] = FALSE; 120 121 $tab[9]['table'] = $this->getTable(); 122 $tab[9]['field'] = 'token'; 123 $tab[9]['linkfield'] = 'token'; 124 $tab[9]['name'] = __('Token'); 125 $tab[9]['datatype'] = 'text'; 126 $tab[9]['massiveaction'] = FALSE; 127 128 $tab[10]['table'] = $this->getTable(); 129 $tab[10]['field'] = 'useragent'; 130 $tab[10]['linkfield'] = 'useragent'; 131 $tab[10]['name'] = __('Useragent', 'fusioninventory'); 132 $tab[10]['datatype'] = 'text'; 133 $tab[10]['massiveaction'] = FALSE; 134 135 $tab[11]['table'] = $this->getTable(); 136 $tab[11]['field'] = 'tag'; 137 $tab[11]['name'] = __('FusionInventory tag', 'fusioninventory'); 138 $tab[11]['datatype'] = 'text'; 139 $tab[11]['massiveaction'] = FALSE; 140 141 $tab[12]['table'] = $this->getTable(); 142 $tab[12]['field'] = 'threads_networkdiscovery'; 143 $tab[12]['name'] = __('Threads number', 'fusioninventory')." (". 144 strtolower(__('Network discovery', 'fusioninventory')). 145 ")"; 146 $tab[12]['datatype'] = 'integer'; 147 148 $tab[13]['table'] = $this->getTable(); 149 $tab[13]['field'] = 'threads_networkinventory'; 150 $tab[13]['name'] = __('Threads number', 'fusioninventory')." (". 151 strtolower(__('Network inventory (SNMP)', 'fusioninventory')). 152 ")"; 153 $tab[13]['datatype'] = 'integer'; 154 155 $tab[14]['table'] = $this->getTable(); 156 $tab[14]['field'] = 'agent_port'; 157 $tab[14]['linkfield'] = 'agent_port'; 158 $tab[14]['name'] = __('Agent port', 'fusioninventory'); 159 160 $i = 20; 161 $pfAgentmodule = new PluginFusioninventoryAgentmodule(); 162 $a_modules = $pfAgentmodule->find(); 163 foreach ($a_modules as $data) { 164 $tab[$i]['table'] = $pfAgentmodule->getTable(); 165 $tab[$i]['field'] = $data["modulename"]; 166 $tab[$i]['linkfield'] = $data["modulename"]; 167 $tab[$i]['name'] = __('Module', 'fusioninventory')." - ".$data["modulename"]; 168 $tab[$i]['datatype'] = 'bool'; 169 $tab[$i]['massiveaction'] = FALSE; 170 $i++; 171 } 172 return $tab; 173 } 174 175 176 177 function defineTabs($options=array()){ 178 179 $ong = array(); 180 $this->addDefaultFormTab($ong); 181 $this->addStandardTab('PluginFusioninventoryAgentmodule', $ong, $options); 182 $this->addStandardTab('Log', $ong, $options); 183 184 return $ong; 185 } 186 187 function getTabNameForItem(CommonGLPI $item, $withtemplate=0) { 188 global $CFG_GLPI; 189 $tab_names = array(); 190 if ( $this->can(0, CREATE) ) { 191 if ($item->getType() == 'Computer') { 192 $tab_names[] = __('FusInv', 'fusioninventory').' '. __('Agent'); 193 } 194 195 } 196 197 if (!empty($tab_names)) { 198 return $tab_names; 199 } else { 200 return ''; 201 } 202 } 203 204 static function displayTabContentForItem(CommonGLPI $item, $tabnum=1, $withtemplate=0) { 205 206 if ($item->getType() == 'Computer') { 207 208 // Possibility to remote agent 209 if (PluginFusioninventoryToolbox::isAllowurlfopen(1)) { 210 $pfAgent = new PluginFusioninventoryAgent(); 211 if ($pfAgent->getAgentWithComputerid($item->fields['id'])) { 212 $pfAgent->showRemoteStatus($item); 213 } 214 } 215 } 216 } 217 218 /** 219 * Display personalized comments (in tooltip) of item 220 */ 221 function getComments() { 222 223 $comment = __('Useragent', 'fusioninventory').' : '.$this->fields['useragent'].'<br/>'. 224 __('Last contact', 'fusioninventory').' : '. 225 Html::convDateTime($this->fields['last_contact']).' minutes'; 226 227 if (!empty($comment)) { 228 return Html::showToolTip($comment, array('display' => FALSE)); 229 } 230 return $comment; 231 } 232 233 234 235 /** 236 * Massive action () 237 */ 238 function getSpecificMassiveActions($checkitem=NULL) { 239 240 $actions = array(); 241 if (Session::haveRight("plugin_fusioninventory_agent", UPDATE)) { 242 $pfAgentmodule = new PluginFusioninventoryAgentmodule(); 243 $a_modules = $pfAgentmodule->find(); 244 foreach ($a_modules as $data) { 245 $actions[__CLASS__.MassiveAction::CLASS_ACTION_SEPARATOR.$data["modulename"]] = 246 __('Module', 'fusioninventory')." - ".$data['modulename']; 247 } 248 $actions[__CLASS__.MassiveAction::CLASS_ACTION_SEPARATOR.'transfert'] = __('Transfer'); 249 } 250 251 return $actions; 252 } 253 254 255 256 /** 257 * @since version 0.85 258 * 259 * @see CommonDBTM::showMassiveActionsSubForm() 260 **/ 261 static function showMassiveActionsSubForm(MassiveAction $ma) { 262 263 switch ($ma->getAction()) { 264 case 'transfert' : 265 Dropdown::show('Entity'); 266 echo "<br><br>".Html::submit(__('Post'), 267 array('name' => 'massiveaction')); 268 return true; 269 270 } 271 $pfAgentmodule = new PluginFusioninventoryAgentmodule(); 272 $a_modules = $pfAgentmodule->find(); 273 foreach ($a_modules as $data) { 274 if ($ma->getAction() == $data['modulename']) { 275 Dropdown::showYesNo($ma->getAction()); 276 echo "<br><br>".Html::submit(__('Post'), 277 array('name' => 'massiveaction')); 278 return true; 279 } 280 } 281 return parent::showMassiveActionsSubForm($ma); 282 } 283 284 285 286 static function processMassiveActionsForOneItemtype(MassiveAction $ma, CommonDBTM $item, 287 array $ids) { 288 289 $pfAgent = new self(); 290 291 switch ($ma->getAction()) { 292 293 case 'transfert' : 294 foreach ($ids as $key) { 295 if ($pfAgent->getFromDB($key)) { 296 $input = array(); 297 $input['id'] = $key; 298 $input['entities_id'] = $_POST['entities_id']; 299 if ($pfAgent->update($input)) { 300 //set action massive ok for this item 301 $ma->itemDone($item->getType(), $key, MassiveAction::ACTION_OK); 302 } else { 303 // KO 304 $ma->itemDone($item->getType(), $key, MassiveAction::ACTION_KO); 305 } 306 } 307 } 308 return; 309 break; 310 } 311 312 $pfAgentmodule = new PluginFusioninventoryAgentmodule(); 313 $a_modules = $pfAgentmodule->find(); 314 foreach ($a_modules as $data2) { 315 if ($ma->getAction() == $data2['modulename']) { 316 foreach ($ids as $key) { 317 if ($ma->POST[$data2['modulename']] == $data2['is_active']) { 318 // Remove from exceptions 319 $a_exceptions = importArrayFromDB($data2['exceptions']); 320 if (in_array($key, $a_exceptions)) { 321 foreach ($a_exceptions as $key2=>$value2) { 322 if ($value2 == $key) { 323 unset($a_exceptions[$key2]); 324 } 325 } 326 } 327 $data2['exceptions'] = exportArrayToDB($a_exceptions); 328 } else { 329 // Add to exceptions 330 $a_exceptions = importArrayFromDB($data2['exceptions']); 331 if (!in_array($key, $a_exceptions)) { 332 $a_exceptions[] = (string)$key; 333 } 334 $data2['exceptions'] = exportArrayToDB($a_exceptions); 335 } 336 $ma->itemDone($item->getType(), $key, MassiveAction::ACTION_OK); 337 } 338 $pfAgentmodule->update($data2); 339 } 340 } 341 342 return; 343 } 344 345 346 347 /** 348 * Display form for agent configuration 349 * 350 * @param $computers_id integer ID of the agent 351 * @param $options array 352 * 353 * @return bool TRUE if form is ok 354 * 355 **/ 356 function showForm($computers_id, $options=array()) { 357 358 359 if ($computers_id!='') { 360 $this->getFromDB($computers_id); 361 } else { 362 $this->getEmpty(); 363 $pfConfig = new PluginFusioninventoryConfig(); 364 unset($this->fields['id']); 365 $this->fields['threads_networkdiscovery'] = 366 $pfConfig->getValue('threads_networkdiscovery'); 367 $this->fields['timeout_networkdiscovery'] = 368 $pfConfig->getValue('timeout_networkdiscovery'); 369 $this->fields['threads_networkinventory'] = 370 $pfConfig->getValue('threads_networkinventory'); 371 $this->fields['timeout_networkinventory'] = 372 $pfConfig->getValue('timeout_networkinventory'); 373 $this->fields['senddico'] = 0; 374 } 375 $this->initForm($computers_id, $options); 376 $this->showFormHeader($options); 377 378 echo "<tr class='tab_bg_1'>"; 379 echo "<td>".__('Name')." :</td>"; 380 echo "<td align='center'>"; 381 Html::autocompletionTextField($this,'name', array('size' => 40)); 382 echo "</td>"; 383 echo "<td>".__('Device_id', 'fusioninventory')." :</td>"; 384 echo "<td align='center'>"; 385 echo $this->fields["device_id"]; 386 echo "</td>"; 387 echo "</tr>"; 388 389 echo "<tr class='tab_bg_1'>"; 390 echo "<td>".__('Computer link', 'fusioninventory')." :</td>"; 391 echo "<td align='center'>"; 392 if (!empty($this->fields["computers_id"])) { 393 $oComputer = new Computer(); 394 $oComputer->getFromDB($this->fields["computers_id"]); 395 echo $oComputer->getLink(1); 396 echo Html::hidden('computers_id', 397 array('value' => $this->fields["computers_id"])); 398 } else { 399 Computer_Item::dropdownConnect("Computer", "Computer", 'computers_id', 400 $_SESSION['glpiactive_entity']); 401 } 402 echo "</td>"; 403 echo "<td>".__('Token')." :</td>"; 404 echo "<td align='center'>"; 405 echo $this->fields["token"]; 406 echo "</td>"; 407 echo "</tr>"; 408 409 echo "<tr class='tab_bg_1'>"; 410 echo "<td>".__('locked', 'fusioninventory')." :</td>"; 411 echo "<td align='center'>"; 412 Dropdown::showYesNo('lock', $this->fields["lock"]); 413 echo "</td>"; 414 echo "<td>".__('Version')." :</td>"; 415 echo "<td align='center'>"; 416 $a_versions = importArrayFromDB($this->fields["version"]); 417 foreach ($a_versions as $module => $version) { 418 echo "<strong>".$module. "</strong>: ".$version."<br/>"; 419 } 420 echo "</td>"; 421 echo "</tr>"; 422 423 echo "<tr class='tab_bg_1'>"; 424 echo "<td>".__('Threads number', 'fusioninventory')." ". 425 "(".strtolower(__('Network discovery', 'fusioninventory')).") :</td>"; 426 echo "<td align='center'>"; 427 Dropdown::showNumber("threads_networkdiscovery", array( 428 'value' => $this->fields["threads_networkdiscovery"], 429 'min' => 1, 430 'max' => 400) 431 ); 432 433 echo "</td>"; 434 echo "<td>".__('Useragent', 'fusioninventory')." :</td>"; 435 echo "<td align='center'>"; 436 echo $this->fields["useragent"]; 437 echo "</td>"; 438 echo "</tr>"; 439 440 echo "<tr class='tab_bg_1'>"; 441 echo "<td>".__('SNMP timeout', 'fusioninventory')." ". 442 "(".strtolower(__('Network discovery', 'fusioninventory')).") :</td>"; 443 echo "<td align='center'>"; 444 Dropdown::showNumber("timeout_networkdiscovery", array( 445 'value' => $this->fields["timeout_networkdiscovery"], 446 'min' => 0, 447 'max' => 60) 448 ); 449 echo "</td>"; 450 echo "<td>".__('Last contact', 'fusioninventory')." :</td>"; 451 echo "<td align='center'>"; 452 echo Html::convDateTime($this->fields["last_contact"]); 453 echo "</td>"; 454 echo "</tr>"; 455 456 457 echo "<tr class='tab_bg_1'>"; 458 echo "<td>".__('Threads number', 'fusioninventory')." ". 459 "(".strtolower(__('Network inventory (SNMP)', 'fusioninventory')).") :</td>"; 460 echo "<td align='center'>"; 461 Dropdown::showNumber("threads_networkinventory", array( 462 'value' => $this->fields["threads_networkinventory"], 463 'min' => 1, 464 'max' => 400) 465 ); 466 echo "</td>"; 467 echo "<td>".__('FusionInventory tag', 'fusioninventory')." :</td>"; 468 echo "<td align='center'>"; 469 echo $this->fields["tag"]; 470 echo "</td>"; 471 echo "</tr>"; 472 473 echo "<td>".__('SNMP timeout', 'fusioninventory')." ". 474 "(".strtolower(__('Network inventory (SNMP)', 'fusioninventory')).") :</td>"; 475 echo "<td align='center'>"; 476 Dropdown::showNumber("timeout_networkinventory", array( 477 'value' => $this->fields["timeout_networkinventory"], 478 'min' => 0, 479 'max' => 60) 480 ); 481 echo "</td>"; 482 echo "<td colspan='2'>"; 483 echo "</td>"; 484 echo "</tr>"; 485 486 echo "<tr class='tab_bg_1'>"; 487 $pfConfig = new PluginFusioninventoryConfig(); 488 echo "<td>".__('Agent port', 'fusioninventory')." (". 489 __('if empty use port configured in general options', 'fusioninventory') 490 ." <i>".$pfConfig->getValue('agent_port')."</i>) :</td>"; 491 echo "<td align='center'>"; 492 echo "<input type='text' name='agent_port' value='".$this->fields['agent_port']."'/>"; 493 echo "</td>"; 494 echo "<td colspan='2'>"; 495 echo "</td>"; 496 echo "</tr>"; 497 498 $this->showFormButtons($options); 499 500 return TRUE; 501 } 502 503 504 505 /** 506 * Get agent informations by device_id 507 * 508 * @param $device_id value device_id unique of agent (key) 509 * 510 * @return array all DB fields of this agent 511 * 512 **/ 513 function InfosByKey($device_id) { 514 global $DB; 515 516 $query = "SELECT * FROM `".$this->getTable()."` 517 WHERE `device_id`='".$device_id."' LIMIT 1"; 518 519 $agent = array(); 520 $result = $DB->query($query); 521 if ($result) { 522 if ($DB->numrows($result) != 0) { 523 $agent = $DB->fetch_assoc($result); 524 } 525 } 526 return $agent; 527 } 528 529 530 531 /** 532 * Import agent : create if not exist and update if yet exist 533 * 534 * @param $p_xml simpleXMLobject 535 * 536 **/ 537 function importToken($arrayinventory) { 538 539 if (isset($arrayinventory['DEVICEID'])) { 540 $pfAgent = new PluginFusioninventoryAgent(); 541 $a_agent = $pfAgent->find("`device_id`='".$arrayinventory['DEVICEID']."'", "", "1"); 542 if (empty($a_agent)) { 543 $a_input = array(); 544 if (isset($arrayinventory['TOKEN'])) { 545 $a_input['token'] = $arrayinventory['TOKEN']; 546 } 547 $a_input['name'] = $arrayinventory['DEVICEID']; 548 $a_input['device_id'] = $arrayinventory['DEVICEID']; 549 $a_input['entities_id'] = 0; 550 $a_input['last_contact'] = date("Y-m-d H:i:s"); 551 if (isset($_SERVER['HTTP_USER_AGENT'])) { 552 $a_input['useragent'] = $_SERVER['HTTP_USER_AGENT']; 553 } 554 return $pfAgent->add($a_input); 555 } else { 556 foreach ($a_agent as $data) { 557 $input = array(); 558 $input['id'] = $data['id']; 559 if (isset($arrayinventory['TOKEN'])) { 560 $input['token'] = $arrayinventory['TOKEN']; 561 } 562 $input['last_contact'] = date("Y-m-d H:i:s"); 563 if (isset($_SERVER['HTTP_USER_AGENT'])) { 564 $input['useragent'] = $_SERVER['HTTP_USER_AGENT']; 565 } 566 $pfAgent->update($input); 567 return $data['id']; 568 } 569 } 570 } 571 return; 572 } 573 574 575 576 /** 577 * Get all IP of an agent or a computer 578 * 579 * @param $items_id integer ID of the item 580 * @param $type 'Agent' by default to get IP of agent or of a computer if set other text 581 * 582 * @return Every IP addresses registered for this agent or false 583 * 584 **/ 585 function getIPs() { 586 $ip_addresses = array(); 587 588 $computers_id = 0; 589 590 if (isset($this->fields['computers_id']) ) { 591 if ( $this->fields['computers_id'] > 0 ) { 592 } 593 } else { 594 trigger_error('Agent must be initialized'); 595 } 596 597 $ip_addresses = PluginFusioninventoryToolbox::getIPforDevice('Computer', $this->fields['computers_id']); 598 599 return $ip_addresses; 600 } 601 602 603 604 /** 605 * Get agent id of a computer 606 * 607 * @param $computers_id integer ID of the computer 608 * 609 * @return agent id or False 610 * 611 **/ 612 function getAgentWithComputerid($computers_id) { 613 614 $agent = $this->find("`computers_id`='".$computers_id."'", "", 1); 615 616 if (count($agent) == '1') { 617 $data = current($agent); 618 $this->getFromDB($data['id']); 619 return $data['id']; 620 } 621 return FALSE; 622 } 623 624 /** 625 * Get agent id of a computer 626 * 627 * @param $computers_id integer ID of the computer 628 * 629 * @return agent id or False 630 * 631 **/ 632 function getAgentsFromComputers($computer_ids = array()) { 633 634 if (count($computer_ids) == 0) { 635 return array(); 636 } 637 638 $computer_ids = "'" . implode("','", $computer_ids) . "'"; 639 640 $agents = $this->find("`computers_id` in (".$computer_ids.")", ""); 641 642 return $agents; 643 } 644 645 /** 646 * Get Computer associated with this agent 647 * 648 * @return A Computer object or False 649 * 650 **/ 651 652 function getAssociatedComputer() { 653 654 $computer = new Computer(); 655 656 if (!isset($this->fields['id'])) { 657 trigger_error("Agent must be initialized!"); 658 return false; 659 } 660 661 $computer->getFromDB($this->fields['computers_id']); 662 return $computer; 663 } 664 665 666 /** 667 * Create links between agent and computer. 668 * 669 * @param $computers_id integer ID of the computer 670 * @param $device_id value of device_id from XML to identify agent 671 * @param $entities_id integer ID of the computer entity 672 * 673 * @return Nothing 674 * 675 **/ 676 function setAgentWithComputerid($computers_id, $device_id, $entities_id) { 677 678 $a_agent = $this->find("`computers_id`='".$computers_id."'", "", 1); 679 // Is this computer already linked to an agent? 680 $agent = array_shift($a_agent); 681 if (is_array($agent)) { 682 683 // relation 684 if ($agent['device_id'] != $device_id 685 || $agent['entities_id'] != $entities_id) { 686 $input = array(); 687 $input['id'] = $agent['id']; 688 $input['device_id'] = $device_id; 689 $input['entities_id'] = $entities_id; 690 $this->update($input); 691 } 692 693// // Clean up the agent list 694// $oldAgent_deviceids = $this->find( 695// // computer linked to the wrong agent 696// "(`computers_id`='".$computers_id."' AND `device_id` <> '".$device_id."')"); 697// foreach ($oldAgent_deviceids as $oldAgent) { 698// $this->delete($oldAgent); 699// } 700 $oldAgents = $this->find( 701 // the same device_id but linked on the wrong computer 702 "(`device_id`='".$device_id."' AND `computers_id`<>'".$computers_id."')"); 703 foreach ($oldAgents as $oldAgent) { 704 $input = array(); 705 $input['id'] = $agent['id']; 706 $input['last_contact'] = $oldAgent['last_contact']; 707 $input['version'] = $oldAgent['version']; 708 $input['name'] = $oldAgent['name']; 709 $input['useragent'] = $oldAgent['useragent']; 710 $input['token'] = $oldAgent['token']; 711 $input['tag'] = $oldAgent['tag']; 712 $input['entities_id'] = $entities_id; 713 $this->update($input); 714 $this->delete($oldAgent); 715 } 716 return TRUE; 717 } else { # This is a new computer 718 // Link agent with computer 719 $agent = $this->InfosByKey($device_id); 720 if (isset($agent['id'])) { 721 $agent['computers_id'] = $computers_id; 722 $agent['entities_id'] = $entities_id; 723 $this->update($agent); 724 return TRUE; 725 } 726 } 727 return FALSE; 728 } 729 730 731 732 /** 733 * Display if agent is online 734 * 735 * @return Nothing (display) 736 * 737 **/ 738 function showRemoteStatus($computer = null) { 739 global $CFG_GLPI; 740 741 /** 742 * Check for initialized agent 743 */ 744 if (!isset($this->fields['id'])) { 745 return; 746 } 747 748 /** 749 * Check for initialized $computer 750 */ 751 if ( is_null($computer) && !isset($computer->fields['id']) ) { 752 return; 753 } 754 755 $agent_id = $this->fields['id']; 756 757 $pfTaskjob = new PluginFusioninventoryTaskjob(); 758 759 echo "<form method='post' name='' id='' action=\"".$CFG_GLPI['root_doc'] . 760 "/plugins/fusioninventory/front/agent.form.php\">"; 761 echo "<table class='tab_cadre' width='500'>"; 762 763 echo "<tr>"; 764 echo "<th colspan='2'>"; 765 echo __('Agent state', 'fusioninventory'); 766 echo "</th>"; 767 echo "</tr>"; 768 769 echo "<tr class='tab_bg_1'>"; 770 echo "<td>"; 771 echo __('Agent', 'fusioninventory')." :"; 772 echo "</td>"; 773 echo "<td>"; 774 echo $this->getLink(1); 775 echo "</td>"; 776 echo "</tr>"; 777 778 echo "<tr class='tab_bg_1'>"; 779 echo "<td>"; 780 echo __('Status')." :"; 781 echo "</td>"; 782 echo "<td>"; 783 784 $waiting = 0; 785 786 $agentStatus = $this->getStatus(); 787 788 switch($agentStatus['message']) { 789 790 case 'executing scheduled tasks': 791 case 'running': 792 echo __('Running'); 793 break; 794 795 case 'noanswer': 796 echo __('Impossible to communicate with agent!', 'fusioninventory'); 797 break; 798 799 case 'waiting': 800 $waiting = 1; 801 echo __( 802 'Available on <a target="_blank" href="'. $agentStatus['url_ok'] . '">' . 803 $agentStatus['url_ok'] . 804 '</a>' 805 ); 806 echo Html::hidden('agent_id', array('value' => $agent_id)); 807 break; 808 809 default: 810 if (strstr($agentStatus['message'], 'running')) { 811 echo $agentStatus['message']; 812 } else { 813 echo "SELinux problem, do 'setsebool -P httpd_can_network_connect on'"; 814 } 815 break; 816 817 } 818 819 echo "</td>"; 820 echo "</tr>"; 821 822 if ($waiting == '1') { 823 echo "<tr>"; 824 echo "<th colspan='2'>"; 825 echo "<input name='startagent' value=\"".__('Force inventory', 'fusioninventory'). 826 "\" class='submit' type='submit'>"; 827 echo "</th>"; 828 echo "</tr>"; 829 } 830 831 echo "</table>"; 832 Html::closeForm(); 833 echo "<br/>"; 834 } 835 836 /** 837 * Get current state of the agent 838 * 839 * @param $items_id integer id of the agent 840 * 841 * @return string message/state of the agent 842 * 843 */ 844 function getStatus() { 845 846 $url_addresses = $this->getAgentStatusURLs(); 847 848 $this->disableDebug(); 849 850 ob_start(); 851 ini_set("allow_url_fopen", "1"); 852 853 $ctx = stream_context_create(array( 854 'http' => array( 855 'timeout' => 1 856 ) 857 ) 858 ); 859 860 $contents=""; 861 $url_ok = null; 862 $url_headers=array(); 863 foreach( $url_addresses as $url) { 864 if ( $stream = fopen($url, 'r', false, $ctx) ) { 865 //$result = file_get_contents($url, FALSE, $ctx); 866 $contents = stream_get_contents($stream); 867 $url_headers[$url] = stream_get_meta_data($stream); 868 fclose($stream); 869 if ($contents !== false) { 870 $url_ok = $url; 871 break; 872 } 873 } 874 } 875 $error = ob_get_contents(); 876 ob_end_clean(); 877 $this->restoreDebug(); 878 879 $status = array( 880 "url_ok" => $url_ok, 881 "message" => "" 882 ); 883 884 if ($contents !== "") { 885 $status['message'] = preg_replace("/^status: /", "", $contents); 886 } 887 888 if ($contents == '' AND !strstr($error, "failed to open stream: Permission denied")) { 889 $status['message'] = "noanswer"; 890 } 891 892 return $status; 893 } 894 895 896 /** 897 * Start agent remotly from server 898 * 899 * @param $agent_id integer id of the agent 900 * 901 * @return bool TRUE if agent wake up 902 * 903 **/ 904 function wakeUp() { 905 906 $ret = FALSE; 907 908 $this->disableDebug(); 909 $urls = $this->getAgentRunURLs(); 910 911 $ctx = stream_context_create(array('http' => array('timeout' => 2))); 912 foreach ( $urls as $url ) { 913 if (!$ret) { 914 if (@file_get_contents($url, 0, $ctx) !== FALSE) { 915 $ret = TRUE; 916 break; 917 } 918 } 919 } 920 $this->restoreDebug(); 921 922 return $ret; 923 } 924 925 /** 926 * Get state of agent 927 * 928 * @param $ip value IP address of the computer where agent is installed 929 * @param $agentid integer id of the agent 930 * 931 * @return bool TRUE if agent is ready else FALSE 932 * 933 **/ 934 function isAgentAlive() { 935 936 if ( $this->getStatus() === 'waiting') { 937 return true; 938 } 939 940 return false; 941 } 942 943 944 /** 945 * Disable debug mode because we don't want the errors 946 * 947 **/ 948 function disableDebug() { 949 error_reporting(0); 950 set_error_handler(array($this, 'errorempty')); 951 } 952 953 /** 954 * When debug is disabled, we transfer every errors in this emtpy function. 955 * 956 **/ 957 static function errorempty() {} 958 959 /** 960 * Resotre debug mode if it has been explicitely set by the user in his settings. 961 * 962 **/ 963 function restoreDebug() { 964 if ($_SESSION['glpi_use_mode'] == Session::DEBUG_MODE){ 965 ini_set('display_errors', 'On'); 966 // Recommended development settings 967 error_reporting(E_ALL | E_STRICT); 968 set_error_handler(array('Toolbox', 'userErrorHandlerDebug')); 969 } else { 970 ini_set('display_errors', 'Off'); 971 error_reporting(E_ALL); 972 set_error_handler(array('Toolbox', 'userErrorHandlerNormal')); 973 } 974 975 } 976 977 /** 978 * Set agent version of each module 979 * 980 * @param $agent_id integer ID of the agent 981 * @param $module value Module name (WAKEONLAN, NETWORKDISCOVERY, INVENTORY, NETWORKINVENTORY...) 982 * @param $version value version of the module 983 * 984 * @return nothing 985 * 986 **/ 987 function setAgentVersions($agent_id, $module, $version) { 988 $this->getFromDB($agent_id); 989 $a_version = importArrayFromDB($this->fields['version']); 990 if (!is_array($a_version)) { 991 $versionTmp = $a_version; 992 $a_version = array(); 993 $a_version["INVENTORY"] = $versionTmp; 994 } 995 $a_version[$module] = $version; 996 $input = array(); 997 $input['id'] = $this->fields['id']; 998 $input['version'] = exportArrayToDB($a_version); 999 $this->update($input); 1000 } 1001 1002 1003 1004 /** 1005 * Get agent version 1006 * 1007 * @param type $agent_id 1008 */ 1009 function getAgentVersion($agent_id) { 1010 $this->getFromDB($agent_id); 1011 $a_version = importArrayFromDB($this->fields['version']); 1012 if (isset($a_version['INVENTORY'])) { 1013 return str_replace('v', '', $a_version['INVENTORY']); 1014 } 1015 return '0'; 1016 } 1017 1018 1019 1020 /** 1021 * Return an agent by it deviceid 1022 * 1023 * @param device_id the device_id coming from the agent itself 1024 * 1025 * @return an array with the agent's attributes or an empty array if no agent found 1026 */ 1027 static function getByDeviceID($device_id) { 1028 $agents = getAllDatasFromTable('glpi_plugin_fusioninventory_agents', 1029 "`device_id`='$device_id' AND `lock`='0'"); 1030 if (!empty($agents)) { 1031 return array_pop($agents); 1032 } else { 1033 return FALSE; 1034 } 1035 } 1036 1037 1038 1039 /** 1040 * Get base URL to communicate with an agent 1041 * 1042 * @param ip agent's IP 1043 * 1044 * @return a list of http url to contact the agent 1045 */ 1046 public function getAgentBaseURLs() { 1047 $config = new PluginFusioninventoryConfig(); 1048 1049 $port = $config->getValue('agent_port'); 1050 $url_addresses = array(); 1051 1052 1053 if ( isset($this->fields['id']) ) { 1054 $computer = $this->getAssociatedComputer(); 1055 if ($this->fields['agent_port'] != '' 1056 && is_numeric($this->fields['agent_port'])) { 1057 $port = $this->fields['agent_port']; 1058 } 1059 if ($computer->fields["name"] && $computer->fields["name"] != "localhost") { 1060 array_push($url_addresses, "http://".$computer->fields["name"]. 1061 ":".$port); 1062 1063 $domain = new Domain(); 1064 if ($computer->fields['domains_id'] != 0) { 1065 $domain->getFromDB($computer->fields['domains_id']); 1066 array_push($url_addresses, "http://". 1067 $computer->fields["name"].'.'. 1068 $domain->fields["name"]. 1069 ":".$port); 1070 } 1071 } 1072 } 1073 1074 # Guess the machine name from the DEVICEID, 1075 # useful when Windows domain != DNS domain 1076 $stack = array(); 1077 if(preg_match('/(\S+)-\d{4}-\d{2}-\d{2}-\d{2}-\d{2}-\d{2}$/', 1078 $this->fields['name'], 1079 $stack)) { 1080 array_push($url_addresses, "http://".$stack[1].":".$port); 1081 } 1082 1083 $ip_addresses = $this->getIPs(); 1084 foreach ($ip_addresses as $ip_address) { 1085 if ($ip_address != '') { 1086 array_push($url_addresses, "http://".$ip_address.":".$port); 1087 } 1088 } 1089 return $url_addresses; 1090 } 1091 1092 1093 1094 /** 1095 * URL to get agent's state 1096 * 1097 * @param ip agent's IP 1098 * 1099 * @return an array of http url to get the agent's state 1100 */ 1101 public function getAgentStatusURLs() { 1102 $ret = array(); 1103 1104 foreach ($this->getAgentBaseURLs() as $url) { 1105 array_push($ret, $url."/status"); 1106 } 1107 return $ret; 1108 } 1109 1110 1111 1112 /** 1113 * URL to ask the agent to wake up 1114 * 1115 * @param interger agents_id agent id 1116 * 1117 * @return an http url to ask the agent to wake up 1118 */ 1119 public function getAgentRunURLs() { 1120 $ret = array(); 1121 1122 foreach ($this->getAgentBaseURLs() as $url) { 1123 array_push($ret, $url."/now/".$this->fields['token']); 1124 } 1125 return $ret; 1126 } 1127 1128 1129 1130 /** 1131 * Show configuration form of agent 1132 * 1133 */ 1134 static function showConfig() { 1135 1136 echo "<table width='950' class='tab_cadre_fixe'>"; 1137 1138 echo "<tr>"; 1139 echo "<th colspan='2'>"; 1140 echo __('Informations for agent configuration', 'fusioninventory'); 1141 1142 echo "</th>"; 1143 echo "</tr>"; 1144 1145 echo "<tr class='tab_bg_1'>"; 1146 echo "<td width='50%'>"; 1147 $array = explode("/", $_SERVER['HTTP_REFERER']); 1148 $create_url = $array[0]."//".$array[2]. 1149 str_replace("front/wizard.php", "", $_SERVER['PHP_SELF']); 1150 echo __('Communication url of the server', 'fusioninventory')." :"; 1151 echo "</td>"; 1152 echo "<td>"; 1153 echo "<strong>".$create_url."</strong>"; 1154 1155 echo "</td>"; 1156 echo "</tr>"; 1157 echo "</table>"; 1158 } 1159 1160 1161 1162 /** 1163 * Disable data to put in table glpi_logs 1164 * 1165 */ 1166 function pre_updateInDB() { 1167 if (isset($this->oldvalues['version']) 1168 AND $this->input['version'] == $this->oldvalues['version']) { 1169 1170 $key = array_search('version', $this->updates); 1171 unset($this->updates[$key]); 1172 unset($this->oldvalues['version']); 1173 } 1174 if (isset($this->oldvalues['last_contact'])) { 1175 $key = array_search('last_contact', $this->updates); 1176 unset($this->oldvalues['last_contact']); 1177 } 1178 if (isset($this->oldvalues['token'])) { 1179 $key = array_search('token', $this->updates); 1180 unset($this->oldvalues['token']); 1181 } 1182 } 1183 1184 1185 1186 /** 1187 * Display agent infos for a computer 1188 * 1189 * @param type $computers_id id of the computer 1190 */ 1191 function showInfoForComputer($computers_id) { 1192 1193 if ($this->getAgentWithComputerid($computers_id)) { 1194 1195 echo '<tr class="tab_bg_1">'; 1196 echo '<td>'.__('Agent', 'fusioninventory').'</td>'; 1197 echo '<td>'.$this->getLink(1).'</td>'; 1198 echo '</tr>'; 1199 1200 echo '<tr class="tab_bg_1">'; 1201 echo '<td>'.__('Useragent', 'fusioninventory').'</td>'; 1202 echo '<td>'.$this->fields['useragent'].'</td>'; 1203 echo '</tr>'; 1204 1205 echo '<tr class="tab_bg_1">'; 1206 echo '<td>'.__('FusionInventory tag', 'fusioninventory').'</td>'; 1207 echo '<td>'.$this->fields['tag'].'</td>'; 1208 echo '</tr>'; 1209 } 1210 } 1211 1212 1213 1214 /** 1215 * Clean agent too old (so haven't contacted glpi 1216 * since xx days) 1217 * 1218 * @return bool cron is ok or not 1219 * 1220 **/ 1221 static function cronCleanoldagents($task=NULL) { 1222 global $DB; 1223 1224 $pfConfig = new PluginFusioninventoryConfig(); 1225 $pfAgent = new PluginFusioninventoryAgent(); 1226 1227 $retentiontime = $pfConfig->getValue('agents_old_days'); 1228 if ($retentiontime == 0) { 1229 return TRUE; 1230 } 1231 $sql = "SELECT * FROM `glpi_plugin_fusioninventory_agents` 1232 WHERE `last_contact` < date_add(now(), interval -".$retentiontime." day)"; 1233 $result = $DB->query($sql); 1234 1235 if ($result) { 1236 $cron_status = FALSE; 1237 $action = $pfConfig->getValue('agents_action'); 1238 if ($action == PluginFusioninventoryConfig::ACTION_CLEAN) { 1239 //delete agents 1240 while ($data = $DB->fetch_array($result)) { 1241 $pfAgent->delete($data); 1242 $task->addVolume(1); 1243 $cron_status = TRUE; 1244 } 1245 } else { 1246 //change status of agents 1247 while ($data = $DB->fetch_array($result)) { 1248 $computer = new Computer(); 1249 if($computer->getFromDB($data['computers_id'])){ 1250 $computer->update(array( 1251 'id' => $data['computers_id'], 1252 'states_id' => $pfConfig->getValue('agents_status'))); 1253 $task->addVolume(1); 1254 $cron_status = TRUE; 1255 } 1256 } 1257 } 1258 } 1259 return $cron_status; 1260 } 1261 1262} 1263 1264?> 1265