530 lines
18 KiB
PHP
530 lines
18 KiB
PHP
<?php
|
|
/**
|
|
* Observium
|
|
*
|
|
* This file is part of Observium.
|
|
*
|
|
* @package observium
|
|
* @subpackage web
|
|
* @copyright (C) Adam Armstrong
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* Humanize status indicator.
|
|
*
|
|
* Returns a the $status array with processed information:
|
|
* sensor_state (TRUE: state sensor, FALSE: normal sensor)
|
|
* human_value, sensor_symbol, state_name, state_event, event_class
|
|
*
|
|
* @param array $status
|
|
*
|
|
* @return array $status
|
|
*
|
|
*/
|
|
// TESTME needs unit testing
|
|
function humanize_status(&$status)
|
|
{
|
|
global $config;
|
|
|
|
// Exit if already humanized
|
|
if ($status['humanized']) {
|
|
return;
|
|
}
|
|
|
|
if (isset($config['entity_events'][$status['status_event']])) {
|
|
$status = array_merge($status, $config['entity_events'][$status['status_event']]);
|
|
} else {
|
|
$status['event_class'] = 'label label-primary';
|
|
$status['row_class'] = '';
|
|
}
|
|
if ($status['status_deleted']) {
|
|
$status['row_class'] = 'disabled';
|
|
}
|
|
|
|
$device = device_by_id_cache($status['device_id']);
|
|
if ((isset($device['status']) && !$device['status']) ||
|
|
(isset($device['disabled']) && $device['disabled'])) {
|
|
$status['row_class'] = $status['row_class'] !== 'disabled' ? 'error' : $status['row_class'];
|
|
}
|
|
// this is pseudo class only for js selectors
|
|
$status['row_class'] .= ' entity-status';
|
|
|
|
// Set humanized entry in the array so we can tell later
|
|
$status['humanized'] = TRUE;
|
|
}
|
|
|
|
function generate_status_query($vars, $query_count = FALSE) {
|
|
|
|
if ($query_count) {
|
|
$sql = "SELECT COUNT(*) FROM `status`";
|
|
} else {
|
|
$sql = "SELECT * FROM `status`";
|
|
|
|
if ($vars['sort'] == 'hostname' || $vars['sort'] == 'device' || $vars['sort'] == 'device_id') {
|
|
$sql .= ' LEFT JOIN `devices` USING(`device_id`)';
|
|
}
|
|
}
|
|
|
|
// Build query
|
|
$where_array = [];
|
|
foreach ($vars as $var => $value) {
|
|
switch ($var) {
|
|
case "group":
|
|
case "group_id":
|
|
$values = get_group_entities($value, 'status');
|
|
$where_array[] = generate_query_values($values, 'status.status_id');
|
|
break;
|
|
|
|
case 'device_group_id':
|
|
case 'device_group':
|
|
$values = get_group_entities($value, 'device');
|
|
$where_array[] = generate_query_values($values, 'status.device_id');
|
|
break;
|
|
|
|
case "device":
|
|
case "device_id":
|
|
$where_array[] = generate_query_values($value, 'status.device_id');
|
|
break;
|
|
|
|
case "id":
|
|
case 'status_id':
|
|
$where_array[] = generate_query_values($value, 'status.status_id');
|
|
break;
|
|
|
|
case "entity_id":
|
|
$where_array[] = generate_query_values($value, 'measured_entity');
|
|
break;
|
|
|
|
case "entity_type":
|
|
$where_array[] = generate_query_values($value, 'measured_class');
|
|
break;
|
|
|
|
case 'entity_state':
|
|
case "measured_state":
|
|
$where_array[] = generate_query_entity_measured('status', [ 'measured_state' => $value ]);
|
|
break;
|
|
|
|
case "class":
|
|
case 'entPhysicalClass':
|
|
$where_array[] = generate_query_values($value, 'entPhysicalClass');
|
|
break;
|
|
|
|
case "event":
|
|
case "status_event":
|
|
$where_array[] = generate_query_values($value, 'status_event');
|
|
break;
|
|
|
|
case "status":
|
|
case "status_name":
|
|
$where_array[] = generate_query_values($value, 'status_name');
|
|
break;
|
|
|
|
case "descr":
|
|
case "status_descr":
|
|
$where_array[] = generate_query_values($value, 'status_descr', '%LIKE%');
|
|
break;
|
|
|
|
case 'type':
|
|
case "status_type":
|
|
$where_array[] = generate_query_values($value, 'status_type', '%LIKE%');
|
|
break;
|
|
}
|
|
}
|
|
$where_array[] = '`status_deleted` = 0';
|
|
|
|
$sql .= generate_where_clause($where_array, generate_query_permitted_ng([ 'device', 'status' ]));
|
|
|
|
// If need count, just return sql without sorting
|
|
if ($query_count) {
|
|
return $sql;
|
|
}
|
|
|
|
if (isset($vars['sort'])) {
|
|
switch ($vars['sort']) {
|
|
case 'device':
|
|
$sql .= generate_query_sort('hostname', get_sort_order($vars));
|
|
break;
|
|
|
|
case 'descr':
|
|
$sql .= generate_query_sort('status_descr', get_sort_order($vars));
|
|
break;
|
|
|
|
case 'class':
|
|
case 'entPhysicalClass':
|
|
$sql .= generate_query_sort('entPhysicalClass', get_sort_order($vars));
|
|
break;
|
|
|
|
case 'event':
|
|
$sql .= generate_query_sort('status_event', get_sort_order($vars));
|
|
break;
|
|
|
|
case 'status':
|
|
$sql .= generate_query_sort('status_name', get_sort_order($vars));
|
|
break;
|
|
|
|
case 'last_change':
|
|
$sql .= generate_query_sort('status_last_change', get_sort_order($vars, TRUE));
|
|
break;
|
|
|
|
case 'mib':
|
|
$sql .= generate_query_sort([ 'status_mib', 'status_object', 'status_type', 'status_index:integer' ], get_sort_order($vars));
|
|
break;
|
|
|
|
default:
|
|
$sql .= generate_query_sort([ 'measured_entity_label', 'status_descr' ], get_sort_order($vars));
|
|
}
|
|
} else {
|
|
$sql .= generate_query_sort([ 'measured_entity_label', 'status_descr' ]);
|
|
}
|
|
|
|
if (isset($vars['pageno'])) {
|
|
//$sql .= generate_query_limit($vars);
|
|
}
|
|
|
|
return $sql;
|
|
}
|
|
|
|
|
|
function print_status_table($vars)
|
|
{
|
|
|
|
pagination($vars, 0, TRUE); // Get default pagesize/pageno
|
|
|
|
$sql = generate_status_query($vars);
|
|
|
|
$status_list = [];
|
|
foreach (dbFetchRows($sql) as $status) {
|
|
$status['hostname'] = get_device_hostname_by_id($status['device_id']);
|
|
$status_list[] = $status;
|
|
}
|
|
|
|
//$status_count = count($status_list); // This is count incorrect, when pagination used!
|
|
$status_count = dbFetchCell(generate_status_query($vars, TRUE));
|
|
|
|
// Pagination
|
|
$pagination_html = pagination($vars, $status_count);
|
|
echo $pagination_html;
|
|
|
|
if ($vars['pageno']) {
|
|
$status_list = array_chunk($status_list, $vars['pagesize']);
|
|
$status_list = $status_list[$vars['pageno'] - 1];
|
|
}
|
|
// End Pagination
|
|
|
|
echo generate_box_open();
|
|
|
|
print_status_table_header($vars);
|
|
|
|
foreach ($status_list as $status) {
|
|
print_status_row($status, $vars);
|
|
}
|
|
|
|
echo("</tbody></table>");
|
|
|
|
echo generate_box_close();
|
|
|
|
echo $pagination_html;
|
|
}
|
|
|
|
function print_status_table_header($vars)
|
|
{
|
|
if ($vars['view'] == "graphs" || isset($vars['id'])) {
|
|
$stripe_class = "table-striped-two";
|
|
} else {
|
|
$stripe_class = "table-striped";
|
|
}
|
|
|
|
echo('<table class="table ' . $stripe_class . ' table-condensed ">' . PHP_EOL);
|
|
$cols = [
|
|
[NULL, 'class="state-marker"'],
|
|
'device' => ['Device', 'style="width: 250px;"'],
|
|
//array(NULL, 'class="no-width"'), // Measure entity link
|
|
'descr' => ['Description'],
|
|
'mib' => ['MIB::Object'],
|
|
'entPhysicalClass' => ['Phys Class', 'style="width: 100px;"'],
|
|
['History', 'style="width: 90px;"'],
|
|
'last_change' => ['Last changed', 'style="width: 80px;"'],
|
|
'event' => ['Event', 'style="width: 60px; text-align: right;"'],
|
|
'status' => ['Status', 'style="width: 80px; text-align: right;"'],
|
|
];
|
|
|
|
if ($vars['page'] == "device") {
|
|
unset($cols['device']);
|
|
}
|
|
if ($vars['page'] != "device" || $vars['tab'] == "overview") {
|
|
unset($cols['mib']);
|
|
unset($cols['object']);
|
|
}
|
|
|
|
echo(get_table_header($cols, $vars));
|
|
echo('<tbody>' . PHP_EOL);
|
|
}
|
|
|
|
function print_status_row($status, $vars)
|
|
{
|
|
echo generate_status_row($status, $vars);
|
|
}
|
|
|
|
function generate_status_row($status, $vars)
|
|
{
|
|
|
|
$table_cols = 7;
|
|
|
|
humanize_status($status);
|
|
|
|
// FIXME - make this "four graphs in popup" a function/include and "small graph" a function.
|
|
// FIXME - DUPLICATED IN device/overview/status
|
|
|
|
$graph_array = [];
|
|
$graph_array['to'] = get_time();
|
|
$graph_array['id'] = $status['status_id'];
|
|
$graph_array['type'] = "status_graph";
|
|
$graph_array['legend'] = "no";
|
|
$graph_array['width'] = 80;
|
|
$graph_array['height'] = 20;
|
|
$graph_array['bg'] = 'ffffff00';
|
|
$graph_array['from'] = get_time('day');
|
|
|
|
//$status_misc = '<span class="label">' . $status['entPhysicalClass'] . '</span>';
|
|
$short = $vars['page'] === "device" && $vars['tab'] === "overview";
|
|
$hide_style = $status['status_event'] === 'ignore' && $short ? ' style="display: none;"' : '';
|
|
|
|
$row = '<tr class="' . $status['row_class'] . '"' . $hide_style . '>
|
|
<td class="state-marker"></td>';
|
|
|
|
if ($vars['page'] !== "device" && $vars['popup'] != TRUE) {
|
|
$row .= '<td class="entity">' . generate_device_link($status) . '</td>';
|
|
$table_cols++;
|
|
}
|
|
|
|
if ($status['status_event'] && $status['status_name']) {
|
|
$mini_graph = generate_graph_tag($graph_array);
|
|
} else {
|
|
// Do not show "Draw Error" minigraph
|
|
$mini_graph = '';
|
|
}
|
|
|
|
// Measured link & icon
|
|
/* Disabled because it breaks the overview table layout
|
|
$row .= ' <td style="padding-right: 0px;" class="no-width vertical-align">'; // minify column if empty
|
|
if ($status['measured_entity'] &&
|
|
(!isset($vars['measured_icon']) || $vars['measured_icon'])) // hide measured icon if not required
|
|
{
|
|
$row .= generate_entity_icon_link($status['measured_class'], $status['measured_entity']);
|
|
}
|
|
$row .= '</td>';
|
|
$table_cols++;
|
|
*/
|
|
|
|
$row .= '<td class="entity">' . generate_entity_link('status', $status) . '</td>';
|
|
|
|
// FIXME -- Generify this. It's not just for sensors.
|
|
if ($vars['page'] === "device" && $vars['tab'] !== "overview") {
|
|
$row .= ' <td><span class="label-group">' . (!safe_empty($status['status_mib']) ? '<span class="label label-primary"><a href="' . OBSERVIUM_MIBS_URL . '/' . $status['status_mib'] . '/" target="_blank">' . nicecase($status['status_mib']) . '</a></span>' : '') .
|
|
(!safe_empty($status['status_mib']) ? '<span class="label label-success"><a href="' . OBSERVIUM_MIBS_URL . '/' . $status['status_mib'] . '/#' . $status['status_object'] . '" target="_blank">' . $status['status_object'] . '</a></span>' : '') .
|
|
'<span class="label label-delayed">' . $status['status_index'] . '</span></span></td>' . PHP_EOL;
|
|
$table_cols++;
|
|
}
|
|
|
|
if ($vars['tab'] !== "overview") {
|
|
$row .= '<td>' . get_type_class_label($status['entPhysicalClass'], 'physicalclass') . '</td>';
|
|
$table_cols++;
|
|
}
|
|
$row .= '<td style="width: 90px; text-align: right;">' . generate_entity_link('status', $status, $mini_graph, NULL, FALSE) . '</td>';
|
|
if ($vars['tab'] !== "overview") {
|
|
$row .= '<td style="white-space: nowrap">' . generate_tooltip_time($status['status_last_change'], 'ago') . '</td>
|
|
<td style="text-align: right;"><strong>' . generate_tooltip_link('', $status['status_event'], $status['event_descr'], $status['event_class']) . '</strong></td>';
|
|
$table_cols++;
|
|
$table_cols++;
|
|
}
|
|
$row .= '<td style="width: 80px; text-align: right;"><strong>' . generate_tooltip_link('', $status['status_name'], $status['event_descr'], $status['event_class']) . '</strong></td>
|
|
</tr>' . PHP_EOL;
|
|
|
|
if ($vars['view'] === "graphs") {
|
|
$vars['graph'] = "status";
|
|
}
|
|
|
|
if ($vars['graph'] || $vars['id'] == $status['status_id']) {
|
|
// If id set in vars, display only specific graphs
|
|
$row .= '<tr class="' . $status['row_class'] . '">
|
|
<td class="state-marker"></td>
|
|
<td colspan="' . $table_cols . '">';
|
|
|
|
unset($graph_array['height'], $graph_array['width'], $graph_array['legend']);
|
|
$graph_array['to'] = get_time();
|
|
$graph_array['id'] = $status['status_id'];
|
|
$graph_array['type'] = "status_graph";
|
|
|
|
$row .= generate_graph_row($graph_array, TRUE);
|
|
|
|
$row .= '</td></tr>';
|
|
} # endif graphs
|
|
|
|
return $row;
|
|
|
|
}
|
|
|
|
function print_status_form($vars, $single_device = FALSE)
|
|
{
|
|
global $config;
|
|
|
|
$form = ['type' => 'rows',
|
|
'space' => '10px',
|
|
'submit_by_key' => TRUE,
|
|
'url' => generate_url($vars)];
|
|
|
|
$form_items = [];
|
|
|
|
if ($single_device) {
|
|
// Single device, just hidden field
|
|
$form['row'][0]['device_id'] = [
|
|
'type' => 'hidden',
|
|
'name' => 'Device',
|
|
'value' => $vars['device_id'],
|
|
'grid' => 2,
|
|
'width' => '100%'];
|
|
} else {
|
|
$form_items['devices'] = generate_form_values('device', dbFetchColumn('SELECT DISTINCT `device_id` FROM `status`'));
|
|
|
|
$form['row'][0]['device_id'] = [
|
|
'type' => 'multiselect',
|
|
'name' => 'Device',
|
|
'value' => $vars['device_id'],
|
|
'grid' => 2,
|
|
'width' => '100%', //'180px',
|
|
'values' => $form_items['devices']];
|
|
}
|
|
|
|
$status_permitted = generate_query_permitted(['device', 'status']);
|
|
foreach (['entPhysicalClass' => 'Physical Class', 'status_event' => 'Status Event', 'status_name' => 'Status'] as $param => $param_name) {
|
|
$sql = 'SELECT DISTINCT `' . $param . '` FROM `status` WHERE `status_deleted` = ?' . $status_permitted;
|
|
if ($entries = dbFetchColumn($sql, [0])) {
|
|
asort($entries);
|
|
}
|
|
foreach ($entries as $entry) {
|
|
if (safe_empty($entry)) {
|
|
$entry = OBS_VAR_UNSET;
|
|
}
|
|
if ($param === 'entPhysicalClass') {
|
|
$name = nicecase($entry);
|
|
if (isset($config['icon'][strtolower($entry)])) {
|
|
$name = ['name' => $name, 'icon' => $config['icon'][strtolower($entry)]];
|
|
} else {
|
|
$name = ['name' => $name, 'icon' => $config['icon']['status']];
|
|
}
|
|
} else {
|
|
$name = $entry;
|
|
}
|
|
$form_items[$param][$entry] = $name;
|
|
}
|
|
|
|
// Alternative param name, ie event
|
|
$short_param = str_replace('status_', '', $param);
|
|
if (!isset($vars[$param]) && isset($vars[$short_param])) {
|
|
$vars[$param] = $vars[$short_param];
|
|
}
|
|
|
|
// Status specific forms
|
|
$form['row'][0][$param] = [
|
|
'type' => 'multiselect',
|
|
'name' => $param_name,
|
|
'width' => '100%', //'180px',
|
|
'grid' => 2,
|
|
'value' => $vars[$param],
|
|
'values' => $form_items[$param]];
|
|
}
|
|
|
|
// Measured entities
|
|
$form['row'][0]['measured_state'] = [
|
|
'type' => 'multiselect',
|
|
'name' => 'Measured State',
|
|
'width' => '100%', //'180px',
|
|
'grid' => 2,
|
|
'value' => $vars['measured_state'],
|
|
'values' => ['none' => ['name' => 'Without Measure', 'icon' => $config['icon']['filter']],
|
|
'up' => ['name' => 'Measured UP', 'icon' => $config['icon']['up']],
|
|
'down' => ['name' => 'Measured DOWN', 'icon' => $config['icon']['down']],
|
|
'shutdown' => ['name' => 'Measured SHUTDOWN', 'icon' => $config['icon']['shutdown']]]];
|
|
|
|
$form['row'][1]['status_descr'] = [
|
|
'type' => 'text',
|
|
'placeholder' => 'Status description',
|
|
'width' => '100%', //'180px',
|
|
'grid' => 4,
|
|
'value' => $vars['status_descr']];
|
|
|
|
$form['row'][1]['status_type'] = [
|
|
'type' => 'text',
|
|
'placeholder' => 'Status type',
|
|
'width' => '100%', //'180px',
|
|
'grid' => 4,
|
|
'value' => $vars['status_descr']];
|
|
|
|
// Groups
|
|
foreach (get_type_groups('status') as $entry) {
|
|
$form_items['group'][$entry['group_id']] = $entry['group_name'];
|
|
}
|
|
$form['row'][1]['group'] = [
|
|
'community' => FALSE,
|
|
'type' => 'multiselect',
|
|
'name' => 'Select Groups',
|
|
'width' => '100%', //'180px',
|
|
'grid' => 2,
|
|
'value' => $vars['group'],
|
|
'values' => $form_items['group']];
|
|
|
|
$form['row'][1]['search'] = [
|
|
'type' => 'submit',
|
|
'grid' => 2,
|
|
//'name' => 'Search',
|
|
//'icon' => 'icon-search',
|
|
'right' => TRUE,
|
|
];
|
|
|
|
// Show search form
|
|
echo '<div class="hidden-xl">';
|
|
print_form($form);
|
|
echo '</div>';
|
|
|
|
// Custom panel form
|
|
$panel_form = ['type' => 'rows',
|
|
'title' => 'Search Statuses',
|
|
'space' => '10px',
|
|
//'brand' => NULL,
|
|
//'class' => '',
|
|
'submit_by_key' => TRUE,
|
|
'url' => generate_url($vars)];
|
|
|
|
// Clean grids
|
|
foreach ($form['row'] as $row => $rows) {
|
|
foreach (array_keys($rows) as $param) {
|
|
if (isset($form['row'][$row][$param]['grid'])) {
|
|
unset($form['row'][$row][$param]['grid']);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Copy forms
|
|
$panel_form['row'][0]['device_id'] = $form['row'][0]['device_id'];
|
|
$panel_form['row'][0]['entPhysicalClass'] = $form['row'][0]['entPhysicalClass'];
|
|
|
|
$panel_form['row'][1]['status_event'] = $form['row'][0]['status_event'];
|
|
$panel_form['row'][1]['status_name'] = $form['row'][0]['status_name'];
|
|
|
|
$panel_form['row'][2]['measured_state'] = $form['row'][0]['measured_state'];
|
|
$panel_form['row'][2]['group'] = $form['row'][1]['group'];
|
|
|
|
$panel_form['row'][3]['status_type'] = $form['row'][1]['status_type'];
|
|
|
|
$panel_form['row'][4]['status_descr'] = $form['row'][1]['status_descr'];
|
|
|
|
//$panel_form['row'][5]['sort'] = $form['row'][0]['sort'];
|
|
$panel_form['row'][5]['search'] = $form['row'][1]['search'];
|
|
|
|
// Register custom panel
|
|
register_html_panel(generate_form($panel_form));
|
|
}
|
|
|
|
// EOF
|