/** * @test */ public function getDevicesToInventory() { global $DB; // Verify prepare a network discovery task $DB->connect(); $pfNetworkinventory = new PluginFusioninventoryNetworkinventory(); $jobstate = new PluginFusioninventoryTaskjobstate(); $jobstate->getFromDB(1); $data = $pfNetworkinventory->run($jobstate); $this->mark_incomplete("This test doesn't assert anything! Also, there are too much notices thrown ... needs" . "investigations."); }
function prepareRun($taskjobs_id) { $pfTask = new PluginFusioninventoryTask(); $pfTaskjob = new PluginFusioninventoryTaskjob(); $pfTaskjoblog = new PluginFusioninventoryTaskjoblog(); $pfTaskjobstate = new PluginFusioninventoryTaskjobstate(); $pfAgentmodule = new PluginFusioninventoryAgentmodule(); $pfIPRange = new PluginFusioninventoryIPRange(); $pfAgent = new PluginFusioninventoryAgent(); $uniqid = uniqid(); $pfTaskjob->getFromDB($taskjobs_id); $pfTask->getFromDB($pfTaskjob->fields['plugin_fusioninventory_tasks_id']); $communication = $pfTask->fields['communication']; //list all iprange $a_iprange = importArrayFromDB($pfTaskjob->fields['definition']); $count_ip = 0; $a_iprangelist = array(); $a_subnet_nbip = array(); foreach ($a_iprange as $iprange) { $iprange_id = current($iprange); $a_iprangelist[] = $iprange_id; $pfIPRange->getFromDB($iprange_id); $s = $pfIPRange->getIp2long($pfIPRange->fields['ip_start']); $e = $pfIPRange->getIp2long($pfIPRange->fields['ip_end']); $a_subnet_nbip[$iprange_id] = $e - $s; $count_ip += $e - $s; } //list all agents $a_agent = importArrayFromDB($pfTaskjob->fields['action']); $dynagent = 0; $a_agentlist = array(); foreach ($a_agent as $agent) { $agent_id = current($agent); if ($agent_id == '.1') { $dynagent = 1; } else { if ($agent_id == '.2') { $dynagent = 2; } else { // Detect if agent exists if ($pfAgent->getFromDB($agent_id)) { if ($pfTask->fields['communication'] == 'pull') { $a_agentlist[$agent_id] = 1; } else { if ($pfTaskjob->isAgentAlive('1', $agent_id)) { $a_agentlist[$agent_id] = 1; } } } } } } if ($dynagent == '1') { $a_agents = $pfAgentmodule->getAgentsCanDo('NETWORKDISCOVERY'); foreach ($a_agents as $data) { if ($count_ip / 10 >= count($a_agentlist)) { $pfAgent->getFromDB($data['id']); $a_ip = $pfAgent->getIPs(); foreach ($a_ip as $ip) { if ($pfTask->fields['communication'] == 'push') { if ($pfTaskjob->isAgentAlive('1', $data['id'])) { $a_agentlist[$data['id']] = 1; } } else { if ($pfTask->fields['communication'] == 'pull') { $a_agentlist[$data['id']] = 1; } } } } } } if ($dynagent == '2') { // Dynamic with subnet $pfSnmpinventory = new PluginFusioninventoryNetworkinventory(); $taskvalid = 0; foreach ($a_subnet_nbip as $iprange_id => $nbips) { //$maxagentpossible = $nbips/10; $pfIPRange->getFromDB($iprange_id); $a_agentListComplete = array(); $a_agentList = $pfSnmpinventory->getAgentsSubnet($nbips, "push", "", $pfIPRange->fields['ip_start'], $pfIPRange->fields['ip_end']); if (isset($a_agentList)) { $a_agentListComplete = array_merge($a_agentListComplete, $a_agentList); } if (!isset($a_agentListComplete) or empty($a_agentListComplete)) { $a_input = array(); $a_input['plugin_fusioninventory_taskjobs_id'] = $taskjobs_id; $a_input['plugin_fusioninventory_agents_id'] = 0; $a_input['state'] = 1; $a_input['itemtype'] = 'PluginFusioninventoryIPRange'; $a_input['items_id'] = $iprange_id; $a_input['uniqid'] = $uniqid; $a_input['execution_id'] = $task->fields['execution_id']; $Taskjobstates_id = $pfTaskjobstate->add($a_input); //Add log of taskjob $a_input['plugin_fusioninventory_taskjobstates_id'] = $Taskjobstates_id; $a_input['state'] = 7; $a_input['date'] = date("Y-m-d H:i:s"); $pfTaskjoblog->add($a_input); $pfTaskjobstate->changeStatusFinish($Taskjobstates_id, 0, 'PluginFusioninventoryIPRange', 1, "Unable to find agent to run this job"); $input_taskjob = array(); $input_taskjob['id'] = $pfTaskjob->fields['id']; //$input_taskjob['status'] = 1; $pfTaskjob->update($input_taskjob); } else { $s = $pfIPRange->getIp2long($pfIPRange->fields['ip_start']); $e = $pfIPRange->getIp2long($pfIPRange->fields['ip_end']); $nbIpAgent = ceil(($e - $s) / count($a_agentListComplete)); $iptimes = 0; foreach ($a_agentListComplete as $agent_id) { $_SESSION['glpi_plugin_fusioninventory']['agents'][$agent_id] = 1; //Add jobstate and put status (waiting on server = 0) $a_input = array(); $a_input['plugin_fusioninventory_taskjobs_id'] = $taskjobs_id; $a_input['state'] = 0; $a_input['plugin_fusioninventory_agents_id'] = $agent_id; $a_input['itemtype'] = 'PluginFusioninventoryIPRange'; $a_input['uniqid'] = $uniqid; $a_input['execution_id'] = $task->fields['execution_id']; $a_input['items_id'] = $iprange_id; if ($iptimes + $nbIpAgent > $e - $s) { $a_input['specificity'] = $iptimes . "-" . ($e - $s); } else { $a_input['specificity'] = $iptimes . "-" . ($iptimes + $nbIpAgent); } $taskvalid++; $Taskjobstates_id = $pfTaskjobstate->add($a_input); //Add log of taskjob $a_input['plugin_fusioninventory_taskjobstates_id'] = $Taskjobstates_id; $a_input['state'] = 7; $a_input['date'] = date("Y-m-d H:i:s"); $pfTaskjoblog->add($a_input); unset($a_input['state']); $iptimes += $nbIpAgent + 1; if ($iptimes >= $e - $s + 1) { break; } $input_taskjob = array(); $input_taskjob['id'] = $pfTaskjob->fields['id']; $input_taskjob['status'] = 1; $pfTaskjob->update($input_taskjob); } } } if ($taskvalid == "0") { $pfTaskjob->reinitializeTaskjobs($pfTaskjob->fields['plugin_fusioninventory_tasks_id']); } // *** Add jobstate } else { if (count($a_agentlist) == 0) { $a_input = array(); $a_input['plugin_fusioninventory_taskjobs_id'] = $taskjobs_id; $a_input['state'] = 1; $a_input['plugin_fusioninventory_agents_id'] = 0; $a_input['itemtype'] = 'PluginFusioninventoryIPRange'; $a_input['items_id'] = 0; $a_input['uniqid'] = $uniqid; $a_input['execution_id'] = $task->fields['execution_id']; $Taskjobstates_id = $pfTaskjobstate->add($a_input); //Add log of taskjob $a_input['plugin_fusioninventory_taskjobstates_id'] = $Taskjobstates_id; $a_input['state'] = 7; $a_input['date'] = date("Y-m-d H:i:s"); $pfTaskjoblog->add($a_input); $pfTaskjobstate->changeStatusFinish($Taskjobstates_id, 0, 'PluginFusioninventoryIPRange', 1, "Unable to find agent to run this job"); $input_taskjob = array(); $input_taskjob['id'] = $pfTaskjob->fields['id']; //$input_taskjob['status'] = 1; $pfTaskjob->update($input_taskjob); } else { $iptimes = 0; $nbIpadded = 0; $break = 0; $numberIpByAgent = ceil($count_ip / count($a_agentlist)); $a_iprangelistTmp = $a_iprangelist; $ip_id = array_shift($a_iprangelistTmp); foreach ($a_agentlist as $agent_id => $ip) { //Add jobstate and put status (waiting on server = 0) $a_input = array(); $a_input['plugin_fusioninventory_taskjobs_id'] = $taskjobs_id; $a_input['state'] = 0; $a_input['plugin_fusioninventory_agents_id'] = $agent_id; $a_input['itemtype'] = 'PluginFusioninventoryIPRange'; $a_input['uniqid'] = $uniqid; $a_input['execution_id'] = $task->fields['execution_id']; // $nbIpAgent = $numberIpByAgent; $nbIpadded = 0; foreach ($a_iprangelist as $iprange_id) { if ($ip_id == $iprange_id) { $pfIPRange->getFromDB($iprange_id); $s = $pfIPRange->getIp2long($pfIPRange->fields['ip_start']); $e = $pfIPRange->getIp2long($pfIPRange->fields['ip_end']); if ($communication == "push") { $_SESSION['glpi_plugin_fusioninventory']['agents'][$agent_id] = 1; } $a_input['items_id'] = $iprange_id; $nbIpAgent = $numberIpByAgent - $nbIpadded; if ($iptimes + $nbIpAgent > $e - $s) { $a_input['specificity'] = $iptimes . "-" . ($e - $s); $nbIpadded = $e - $s - $iptimes; $ip_id = array_shift($a_iprangelistTmp); $iptimes = 0; } else { $a_input['specificity'] = $iptimes . "-" . ($iptimes + $nbIpAgent); $iptimes += $nbIpAgent + 1; $nbIpadded = 0; $break = 1; } $Taskjobstates_id = $pfTaskjobstate->add($a_input); //Add log of taskjob $a_input['plugin_fusioninventory_taskjobstates_id'] = $Taskjobstates_id; $a_input['state'] = 7; $a_input['date'] = date("Y-m-d H:i:s"); $pfTaskjoblog->add($a_input); unset($a_input['state']); } } $input_taskjob = array(); $input_taskjob['id'] = $pfTaskjob->fields['id']; $input_taskjob['status'] = 1; $pfTaskjob->update($input_taskjob); } } } return $uniqid; }
/** * Get logs of job * * @param array $task_ids list of tasks id * @return array */ function getJoblogs($task_ids = array()) { global $DB; $debug_mode = $_SESSION['glpi_use_mode'] == Session::DEBUG_MODE; $runclass = new PluginFusioninventoryTaskjobstate(); $run_states = $runclass->getStateNames(); $query_where = array(); $query_where[] = "WHERE 1"; if (isset($_SESSION['glpiactiveentities_string'])) { $query_where[] = getEntitiesRestrictRequest("AND", 'task'); } if (is_array($task_ids) and count($task_ids) > 0) { $query_where[] = "AND task.`id` IN (" . implode(",", $task_ids) . ")"; } // quickly filter empty WHERE entry $query_where = array_filter($query_where); $query_fields = array(array('task.id', 'task.`id`'), array('task.name', 'task.`name`'), array('job.id', 'job.`id`'), array('job.name', 'job.`name`'), array('job.method', 'job.`method`'), array('job.targets', 'job.`targets`')); $fieldmap = array(); foreach ($query_fields as $index => $key) { $fieldmap[$key[0]] = $index; } $query_select = array(); foreach ($query_fields as $index => $key) { $query_select[] = $key[1] . " AS '" . $key[0] . "'"; } $query_joins = array(); $query_joins['task'] = implode("\n", array("INNER JOIN `glpi_plugin_fusioninventory_tasks` as task", " ON job.`plugin_fusioninventory_tasks_id` = task.`id`", " AND task.`is_active` = 1")); $data_structure = array('query' => implode("\n", array("SELECT", implode(",\n", $query_select), "FROM `glpi_plugin_fusioninventory_taskjobs` as job", implode("\n", $query_joins), implode("\n", $query_where))), 'result' => null); $data_structure['result'] = $DB->query($data_structure['query']); //Results grouped by tasks > jobs > jobstates $logs = array(); //Target cache (used to speed up data formatting) $targets_cache = array(); $expanded = array(); if (isset($_SESSION['plugin_fusioninventory_tasks_expanded'])) { $expanded = $_SESSION['plugin_fusioninventory_tasks_expanded']; } while ($result = $data_structure['result']->fetch_row()) { $task_id = $result[$fieldmap['task.id']]; if (!array_key_exists($task_id, $logs)) { $logs[$task_id] = array('task_name' => $result[$fieldmap['task.name']], 'task_id' => $result[$fieldmap['task.id']], 'expanded' => false, 'jobs' => array()); } if (isset($expanded[$task_id])) { $logs[$task_id]['expanded'] = $expanded[$task_id]; } $job_id = $result[$fieldmap['job.id']]; $jobs_handle =& $logs[$task_id]['jobs']; if (!array_key_exists($job_id, $jobs_handle)) { $jobs_handle[$job_id] = array('name' => $result[$fieldmap['job.name']], 'id' => $result[$fieldmap['job.id']], 'method' => $result[$fieldmap['job.method']], 'targets' => array()); } $targets = importArrayFromDB($result[$fieldmap['job.targets']]); $targets_handle =& $jobs_handle[$job_id]['targets']; $agent_state_types = array('agents_prepared', 'agents_cancelled', 'agents_running', 'agents_success', 'agents_error', 'agents_notdone'); if ($result[$fieldmap['job.method']] == 'networkinventory') { $pfNetworkinventory = new PluginFusioninventoryNetworkinventory(); foreach ($targets as $keyt => $target) { $item_type = key($target); $items_id = current($target); if ($item_type == 'PluginFusioninventoryIPRange') { unset($targets[$keyt]); // In this case get devices of this iprange $deviceList = $pfNetworkinventory->getDevicesOfIPRange($items_id); $targets = array_merge($targets, $deviceList); } } } foreach ($targets as $target) { $item_type = key($target); $item_id = current($target); $target_id = $item_type . "_" . $item_id; if (isset($targets_cache[$target_id])) { $item = $targets_cache[$target_id]; } else { $item = new $item_type(); $item->getFromDB($item_id); $targets_cache[$target_id] = $item; } $targets_handle[$target_id] = array('id' => $item->fields['id'], 'name' => $item->fields['name'], 'type_name' => $item->getTypeName(), 'item_link' => $item->getLinkUrl(), 'counters' => array(), 'agents' => array()); // create agent states counter lists foreach ($agent_state_types as $type) { $targets_handle[$target_id]['counters'][$type] = array(); } } } // Query fields mapping used to easily select fields by name $query_fields = array(array('task.id', 'task.`id`'), array('task.name', 'task.`name`'), array('job.id', 'job.`id`'), array('job.name', 'job.`name`'), array('job.method', 'job.`method`'), array('agent.id', 'agent.`id`'), array('agent.name', 'agent.`name`'), array('run.id', 'run.`id`'), array('run.itemtype', 'run.`itemtype`'), array('run.items_id', 'run.`items_id`'), array('run.state', 'run.`state`'), array('log.last_date', 'log.`date`'), array('log.last_timestamp', 'UNIX_TIMESTAMP(log.`date`)'), array('log.last_id', 'log.`id`'), array('log.last_comment', 'log.`comment`')); $fieldmap = array(); foreach ($query_fields as $index => $key) { $fieldmap[$key[0]] = $index; } $query_select = array(); foreach ($query_fields as $index => $key) { $query_select[] = $key[1] . " AS '" . $key[0] . "'"; } $query_joins = array(); $query_joins['max_run'] = implode("\n", array("INNER JOIN (", " SELECT", " MAX(run.`id`) AS max_id,", " run.`plugin_fusioninventory_agents_id`,", " run.`plugin_fusioninventory_taskjobs_id`,", " run.`items_id`, run.`itemtype`,", " MAX(log.`id`) AS max_log_id", " FROM `glpi_plugin_fusioninventory_taskjobstates` AS run", " LEFT JOIN `glpi_plugin_fusioninventory_taskjoblogs` AS log", " ON log.`plugin_fusioninventory_taskjobstates_id` = run.`id`", " GROUP BY", " run.`plugin_fusioninventory_agents_id`,", " run.`plugin_fusioninventory_taskjobs_id`,", " run.`items_id`, run.`itemtype`", ") max_run ON max_run.`plugin_fusioninventory_agents_id` = agent.`id`")); $query_joins['run'] = implode("\n", array("INNER JOIN `glpi_plugin_fusioninventory_taskjobstates` AS run", " ON max_run.`max_id` = run.`id`")); $query_joins['log'] = implode("\n", array("LEFT JOIN `glpi_plugin_fusioninventory_taskjoblogs` as log", " ON log.`id` = max_run.`max_log_id`")); $query_joins['job'] = implode("\n", array("INNER JOIN `glpi_plugin_fusioninventory_taskjobs` AS job", " ON job.`id` = run.`plugin_fusioninventory_taskjobs_id`")); $query_joins['task'] = implode("\n", array("INNER JOIN `glpi_plugin_fusioninventory_tasks` as task", " ON job.`plugin_fusioninventory_tasks_id` = task.`id`")); $queries = array(); /* * Get latest jobstates for agents */ $queries['1_last_runs'] = array('query' => implode(" \n", array("SELECT", implode(",\n", $query_select), "FROM `glpi_plugin_fusioninventory_agents` AS agent", implode("\n", $query_joins), implode("\n", $query_where), "GROUP BY job.`id`, agent.`id`, run.`id`")), 'result' => null); /* * Get last finished jobstates (ie. `state` >= 3) */ $query_joins['max_run'] = implode("\n", array("INNER JOIN (", " SELECT", " MAX(run.`id`) AS max_id,", " run.`plugin_fusioninventory_agents_id`,", " run.`plugin_fusioninventory_taskjobs_id`,", " run.`items_id`, run.`itemtype`,", " MAX(log.`id`) AS max_log_id", " FROM `glpi_plugin_fusioninventory_taskjobstates` AS run", " LEFT JOIN `glpi_plugin_fusioninventory_taskjoblogs` AS log", " ON log.`plugin_fusioninventory_taskjobstates_id` = run.`id`", " WHERE run.`state` IN ( " . implode(",", array(PluginFusioninventoryTaskjobstate::FINISHED, PluginFusioninventoryTaskjobstate::IN_ERROR)) . " )", " GROUP BY", " run.`plugin_fusioninventory_agents_id`,", " run.`plugin_fusioninventory_taskjobs_id`,", " run.`items_id`, run.`itemtype`", ") max_run ON max_run.`plugin_fusioninventory_agents_id` = agent.`id`")); $queries['2_finished_runs'] = array('query' => implode(" \n", array("SELECT", implode(",\n", $query_select), "FROM `glpi_plugin_fusioninventory_agents` AS agent", implode("\n", $query_joins), implode("\n", $query_where), "GROUP BY job.`id`, agent.`id`, run.`id`")), 'result' => null); $query_chrono = array("start" => microtime(true), "end" => 0); ksort($queries); foreach ($queries as $query_name => $contents) { $queries[$query_name]['result'] = $DB->query($contents['query']); $query_chrono['end'] = microtime(true); // For debug only //if ($debug_mode) { // file_put_contents("/tmp/glpi_".$query_name.".sql",$contents['query']); //} } $agents = array(); $format_chrono = array("start" => microtime(true), "end" => 0); foreach ($queries as $query_name => $contents) { if (!is_null($contents['result'])) { while ($result = $contents['result']->fetch_row()) { // We need to check if the results are consistent with the view's structure gathered // by the first query $task_id = $result[$fieldmap['task.id']]; //if (!array_key_exists($task_id, $logs)) { if (!isset($logs[$task_id])) { continue; } $job_id = $result[$fieldmap['job.id']]; $jobs =& $logs[$task_id]['jobs']; if (!isset($jobs[$job_id])) { continue; } $target_id = $result[$fieldmap['run.itemtype']] . '_' . $result[$fieldmap['run.items_id']]; $targets =& $jobs[$job_id]['targets']; if (!isset($targets[$target_id])) { continue; } $counters =& $targets[$target_id]['counters']; $agent_id = $result[$fieldmap['agent.id']]; $agents[$agent_id] = $result[$fieldmap['agent.name']]; if (!isset($targets[$target_id]['agents'][$agent_id])) { $targets[$target_id]['agents'][$agent_id] = array(); } $agent_state = ''; // Update counters switch ($result[$fieldmap['run.state']]) { case PluginFusioninventoryTaskjobstate::CANCELLED: // We put this agent in the cancelled counter if it does not have any other job // states. if (!isset($counters['agents_prepared'][$agent_id]) and !isset($counters['agents_running'][$agent_id])) { $counters['agents_cancelled'][$agent_id] = 1; $agent_state = 'cancelled'; } break; case PluginFusioninventoryTaskjobstate::PREPARED: // We put this agent in the prepared counter if it has not yet completed any job. $counters['agents_prepared'][$agent_id] = 1; $agent_state = 'prepared'; break; case PluginFusioninventoryTaskjobstate::SERVER_HAS_SENT_DATA: case PluginFusioninventoryTaskjobstate::AGENT_HAS_SENT_DATA: // This agent is running so it must not be in any other counter foreach ($agent_state_types as $type) { if (isset($counters[$type][$agent_id])) { unset($counters[$type][$agent_id]); } } $counters['agents_running'][$agent_id] = 1; $agent_state = 'running'; break; case PluginFusioninventoryTaskjobstate::IN_ERROR: if (isset($counters['agents_success'][$agent_id])) { unset($counters['agents_success'][$agent_id]); } $counters['agents_error'][$agent_id] = 1; $agent_state = 'error'; if (isset($counters['agents_notdone'][$agent_id])) { unset($counters['agents_notdone'][$agent_id]); } break; case PluginFusioninventoryTaskjobstate::FINISHED: if (isset($counters['agents_error'][$agent_id])) { unset($counters['agents_error'][$agent_id]); } $counters['agents_success'][$agent_id] = 1; $agent_state = 'success'; if (isset($counters['agents_notdone'][$agent_id])) { unset($counters['agents_notdone'][$agent_id]); } break; } if (!isset($counters['agents_error'][$agent_id]) and !isset($counters['agents_success'][$agent_id])) { $counters['agents_notdone'][$agent_id] = 1; } if (isset($counters['agents_running'][$agent_id]) or isset($counters['agents_prepared'][$agent_id])) { unset($counters['agents_cancelled'][$agent_id]); } $targets[$target_id]['agents'][$agent_id][] = array('agent_id' => $agent_id, 'numstate' => $result[$fieldmap['run.state']], 'state' => $agent_state, 'jobstate_id' => $result[$fieldmap['run.id']], 'last_log_id' => $result[$fieldmap['log.last_id']], 'last_log_date' => $result[$fieldmap['log.last_date']], 'timestamp' => $result[$fieldmap['log.last_timestamp']], 'last_log' => $result[$fieldmap['log.last_comment']]); } } } $format_chrono['end'] = microtime(true); if ($debug_mode) { function tmp_display_log($log) { return "ID:" . $log['task_id'] . "(" . $log['task_name'] . ")"; } if (PluginFusioninventoryConfig::isExtradebugActive()) { Toolbox::logDebug(array("tasks" => implode(',', array_map('tmp_display_log', $logs)), "row count" => count($logs), "Joblogs Query" => self::FormatChrono($query_chrono), "Format logs results" => self::FormatChrono($format_chrono))); } } return array('tasks' => $logs, 'agents' => $agents); }