initial commit; version 22.5.12042

This commit is contained in:
2022-12-12 23:28:25 -05:00
commit af1b03d79f
17653 changed files with 22692970 additions and 0 deletions

View File

@ -0,0 +1,158 @@
<?php
/**
* Observium
*
* This file is part of Observium.
*
* @package observium
* @subpackage web
* @copyright (C) 2006-2013 Adam Armstrong, (C) 2013-2021 Observium Limited
*
*/
function build_cbqos_query($vars)
{
$sql = 'SELECT * FROM `ports_cbqos`';
//if ($vars['sort'] == 'hostname' || $vars['sort'] == 'device' || $vars['sort'] == 'device_id') {
$sql .= ' LEFT JOIN `devices` USING(`device_id`)';
//}
$sql .= ' LEFT JOIN `ports` USING (`port_id`)';
// Rewrite `device_id` to use `ports_cbqos` table name to avoid dupe field error.
$sql .= ' WHERE 1' . str_replace('`device_id`', '`ports_cbqos`.`device_id`', generate_query_permitted(array('device')));
// Build query
foreach ($vars as $var => $value) {
switch ($var) {
case "policy_name":
case "object_name":
$sql .= generate_query_values($value, $var);
break;
case "group":
case "group_id":
$values = get_group_entities($value);
$sql .= generate_query_values($values, 'cbqos_id');
break;
case 'device_group_id':
case 'device_group':
$values = get_group_entities($value, 'device');
$sql .= generate_query_values($values, 'ports_cbqos.device_id');
break;
case "device":
case "device_id":
$sql .= generate_query_values($value, 'ports_cbqos.device_id');
break;
}
}
switch ($vars['sort_order']) {
case 'desc':
$sort_order = 'DESC';
$sort_neg = 'ASC';
break;
case 'reset':
unset($vars['sort'], $vars['sort_order']);
// no break here
default:
$sort_order = 'ASC';
$sort_neg = 'DESC';
}
switch ($vars['sort']) {
case 'policy_name':
case 'object_name':
case 'PrePolicyByte_rate':
case 'PostPolicyByte_rate':
case 'DropByte_rate':
$sql .= ' ORDER BY '.$vars['sort'].' ' . $sort_order;
break;
default:
$sql .= ' ORDER BY `hostname` ' . $sort_order . ', `port_label_short` '. $sort_order;
}
return $sql;
}
function print_cbqos_table_header($vars)
{
echo('<table class="' . (get_var_true($vars['graphs']) ? OBS_CLASS_TABLE_STRIPED_TWO : OBS_CLASS_TABLE_STRIPED) . '">');
$cols[] = array('', 'class="state-marker"');
if(!isset($vars['device_id'])) { $cols['hostname'] = array('Device', 'style="width: 200px;"'); }
if(!isset($vars['device_id'])) { $cols['port_label'] = array('Port', 'style="width: 200px;"'); }
$cols['policy_name'] = array('Policy', 'style="width: 150px;"');
$cols['object_name'] = array('Object', 'style="width: 200px;"');
$cols['PrePolicyByte_rate'] = array('Traffic');
$cols['DropByte_rate'] = array('Dropped');
$cols[] = array();
echo get_table_header($cols, $vars);
echo '<tbody>' . PHP_EOL;
}
function print_cbqos_table($vars) {
global $config;
$sql = build_cbqos_query($vars);
$entries = dbFetchRows($sql);
if (!safe_empty($entries)) {
echo generate_box_open();
print_cbqos_table_header($vars);
foreach ($entries as $cbqos_id => $entry) {
$perc_drop = float_div($entry['DropByte_rate'], $entry['PrePolicyByte_rate']) * 100;
echo '<tr>';
echo '<td class="state-marker"></td>';
echo '<td class="entity">'.generate_device_link($entry).'</td>';
echo '<td class="entity">'.generate_port_link($entry).'</td>';
echo '<td class="entity"><a href="'.generate_url(array('page' => 'device', 'device' => $entry['device_id'], 'tab' => 'port', 'port' => $entry['port_id'], 'view' => 'cbqos')).'">'.$entry['policy_name'].'</a></td>';
echo '<td class="entity"><a href="'.generate_url(array('page' => 'device', 'device' => $entry['device_id'], 'tab' => 'port', 'port' => $entry['port_id'], 'view' => 'cbqos')).'">'.$entry['object_name'].'</a></td>';
echo '<td>'.format_number($entry['PrePolicyByte_rate']).'bps / '.format_number($entry['PostPolicyByte_rate']).'bps</td>';
echo '<td>'.format_number($entry['DropByte_rate']).'bps ('.$perc_drop.'%)</td>';
echo '<td></td>';
echo '</tr>';
if (get_var_true($vars['graphs'])) {
$vars['graph'] = "graph";
}
if ($vars['graph']) {
$graph_array = array();
$graph_title = $entry['oid_descr'];
$graph_array['type'] = "cbqos_".$vars['graph'];
$graph_array['id'] = $entry['cbqos_id'];
echo '<tr>';
echo ' <td class="state-marker"></td>';
echo ' <td colspan=8>';
print_graph_row($graph_array);
echo ' </td>';
echo '</tr>';
}
}
echo ' </table>' . PHP_EOL;
echo generate_box_close();
}
}
// EOF

View File

@ -0,0 +1,681 @@
<?php
/**
* Observium
*
* This file is part of Observium.
*
* @package observium
* @subpackage web
* @copyright (C) 2006-2013 Adam Armstrong, (C) 2013-2021 Observium Limited
*
*/
/**
* Humanize counter.
*
* Returns a the $counter array with processed information:
* counter_state (TRUE: state counter, FALSE: normal counter)
* human_value, counter_symbol, state_name, state_event, state_class
*
* @param array $counter
* @return array $counter
*
*/
// TESTME needs unit testing
function humanize_counter(&$counter)
{
global $config;
// Exit if already humanized
if ($counter['humanized']) { return; }
$counter['counter_symbol'] = $GLOBALS['config']['counter_types'][$counter['counter_class']]['symbol'];
$counter['counter_format'] = strval($GLOBALS['config']['counter_types'][$counter['counter_class']]['format']);
$counter['state_class'] = ''; //'text-success';
// Generate "pretty" thresholds
$have_limit = FALSE;
if (is_numeric($counter['counter_limit_low']))
{
$counter_limit_low = format_value($counter['counter_limit_low'], $counter['counter_format']) . $counter['counter_symbol'];
$have_limit = TRUE;
} else {
$counter_limit_low = "&infin;";
}
if (is_numeric($counter['counter_limit_low_warn']))
{
$counter_warn_low = format_value($counter['counter_limit_low_warn'], $counter['counter_format']) . $counter['counter_symbol'];
$have_limit = TRUE;
} else {
$counter_warn_low = NULL;
}
if ($counter_warn_low) { $counter_limit_low = $counter_limit_low . " (".$counter_warn_low.")"; }
if (is_numeric($counter['counter_limit']))
{
$counter_limit_high = format_value($counter['counter_limit'], $counter['counter_format']) . $counter['counter_symbol'];
$have_limit = TRUE;
} else {
$counter_limit_high = "&infin;";
}
if (is_numeric($counter['counter_limit_warn']))
{
$counter_warn_high = format_value($counter['counter_limit_warn'], $counter['counter_format']) . $counter['counter_symbol'];
$have_limit = TRUE;
} else {
$counter_warn_high = "&infin;";
}
if ($counter_warn_high) { $counter_limit_high = "(".$counter_warn_high.") " . $counter_limit_high; }
switch ($counter['counter_limit_by'])
{
case 'sec':
$limit_by = 'Rate /sec';
break;
case 'min':
$limit_by = 'Rate /min';
break;
case '5min':
$limit_by = 'Rate /5min';
break;
case 'hour':
$limit_by = 'Rate /hour';
break;
case 'value':
$limit_by = 'Value';
break;
}
$counter['counter_thresholds'] = $have_limit ? "$limit_by: $counter_limit_low - $counter_limit_high" : '&infin;';
// generate pretty value / rate
foreach (['value', 'rate', 'rate_5min', 'rate_hour'] as $param)
{
if (!is_numeric($counter['counter_'.$param]))
{
//$counter['human_'.$param] = 'NaN';
if ($param == 'value')
{
$counter['counter_symbol'] = '';
$counter['human_'.$param] = 'NaN';
} else {
// Rates
$counter['human_'.$param] = '-';
}
} else {
// Rate can be negative (ie lifetime always grow down)
if ($counter['counter_'.$param] < 0)
{
$counter['human_' . $param] = '-' . format_value(abs($counter['counter_' . $param]), $counter['counter_format']);
} else {
$counter['human_' . $param] = format_value($counter['counter_' . $param], $counter['counter_format']);
}
}
}
if (isset($config['entity_events'][$counter['counter_event']]))
{
$counter = array_merge($counter, $config['entity_events'][$counter['counter_event']]);
} else {
$counter['event_class'] = 'label label-primary';
$counter['row_class'] = '';
}
//r($counter);
if ($counter['counter_deleted'])
{
$counter['row_class'] = 'disabled';
}
$device = &$GLOBALS['cache']['devices']['id'][$counter['device_id']];
if ((isset($device['status']) && !$device['status']) || (isset($device['disabled']) && $device['disabled']))
{
$counter['row_class'] = 'error';
}
// Set humanized entry in the array so we can tell later
$counter['humanized'] = TRUE;
}
function build_counter_query($vars, $query_count = FALSE)
{
if ($query_count)
{
$sql = "SELECT COUNT(*) FROM `counters`";
} else {
$sql = "SELECT * FROM `counters`";
if ($vars['sort'] == 'hostname' || $vars['sort'] == 'device' || $vars['sort'] == 'device_id')
{
$sql .= ' LEFT JOIN `devices` USING(`device_id`)';
}
}
$sql .= " WHERE `counter_deleted` = 0";
// Build query
foreach($vars as $var => $value)
{
switch ($var)
{
case "group":
case "group_id":
$values = get_group_entities($value);
$sql .= generate_query_values($values, 'counters.counter_id');
break;
case 'device_group_id':
case 'device_group':
$values = get_group_entities($value, 'device');
$sql .= generate_query_values($values, 'counters.device_id');
break;
case "device":
case "device_id":
$sql .= generate_query_values($value, 'counters.device_id');
break;
case "id":
case "counter_id":
$sql .= generate_query_values($value, 'counters.counter_id');
break;
case "entity_id":
$sql .= generate_query_values($value, 'counters.measured_entity');
break;
case "entity_type":
$sql .= generate_query_values($value, 'counters.measured_class');
break;
case 'entity_state':
case "measured_state":
$sql .= build_entity_measured_where('counter', ['measured_state' => $value]);
break;
case 'class':
case "counter_class":
$sql .= generate_query_values($value, 'counter_class');
break;
case "descr":
case "counter_descr":
$sql .= generate_query_values($value, 'counters.counter_descr', '%LIKE%');
break;
case "event":
case "counter_event":
$sql .= generate_query_values($value, 'counter_event');
break;
}
}
// $sql .= $GLOBALS['cache']['where']['devices_permitted'];
$sql .= generate_query_permitted(array('device', 'counter'));
// If need count, just return sql without sorting
if ($query_count)
{
return $sql;
}
switch ($vars['sort_order'])
{
case 'desc':
$sort_order = 'DESC';
$sort_neg = 'ASC';
break;
case 'reset':
unset($vars['sort'], $vars['sort_order']);
// no break here
default:
$sort_order = 'ASC';
$sort_neg = 'DESC';
}
switch($vars['sort'])
{
case 'device':
$sql .= ' ORDER BY `hostname` '.$sort_order;
break;
case 'descr':
case 'event':
$sql .= ' ORDER BY `counter_'.$vars['sort'].'` '.$sort_order;
break;
case 'value':
case 'rate':
case 'rate_hour':
case 'last_change':
$sql .= ' ORDER BY `counter_'.$vars['sort'].'` '.$sort_order;
break;
default:
// $sql .= ' ORDER BY `hostname` '.$sort_order.', `counter_descr` '.$sort_order;
}
if (isset($vars['pageno']))
{
$start = $vars['pagesize'] * ($vars['pageno'] - 1);
$sql .= ' LIMIT '.$start.','.$vars['pagesize'];
}
return $sql;
}
function print_counter_table($vars)
{
pagination($vars, 0, TRUE); // Get default pagesize/pageno
$sql = build_counter_query($vars);
//r($vars);
//r($sql);
$counters = array();
//foreach(dbFetchRows($sql, NULL, TRUE) as $counter)
foreach(dbFetchRows($sql) as $counter)
{
//if (isset($GLOBALS['cache']['devices']['id'][$counter['device_id']]))
//{
$counter['hostname'] = $GLOBALS['cache']['devices']['id'][$counter['device_id']]['hostname'];
$counters[] = $counter;
//}
}
//$counters_count = count($counters); // This is count incorrect, when pagination used!
//$counters_count = dbFetchCell(build_counter_query($vars, TRUE), NULL, TRUE);
$counters_count = dbFetchCell(build_counter_query($vars, TRUE));
// Pagination
$pagination_html = pagination($vars, $counters_count);
echo $pagination_html;
echo generate_box_open();
print_counter_table_header($vars);
foreach($counters as $counter)
{
print_counter_row($counter, $vars);
}
echo("</tbody></table>");
echo generate_box_close();
echo $pagination_html;
}
function print_counter_table_header($vars)
{
if ($vars['view'] == "graphs" || $vars['graph'] || isset($vars['id']))
{
$stripe_class = "table-striped-two";
} else {
$stripe_class = "table-striped";
}
echo('<table class="table ' . $stripe_class . ' table-condensed ">' . PHP_EOL);
$cols = [];
$cols[] = array(NULL, 'class="state-marker"');
$cols['device'] = array('Device', 'style="width: 250px;"');
//$cols[] = array(NULL, 'class="no-width"'); // Measure entity link
$cols['descr'] = array('Description');
$cols['class'] = array('Class', 'style="width: 100px;"');
$cols['mib'] = array('MIB::Object');
//$cols[] = array('Thresholds', 'style="width: 100px;"');
$cols[] = array('History', 'style="text-align: right;"');
$cols['last_change'] = array('Last&nbsp;changed', 'style="width: 80px;"');
$cols['event'] = array('Event', 'style="width: 60px; text-align: right;"');
$cols['rate'] = array('Rate', 'style="width: 80px; text-align: right;"');
$cols['value'] = array('Value', 'style="width: 70px; text-align: right;"');
if ($vars['page'] == "device") { unset($cols['device']); }
if ($vars['page'] != "device" || $vars['tab'] == "overview") { unset($cols['mib']); unset($cols['object']); }
if (!$vars['show_class']) { unset($cols['class']); }
if ($vars['tab'] == "overview") { unset($cols[2]); } // Thresholds
echo(get_table_header($cols, $vars));
echo('<tbody>' . PHP_EOL);
}
function print_counter_row($counter, $vars)
{
echo generate_counter_row($counter, $vars);
}
function generate_counter_row($counter, $vars)
{
global $config;
humanize_counter($counter);
$table_cols = 4;
if ($counter['counter_event'] && is_numeric($counter['counter_value']))
{
$graph_array = array();
$graph_array['to'] = $config['time']['now'];
$graph_array['id'] = $counter['counter_id'];
$graph_array['type'] = "counter_graph";
$graph_array['width'] = 80;
$graph_array['height'] = 20;
$graph_array['bg'] = 'ffffff00';
$graph_array['from'] = $config['time']['day'];
$mini_graph = generate_graph_tag($graph_array);
$graph_array = array();
$graph_array['to'] = $config['time']['now'];
$graph_array['id'] = $counter['counter_id'];
$graph_array['type'] = "counter_rate";
$graph_array['width'] = 80;
$graph_array['height'] = 20;
$graph_array['bg'] = 'ffffff00';
$graph_array['from'] = $config['time']['day'];
$mini_graph .= generate_graph_tag($graph_array);
} else {
// Do not show "Draw Error" minigraph
$mini_graph = '';
}
$row = '
<tr class="'.$counter['row_class'].'">
<td class="state-marker"></td>';
if ($vars['page'] != "device" && $vars['popup'] != TRUE)
{
$row .= ' <td class="entity">' . generate_device_link($counter) . '</td>' . PHP_EOL;
$table_cols++;
}
// Measured link & icon
/* Disabled because it breaks the overview table layout
if ($vars['entity_icon']) // this used for entity popup
{
$row .= get_icon($config['counter_types'][$counter['counter_class']]['icon']);
}
elseif ($counter['measured_entity'] &&
(!isset($vars['measured_icon']) || $vars['measured_icon'])) // hide measured icon if not required
{
//$row .= generate_entity_link($counter['measured_class'], $counter['measured_entity'], get_icon($counter['measured_class']));
$row .= generate_entity_icon_link($counter['measured_class'], $counter['measured_entity']);
}
$row .= '</td>';
$table_cols++;
*/
$row .= ' <td class="entity">' . generate_entity_link("counter", $counter) . '</td>';
$table_cols++;
if ($vars['show_class'])
{
$row .= ' <td>' . nicecase($counter['counter_class']). '</td>' . PHP_EOL;
$table_cols++;
}
// FIXME -- Generify this. It's not just for counters.
if ($vars['page'] === "device" && $vars['tab'] !== "overview") {
$row .= ' <td>' . (!safe_empty($counter['counter_mib']) ? '<a href="'.OBSERVIUM_MIBS_URL.'/'.$counter['counter_mib'].'/" target="_blank">' . nicecase($counter['counter_mib']) .'</a>' : '') .
( ( !safe_empty($counter['counter_mib']) && !safe_empty($counter['counter_object'])) ? '::' : '') .
(!safe_empty($counter['counter_mib']) ? '<a href="'.OBSERVIUM_MIBS_URL.'/'.$counter['counter_mib'].'/#'.$counter['counter_object'].'" target="_blank">' . $counter['counter_object'] .'</a>' : '') .
'.'.$counter['counter_index'].'</td>' . PHP_EOL;
$table_cols++;
}
// Disable show thresholds
// if ($vars['tab'] != 'overview')
// {
// $row .= ' <td><span class="label ' . ($counter['counter_custom_limit'] ? 'label-warning' : '') . '">' . $counter['counter_thresholds'] . '</span></td>' . PHP_EOL;
// $table_cols++;
// }
$row .= ' <td style="width: 180px; text-align: right;">' . generate_entity_link('counter', $counter, $mini_graph, NULL, FALSE) . '</td>';
if ($vars['tab'] != 'overview')
{
$row .= ' <td style="white-space: nowrap">' . ($counter['counter_last_change'] == '0' ? 'Never' : generate_tooltip_link(NULL, format_uptime(($config['time']['now'] - $counter['counter_last_change']), 'short-2') . ' ago', format_unixtime($counter['counter_last_change']))) . '</td>';
$table_cols++;
$row .= ' <td style="text-align: right;"><strong>' . generate_tooltip_link('', $counter['counter_event'], $counter['event_descr'], $counter['event_class']) . '</strong></td>';
$table_cols++;
}
$counter_tooltip = $counter['event_descr'];
// Append value in alternative units to tooltip
if (isset($config['counter_types'][$counter['counter_class']]['alt_units']))
{
foreach (value_to_units($counter['counter_value'],
$config['counter_types'][$counter['counter_class']]['symbol'],
$counter['counter_class'],
$config['counter_types'][$counter['counter_class']]['alt_units']) as $unit => $unit_value)
{
if (is_numeric($unit_value)) { $counter_tooltip .= "<br />${unit_value}${unit}"; }
}
}
// Set to TRUE if this counter in time based format (ie lifetime)
$format_time = isset($config['counter_types'][$counter['counter_class']]['format']) &&
str_contains_array($config['counter_types'][$counter['counter_class']]['format'], 'time');
$rates = [];
// FIXME. Probably do not show rates for time based counters?.. (it's always around 1s/5m/1h)
if (!$format_time)
{
$rate_text = $format_time ? $counter['human_rate'] : $counter['human_rate'] . ' /s';
if ($counter['counter_limit_by'] == 'sec' && $counter['counter_event'] != 'ok')
{
$rates[] = ['event' => $counter['event_class'], 'text' => $rate_text];
} else {
$rates[] = ['event' => 'success', 'text' => $rate_text];
}
$rate_text = $format_time ? $counter['human_rate_5min'] : $counter['human_rate_5min'] . ' /5min';
if ($counter['counter_limit_by'] == '5min' && $counter['counter_event'] != 'ok')
{
$rates[] = ['event' => $counter['event_class'], 'text' => $rate_text];
} else {
$rates[] = ['event' => 'info', 'text' => $rate_text];
}
$rate_text = $format_time ? $counter['human_rate_hour'] : $counter['human_rate_hour'] . ' /h';
if ($counter['counter_limit_by'] == 'hour' && $counter['counter_event'] != 'ok')
{
$rates[] = ['event' => $counter['event_class'], 'text' => $rate_text];
} else {
$rates[] = ['event' => 'primary', 'text' => $rate_text];
}
}
$row .= ' <td style="width: 80px; text-align: right;">' . get_label_group($rates) . '</td>';
$row .= ' <td style="width: 70px; text-align: right;"><strong>' . generate_tooltip_link('', $counter['human_value'] . $counter['counter_symbol'], $counter_tooltip, $counter['event_class']) . '</strong></td>';
$row .= ' </tr>' . PHP_EOL;
if ($vars['view'] == "graphs" || $vars['id'] == $counter['counter_id']) { $vars['graph'] = "graph"; }
if ($vars['graph'])
{
$row .= '
<tr class="'.$counter['row_class'].'">
<td class="state-marker"></td>
<td colspan="'.$table_cols.'">';
$graph_array = array();
$graph_array['to'] = $config['time']['now'];
$graph_array['id'] = $counter['counter_id'];
$graph_array['type'] = 'counter_'.$vars['graph'];
$row .= generate_graph_row($graph_array, TRUE);
$graph_array = array();
$graph_array['to'] = $config['time']['now'];
$graph_array['id'] = $counter['counter_id'];
$graph_array['type'] = 'counter_rate';
$row .= generate_graph_row($graph_array, TRUE);
$row .= '</td></tr>';
} # endif graphs
return $row;
}
function print_counter_form($vars, $single_device = FALSE)
{
global $config;
$form = array('type' => 'rows',
'space' => '10px',
'submit_by_key' => TRUE,
'url' => generate_url($vars));
$form_items = array();
if ($single_device)
{
// Single device, just hidden field
$form['row'][0]['device_id'] = array(
'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 `counters`'));
$form['row'][0]['device_id'] = array(
'type' => 'multiselect',
'name' => 'Device',
'value' => $vars['device_id'],
'grid' => 2,
'width' => '100%', //'180px',
'values' => $form_items['devices']);
}
$counter_permitted = generate_query_permitted(array('device', 'counter'));
foreach ([ 'counter_class' => 'Counter Class', 'counter_event' => 'Counter Event' ] as $param => $param_name) {
$sql = 'SELECT DISTINCT `'.$param.'` FROM `counters` WHERE `counter_deleted` = ?' . $counter_permitted;
if ($entries = dbFetchColumn($sql, [ 0 ])) {
asort($entries);
}
foreach ($entries as $entry) {
if (safe_empty($entry)) { $entry = OBS_VAR_UNSET; }
if ($param === 'counter_class')
{
$name = nicecase($entry);
if (isset($config['counter_types'][$entry]['icon']))
{
$name = ['name' => $name, 'icon' => $config['counter_types'][$entry]['icon']];
} else {
$name = ['name' => $name, 'icon' => $config['icon']['counter']];
}
} else {
$name = $entry;
}
$form_items[$param][$entry] = $name;
}
// Alternative param name, ie event
$short_param = str_replace('counter_', '', $param);
if (!isset($vars[$param]) && isset($vars[$short_param]))
{
$vars[$param] = $vars[$short_param];
}
$form['row'][0][$param] = array(
'type' => 'multiselect',
'name' => $param_name,
'width' => '100%', //'180px',
'grid' => 2,
'value' => $vars[$param],
'values' => $form_items[$param]);
}
// Currently unused, just dumb space
$form['row'][0]['counter_value'] = array(
'type' => 'hidden',
'name' => 'Value',
'width' => '100%', //'180px',
'grid' => 0,
'value' => $vars['counter_value']);
// Measured entities
$form['row'][0]['measured_state'] = array(
'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]['counter_descr'] = array(
'type' => 'text',
'placeholder' => 'Counter description',
'width' => '100%', //'180px',
'grid' => 6,
'value' => $vars['counter_descr']);
// $form['row'][1]['counter_type'] = array(
// 'type' => 'text',
// 'placeholder' => 'Counter type',
// 'width' => '100%', //'180px',
// 'grid' => 4,
// 'value' => $vars['status_descr']);
// Groups
foreach (get_type_groups('counter') as $entry)
{
$form_items['group'][$entry['group_id']] = $entry['group_name'];
}
$form['row'][1]['group'] = array(
'community' => FALSE,
'type' => 'multiselect',
'name' => 'Select Groups',
'width' => '100%', //'180px',
'grid' => 2,
'value' => $vars['group'],
'values' => $form_items['group']);
$form['row'][1]['search'] = array(
'type' => 'submit',
'grid' => 4,
//'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 = array('type' => 'rows',
'title' => 'Search Counters',
'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]['counter_class'] = $form['row'][0]['counter_class'];
$panel_form['row'][1]['counter_event'] = $form['row'][0]['counter_event'];
$panel_form['row'][1]['counter_value'] = $form['row'][0]['counter_value'];
$panel_form['row'][2]['measured_state'] = $form['row'][0]['measured_state'];
$panel_form['row'][2]['group'] = $form['row'][1]['group'];
//$panel_form['row'][3]['counter_type'] = $form['row'][1]['counter_type'];
$panel_form['row'][4]['counter_descr'] = $form['row'][1]['counter_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

View File

@ -0,0 +1,801 @@
<?php
/**
* Observium
*
* This file is part of Observium.
*
* @package observium
* @subpackage web
* @copyright (C) 2006-2013 Adam Armstrong, (C) 2013-2021 Observium Limited
*
*/
/**
* Build devices where array
*
* This function returns an array of "WHERE" statements from a $vars array.
* The returned array can be implode()d and used on the devices table.
* Originally extracted from the /devices/ page
*
* @param array $vars
* @return array
*/
function build_devices_where_array($vars)
{
$where_array = array();
foreach ($vars as $var => $value)
{
if ($value != '')
{
switch ($var)
{
case 'group':
case 'group_id':
$values = get_group_entities($value);
$where_array[$var] = generate_query_values($values, 'device_id');
break;
case 'device':
case 'device_id':
$where_array[$var] = generate_query_values($value, 'device_id');
break;
case 'hostname':
case 'sysname':
case 'sysContact':
case 'sysDescr':
case 'serial':
case 'purpose':
$where_array[$var] = generate_query_values($value, $var, '%LIKE%');
break;
case 'location_text':
$where_array[$var] = generate_query_values($value, 'devices.location', '%LIKE%');
break;
case 'location':
$where_array[$var] = generate_query_values($value, 'devices.location');
break;
case 'location_lat':
case 'location_lon':
case 'location_country':
case 'location_state':
case 'location_county':
case 'location_city':
if ($GLOBALS['config']['geocoding']['enable'])
{
$where_array[$var] = generate_query_values($value, 'devices_locations.' . $var);
}
break;
case 'os':
case 'version':
case 'hardware':
case 'vendor':
case 'features':
case 'type':
case 'status':
case 'status_type':
case 'distro':
case 'ignore':
case 'disabled':
$where_array[$var] = generate_query_values($value, $var);
break;
case 'graph':
$where_array[$var] = generate_query_values(devices_with_graph($value), "devices.device_id");
}
}
}
return $where_array;
}
function devices_with_graph($graph)
{
$devices = array();
$sql = "SELECT `device_id` FROM `device_graphs` WHERE `graph` = ? AND `enabled` = '1'";
foreach(dbFetchRows($sql, array($graph)) AS $entry)
{
$devices[$entry['device_id']] = $entry['device_id'];
}
return $devices;
}
function build_devices_sort($vars)
{
$order = '';
$desc_order = isset($vars['sort_desc']) && $vars['sort_desc'];
switch ($vars['sort'])
{
case 'uptime':
case 'location':
case 'version':
case 'features':
case 'type':
case 'os':
case 'device_id':
$order = ' ORDER BY `devices`.`'.$vars['sort'].'`';
if ($desc_order)
{
$order .= " DESC";
}
break;
case 'domain':
// Special order hostnames in Domain Order
// SELECT `hostname`,
// SUBSTRING_INDEX(SUBSTRING_INDEX(`hostname`,'.',-3),'.',1) AS `leftmost`,
// SUBSTRING_INDEX(SUBSTRING_INDEX(`hostname`,'.',-2),'.',1) AS `middle`,
// SUBSTRING_INDEX(`hostname`,'.',-1) AS `rightmost`
// FROM `devices` ORDER by `middle`, `rightmost`, `leftmost`;
if ($desc_order)
{
$order = ' ORDER BY `middle` DESC, `rightmost` DESC, `leftmost` DESC';
} else {
$order = ' ORDER BY `middle`, `rightmost`, `leftmost`';
}
break;
default:
$order = ' ORDER BY `devices`.`hostname`';
if ($desc_order)
{
$order .= " DESC";
}
break;
}
return $order;
}
// DOCME needs phpdoc block
function print_device_header($device, $args = array()) {
global $config;
if (!is_array($device)) { print_error("Invalid device passed to print_device_header()!"); }
/* FIXME. Unused?
if ($device['status'] == '0') { $class = "div-alert"; } else { $class = "div-normal"; }
if ($device['ignore'] == '1')
{
$class = "div-ignore-alert";
if ($device['status'] == '1')
{
$class = "div-ignore";
}
}
if ($device['disabled'] == '1')
{
$class = "div-disabled";
}
$type = strtolower($device['os']);
*/
$div_class = 'box box-solid';
if (!safe_empty($args['div-class'])) {
$div_class .= " ${args['div-class']}";
}
echo '<div class="'.$div_class.'">
<table class=" table table-hover table-condensed '.$args['class'].'" style="margin-bottom: 10px; min-height: 70px; border-radius: 2px;">';
echo '
<tr class="'.$device['html_row_class'].' vertical-align">
<td class="state-marker"></td>
<td style="width: 70px; text-align: center;">'.get_device_icon($device).'</td>
<td><span style="font-size: 20px;">' . generate_device_link($device) . '</span>
<br /><a href="'.generate_location_url($device['location']).'">' . escape_html($device['location']) . '</a></td>
';
if (device_permitted($device) && !$args['no_graphs']) {
echo '<td>';
// Only show graphs for device_permitted(), don't show device graphs to users who can only see a single entity.
if (isset($config['os'][$device['os']]['graphs'])) {
$graphs = $config['os'][$device['os']]['graphs'];
} elseif (isset($device['os_group'], $config['os'][$device['os_group']]['graphs'])) {
$graphs = $config['os'][$device['os_group']]['graphs'];
} else {
// Default group
$graphs = $config['os_group']['default']['graphs'];
}
$graph_array = [];
$graph_array['height'] = "100";
$graph_array['width'] = "310";
$graph_array['to'] = $config['time']['now'];
$graph_array['device'] = $device['device_id'];
$graph_array['type'] = "device_bits";
$graph_array['from'] = $config['time']['day'];
$graph_array['legend'] = "no";
$graph_array['height'] = "45";
$graph_array['width'] = "150";
$graph_array['style'] = array('width: 150px !important'); // Fix for FF issue on HiDPI screen
$graph_array['bg'] = "FFFFFF00";
// Preprocess device graphs array
$graphs_enabled = [];
foreach ($device['graphs'] as $graph) {
$graphs_enabled[] = $graph['graph'];
}
foreach ($graphs as $entry) {
if ($entry && in_array(str_replace('device_', '', $entry), $graphs_enabled, TRUE)) {
$graph_array['type'] = $entry;
if (preg_match(OBS_PATTERN_GRAPH_TYPE, $entry, $graphtype)) {
$type = $graphtype['type'];
$subtype = $graphtype['subtype'];
$text = $config['graph_types'][$type][$subtype]['descr'];
} else {
$text = nicecase($entry); // Fallback to the type itself as a string, should not happen!
}
echo '<div class="pull-right" style="padding: 2px; margin: 0;">';
//echo generate_graph_tag($graph_array);
echo generate_graph_popup($graph_array);
echo '<div style="padding: 0px; font-weight: bold; font-size: 7pt; text-align: center;">'.$text.'</div>';
echo '</div>';
}
}
echo ' </td>';
} // Only show graphs for device_permitted()
echo('
</tr>
</table>
</div>');
}
function print_device_row($device, $vars = array('view' => 'basic'), $link_vars = array())
{
global $config, $cache;
if (!is_array($device)) { print_error("Invalid device passed to print_device_row()!"); }
if (!is_array($vars)) { $vars = array('view' => $vars); } // For compatibility
humanize_device($device);
$tags = array(
'html_row_class' => $device['html_row_class'],
'device_id' => $device['device_id'],
'device_link' => generate_device_link($device, NULL, $link_vars),
'device_url' => generate_device_url($device, $link_vars),
'hardware' => escape_html($device['hardware']),
'features' => escape_html($device['features']),
'os_text' => $device['os_text'],
'version' => escape_html($device['version']),
//'sysName' => escape_html($device['sysName']),
'device_uptime' => deviceUptime($device, 'short'),
'location' => escape_html(truncate($device['location'], 40, ''))
);
switch (strtolower($config['web_device_name'])) {
case 'sysname':
case 'purpose':
case 'descr':
case 'description':
$tags['sysName'] = escape_html($device['hostname']);
if (!safe_empty($device['sysName'])) {
$tags['sysName'] .= ' / ' . escape_html($device['sysName']);
}
break;
default:
$tags['sysName'] = escape_html($device['sysName']);
}
switch ($vars['view'])
{
case 'detail':
case 'details':
$table_cols = 7;
$tags['device_image'] = get_device_icon($device);
$tags['ports_count'] = dbFetchCell("SELECT COUNT(*) FROM `ports` WHERE `device_id` = ? AND `deleted` = ?", array($device['device_id'], 0));
//$tags['sensors_count'] = dbFetchCell("SELECT COUNT(*) FROM `sensors` WHERE `device_id` = ? AND `sensor_deleted` = ?", array($device['device_id'], 0));
//$tags['sensors_count'] += dbFetchCell("SELECT COUNT(*) FROM `status` WHERE `device_id` = ? AND `status_deleted` = ?", array($device['device_id'], 0));
$tags['sensors_count'] = $cache['sensors']['devices'][$device['device_id']]['count'];
$tags['sensors_count'] += $cache['statuses']['devices'][$device['device_id']]['count'];
$hostbox = '
<tr class="'.$tags['html_row_class'].'" onclick="openLink(\''.$tags['device_url'].'\')" style="cursor: pointer;">
<td class="state-marker"></td>
<td class="text-center vertical-align" style="width: 64px; text-align: center;">'.$tags['device_image'].'</td>
<td style="width: 300px;"><span class="entity-title">'.$tags['device_link'].'</span><br />'.$tags['location'].'</td>
<td class="text-nowrap" style="width: 55px;">';
if ($tags['ports_count'])
{
$hostbox .= '<i class="'.$config['icon']['port'].'"></i> <span class="label">'.$tags['ports_count'].'</span>';
}
$hostbox .= '<br />';
if ($tags['sensors_count'])
{
$hostbox .= '<i class="'.$config['icon']['sensor'].'"></i> ';
$sensor_items = [];
// Ok
if ($event_count = $cache['sensors']['devices'][$device['device_id']]['ok'] + $cache['statuses']['devices'][$device['device_id']]['ok'])
{
$sensor_items[] = ['event' => 'success', 'text' => $event_count];
}
// Warning
if ($event_count = $cache['sensors']['devices'][$device['device_id']]['warning'] + $cache['statuses']['devices'][$device['device_id']]['warning'])
{
$sensor_items[] = ['event' => 'warning', 'text' => $event_count];
}
// Alert
if ($event_count = $cache['sensors']['devices'][$device['device_id']]['alert'] + $cache['statuses']['devices'][$device['device_id']]['alert'])
{
$sensor_items[] = ['event' => 'danger', 'text' => $event_count];
}
// Ignored
if ($event_count = $cache['sensors']['devices'][$device['device_id']]['ignored'] + $cache['statuses']['devices'][$device['device_id']]['ignored'])
{
$sensor_items[] = ['event' => 'default', 'text' => $event_count];
}
$hostbox .= get_label_group($sensor_items);
//'<span class="label">'.$tags['sensors_count'].'</span>';
}
$hostbox .= '</td>
<td>'.$tags['os_text'].' '.$tags['version']. (!empty($tags['features']) ? ' ('.$tags['features'].')' : '').'<br />
'.$tags['hardware'].'</td>
<td>'.$tags['device_uptime'].'<br />'.$tags['sysName'].'</td>
</tr>';
break;
case 'perf':
if ($_SESSION['userlevel'] >= "10")
{
$tags['device_image'] = get_device_icon($device);
$graph_array = array(
'type' => 'device_poller_perf',
'device' => $device['device_id'],
'operation' => 'poll',
'legend' => 'no',
'width' => 600,
'height' => 90,
'from' => $config['time']['week'],
'to' => $config['time']['now'],
);
$hostbox = '
<tr class="'.$tags['html_row_class'].'" onclick="openLink(\''.generate_device_url($device, ['tab' => 'perf']).'\')" style="cursor: pointer;">
<td class="state-marker"></td>
<td class="vertical-align" style="width: 64px; text-align: center;">'.$tags['device_image'].'</td>
<td class="vertical-align" style="width: 300px;"><span class="entity-title">' . $tags['device_link'] . '</span><br />'.$tags['location'].'</td>
<td><div class="pull-right" style="height: 130px; padding: 2px; margin: 0;">' . generate_graph_tag($graph_array) . '</div></td>
</tr>';
}
break;
case 'status':
$tags['device_image'] = get_device_icon($device);
// Graphs
$graph_array = array();
$graph_array['height'] = "100";
$graph_array['width'] = "310";
$graph_array['to'] = $config['time']['now'];
$graph_array['device'] = $device['device_id'];
$graph_array['type'] = "device_bits";
$graph_array['from'] = $config['time']['day'];
$graph_array['legend'] = "no";
$graph_array['height'] = "45";
$graph_array['width'] = "175";
$graph_array['bg'] = "FFFFFF00";
if (isset($config['os'][$device['os']]['graphs']))
{
$graphs = $config['os'][$device['os']]['graphs'];
}
else if (isset($device['os_group']) && isset($config['os'][$device['os_group']]['graphs']))
{
$graphs = $config['os'][$device['os_group']]['graphs'];
} else {
// Default group
$graphs = $config['os_group']['default']['graphs'];
}
// Preprocess device graphs array
$graphs_enabled = [];
foreach ($GLOBALS['cache']['devices']['id'][$device['device_id']]['graphs'] as $graph)
{
$graphs_enabled[] = $graph['graph'];
}
foreach ($graphs as $entry)
{
list(,$graph_subtype) = explode("_", $entry, 2);
if ($entry && in_array(str_replace("device_", "", $entry), $graphs_enabled))
{
$graph_array['type'] = $entry;
if(isset($config['graph_types']['device'][$graph_subtype]))
{
$title = $config['graph_types']['device'][$graph_subtype]['descr'];
} else {
$title = nicecase(str_replace("_", " ", $graph_subtype));
}
$tags['graphs'][] = '<div class="pull-right" style="margin: 5px; margin-bottom: 0px;">'. generate_graph_popup($graph_array) .'<br /><div style="text-align: center; padding: 0px; font-size: 7pt; font-weight: bold;">'.$title.'</div></div>';
}
}
$hostbox = '
<tr class="'.$tags['html_row_class'].'" onclick="openLink(\''.$tags['device_url'].'\')" style="cursor: pointer;">
<td class="state-marker"></td>
<td class="vertical-align" style="width: 64px; text-align: center;">'.$tags['device_image'].'</td>
<td style="width: 300px;"><span class="entity-title">'.$tags['device_link'].'</span><br />'.$tags['location'].'</td>
<td>';
if ($tags['graphs'])
{
$hostbox .= '' . implode($tags['graphs']) . '';
}
$hostbox .= '</td>
</tr>';
break;
default: // basic
$table_cols = 6;
$tags['device_image'] = get_device_icon($device);
$tags['ports_count'] = dbFetchCell("SELECT COUNT(*) FROM `ports` WHERE `device_id` = ? AND `deleted` = 0;", array($device['device_id']));
$tags['sensors_count'] = dbFetchCell("SELECT COUNT(*) FROM `sensors` WHERE `device_id` = ?;", array($device['device_id']));
$tags['sensors_count'] += dbFetchCell("SELECT COUNT(*) FROM `status` WHERE `device_id` = ?;", array($device['device_id']));
$hostbox = '
<tr class="'.$tags['html_row_class'].'" onclick="openLink(\''.$tags['device_url'].'\')" style="cursor: pointer;">
<td class="state-marker"></td>
<td class="vertical-align" style="width: 64px; text-align: center;">'.$tags['device_image'].'</td>
<td style="width: 300;"><span class="entity-title">'.$tags['device_link'].'</span><br />'.$tags['location'].'</td>
<td>'.$tags['hardware'].' '.$tags['features'].'</td>
<td>'.$tags['os_text'].' '.$tags['version'].'</td>
<td>'.$tags['device_uptime'].'</td>
</tr>';
}
// If we're showing graphs, generate the graph
if ($vars['graph'])
{
$hostbox .= '<tr><td colspan="'.$table_cols.'">';
$graph_array['to'] = $config['time']['now'];
$graph_array['device'] = $device['device_id'];
$graph_array['type'] = 'device_'.$vars['graph'];
$hostbox .= generate_graph_row($graph_array);
$hostbox .= '</td></tr>';
}
echo($hostbox);
}
/**
* Returns icon tag (by default) or icon name for current device array
*
* @param array $device Array with device info (from DB)
* @param bool $base_icon Return complete img tag with icon (by default) or just base icon name
* @param bool $dark Prefer dark variant of icon (also set by session var)
*
* @return string Img tag with icon or base icon name
*/
function get_device_icon($device, $base_icon = FALSE, $dark = FALSE) {
global $config;
$icon = 'generic';
$device['os'] = strtolower($device['os']);
$model = $config['os'][$device['os']]['model'];
if (!safe_empty($device['icon']) && is_file($config['html_dir'] . '/images/os/' . $device['icon'] . '.png')) {
// Custom device icon from DB
$icon = $device['icon'];
} elseif ($model && isset($config['model'][$model][$device['sysObjectID']]['icon']) &&
is_file($config['html_dir'] . '/images/os/' . $config['model'][$model][$device['sysObjectID']]['icon'] . '.png')) {
// Per model icon
$icon = $config['model'][$model][$device['sysObjectID']]['icon'];
} elseif (isset($config['os'][$device['os']]['icon']) &&
is_file($config['html_dir'] . '/images/os/' . $config['os'][$device['os']]['icon'] . '.png')) {
// Icon defined in os definition
$icon = $config['os'][$device['os']]['icon'];
} else {
if ($device['distro']) {
// Icon by distro name
// Red Hat Enterprise -> redhat
$distro = strtolower(trim(str_replace([ ' Enterprise', 'Red Hat' ], [ '', 'redhat' ], $device['distro'])));
$distro = safename($distro);
if (is_file($config['html_dir'] . '/images/os/' . $distro . '.png')) {
$icon = $distro;
}
}
if ($icon === 'generic' && is_file($config['html_dir'] . '/images/os/' . $device['os'] . '.png')) {
// Icon by OS name
$icon = $device['os'];
}
}
// Icon by vendor name
if ($icon === 'generic' && ($config['os'][$device['os']]['vendor'] || $device['vendor']))
{
if ($device['vendor'])
{
$vendor = $device['vendor'];
} else {
$vendor = rewrite_vendor($config['os'][$device['os']]['vendor']); // Compatibility, if device not polled for long time
}
$vendor_safe = safename(strtolower($vendor));
if (isset($config['vendors'][$vendor_safe]['icon']))
{
$icon = $config['vendors'][$vendor_safe]['icon'];
}
elseif (is_file($config['html_dir'] . '/images/os/' . $vendor_safe . '.png'))
{
$icon = $vendor_safe;
}
elseif (isset($config['os'][$device['os']]['icons']))
{
// Fallback to os alternative icon
$icon = array_values($config['os'][$device['os']]['icons'])[0];
}
}
// Set dark mode by session
if (isset($_SESSION['theme']))
{
$dark = str_contains($_SESSION['theme'], 'dark');
}
// Prefer dark variant of icon in dark mode
if ($dark && is_file($config['html_dir'] . '/images/os/' . $icon . '-dark.png'))
{
$icon .= '-dark';
}
if ($base_icon)
{
// return base name for os icon
return $icon;
}
// return image html tag
$srcset = '';
// Now we always have 2x icon variant!
//if (is_file($config['html_dir'] . '/images/os/' . $icon . '_2x.png')) // HiDPI image exist?
//{
// Detect allowed screen ratio for current browser
$ua_info = detect_browser();
if ($ua_info['screen_ratio'] > 1)
{
$srcset = ' srcset="' .$config['base_url'] . '/images/os/' . $icon . '_2x.png'.' 2x"';
}
//}
// Image tag -- FIXME re-engineer this code to do this properly. This is messy.
return '<img src="' . $config['base_url'] . '/images/os/' . $icon . '.png"' . $srcset . ' alt="" />';
}
// TESTME needs unit testing
// DOCME needs phpdoc block
function generate_device_url($device, $vars = array())
{
return generate_url(array('page' => 'device', 'device' => $device['device_id']), $vars);
}
// TESTME needs unit testing
// DOCME needs phpdoc block
function generate_device_popup_header($device, $vars = []) {
humanize_device($device);
$device_name = device_name($device);
if ($device['hostname'] !== $device_name) {
$sysName = $device['hostname'];
if (!safe_empty($device['sysName'])) {
$sysName .= ' / ' . $device['sysName'];
}
} else {
$sysName = $device['sysName'];
}
return generate_box_open() . '
<table class="table table-striped table-rounded table-condensed">
<tr class="' . $device['html_row_class'] . '" style="font-size: 10pt;">
<td class="state-marker"></td>
<td class="vertical-align" style="width: 64px; text-align: center;">' . get_device_icon($device) . '</td>
<td width="200px"><a href="'.generate_device_url($device).'" class="' . device_link_class($device) . '" style="font-size: 15px; font-weight: bold;">' .
escape_html(device_name($device)) . '</a><br />' . escape_html(truncate($device['location'], 64, '')) . '</td>
<td>' . $device['os_text'] . ' ' . escape_html($device['version']) . ' <br /> ' .
($device['vendor'] ? escape_html($device['vendor']).' ' : '') . escape_html($device['hardware']) . '</td>
<td>' . deviceUptime($device, 'short') . '<br />' . escape_html($sysName) . '</td>
</tr>
</table>
' . generate_box_close();
}
// TESTME needs unit testing
// DOCME needs phpdoc block
function generate_device_popup($device, $vars = []) {
global $config;
$content = generate_device_popup_header($device, $vars);
if (isset($config['os'][$device['os']]['graphs'])) {
$graphs = $config['os'][$device['os']]['graphs'];
} elseif (isset($device['os_group'], $config['os'][$device['os_group']]['graphs'])) {
$graphs = $config['os'][$device['os_group']]['graphs'];
} else {
// Default group
$graphs = $config['os_group']['default']['graphs'];
}
// Preprocess device graphs array
$graphs_enabled = [];
foreach ($device['graphs'] as $graph) {
if ($graph['enabled'] != '0') {
$graphs_enabled[] = $graph['graph'];
}
}
foreach ($graphs as $entry) {
if ($entry && in_array(str_replace('device_', '', $entry), $graphs_enabled, TRUE)) {
// No text provided for the minigraph, fetch from array
if (preg_match(OBS_PATTERN_GRAPH_TYPE, $entry, $graphtype)) {
$type = $graphtype['type'];
$subtype = $graphtype['subtype'];
$text = $config['graph_types'][$type][$subtype]['descr'];
} else {
$text = nicecase($entry); // Fallback to the type itself as a string, should not happen!
}
// FIXME -- function!
$graph_array = array();
$graph_array['height'] = "100";
$graph_array['width'] = "290";
$graph_array['to'] = get_time();
$graph_array['device'] = $device['device_id'];
$graph_array['type'] = $entry;
$graph_array['from'] = get_time('day');
$graph_array['legend'] = "no";
$content .= '<div style="width: 730px; white-space: nowrap;">';
$content .= "<div class=entity-title><h4>" . $text . "</h4></div>";
/*
$content .= generate_box_open(array('title' => $text,
'body-style' => 'white-space: nowrap;'));
*/
$content .= generate_graph_tag($graph_array);
$graph_array['from'] = get_time('week');
$content .= generate_graph_tag($graph_array);
$content .= '</div>';
//$content .= generate_box_close();
}
}
//r($content);
return $content;
}
// TESTME needs unit testing
// DOCME needs phpdoc block
function generate_device_link($device, $text = NULL, $vars = array(), $escape = TRUE, $short = FALSE) {
if (is_array($device) && !($device['hostname'] && isset($device['status']))) {
// partial device array, get full
$device = device_by_id_cache($device['device_id']);
} elseif (is_numeric($device)) {
$device = device_by_id_cache($device);
}
if (!$device) {
return escape_html($text);
}
if (!device_permitted($device['device_id'])) {
$text = device_name($device, $short);
return $escape ? escape_html($text) : $text;
}
$class = device_link_class($device);
if (safe_empty($text)) {
$text = device_name($device, $short);
}
$url = generate_device_url($device, $vars);
if ($escape) {
$text = escape_html($text);
}
return '<a href="' . $url . '" class="entity-popup ' . $class . ' text-nowrap" data-eid="' . $device['device_id'] . '" data-etype="device">' . $text . '</a>';
}
// Simple wrapper to generate_device_link() for common usage with only device_name
function generate_device_link_short($device, $vars = [], $short = TRUE) {
// defaults - always short device name, escaped
return generate_device_link($device, NULL, $vars, TRUE, $short);
}
function device_name($device, $max_len = FALSE) {
global $config;
switch (strtolower($config['web_device_name'])) {
case 'sysname':
$name_field = 'sysName';
break;
case 'purpose':
case 'descr':
case 'description':
$name_field = 'purpose';
break;
default:
$name_field = 'hostname';
}
if ($max_len && !is_intnum($max_len)) {
$max_len = $config['short_hostname']['length'];
}
if ($name_field !== 'hostname' && !safe_empty($device[$name_field])) {
if ($name_field === 'sysName' && $max_len && $max_len > 3) {
// short sysname when is valid hostname (do not escape here)
return short_hostname($device[$name_field], $max_len, FALSE);
}
return $device[$name_field];
}
if ($max_len && $max_len > 3) {
// short hostname (do not escape here)
return short_hostname($device['hostname'], $max_len, FALSE);
}
return $device['hostname'];
}
function generate_device_form_values($form_filter = FALSE, $column = 'device_id', $options = array())
{
global $cache;
$form_items = array();
foreach ($cache['devices']['hostname'] as $hostname => $device_id)
{
if (is_array($form_filter) && !in_array($device_id, $form_filter)) { continue; } // Devices only with entries
if ($cache['devices']['id'][$device_id]['disabled'] === '1')
{
if (isset($options['disabled']))
{
// Force display disabled devices
if (!$options['disabled']) { continue; }
}
elseif ($cache['devices']['id'][$device_id]['disabled'] && !$GLOBALS['config']['web_show_disabled']) { continue; }
$form_items[$device_id]['group'] = 'DISABLED';
}
elseif ($cache['devices']['id'][$device_id]['status'] === '0')
{
if (isset($options['down']) && !$options['down']) { continue; } // Skip down
$form_items[$device_id]['group'] = 'DOWN';
} else {
if (isset($options['up']) && !$options['up']) { continue; } // Skip up
$form_items[$device_id]['group'] = 'UP';
}
$form_items[$device_id]['name'] = $hostname;
if (isset($cache['devices']['id'][$device_id]['row_class'][0]))
{
// Set background color for non empty row_class (disabled/down/ignored)
$form_items[$device_id]['class'] = 'bg-' . $cache['devices']['id'][$device_id]['row_class'];
}
}
return $form_items;
}
// EOF

View File

@ -0,0 +1,442 @@
<?php
/**
* Observium
*
* This file is part of Observium.
*
* @package observium
* @subpackage functions
* @copyright (C) 2006-2013 Adam Armstrong, (C) 2013-2022 Observium Limited
*
*/
// F5 TEMP STUFF
function print_f5_lb_virtual_table_header($vars)
{
if ($vars['view'] == "graphs")
{
$table_class = OBS_CLASS_TABLE_STRIPED_TWO;
} else {
$table_class = OBS_CLASS_TABLE_STRIPED;
}
echo('<table class="' . $table_class . '">' . PHP_EOL);
$cols = array(
array(NULL, 'class="state-marker"'),
'device' => array('Device', 'style="width: 200px;"'),
'virt_name' => array('Virtual'),
array('', 'style="width: 100px;"'),
'virt_ip' => array('Address', 'style="width: 250px;"'),
'virt_type' => array('Type', 'style="width: 250px;"'),
'virt_state' => array('Status', 'style="width: 250px;"'),
);
if ($vars['page'] == "device")
{
unset($cols['device']);
}
echo(get_table_header($cols, $vars));
echo('<tbody>' . PHP_EOL);
}
function get_customoid_by_id($oid_id) {
if (is_numeric($oid_id)) {
$oid = dbFetchRow('SELECT * FROM `oids` WHERE `oid_id` = ?', array($oid_id));
}
if (safe_count($oid)) {
return $oid;
}
return FALSE;
} // end function get_customoid_by_id()
function generate_entity_popup_graphs($entity, $vars)
{
global $config;
$entity_type = $vars['entity_type'];
if (is_array($config['entities'][$entity_type]['graph']))
{
if (isset($config['entities'][$entity_type]['graph']['type']))
{
$graphs[] = $config['entities'][$entity_type]['graph'];
} else {
$graphs = $config['entities'][$entity_type]['graph'];
}
foreach($graphs as $graph_array)
{
//$graph_array = $config['entities'][$entity_type]['graph'];
// We can draw a graph for this type/metric pair!
foreach($graph_array as $key => $val)
{
// Check to see if we need to do any substitution
if (substr($val, 0, 1) == "@")
{
$nval = substr($val, 1);
$graph_array[$key] = $entity[$nval];
}
}
$graph_array['height'] = "100";
$graph_array['width'] = "323";
$content = '<div style="white-space: nowrap;">';
$content .= "<div class=entity-title><h4>" . nicecase(str_replace("_", " ", $graph_array['type'])) . "</h4></div>";
/*
$content = generate_box_open(array('title' => nicecase(str_replace("_", " ", $graph_array['type'])),
'body-style' => 'white-space: nowrap;'));
*/
foreach(array('day', 'month') as $period)
{
$graph_array['from'] = $config['time'][$period];
$content .= generate_graph_tag($graph_array);
}
$content .= "</div>";
//$content .= generate_box_close();
}
//r($content);
return $content;
}
}
function generate_entity_popup_header($entity, $vars)
{
$translate = entity_type_translate_array($vars['entity_type']);
$vars['popup'] = TRUE;
$vars['entity_icon'] = TRUE;
$contents = '';
switch($vars['entity_type'])
{
case "sensor":
$contents .= generate_box_open();
$contents .= '<table class="'. OBS_CLASS_TABLE .'">';
$contents .= generate_sensor_row($entity, $vars);
$contents .= '</table>';
$contents .= generate_box_close();
break;
case "toner":
case "printersupply":
case "supply":
$contents .= generate_box_open();
$contents .= '<table class="'. OBS_CLASS_TABLE .'">';
$contents .= generate_printersupplies_row($entity, $vars);
$contents .= '</table>';
$contents .= generate_box_close();
break;
case "bgp_peer":
if ($entity['peer_device_id'])
{
$peer_dev = device_by_id_cache($entity['peer_device_id']);
$peer_name = '<br /><a class="entity" style="font-weight: bold;">'.$peer_dev['hostname'].'</a>';
}
else if ($entity['reverse_dns'])
{
$peer_name = '<br /><span style="font-weight: bold;">' . $entity['reverse_dns'] . '</span>';
}
$astext = '<span>AS'.$entity['human_remote_as'];
if ($entity['astext'])
{
$astext .= '<br />' . $entity['astext'] . '</span>';
}
$astext .= '</span>';
$contents .= generate_box_open();
$contents .= '
<table class="'. OBS_CLASS_TABLE .'">
<tr class="' . $entity['row_class'] . ' vertical-align" style="font-size: 10pt;">
<td class="state-marker"></td>
<td style="width: 10px;"></td>
<td style="width: 10px;"><i class="'.$translate['icon'].'"></i></td>
<td><a class="entity-popup" style="font-size: 15px; font-weight: bold;">'.escape_html($entity['entity_shortname']).'</a>'.$peer_name.'</td>
<td class="text-nowrap" style="width: 20%;">'.$astext.'</td>
<td></td>
</tr>
</table>';
$contents .= generate_box_close();
break;
case "sla":
$contents .= generate_box_open();
$contents .= '<table class="'. OBS_CLASS_TABLE .'">';
$contents .= generate_sla_row($entity, $vars);
$contents .= '</table>';
$contents .= generate_box_close();
break;
case "processor":
$contents .= generate_box_open();
$contents .= '<table class="'. OBS_CLASS_TABLE .'">';
$contents .= generate_processor_row($entity, $vars);
$contents .= '</table>';
$contents .= generate_box_close();
break;
case "mempool":
$contents .= generate_box_open();
$contents .= '<table class="'. OBS_CLASS_TABLE .'">';
$contents .= generate_mempool_row($entity, $vars);
$contents .= '</table>';
$contents .= generate_box_close();
break;
case "p2pradio":
$contents .= generate_box_open();
$contents .= '<table class="'. OBS_CLASS_TABLE .'">';
$contents .= generate_p2pradio_row($entity, $vars);
$contents .= '</table>';
$contents .= generate_box_close();
break;
case "status":
$contents .= generate_box_open();
$contents .= '<table class="'. OBS_CLASS_TABLE .'">';
$contents .= generate_status_row($entity, $vars);
$contents .= '</table>';
$contents .= generate_box_close();
break;
case "counter":
$contents .= generate_box_open();
$contents .= '<table class="'. OBS_CLASS_TABLE .'">';
$contents .= generate_counter_row($entity, $vars);
$contents .= '</table>';
$contents .= generate_box_close();
break;
case "storage":
$contents .= generate_box_open();
$contents .= '<table class="'. OBS_CLASS_TABLE .'">';
$contents .= generate_storage_row($entity, $vars);
$contents .= '</table>';
$contents .= generate_box_close();
break;
case "netscalervsvr":
$contents .= generate_box_open();
$contents .= '<table class="'. OBS_CLASS_TABLE .'">';
$contents .= generate_netscalervsvr_row($entity, $vars);
$contents .= '</table>';
$contents .= generate_box_close();
break;
case "netscalersvc":
$contents .= generate_box_open();
$contents .= '<table class="'. OBS_CLASS_TABLE .'">';
$contents .= generate_netscalersvc_row($entity, $vars);
$contents .= '</table>';
$contents .= generate_box_close();
break;
case "netscalersvcgrpmem":
$contents .= generate_box_open();
$contents .= '<table class="'. OBS_CLASS_TABLE .'">';
$contents .= generate_netscalersvcmem_row($entity, $vars);
$contents .= '</table>';
$contents .= generate_box_close();
break;
default:
entity_rewrite($vars['entity_type'], $entity);
$contents = generate_box_open(). '
<table class="' . OBS_CLASS_TABLE_STRIPED . '">
<tr class="' . $entity['row_class'] . '" style="font-size: 10pt;">
<td class="state-marker"></td>
<td style="width: 10px;"></td>
<td width="400"><i class="'.$translate['icon'].'" style="margin-right: 10px;"></i> <a class="entity-popup" style="font-size: 15px; font-weight: bold;">'.escape_html($entity['entity_name']).'</a></td>
<td width="100"></td>
<td></td>
</tr>
</table>'.generate_box_close();
}
return $contents;
}
function generate_entity_popup($entity, $vars)
{
if (is_numeric($entity)) { $entity = get_entity_by_id_cache($vars['entity_type'], $entity); }
$device = device_by_id_cache($entity['device_id']);
$content = generate_device_popup_header($device);
$content .= generate_entity_popup_header($entity, $vars);
$content .= generate_entity_popup_graphs($entity, $vars);
return $content;
}
function generate_entity_popup_multi($entities, $vars)
{
// Note here limited only to one entity_type and one device_id
$count = count($entities);
// First element
$entity = array_shift($entities);
if (is_numeric($entity))
{
$entity = get_entity_by_id_cache($vars['entity_type'], $entity);
}
$device = device_by_id_cache($entity['device_id']);
$header = generate_entity_popup_header($entity, $vars);
if ($count > 1)
{
// Multiple entities graph
/// FIXME. Need add multi-graphs
$graphs = generate_entity_popup_graphs($entity, $vars);// This is incorrect, only first graph
} else {
// Single entity graph
$graphs = generate_entity_popup_graphs($entity, $vars);
}
// All other elements
foreach ($entities as $entity)
{
if (is_numeric($entity))
{
$entity = get_entity_by_id_cache($vars['entity_type'], $entity);
}
if ($entity['device_id'] != $device['device_id'])
{
// Skip if passed entity from different device
continue;
}
$header .= generate_entity_popup_header($entity, $vars);
//$graphs .= generate_entity_popup_graphs($entity, $vars); // Currently disabled, need multi graph
}
$content = generate_device_popup_header($device);
$content .= $header;
$content .= $graphs;
return $content;
}
// Measured specific functions
function build_entity_measured_where($entity_type, $vars)
{
$entity_array = entity_type_translate_array($entity_type);
$column_measured_id = $entity_array['table_fields']['measured_id'];
$column_measured_type = $entity_array['table_fields']['measured_type'];
$measure_array = [];
// Build query
foreach($vars as $var => $value)
{
if (!is_array($value)) { $value = explode(',', $value); }
switch ($var)
{
case 'measured_group':
foreach (dbFetchColumn('SELECT DISTINCT `'.$column_measured_type.'` FROM `'.$entity_array['table'].'` WHERE `'.$entity_array['table_fields']['deleted'].'` = ?', [0]) as $measured_type)
{
if (!$measured_type) { continue; }
$entities = get_group_entities($value, $measured_type);
$measure_sql = '';
switch ($measured_type)
{
case 'port':
case 'printersupply':
$measure_sql = generate_query_values($measured_type, $column_measured_type, NULL, OBS_DB_NO_LEADING_AND);
$measure_sql .= generate_query_values($entities, $column_measured_id);
break;
}
if ($measure_sql) { $measure_array[] = $measure_sql; }
}
break;
case 'measured_state':
// UP / DOWN / STUTDOWN / NONE states
//$value = (array)$value;
// Select all without measured entities
if (in_array('none', $value)) {
$measure_array[] = generate_query_values(1, $column_measured_id, 'NULL', OBS_DB_NO_LEADING_AND);
$value = array_diff($value, [ 'none' ]);
}
if (count($value))
{
// Limit statuses with measured entities
foreach (dbFetchColumn('SELECT DISTINCT `'.$column_measured_type.'` FROM `'.$entity_array['table'].'` WHERE `'.$entity_array['table_fields']['deleted'].'` = ?', [0]) as $measured_type)
{
if (!$measured_type) { continue; }
$measure_sql = '';
$measure_entities = dbFetchColumn('SELECT DISTINCT `'.$column_measured_id.'` FROM `'.$entity_array['table'].'` WHERE `'.$column_measured_type.'` = ? AND `'.$entity_array['table_fields']['deleted'].'` = ?', [$measured_type, 0]);
switch ($measured_type)
{
case 'port':
$where_array = build_ports_where_array(['port_id' => $measure_entities, 'state' => $value]);
$entity_sql = 'SELECT `port_id` FROM `ports` WHERE 1 ';
$entity_sql .= implode('', $where_array);
$entities = dbFetchColumn($entity_sql);
//$entities = dbFetchColumn($entity_sql, NULL, TRUE);
//r($entities);
$measure_sql = generate_query_values($measured_type, $column_measured_type, NULL, OBS_DB_NO_LEADING_AND);
$measure_sql .= generate_query_values($entities, $column_measured_id);
break;
case 'printersupply':
break;
}
if ($measure_sql) { $measure_array[] = $measure_sql; }
}
}
break;
}
}
switch (count($measure_array))
{
case 0:
$sql = '';
break;
case 1:
$sql = ' AND ' . $measure_array[0];
break;
default:
$sql = ' AND (('.implode(') OR (', $measure_array).'))';
}
return $sql;
}
// EOF

View File

@ -0,0 +1,359 @@
<?php
/**
* Observium
*
* This file is part of Observium.
*
* @package observium
* @subpackage web
* @copyright (C) 2006-2013 Adam Armstrong, (C) 2013-2021 Observium Limited
*
*/
function build_mempool_query($vars)
{
global $config, $cache;
$sql = 'SELECT *, `mempools`.`mempool_id` AS `mempool_id` FROM `mempools`';
//$sql .= ' LEFT JOIN `mempools-state` USING(`mempool_id`)';
if ($vars['sort'] === 'hostname' || $vars['sort'] === 'device' || $vars['sort'] === 'device_id') {
$sql .= ' LEFT JOIN `devices` USING(`device_id`)';
}
$sql .= ' WHERE 1' . generate_query_permitted(array('device'));
// Build query
foreach ($vars as $var => $value)
{
switch ($var)
{
case "group":
case "group_id":
$values = get_group_entities($value);
$sql .= generate_query_values($values, 'mempools.mempool_id');
break;
case 'device_group_id':
case 'device_group':
$values = get_group_entities($value, 'device');
$sql .= generate_query_values($values, 'mempools.device_id');
break;
case "device":
case "device_id":
$sql .= generate_query_values($value, 'mempools.device_id');
break;
case "descr":
case "mempool_descr";
$sql .= generate_query_values($value, 'mempool_descr', '%LIKE%');
break;
}
}
switch ($vars['sort_order'])
{
case 'desc':
$sort_order = 'DESC';
$sort_neg = 'ASC';
break;
case 'reset':
unset($vars['sort'], $vars['sort_order']);
// no break here
default:
$sort_order = 'ASC';
$sort_neg = 'DESC';
}
switch($vars['sort'])
{
case 'usage':
$sql .= ' ORDER BY `mempool_used` '.$sort_neg;
break;
case 'used':
$sql .= ' ORDER BY `mempool_perc` '.$sort_neg;
break;
case 'hostname':
$sql .= ' ORDER BY `hostname` '.$sort_order.', `mempool_descr` '.$sort_order;
break;
case 'descr':
default:
$sql .= ' ORDER BY `mempool_descr` '.$sort_order;
break;
}
return $sql;
}
function print_mempool_table($vars)
{
global $cache;
$sql = build_mempool_query($vars);
$mempools = array();
foreach (dbFetchRows($sql) as $mempool)
{
if (isset($cache['devices']['id'][$mempool['device_id']]))
{
$mempool['hostname'] = $cache['devices']['id'][$mempool['device_id']]['hostname'];
$mempool['html_row_class'] = $cache['devices']['id'][$mempool['device_id']]['html_row_class'];
$mempools[] = $mempool;
}
}
$mempools_count = count($mempools);
// Pagination
$pagination_html = pagination($vars, $mempools_count);
echo $pagination_html;
if ($vars['pageno'])
{
$mempools = array_chunk($mempools, $vars['pagesize']);
$mempools = $mempools[$vars['pageno'] - 1];
}
// End Pagination
echo generate_box_open();
print_mempool_table_header($vars);
foreach ($mempools as $mempool)
{
print_mempool_row($mempool, $vars);
}
echo("</tbody></table>");
echo generate_box_close();
echo $pagination_html;
}
function print_mempool_table_header($vars)
{
if ($vars['view'] === "graphs")
{
$table_class = OBS_CLASS_TABLE_STRIPED_TWO;
} else {
$table_class = OBS_CLASS_TABLE_STRIPED;
}
echo('<table class="' . $table_class . '">' . PHP_EOL);
$cols = array(
array(NULL, 'class="state-marker"'),
'device' => array('Device', 'style="width: 200px;"'),
'descr' => array('Memory'),
array('', 'style="width: 100px;"'),
'usage' => array('Usage', 'style="width: 280px;"'),
'used' => array('Used', 'style="width: 50px;"'),
);
if ($vars['page'] === "device")
{
unset($cols['device']);
}
echo(get_table_header($cols, $vars));
echo('<tbody>' . PHP_EOL);
}
function print_mempool_row($mempool, $vars)
{
echo generate_mempool_row($mempool, $vars);
}
function generate_mempool_row($mempool, $vars)
{
global $config;
$table_cols = 7;
if ($vars['page'] !== "device" && $vars['popup'] != TRUE) { $table_cols++; } // Add a column for device.
$graph_array = array();
$graph_array['to'] = $config['time']['now'];
$graph_array['id'] = $mempool['mempool_id'];
$graph_array['type'] = "mempool_usage";
$graph_array['legend'] = "no";
$link_array = $graph_array;
$link_array['page'] = "graphs";
unset($link_array['height'], $link_array['width'], $link_array['legend']);
$link_graph = generate_url($link_array);
$link = generate_url(array("page" => "device", "device" => $mempool['device_id'], "tab" => "health", "metric" => 'mempool'));
$overlib_content = generate_overlib_content($graph_array, $mempool['hostname'] . " - " . rewrite_entity_name($mempool['mempool_descr'], 'mempool'));
$graph_array['width'] = 80;
$graph_array['height'] = 20;
$graph_array['bg'] = 'ffffff00';
$graph_array['from'] = $config['time']['day'];
$mini_graph = generate_graph_tag($graph_array);
if ($mempool['mempool_total'] != '100')
{
$total = formatStorage($mempool['mempool_total']);
$used = formatStorage($mempool['mempool_used']);
$free = formatStorage($mempool['mempool_free']);
}
else
{
// If total == 100, than memory not have correct size and uses percents only
$total = $mempool['mempool_total'] . '%';
$used = $mempool['mempool_used'] . '%';
$free = $mempool['mempool_free'] . '%';
}
$background = get_percentage_colours($mempool['mempool_perc']);
$mempool['html_row_class'] = $background['class'];
$row .= '<tr class="' . $mempool['html_row_class'] . '">
<td class="state-marker"></td>';
if ($vars['page'] !== "device" && $vars['popup'] != TRUE)
{
$row .= '<td class="entity">' . generate_device_link($mempool) . '</td>';
}
$row .= '<td class="entity">' . generate_entity_link('mempool', $mempool) . '</td>
<td>' . overlib_link($link_graph, $mini_graph, $overlib_content) . '</td>
<td><a href="' . $link_graph . '">
' . print_percentage_bar(400, 20, $mempool['mempool_perc'], $used . '/' . $total . ' (' . $mempool['mempool_perc'] . '%)', "ffffff", $background['left'], $free . ' (' . (100 - $mempool['mempool_perc']) . '%)', "ffffff", $background['right']) . '
</a>
</td>
<td>' . $mempool['mempool_perc'] . '%</td>
</tr>
';
if ($vars['view'] === "graphs")
{
$vars['graph'] = "usage";
}
if ($vars['graph'])
{
$row .= '<tr class="' . $mempool['html_row_class'] . '">';
$row .= '<td class="state-marker"></td>';
$row .= '<td colspan="' . $table_cols . '">';
unset($graph_array['height'], $graph_array['width'], $graph_array['legend']);
$graph_array['to'] = $config['time']['now'];
$graph_array['id'] = $mempool['mempool_id'];
$graph_array['type'] = 'mempool_' . $vars['graph'];
$row .= generate_graph_row($graph_array, TRUE);
$row .= '</td></tr>';
} # endif graphs
return $row;
}
function print_mempool_form($vars, $single_device = FALSE)
{
//global $config;
$form = array('type' => 'rows',
'space' => '10px',
'submit_by_key' => TRUE,
'url' => generate_url($vars));
$form_items = array();
if ($single_device)
{
// Single device, just hidden field
$form['row'][0]['device_id'] = array(
'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 `mempools`'));
$form['row'][0]['device_id'] = array(
'type' => 'multiselect',
'name' => 'Device',
'value' => $vars['device_id'],
'grid' => 2,
'width' => '100%', //'180px',
'values' => $form_items['devices']);
}
//$sensor_permitted = generate_query_permitted(array('device', 'sensor'));
$form['row'][0]['mempool_descr'] = array(
'type' => 'text',
'placeholder' => 'Mempool',
'width' => '100%', //'180px',
'grid' => 6,
'value' => $vars['mempool_descr']);
// Groups
foreach (get_type_groups('storage') as $entry)
{
$form_items['group'][$entry['group_id']] = $entry['group_name'];
}
$form['row'][0]['group'] = array(
'community' => FALSE,
'type' => 'multiselect',
'name' => 'Select Groups',
'width' => '100%', //'180px',
'grid' => 2,
'value' => $vars['group'],
'values' => $form_items['group']);
$form['row'][0]['search'] = array(
'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 = array('type' => 'rows',
'title' => 'Search Mempools',
'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]['group'] = $form['row'][0]['group'];
//$panel_form['row'][1]['supply_colour'] = $form['row'][0]['supply_colour'];
//$panel_form['row'][1]['supply_type'] = $form['row'][0]['supply_type'];
//$panel_form['row'][2]['measured_state'] = $form['row'][0]['measured_state'];
//$panel_form['row'][2]['group'] = $form['row'][1]['group'];
$panel_form['row'][3]['mempool_descr'] = $form['row'][0]['mempool_descr'];
//$panel_form['row'][5]['sort'] = $form['row'][0]['sort'];
$panel_form['row'][5]['search'] = $form['row'][0]['search'];
// Register custom panel
register_html_panel(generate_form($panel_form));
}
// EOF

View File

@ -0,0 +1,258 @@
<?php
/**
* Observium
*
* This file is part of Observium.
*
* @package observium
* @subpackage web
* @copyright (C) 2006-2013 Adam Armstrong, (C) 2013-2021 Observium Limited
*
*/
function generate_oid_template_link($entry)
{
$url = generate_url(array('page' => 'customoid', 'oid_id' => $entry['oid_id']));
$link = '<a href="'.$url.'">'.$entry['oid_descr'].'</a>';
return $link;
}
function build_oid_query($vars)
{
$sql = 'SELECT * FROM `oids_entries` LEFT JOIN `oids` USING (`oid_id`)';
//if ($vars['sort'] == 'hostname' || $vars['sort'] == 'device' || $vars['sort'] == 'device_id') {
$sql .= ' LEFT JOIN `devices` USING(`device_id`)';
//}
$sql .= ' WHERE 1' . generate_query_permitted(array('device'));
// Build query
foreach ($vars as $var => $value) {
switch ($var) {
case "oid_id":
case "oid_descr":
case "oid":
case "oid_name":
$sql .= generate_query_values($value, $var);
break;
case "group":
case "group_id":
$values = get_group_entities($value);
$sql .= generate_query_values($values, 'oid_entry_id');
break;
case 'device_group_id':
case 'device_group':
$values = get_group_entities($value, 'device');
$sql .= generate_query_values($values, 'oids_entries.device_id');
break;
case "device":
case "device_id":
$sql .= generate_query_values($value, 'oids_entries.device_id');
break;
}
}
switch ($vars['sort_order']) {
case 'desc':
$sort_order = 'DESC';
$sort_neg = 'ASC';
break;
case 'reset':
unset($vars['sort'], $vars['sort_order']);
// no break here
default:
$sort_order = 'ASC';
$sort_neg = 'DESC';
}
switch ($vars['sort']) {
case 'value':
case 'oid_descr':
case 'oid_name':
case 'oid':
case 'event':
$sql .= ' ORDER BY '.$vars['sort'].' ' . $sort_order;
break;
default:
$sql .= ' ORDER BY `hostname` ' . $sort_order;
}
return $sql;
}
function print_oid_table_header($vars, $entries)
{
echo('<table class="' . (get_var_true($vars['graphs']) ? OBS_CLASS_TABLE_STRIPED_TWO : OBS_CLASS_TABLE_STRIPED) . '">');
$cols[] = array('', 'class="state-marker"');
$cols['hostname'] = array('Device', 'style="width: 280px;"');
if(!isset($vars['oid_id'])){
$cols['oid_descr'] = array('OID Description');
} else { $cols[] = array(''); }
$cols[] = array('', 'style="width: 140px;"');
$cols[] = array('Thresholds', 'style="width: 100px;"');
$cols['value'] = array('Value', 'style="width: 80px;"');
$cols['event'] = array('Event', 'style="width: 60px;"');
if ($entries[0]['oid_autodiscover'] == '0' && $vars['page'] === "customoid") {
$cols['actions'] = array('', 'style="width: 40px;"'); echo "derp";
}
echo get_table_header($cols, $vars);
echo '<tbody>' . PHP_EOL;
}
function print_oid_table($vars)
{
global $config;
$sql = build_oid_query($vars);
$entries = dbFetchRows($sql);
$count = count($entries);
if (count($entries)) {
echo generate_box_open();
print_oid_table_header($vars, $entries);
foreach ($entries as $device_id => $entry) {
//$device = device_by_id_cache($device_id);
if (!is_numeric($entry['value'])) {
$entry['human_value'] = 'NaN';
} else {
if($entry['oid_kibi'] == 1) {
$entry['human_value'] = format_value($entry['value'], 'bi') . $entry['oid_symbol'];
} else {
$entry['human_value'] = format_value($entry['value'], 'si') . $entry['oid_symbol'];
}
}
$graph_array = array();
$graph_array['to'] = $config['time']['now'];
$graph_array['id'] = $entry['oid_entry_id'];
$graph_array['type'] = "customoid_graph";
$graph_array['width'] = 100;
$graph_array['height'] = 20;
$graph_array['from'] = $config['time']['day'];
if (is_numeric($entry['value']) || TRUE) {
$mini_graph = generate_graph_tag($graph_array);
} else {
// Do not show "Draw Error" minigraph
$mini_graph = '';
}
$thresholds = threshold_string($entry['alert_low'], $entry['warn_low'], $entry['warn_high'],
$entry['alert_high'], $entry['oid_symbol']);
switch ($entry['event']) {
case "ok";
$entry['html_row_class'] = "up";
$entry['event_class'] = "success";
break;
case "warn";
$entry['html_row_class'] = "warning";
$entry['event_class'] = "warning";
break;
case "alert";
$entry['html_row_class'] = "error";
$entry['event_class'] = "error";
break;
case "ignore";
default:
$entry['html_row_class'] = "ignore";
$entry['event_class'] = "ignore";
break;
}
$event = '<span class="label label-' . $entry['event_class'] . '">' . $entry['event'] . '</span>';
echo '
<tr class="' . $entry['html_row_class'] . '">
<td class="state-marker"></td>
<td><i class="' . $config['entities']['device']['icon'] . '"></i> <b>' . generate_device_link($entry) . '</b></td>';
if(!isset($vars['oid_id']))
{
echo '
<td>'.generate_oid_template_link($entry).'</td> ';
} else {
echo '
<td></td>';
}
echo '
<td>' . $mini_graph . '</td>
<td>' . $thresholds . '</td>
<td><span class="label label-' . $entry['event_class'] . '">' . $entry['human_value'] . '</span></td>
<td>' . $event . '</td>
';
if ($entries[0]['oid_autodiscover'] == '0' && $vars['page'] == "customoid") {
$form = array('type' => 'simple',
//'userlevel' => 10, // Minimum user level for display form
'id' => 'delete_customoid_device_' . $entry['device_id'],
'style' => 'display:inline;',
);
$form['row'][0]['form_oid_id'] = array(
'type' => 'hidden',
'value' => $entry['oid_id']);
$form['row'][0]['form_device_id'] = array(
'type' => 'hidden',
'value' => $entry['device_id']);
$form['row'][99]['action'] = array(
'type' => 'submit',
'icon_only' => TRUE, // hide button styles
'name' => '',
'icon' => $config['icon']['cancel'],
//'right' => TRUE,
//'class' => 'btn-small',
// confirmation dialog
'attribs' => array('data-toggle' => 'confirm', // Enable confirmation dialog
'data-confirm-placement' => 'left',
'data-confirm-content' => 'Delete associated device "' . escape_html($entry['hostname']) . '"?',
),
'value' => 'delete_customoid_device');
echo('<td>');
print_form($form);
unset($form);
echo('</td>');
}
echo '
</tr>';
if ($vars['graphs'] == "yes")
{
$vars['graph'] = "graph";
}
if ($vars['graph'])
{
$graph_array = array();
$graph_title = $entry['oid_descr'];
$graph_array['type'] = "customoid_".$vars['graph'];
$graph_array['id'] = $entry['oid_entry_id'];
echo '<tr><td colspan=8>';
print_graph_row($graph_array);
echo '</td></tr>';
}
}
echo ' </table>' . PHP_EOL;
echo generate_box_close();
} else {
echo '<p class="text-center text-warning bg-warning" style="padding: 10px; margin: 0;"><strong>This Custom OID is not currently associated with any devices</strong></p>';
}
}

View File

@ -0,0 +1,162 @@
<?php
/**
* Observium
*
* This file is part of Observium.
*
* @package observium
* @subpackage web
* @copyright (C) 2006-2013 Adam Armstrong, (C) 2013-2021 Observium Limited
*
*/
function generate_p2pradio_query($vars)
{
$sql = "SELECT * FROM `p2p_radios`";
$sql .= ' WHERE 1' . generate_query_permitted(array('device'));
// Build query
foreach($vars as $var => $value)
{
switch ($var)
{
case "group":
case "group_id":
$values = get_group_entities($value);
$sql .= generate_query_values($values, 'radio_id');
break;
case 'device_group_id':
case 'device_group':
$values = get_group_entities($value, 'device');
$sql .= generate_query_values($values, 'p2p_radios.device_id');
break;
case "device":
case "device_id":
$sql .= generate_query_values($value, 'device_id');
break;
}
}
return $sql;
}
function print_p2pradio_table_header($vars)
{
echo('<thead><tr>
<th class="state-marker"></th>
<th width="1"></th>');
if ($vars['page'] != "device" && $vars['popup'] != TRUE) { echo(' <th style="width: 200px;">Device</th>'); }
echo('
<th>Radio</th>
<th>Modulation</th>
<th>Capacity</th>
<th>Max Capacity</th>
<th>Max Eth Cap</th>
<th># E1/T1</th>
<th>Tx Power</th>
<th>Rx Level</th>
<th>Tx Freq</th>
<th>Rx Freq</th>
</tr></thead>');
}
function print_p2pradio_row($radio, $vars)
{
echo generate_p2pradio_row($radio, $vars);
}
function print_p2pradio_table($vars)
{
if ($vars['view'] == "graphs" || isset($vars['graph']))
{
$stripe_class = "table-striped-two";
} else {
$stripe_class = "table-striped";
}
echo generate_box_open();
echo '<table class="table table-hover '.$stripe_class.' table-condensed">';
print_p2pradio_table_header($vars);
$sql = generate_p2pradio_query($vars);
$radios = dbFetchRows($sql);
foreach($radios as $radio)
{
print_p2pradio_row($radio, $vars);
}
echo('</table>');
echo generate_box_close();
}
function generate_p2pradio_row($radio, $vars)
{
global $config;
$device = device_by_id_cache($radio['device_id']);
$table_cols = 12;
if ($vars['page'] != "device" && $vars['popup'] != TRUE) { $table_cols++; } // Add a column for device.
$row .= '<tr class="' . $radio['row_class'] . '">
<td class="state-marker"></td>
<td></td>';
if ($vars['page'] != "device" && $vars['popup'] != TRUE) {
$row .=('<td class="entity">' . generate_device_link_short($device) . '</td>');
}
$row .= '
<td class="entity">' . generate_entity_link('p2pradio', $radio) . '</td>
<td width="100"><span class="label">' . strtoupper($radio['radio_modulation']) . '</span></td>
<td width="90">' . format_si($radio['radio_cur_capacity']) . 'bps</td>
<td width="100">' . format_si($radio['radio_total_capacity']) . 'bps</td>
<td width="90">' . format_si($radio['radio_eth_capacity']) . 'bps</td>
<td width="70">' . ($radio['radio_e1t1_channels'] ?: "N/A") . '</td>
<td width="70"><span class="label label-error">' . $radio['radio_tx_power'] . 'dBm</span></td>
<td width="70"><span class="label label-warning">' . $radio['radio_rx_level'] . 'dBm</span></td>
<td width="90"><span class="label label-success">' . ($radio['radio_tx_freq'] / 1000000) . 'GHz</span></td>
<td width="90"><span class="label label-info">' . ($radio['radio_rx_freq'] / 1000000) . 'GHz</span></td>
';
$row .= '</tr>';
if ($vars['view'] == "graphs")
{
$graphs = array('capacity', 'power', 'rxlevel', 'gain', 'rmse', 'symbol_rates');
$show_graph_title = TRUE;
} elseif (isset($vars['graph'])) { $graphs = explode(",", $vars['graph']); }
if (is_array($graphs))
{
$row .= '<tr class="' . $radio['row_class'] . '">';
$row .= '<td class="state-marker"></td>';
$row .= '<td colspan=' . $table_cols . '>';
unset($graph_array['height'], $graph_array['width'], $graph_array['legend']);
$graph_array['to'] = $config['time']['now'];
$graph_array['id'] = $radio['radio_id'];
foreach($graphs as $graph_type)
{
$graph_array['type'] = 'p2pradio_' . $graph_type;
if ($show_graph_title) { $row .= '<h3>'.$config['graph_types']['p2pradio'][$graph_type]['name'].'</h3>'; }
$row .= generate_graph_row($graph_array, TRUE);
}
$row .= "</td>";
$row .= "</tr>";
}
return $row;
}
// EOF

View File

@ -0,0 +1,904 @@
<?php
/**
* Observium
*
* This file is part of Observium.
*
* @package observium
* @subpackage web
* @copyright (C) 2006-2013 Adam Armstrong, (C) 2013-2021 Observium Limited
*
*/
/**
* Build ports WHERE array
*
* This function returns an array of "WHERE" statements from a $vars array.
* The returned array can be implode()d and used on the ports table.
* Originally extracted from the /ports/ page
*
* @param array $vars
* @return array
*/
function build_ports_where_array($vars) {
$where = array();
foreach($vars as $var => $value) {
if (!safe_empty($value)) {
switch ($var) {
case 'location':
$where[] = generate_query_values($value, $var);
break;
case 'device_id':
$where[] = generate_query_values($value, 'ports.device_id');
break;
case 'group':
case 'group_id':
$values = get_group_entities($value);
$where[] = generate_query_values($values, 'ports.port_id');
break;
case 'device_group_id':
case 'device_group':
$values = get_group_entities($value, 'device');
$where[] = generate_query_values($values, 'ports.device_id');
break;
case 'disable':
$var = 'disabled';
case 'disabled': // FIXME. 'disabled' column never used in ports..
case 'deleted':
case 'ignore':
case 'ifSpeed':
case 'ifType':
case 'port_id':
$where[] = generate_query_values($value, 'ports.'.$var);
break;
case 'hostname':
case 'ifAlias':
case 'ifDescr': // FIXME, probably better always use port_label instead ifDescr for search
$where[] = generate_query_values($value, $var, '%LIKE%');
break;
case 'label':
case 'port_label':
$where[] = generate_query_values($value, 'port_label', '%LIKE%');
break;
case 'mac':
case 'ifPhysAddress':
$value = str_replace([ '.', '-', ':' ], '', $value);
$where[] = generate_query_values($value, 'ifPhysAddress', '%LIKE%');
break;
case 'port_descr_type':
$where[] = generate_query_values($value, $var, 'LIKE');
break;
case 'errors':
if (get_var_true($value)) {
$where[] = " AND (`ifInErrors_delta` > '0' OR `ifOutErrors_delta` > '0')";
}
break;
case 'alerted':
if (get_var_true($value)) {
// this is just state=down
//$where[] = ' AND `ifAdminStatus` = "up" AND (`ifOperStatus` = "lowerLayerDown" OR `ifOperStatus` = "down")';
$var = 'state';
$value = 'down';
}
// do not break here
case 'state':
// Allowed multiple states as array
$state_where = [];
foreach ((array)$value as $state) {
if ($state === "down") {
$state_where[] = '`ifAdminStatus` = "up" AND `ifOperStatus` IN ("lowerLayerDown", "down")';
//$state_where[] = generate_query_values('up', 'ifAdminStatus', NULL, FALSE) . generate_query_values(['down', 'lowerLayerDown'], 'ifOperStatus');
} elseif ($state === "up") {
$state_where[] = '`ifAdminStatus` = "up" AND `ifOperStatus` IN ("up", "testing", "monitoring")';
//$state_where[] = generate_query_values('up', 'ifAdminStatus', NULL, FALSE) . generate_query_values(['up', 'testing', 'monitoring'], 'ifOperStatus');
} elseif ($state === "admindown" || $state === "shutdown") {
$state_where[] = '`ifAdminStatus` = "down"';
//$state_where[] = generate_query_values('down', 'ifAdminStatus', NULL, FALSE);
}
}
switch (count($state_where)) {
case 0:
// incorrect state passed, ignore
break;
case 1:
$where[] = ' AND ' . $state_where[0];
break;
default:
$where[] = ' AND ((' . implode(') OR (', $state_where) . '))';
}
break;
case 'cbqos':
if ($value && $value !== 'no') {
$where[] = generate_query_values($GLOBALS['cache']['ports']['cbqos'], 'ports.port_id');
}
break;
case 'mac_accounting':
if ($value && $value !== 'no') {
$where[] = generate_query_values($GLOBALS['cache']['ports']['mac_accounting'], 'ports.port_id');
}
break;
}
}
}
return $where;
}
/**
* Returns a string containing an HTML table to be used in popups for the port entity type
*
* @param array $port array
*
* @return string Table containing port header for popups
*/
function generate_port_popup_header($port) {
// Push through processing function to set attributes
humanize_port($port);
$contents = generate_box_open();
$contents .= '<table class="'. OBS_CLASS_TABLE .'">
<tr class="' . $port['row_class'] . '" style="font-size: 10pt;">
<td class="state-marker"></td>
<td style="width: 10px;"></td>
<td style="width: 250px;"><a href="'.generate_entity_url('port', $port).'" class="' . $port['html_class'] .
'" style="font-size: 15px; font-weight: bold;">' . escape_html($port['port_label']) . '</a><br />' .
escape_html($port['ifAlias']) . '</td>
<td style="width: 100px;">' . $port['human_speed'] . '<br />' . $port['ifMtu'] . '</td>
<td>' . $port['human_type'] . '<br />' . $port['human_mac'] . '</td>
</tr>
</table>';
$contents .= generate_box_close();
return $contents;
}
/**
* Returns a string containing an HTML to be used as a port popups
*
* @param array $port array
* @param string $text to be used as port label
* @param string $type graph type to be used in graphs (bits, nupkts, etc)
*
* @return string HTML port popup contents
*/
function generate_port_popup($port, $text = NULL, $type = NULL)
{
$time = $GLOBALS['config']['time'];
if (!isset($port['os']))
{
$port = array_merge($port, device_by_id_cache($port['device_id']));
}
humanize_port($port);
if (!$text)
{
$text = escape_html($port['port_label']);
}
if ($type)
{
$port['graph_type'] = $type;
}
if (!isset($port['graph_type']))
{
$port['graph_type'] = 'port_bits';
}
if (!isset($port['os']))
{
$port = array_merge($port, device_by_id_cache($port['device_id']));
}
$content = generate_device_popup_header($port);
$content .= generate_port_popup_header($port);
$content .= '<div style="width: 700px">';
//$content .= generate_box_open(array('body-style' => 'width: 700px;'));
$graph_array['type'] = $port['graph_type'];
$graph_array['legend'] = "yes";
$graph_array['height'] = "100";
$graph_array['width'] = "275";
$graph_array['to'] = $time['now'];
$graph_array['from'] = $time['day'];
$graph_array['id'] = $port['port_id'];
$content .= generate_graph_tag($graph_array);
$graph_array['from'] = $time['week'];
$content .= generate_graph_tag($graph_array);
$graph_array['from'] = $time['month'];
$content .= generate_graph_tag($graph_array);
$graph_array['from'] = $time['year'];
$content .= generate_graph_tag($graph_array);
$content .= "</div>";
//$content .= generate_box_close();
return $content;
}
/**
* Returns an HTML port page link with mouse-over popup to permitted users or a text label to non-permitted users
*
* @param array $port array
* @param string $text text to be used as port label
* @param string $type graph type to be used in graphs (bits, nupkts, etc)
*
* @return string HTML link or text string
*/
function generate_port_link($port, $text = NULL, $type = NULL, $escape = FALSE, $short = FALSE)
{
humanize_port($port);
// Fixme -- does this function even need alternative $text? I think not. It's a hangover from before label.
// Sometime in $text included html
if (empty($text))
{
$text = $short ? $port['port_label_short'] : $port['port_label'];
$escape = TRUE; // FORCE label escaping
}
if (port_permitted($port['port_id'], $port['device_id']))
{
$url = generate_port_url($port);
if ($escape)
{
$text = escape_html($text);
}
return '<a href="' . $url . '" class="entity-popup ' . $port['html_class'] . '" data-eid="' . $port['port_id'] . '" data-etype="port">' . $text . '</a>';
}
else
{
return escape_html($text);
}
}
// Just simplify function call, instead generate_port_link($port, NULL, NULL, TRUE, TRUE)
function generate_port_link_short($port, $text = NULL, $type = NULL, $escape = FALSE, $short = TRUE)
{
return generate_port_link($port, $text, $type, $escape, $short);
}
/**
* Returns a string containing a page URL built from a $port array and an array of optional variables
*
* @param array $port array
* @param array optional variables used when building the URL
*
* @return string port page URL
*/
function generate_port_url($port, $vars = array())
{
return generate_url(array('page' => 'device', 'device' => $port['device_id'], 'tab' => 'port', 'port' => $port['port_id']), $vars);
}
/**
* Returns or echos a port graph thumbnail
*
* @param array $args of arguments used to build the graph image tag URL
* @param boolean $echo variable defining wether output should be returned or echoed
*
* @return string HTML port popup contents
*/
function generate_port_thumbnail($args, $echo = TRUE)
{
if (!$args['bg'])
{
$args['bg'] = "FFFFFF";
}
$graph_array = array();
$graph_array['from'] = $args['from'];
$graph_array['to'] = $args['to'];
$graph_array['id'] = $args['port_id'];
$graph_array['type'] = $args['graph_type'];
$graph_array['width'] = $args['width'];
$graph_array['height'] = $args['height'];
$graph_array['bg'] = 'FFFFFF00';
$mini_graph = generate_graph_tag($graph_array);
$img = generate_port_link($args, $mini_graph);
if ($echo)
{
echo($img);
} else {
return $img;
}
}
function print_port_row($port, $vars = array())
{
echo generate_port_row($port, $vars);
}
function generate_port_row($port, $vars = array())
{
global $config, $cache;
$device = device_by_id_cache($port['device_id']);
humanize_port($port);
if (!isset($vars['view'])) { $vars['view'] = "basic"; }
// Populate $port_adsl if the port has ADSL-MIB data
if (!isset($cache['ports_option']['ports_adsl']) || in_array($port['port_id'], $cache['ports_option']['ports_adsl'])) {
$port_adsl = dbFetchRow("SELECT * FROM `ports_adsl` WHERE `port_id` = ?", array($port['port_id']));
}
// Populate $port['tags'] with various tags to identify port statuses and features
// Port Errors
if ($port['ifInErrors_delta'] > 0 || $port['ifOutErrors_delta'] > 0) {
$port['tags'] .= generate_port_link($port, '<span class="label label-important">Errors</span>', 'port_errors');
}
// Port Deleted
if ($port['deleted']) {
$port['tags'] .= '<a href="'.generate_url(array('page' => 'deleted-ports')).'"><span class="label label-important">Deleted</span></a>';
}
if ($port['ignore']) {
$port['tags'] .= '<span class="label label-suppressed">Ignored</span>';
}
if ($port['disabled']) {
$port['tags'] .= '<span class="label label-disabled">Poll disabled</span>';
}
// Port IPv6
if (isset($port['attribs']['ipv6-octets'])) {
$port['tags'] .= '<span class="label label-primary">IPv6</span>';
}
// Port CBQoS
if (isset($cache['ports_option']['ports_cbqos']))
{
if (in_array($port['port_id'], $cache['ports_option']['ports_cbqos']))
{
$port['tags'] .= '<a href="' . generate_port_url($port, array('view' => 'cbqos')) . '"><span class="label label-info">CBQoS</span></a>';
}
}
//else if (dbFetchCell("SELECT COUNT(*) FROM `ports_cbqos` WHERE `port_id` = ?", array($port['port_id'])))
else if (dbExist('ports_cbqos', '`port_id` = ?', array($port['port_id'])))
{
$port['tags'] .= '<a href="' . generate_port_url($port, array('view' => 'cbqos')) . '"><span class="label label-info">CBQoS</span></a>';
}
// Port MAC Accounting
if (isset($cache['ports_option']['mac_accounting']))
{
if (in_array($port['port_id'], $cache['ports_option']['mac_accounting']))
{
$port['tags'] .= '<a href="' . generate_port_url($port, array('view' => 'macaccounting')) . '"><span class="label label-info">MAC</span></a>';
}
}
//else if (dbFetchCell("SELECT COUNT(*) FROM `mac_accounting` WHERE `port_id` = ?", array($port['port_id'])))
else if (dbExist('mac_accounting', '`port_id` = ?', array($port['port_id'])))
{
$port['tags'] .= '<a href="' . generate_port_url($port, array('view' => 'macaccounting')) . '"><span class="label label-info">MAC</span></a>';
}
// Populated formatted versions of port rates.
$port['bps_in'] = formatRates($port['ifInOctets_rate'] * 8);
$port['bps_out'] = formatRates($port['ifOutOctets_rate'] * 8);
$port['pps_in'] = format_si($port['ifInUcastPkts_rate'])."pps";
$port['pps_out'] = format_si($port['ifOutUcastPkts_rate'])."pps";
$string = '';
if ($vars['view'] === "basic" || $vars['view'] === "graphs") // Print basic view table row
{
$table_cols = '8';
$string .= '<tr class="' . $port['row_class'] . '">
<td class="state-marker"></td>
<td style="width: 1px;"></td>';
if ($vars['page'] !== "device" && $vars['popup'] != TRUE) // Print device name link if we're not inside the device page hierarchy.
{
$table_cols++; // Increment table columns by one to make sure graph line draws correctly
$string .= ' <td style="width: 200px;"><span class="entity">' . generate_device_link_short($device, [], 20) . '</span><br />
<span class="em">' . escape_html(truncate($port['location'], 32, "")) . '</span></td>';
}
$string .=
' <td><span class="entity">' . generate_port_link($port) . '</span> <span class="pull-right">' . $port['tags'] . '</span><br />' .
' <span class="em">' . escape_html(truncate($port['ifAlias'], 50, '')) . '</span></td>' .
'<td style="width: 110px;">' . get_icon('arrow-down', NULL, [ 'style' => $port['bps_in_style'] ]) . ' <span class="small" style="' . $port['bps_in_style'] . '">' . formatRates($port['in_rate']) . '</span><br />' .
get_icon('arrow-up', NULL, [ 'style' => $port['bps_out_style'] ]) . ' <span class="small" style="' . $port['bps_out_style'] . '">' . formatRates($port['out_rate']) . '</span><br /></td>' .
'<td style="width: 90px;">' . get_icon('arrow-down', NULL, [ 'style' => $port['bps_in_style'] ]) . ' <span class="small" style="' . $port['bps_in_style'] . '">' . $port['ifInOctets_perc'] . '%</span><br />' .
get_icon('arrow-up', NULL, [ 'style' => $port['bps_out_style'] ]) . ' <span class="small" style="' . $port['bps_out_style'] . '">' . $port['ifOutOctets_perc'] . '%</span><br /></td>' .
'<td style="width: 110px;">' . get_icon('arrow-down', NULL, [ 'style' => $port['pps_in_style'] ]) . ' <span class="small" style="' . $port['pps_in_style'] . '">' . format_bi($port['ifInUcastPkts_rate']) . 'pps</span><br />' .
get_icon('arrow-up', NULL, [ 'style' => $port['pps_out_style'] ]) . ' <span class="small" style="' . $port['pps_out_style'] . '">' . format_bi($port['ifOutUcastPkts_rate']) . 'pps</span></td>' .
'<td style="width: 110px;"><small>' . $port['human_speed'] . '<br />' . $port['ifMtu'] . '</small></td>
<td ><small>' . $port['human_type'] . '<br />' . $port['human_mac'] . '</small></td>
</tr>';
}
elseif ($vars['view'] === "details" || $vars['view'] === "detail") // Print detailed view table row
{
$table_cols = '9';
$string .= '<tr class="' . $port['row_class'] . '"';
if ($vars['tab'] !== "port") { $string .= ' onclick="openLink(\'' . generate_port_url($port) . '\')" style="cursor: pointer;"'; }
$string .= '>';
$string .= ' <td class="state-marker"></td>
<td style="width: 1px;"></td>';
if ($vars['page'] !== "device" && $vars['popup'] != TRUE) // Print device name link if we're not inside the device page hierarchy.
{
$table_cols++; // Increment table columns by one to make sure graph line draws correctly
$string .= ' <td width="200"><span class="entity">' . generate_device_link_short($device, [], 20) . '</span><br />
<span class="em">' . escape_html(truncate($port['location'], 32, "")) . '</span></td>';
}
$string .= '
<td style="min-width: 250px;">';
$string .= ' <span class="entity-title">
' . generate_port_link($port) . '</span> <span class="pull-right">'.$port['tags'].'
</span><br /><span class="small">'.escape_html($port['ifAlias']).'</span>';
if ($port['ifAlias']) { $string .= '<br />'; }
unset($break);
$ignore_type = $GLOBALS['config']['ip-address']['ignore_type'];
if (!isset($cache['ports_option']['ipv4_addresses']) || in_array($port['port_id'], $cache['ports_option']['ipv4_addresses'])) {
$sql = "SELECT * FROM `ipv4_addresses` WHERE `port_id` = ?";
// Do not exclude IPv4 link-local
$sql .= generate_query_values(array_diff($ignore_type, [ 'link-local' ]), 'ipv4_type', '!='); // Do not show ignored ip types
foreach (dbFetchRows($sql, array($port['port_id'])) as $ip)
{
$string .= $break . generate_popup_link('ip', $ip['ipv4_address'].'/'.$ip['ipv4_prefixlen'], NULL, 'small');
$break = "<br />";
}
}
if (!isset($cache['ports_option']['ipv6_addresses']) || in_array($port['port_id'], $cache['ports_option']['ipv6_addresses']))
{
$sql = "SELECT * FROM `ipv6_addresses` WHERE `port_id` = ?";
$sql .= generate_query_values($ignore_type, 'ipv6_type', '!='); // Do not show ignored ip types
foreach (dbFetchRows($sql, array($port['port_id'])) as $ip6)
{
$string .= $break . generate_popup_link('ip', $ip6['ipv6_address'].'/'.$ip6['ipv6_prefixlen'], NULL, 'small');
$break = "<br />";
}
}
//$string .= '</span>';
$string .= '</td>';
// Print port graph thumbnails
$string .= '<td style="width: 147px;">';
$port['graph_type'] = "port_bits";
$graph_array = array();
$graph_array['to'] = $config['time']['now'];
$graph_array['id'] = $port['port_id'];
$graph_array['type'] = $port['graph_type'];
$graph_array['width'] = 100;
$graph_array['height'] = 20;
$graph_array['bg'] = 'ffffff00';
$graph_array['from'] = $config['time']['day'];
$string .= generate_port_link($port, generate_graph_tag($graph_array));
$port['graph_type'] = "port_upkts";
$graph_array['type'] = $port['graph_type'];
$string .= generate_port_link($port, generate_graph_tag($graph_array));
$port['graph_type'] = "port_errors";
$graph_array['type'] = $port['graph_type'];
$string .= generate_port_link($port, generate_graph_tag($graph_array));
$string .= '</td>';
$string .= '<td style="width: 100px; white-space: nowrap;">';
if ($port['ifOperStatus'] === "up" || $port['ifOperStatus'] === "monitoring") {
// Colours generated by humanize_port
$string .= '<i class="icon-circle-arrow-down" style="'.$port['bps_in_style']. '"></i> <span class="small" style="'.$port['bps_in_style']. '">' . formatRates($port['in_rate']) . '</span><br />
<i class="icon-circle-arrow-up" style="'.$port['bps_out_style'].'"></i> <span class="small" style="'.$port['bps_out_style'].'">' . formatRates($port['out_rate']). '</span><br />
<i class="icon-circle-arrow-down" style="'.$port['pps_in_style']. '"></i> <span class="small" style="'.$port['pps_in_style']. '">' . format_bi($port['ifInUcastPkts_rate']). 'pps</span><br />
<i class="icon-circle-arrow-up" style="'.$port['pps_out_style'].'"></i> <span class="small" style="'.$port['pps_out_style'].'">' . format_bi($port['ifOutUcastPkts_rate']).'pps</span>';
}
$string .= '</td><td style="width: 110px;">';
if ($port['ifType'] && $port['ifType'] != "") { $string .= '<span class="small">' . $port['human_type'] . '</span>'; } else { $string .= '-'; }
$string .= '<br />';
if ($port['ifSpeed']) { $string .= '<span class="small">'.humanspeed($port['ifSpeed']).'</span>'; }
if ($port['ifDuplex'] && $port['ifDuplex'] !== "unknown") { $string .= '<span class="small"> (' . str_replace("Duplex", "", $port['ifDuplex']) . ')</span>'; }
$string .= '<br />';
if ($port['ifMtu'] && $port['ifMtu'] != "") { $string .= '<span class="small">MTU ' . $port['ifMtu'] . '</span>'; } else { $string .= '<span class="small">Unknown MTU</span>'; }
// if ($ifHardType && $ifHardType != "") { $string .= '<span class="small">" . $ifHardType . "</span>"); } else { $string .= '-'; }
//$string .= '<br />';
// Set VLAN data if the port has ifTrunk populated
if (strlen($port['ifTrunk']) &&
!in_array($port['ifTrunk'], array('access', 'routed'))) // Skip on routed (or access)
{
if ($port['ifVlan']) {
// Native VLAN
if (!isset($cache['ports_vlan'])) {
$native_state = dbFetchCell('SELECT `state` FROM `ports_vlans` WHERE `device_id` = ? AND `port_id` = ?', array($device['device_id'], $port['port_id']));
$native_name = dbFetchCell('SELECT `vlan_name` FROM vlans WHERE `device_id` = ? AND `vlan_vlan` = ?;', array($device['device_id'], $port['ifVlan']));
} else {
$native_state = $cache['ports_vlan'][$port['port_id']][$port['ifVlan']]['state'];
$native_name = $cache['ports_vlan'][$port['port_id']][$port['ifVlan']]['vlan_name'];
}
switch ($native_state) {
case 'blocking': $class = 'text-danger'; break;
case 'forwarding': $class = 'text-success'; break;
default: $class = 'muted';
}
if (empty($native_name)) { $native_name = 'VLAN'.str_pad($port['ifVlan'], 4, '0', STR_PAD_LEFT); }
$native_tooltip = 'NATIVE: <strong class='.$class.'>'.$port['ifVlan'].' ['.$native_name.']</strong><br />';
}
if (!isset($cache['ports_vlan'])) {
$vlans = dbFetchRows('SELECT * FROM `ports_vlans` AS PV
LEFT JOIN vlans AS V ON PV.`vlan` = V.`vlan_vlan` AND PV.`device_id` = V.`device_id`
WHERE PV.`port_id` = ? AND PV.`device_id` = ? ORDER BY PV.`vlan`;', array($port['port_id'], $device['device_id']));
} else {
$vlans = $cache['ports_vlan'][$port['port_id']];
}
$vlans_count = safe_count($vlans);
$rel = ($vlans_count || $native_tooltip) ? 'tooltip' : ''; // Hide tooltip for empty
$string .= '<p class="small"><a class="label label-info" data-rel="'.$rel.'" data-tooltip="<div class=\'small\' style=\'max-width: 320px; text-align: justify;\'>'.$native_tooltip;
if ($vlans_count) {
$string .= 'ALLOWED: ';
$vlans_aggr = array();
foreach ($vlans as $vlan) {
if ($vlans_count > 20) {
// Aggregate VLANs
$vlans_aggr[] = $vlan['vlan'];
} else {
// List VLANs
switch ($vlan['state']) {
case 'blocking': $class = 'text-danger'; break;
case 'forwarding': $class = 'text-success'; break;
default: $class = 'muted';
}
if (empty($vlan['vlan_name'])) {
$vlan['vlan_name'] = 'VLAN'.str_pad($vlan['vlan'], 4, '0', STR_PAD_LEFT);
}
$string .= '<strong class='.$class.'>'.$vlan['vlan'] .' ['.$vlan['vlan_name'].']</strong><br />';
}
}
if ($vlans_count > 20) {
// End aggregate VLANs
$string .= '<strong>'.range_to_list($vlans_aggr, ', ').'</strong>';
}
}
$string .= '</div>">'.$port['ifTrunk'].'</a></p>';
} elseif ($port['ifVlan']) {
if (!isset($cache['ports_vlan'])) {
$native_state = dbFetchCell('SELECT `state` FROM `ports_vlans` WHERE `device_id` = ? AND `port_id` = ?', array($device['device_id'], $port['port_id']));
$native_name = dbFetchCell('SELECT `vlan_name` FROM vlans WHERE `device_id` = ? AND `vlan_vlan` = ?;', array($device['device_id'], $port['ifVlan']));
} else {
$native_state = $cache['ports_vlan'][$port['port_id']][$port['ifVlan']]['state'];
$native_name = $cache['ports_vlan'][$port['port_id']][$port['ifVlan']]['vlan_name'];
}
switch ($native_state) {
case 'blocking': $class = 'label-error'; break;
case 'forwarding': $class = 'label-success'; break;
default: $class = '';
}
$rel = ($native_name) ? 'tooltip' : ''; // Hide tooltip for empty
$vlan_name = ($port['ifTrunk'] !== 'access') ? nicecase($port['ifTrunk']) . ' ' : '';
$vlan_name .= 'VLAN ' . $port['ifVlan'];
$string .= '<br /><span data-rel="'.$rel.'" class="label '.$class.'" data-tooltip="<strong class=\'small\'>'.$port['ifVlan'].' ['.$native_name.']</strong>">' . $vlan_name . '</span>';
} elseif ($port['ifVrf']) { // Print the VRF name if the port is assigned to a VRF
$vrf_name = dbFetchCell("SELECT `vrf_name` FROM `vrfs` WHERE `vrf_id` = ?", array($port['ifVrf']));
$string .= '<br /><span class="label label-success" data-rel="tooltip" data-tooltip="VRF">'.$vrf_name.'</span>';
}
$string .= '</td>';
// If the port is ADSL, print ADSL port data.
if ($port_adsl['adslLineCoding']) {
$string .= '<td style="width: 200px;"><span class="small">';
$string .= '<span class="label">'.$port_adsl['adslLineCoding'].'</span> <span class="label">' . rewrite_adslLineType($port_adsl['adslLineType']).'</span>';
$string .= '<br />';
$string .= 'SYN <i class="icon-circle-arrow-down green"></i> '.formatRates($port_adsl['adslAtucChanCurrTxRate']) . ' <i class="icon-circle-arrow-up blue"></i> '. formatRates($port_adsl['adslAturChanCurrTxRate']);
$string .= '<br />';
//$string .= 'Max:'.formatRates($port_adsl['adslAtucCurrAttainableRate']) . '/'. formatRates($port_adsl['adslAturCurrAttainableRate']);
//$string .= '<br />';
$string .= 'ATN <i class="icon-circle-arrow-down green"></i> '.$port_adsl['adslAtucCurrAtn'] . 'dBm <i class="icon-circle-arrow-up blue"></i> '. $port_adsl['adslAturCurrAtn'] . 'dBm';
$string .= '<br />';
$string .= 'SNR <i class="icon-circle-arrow-down green"></i> '.$port_adsl['adslAtucCurrSnrMgn'] . 'dB <i class="icon-circle-arrow-up blue"></i> '. $port_adsl['adslAturCurrSnrMgn']. 'dB';
$string .= '</span>';
} else {
// Otherwise print normal port data
$string .= '<td style="width: 150px;"><span class="small">';
if ($port['ifPhysAddress'] && $port['ifPhysAddress'] != "") { $string .= $port['human_mac']; } else { $string .= '-'; }
$string .= '<br />' . $port['ifLastChange'] . '</span>';
}
$string .= '</td>';
$string .= '<td style="min-width: 200px" class="small">';
if ($port['ifType'] !== 'softwareLoopback' && !str_contains($port['port_label'], 'oopback') &&
safe_empty($graph_type)) {
$br = '';
// Populate links array for ports with direct links
if (!isset($cache['ports_option']['neighbours']) || in_array($port['port_id'], $cache['ports_option']['neighbours'])) {
foreach (dbFetchRows('SELECT * FROM `neighbours` WHERE `port_id` = ? AND `active` = ?', [ $port['port_id'], 1 ]) as $neighbour) {
// print_r($neighbour);
if ($neighbour['remote_port_id']) {
// Do not show some "non-physical" interfaces links,
// see: https://jira.observium.org/browse/OBS-2979
$remote_port = get_port_by_id_cache($neighbour['remote_port_id']);
if (!in_array($remote_port['ifType'], [ 'propVirtual', 'ieee8023adLag' ])) {
$int_links[$neighbour['remote_port_id']] = $neighbour['remote_port_id'];
$int_links_phys[$neighbour['remote_port_id']] = $neighbour['protocol'];
}
} else {
$int_links_unknown[] = $neighbour;
}
}
} // else { }
// Populate links array for devices which share an IPv4 subnet
if (!isset($cache['ports_option']['ipv4_addresses']) || in_array($port['port_id'], $cache['ports_option']['ipv4_addresses']))
{
foreach (dbFetchColumn('SELECT DISTINCT(`ipv4_network_id`) FROM `ipv4_addresses`
LEFT JOIN `ipv4_networks` USING(`ipv4_network_id`)
WHERE `port_id` = ? AND `ipv4_network` NOT IN (?);', array($port['port_id'], $config['ignore_common_subnet'])) as $network_id)
{
$sql = 'SELECT N.*, P.`port_id`, P.`device_id` FROM `ipv4_addresses` AS A, `ipv4_networks` AS N, `ports` AS P
WHERE A.`port_id` = P.`port_id` AND P.`device_id` != ?
AND A.`ipv4_network_id` = ? AND N.`ipv4_network_id` = A.`ipv4_network_id`
AND P.`ifAdminStatus` = "up"';
$params = array($device['device_id'], $network_id);
foreach (dbFetchRows($sql, $params) as $new)
{
if ($cache['devices']['id'][$new['device_id']]['disabled'] && !$config['web_show_disabled']) { continue; }
$int_links[$new['port_id']] = $new['port_id'];
$int_links_v4[$new['port_id']][] = $new['ipv4_network'];
}
}
}
// Populate links array for devices which share an IPv6 subnet
if (!isset($cache['ports_option']['ipv6_addresses']) || in_array($port['port_id'], $cache['ports_option']['ipv6_addresses']))
{
foreach (dbFetchColumn("SELECT DISTINCT(`ipv6_network_id`) FROM `ipv6_addresses`
LEFT JOIN `ipv6_networks` USING(`ipv6_network_id`)
WHERE `port_id` = ? AND `ipv6_network` NOT IN (?);", array($port['port_id'], $config['ignore_common_subnet'])) as $network_id)
{
$sql = "SELECT N.*, P.`port_id`, P.`device_id` FROM `ipv6_addresses` AS A, `ipv6_networks` AS N, `ports` AS P
WHERE A.`port_id` = P.`port_id` AND P.device_id != ?
AND A.`ipv6_network_id` = ? AND N.`ipv6_network_id` = A.`ipv6_network_id`
AND P.`ifAdminStatus` = 'up' AND A.`ipv6_origin` != 'linklayer' AND A.`ipv6_origin` != 'wellknown'";
$params = array($device['device_id'], $network_id);
foreach (dbFetchRows($sql, $params) as $new)
{
if ($cache['devices']['id'][$new['device_id']]['disabled'] && !$config['web_show_disabled']) { continue; }
$int_links[$new['port_id']] = $new['port_id'];
$int_links_v6[$new['port_id']][] = $new['ipv6_network'];
}
}
}
// Output contents of links array
foreach ($int_links as $int_link)
{
//r($int_link);
//r($int_links_phys);
$link_if = get_port_by_id_cache($int_link);
if (!device_permitted($link_if['device_id'])) { continue; } // Skip not permitted links
$link_dev = device_by_id_cache($link_if['device_id']);
$string .= $br;
if ($int_links_phys[$int_link])
{
$string .= generate_tooltip_link(NULL, NULL, 'Directly connected', $config['icon']['connected']) . ' ';
} else {
$string .= generate_tooltip_link(NULL, NULL, 'Same subnet', $config['icon']['network']) . ' ';
}
// for port_label_short - generate_port_link($link_if, NULL, NULL, TRUE, TRUE)
$string .= '<b>' . generate_port_link_short($link_if) . ' on ' . generate_device_link_short($link_dev) . '</b>';
if (isset($int_links_phys[$int_link]) && !is_numeric($int_links_phys[$int_link]))
{
$string .= '&nbsp;<span class="label">'.nicecase($int_links_phys[$int_link]).'</span>';
}
## FIXME -- do something fancy here.
if ($int_links_v6[$int_link]) { $string .= '&nbsp;'.overlib_link('', '<span class="label label-success">IPv6</span>', implode("<br />", $int_links_v6[$int_link]), NULL); }
if ($int_links_v4[$int_link]) { $string .= '&nbsp;'.overlib_link('', '<span class="label label-info">IPv4</span>', implode("<br />", $int_links_v4[$int_link]), NULL); }
$br = "<br />";
}
// Output content of unknown links array (where ports don't exist in our database, or they weren't matched)
foreach ($int_links_unknown as $int_link) {
//r($int_link);
$string .= generate_tooltip_link(NULL, NULL, 'Directly connected', $config['icon']['connected']) . ' ';
$string .= '<b><i>'.short_ifname($int_link['remote_port']).'</i></b> on ';
$text = '<div class="small" style="max-width: 500px;">';
if (!safe_empty($int_link['remote_platform'])) {
$text .= '<strong>' . $int_link['remote_platform'].'</strong><br />';
}
$text .= $int_link['remote_version'].'</div>';
$string .= '<i><b>'.generate_tooltip_link(NULL, $int_link['remote_hostname'], $text).'</b></i>';
$string .= '&nbsp;<span class="label">'.nicecase($int_link['protocol']).'</span><br />';
}
}
if (!isset($cache['ports_option']['pseudowires']) || in_array($port['port_id'], $cache['ports_option']['pseudowires'])) {
foreach (dbFetchRows("SELECT * FROM `pseudowires` WHERE `port_id` = ?", array($port['port_id'])) as $pseudowire) {
//`port_id`,`peer_device_id`,`peer_ldp_id`,`pwID`,`pwIndex`
# $pw_peer_dev = dbFetchRow("SELECT * FROM `devices` WHERE `device_id` = ?", array($pseudowire['peer_device_id']));
$pw_peer_int = dbFetchRow("SELECT * FROM `ports` AS I, `pseudowires` AS P WHERE I.`device_id` = ? AND P.`pwID` = ? AND P.`port_id` = I.`port_id`", array($pseudowire['peer_device_id'], $pseudowire['pwID']));
# $pw_peer_int = get_port_by_id_cache($pseudowire['peer_device_id']);
$pw_peer_dev = device_by_id_cache($pseudowire['peer_device_id']);
if (is_array($pw_peer_int))
{
humanize_port($pw_peer_int);
$string .= $br.'<i class="'.$config['icon']['cross-connect'].'"></i> <strong>' . generate_port_link_short($pw_peer_int) .' on '. generate_device_link_short($pw_peer_dev) . '</strong>';
} else {
$string .= $br.'<i class="'.$config['icon']['cross-connect'].'"></i> <strong> VC ' . $pseudowire['pwID'] .' on '. $pseudowire['peer_addr'] . '</strong>';
}
$string .= ' <span class="label">'.$pseudowire['pwPsnType'].'</span>';
$string .= ' <span class="label">'.$pseudowire['pwType'].'</span>';
$br = "<br />";
}
}
/** Disabled pending database rejigging to add it back
if (!isset($cache['ports_option']['ports_pagp']) || in_array($port['ifIndex'], $cache['ports_option']['ports_pagp']))
{
foreach (dbFetchRows("SELECT * FROM `ports` WHERE `pagpGroupIfIndex` = ? AND `device_id` = ?", array($port['ifIndex'], $device['device_id'])) as $member)
{
humanize_port($member);
$pagp[$device['device_id']][$port['ifIndex']][$member['ifIndex']] = TRUE;
$string .= $br.'<i class="'.$config['icon']['merge'].'"></i> <strong>' . generate_port_link($member) . ' [PAgP]</strong>';
$br = "<br />";
}
}
if ($port['pagpGroupIfIndex'] && $port['pagpGroupIfIndex'] != $port['ifIndex'])
{
$pagp[$device['device_id']][$port['pagpGroupIfIndex']][$port['ifIndex']] = TRUE;
$parent = dbFetchRow("SELECT * FROM `ports` WHERE `ifIndex` = ? and `device_id` = ?", array($port['pagpGroupIfIndex'], $device['device_id']));
humanize_port($parent);
$string .= $br.'<i class="'.$config['icon']['split'].'"></i> <strong>' . generate_port_link($parent) . ' [PAgP]</strong>';
$br = "<br />";
}
**/
if (!isset($cache['ports_option']['ports_stack_low']) ||
in_array($port['ifIndex'], $cache['ports_option']['ports_stack_low'])) {
foreach (dbFetchRows("SELECT * FROM `ports_stack` WHERE `port_id_low` = ? AND `device_id` = ? AND `ifStackStatus` = ?", [ $port['ifIndex'], $device['device_id'], 'active' ]) as $higher_if) {
if ($higher_if['port_id_high']) {
if (isset($pagp[$device['device_id']][$higher_if['port_id_high']][$port['ifIndex']])) { continue; } // Skip if same PAgP port
if ($this_port = get_port_by_index_cache($device['device_id'], $higher_if['port_id_high'])) {
$label = '';
if ($this_port['ifType'] === 'l2vlan') {
$label = '<span class="label label-primary">L2 VLAN</span> ';
} elseif ($this_port['ifType'] === 'l3ipvlan' || $this_port['ifType'] === 'l3ipxvlan') {
$label = '<span class="label label-info">L3 VLAN</span> ';
} elseif ($this_port['ifType'] === 'ieee8023adLag') {
$label = '<span class="label label-success">LAG</span> ';
} elseif (str_starts($this_port['port_label'], 'Stack')) {
$label = '<span class="label label-warning">STACK</span> ';
} else {
$label = '<span class="label label-default">'.$this_port['human_type'].'</span> ';
//r($this_port);
}
$string .= $br.'<i class="'.$config['icon']['split'].'"></i> <strong>' . generate_port_link($this_port) . '</strong> '.$label;
$br = "<br />";
}
}
}
}
if (!isset($cache['ports_option']['ports_stack_high']) ||
in_array($port['ifIndex'], $cache['ports_option']['ports_stack_high'])) {
foreach (dbFetchRows("SELECT * FROM `ports_stack` WHERE `port_id_high` = ? AND `device_id` = ? AND `ifStackStatus` = ?", [ $port['ifIndex'], $device['device_id'], 'active' ]) as $lower_if) {
if ($lower_if['port_id_low']) {
if (isset($pagp[$device['device_id']][$port['ifIndex']][$lower_if['port_id_low']])) { continue; } // Skip if same PAgP ports
if ($this_port = get_port_by_index_cache($device['device_id'], $lower_if['port_id_low'])) {
$string .= $br.'<i class="'.$config['icon']['merge'].'"></i> <strong>' . generate_port_link($this_port) . '</strong>';
$br = "<br />";
}
}
}
}
unset($int_links, $int_links_v6, $int_links_v4, $int_links_phys, $br);
$string .= '</td></tr>';
} // End Detailed View
// If we're showing graphs, generate the graph and print the img tags
if ($vars['graph'] === "etherlike")
{
$graph_file = get_port_rrdfilename($port, "dot3", TRUE);
} else {
$graph_file = get_port_rrdfilename($port, NULL, TRUE);
}
if ($vars['graph'] && is_file($graph_file))
{
$string .= '<tr><td colspan="'.$table_cols.'">';
$graph_array['to'] = $config['time']['now'];
$graph_array['id'] = $port['port_id'];
$graph_array['type'] = 'port_'.$vars['graph'];
$string .= generate_graph_row($graph_array);
$string .= '</td></tr>';
}
return $string;
}
function print_port_minigraph($port, $graph_type = 'port_bits', $period = 'day') {
$port['graph_type'] = $graph_type;
$graph_array = [];
$graph_array['to'] = get_time();
$graph_array['from'] = get_time($period);
$graph_array['id'] = $port['port_id'];
$graph_array['type'] = $port['graph_type'];
$graph_array['width'] = 400; //100;
$graph_array['height'] = 150; //20;
$graph_array['bg'] = 'ffffff00';
$graph_array['legend'] = "no";
$graph_array['graph_only'] = "yes";
$graph_array_zoom = $graph_array;
$graph_array_zoom['height'] = "175";
$graph_array_zoom['width'] = "600";
unset($graph_array_zoom['legend'], $graph_array_zoom['graph_only']);
$link_array = $graph_array;
$link_array['page'] = "graphs";
unset($link_array['height'], $link_array['width']);
$link = generate_url($link_array);
echo '
<div class="box box-solid" style="float: left; margin-left: 10px; margin-bottom: 10px; width:302px; min-width: 302px; max-width:302px; min-height:158px; max-height:158;">
<div class="box-header with-border">
<a href="device/device=682/"><h3 class="box-title">'.escape_html($port['port_label_short']).'</h3></a>
</div>
<div class="box-body no-padding">
'.overlib_link($link, generate_graph_tag($graph_array), generate_graph_tag($graph_array_zoom), NULL).'
</div>
<div class="box-footer" style="padding: 0px 10px"><span style="font-size: 0.7em">'.short_port_descr($port['ifAlias']).'</span></div>
</div>';
}
// EOF

View File

@ -0,0 +1,329 @@
<?php
/**
* Observium
*
* This file is part of Observium.
*
* @package observium
* @subpackage web
* @copyright (C) 2006-2013 Adam Armstrong, (C) 2013-2021 Observium Limited
*
*/
function build_printersupplies_query($vars)
{
$sql = 'SELECT * FROM `printersupplies`';
$sql .= ' WHERE 1' . generate_query_permitted(array('device'));
// Build query
foreach($vars as $var => $value)
{
switch ($var)
{
case "group":
case "group_id":
$values = get_group_entities($value);
$sql .= generate_query_values($values, 'printersupplies.supply_id');
break;
case 'device_group_id':
case 'device_group':
$values = get_group_entities($value, 'device');
$sql .= generate_query_values($values, 'printersupplies.device_id');
break;
case "device":
case "device_id":
$sql .= generate_query_values($value, 'printersupplies.device_id');
break;
case "supply":
case "supply_type";
$sql .= generate_query_values($value, 'printersupplies.supply_type');
break;
case "colour":
case "supply_colour";
$sql .= generate_query_values($value, 'supply_colour');
break;
case "descr":
case "supply_descr";
$sql .= generate_query_values($value, 'supply_descr', '%LIKE%');
break;
}
}
return $sql;
}
function print_printersupplies_table($vars)
{
$supplies = array();
foreach(dbFetchRows(build_printersupplies_query($vars)) as $supply)
{
global $cache;
if (isset($cache['devices']['id'][$supply['device_id']]))
{
$supply['hostname'] = $cache['devices']['id'][$supply['device_id']]['hostname'];
$supply['html_row_class'] = $cache['devices']['id'][$supply['device_id']]['html_row_class'];
$supplies[] = $supply;
}
}
$supplies = array_sort_by($supplies, 'hostname', SORT_ASC, SORT_STRING, 'supply_descr', SORT_ASC, SORT_STRING);
$supplies_count = count($supplies);
echo generate_box_open();
// Pagination
$pagination_html = pagination($vars, $supplies_count);
echo $pagination_html;
if ($vars['pageno'])
{
$supplies = array_chunk($supplies, $vars['pagesize']);
$supplies = $supplies[$vars['pageno'] - 1];
}
// End Pagination
if ($vars['view'] == "graphs")
{
$stripe_class = "table-striped-two";
} else {
$stripe_class = "table-striped";
}
// Allow the table to be printed headerless for use in some places.
if ($vars['headerless'] != TRUE)
{
echo('<table class="table ' . $stripe_class . ' table-condensed">');
echo(' <thead>');
echo '<tr class="strong">';
echo '<th class="state-marker"></th>';
if ($vars['page'] != "device" && $vars['popup'] != TRUE)
{
echo(' <th style="width: 250px;">Device</th>');
}
echo '<th>Toner</th>';
if (!isset($vars['supply']))
{
echo '<th>Type</th>';
}
echo '<th></th>';
echo '<th>Level</th>';
echo '<th>Remaining</th>';
echo '</tr>';
echo '</thead>';
}
foreach($supplies as $supply)
{
print_printersupplies_row($supply, $vars);
}
echo("</table>");
echo generate_box_close();
echo $pagination_html;
}
function print_printersupplies_row($supply, $vars)
{
echo generate_printersupplies_row($supply, $vars);
}
function generate_printersupplies_row($supply, $vars)
{
$graph_type = "printersupply_usage";
$table_cols = 5;
$total = $supply['supply_capacity'];
$perc = $supply['supply_value'];
$graph_array['type'] = $graph_type;
$graph_array['id'] = $supply['supply_id'];
$graph_array['from'] = $GLOBALS['config']['time']['day'];
$graph_array['to'] = $GLOBALS['config']['time']['now'];
$graph_array['height'] = "20";
$graph_array['width'] = "80";
if ($supply['supply_colour'] != '')
{
$background = toner_to_colour($supply['supply_colour'], $perc);
} else {
$background = toner_to_colour($supply['supply_descr'], $perc);
}
/// FIXME - popup for printersupply entity.
$output = '<tr class="' . $supply['html_row_class'] . '">';
$output .= '<td class="state-marker"></td>';
if ($vars['popup'] == TRUE )
{
$output .= '<td style="width: 40px; text-align: center;">'.get_icon($GLOBALS['config']['entities']['printersupply']['icon']).'</td>';
} else {
//$output .= '<td style="width: 1px;"></td>';
}
if ($vars['page'] != "device" && $vars['popup'] != TRUE)
{
$output .= '<td class="entity">' . generate_device_link($supply) . '</td>';
$table_cols++;
}
$output .= '<td class="entity">' . generate_entity_link('printersupply', $supply) . '</td>';
if (!isset($vars['supply']))
{
$output .= '<td><span class="label">' . nicecase($supply['supply_type']) . '</label></td>';
}
$output .= '<td style="width: 70px;">' . generate_graph_popup($graph_array) . '</td>';
$output .= '<td style="width: 200px;">' . print_percentage_bar(400, 20, $perc, $perc . '%', 'ffffff', $background['right'], NULL, "ffffff", $background['left']) . '</td>';
if ($vars['popup'] != TRUE)
{
$output .= '<td style="width: 50px; text-align: right;"><span class="label">' . $perc . '%</span></td>';
}
$output .= '</tr>';
if ($vars['view'] == "graphs")
{
$output .= '<tr class="' . $supply['html_row_class'] . '">';
$output .= '<td class="state-marker"></td>';
$output .= '<td colspan='.$table_cols.'>';
unset($graph_array['height'], $graph_array['width'], $graph_array['legend']);
$graph_array['to'] = $config['time']['now'];
$graph_array['id'] = $supply['supply_id'];
$graph_array['type'] = $graph_type;
$output .= generate_graph_row($graph_array, TRUE);
$output .= "</td></tr>";
} # endif graphs
return $output;
}
function print_printersupplies_form($vars, $single_device = FALSE)
{
global $config;
$form = array('type' => 'rows',
'space' => '10px',
'submit_by_key' => TRUE,
'url' => generate_url($vars));
$form_items = array();
if ($single_device)
{
// Single device, just hidden field
$form['row'][0]['device_id'] = array(
'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 `printersupplies`'));
$form['row'][0]['device_id'] = array(
'type' => 'multiselect',
'name' => 'Device',
'value' => $vars['device_id'],
'grid' => 2,
'width' => '100%', //'180px',
'values' => $form_items['devices']);
}
//$sensor_permitted = generate_query_permitted(array('device', 'sensor'));
$form['row'][0]['supply_descr'] = array(
'type' => 'text',
'placeholder' => 'Toner',
'width' => '100%', //'180px',
'grid' => 3,
'value' => $vars['status_descr']);
foreach ([ 'supply_colour' => 'Colour', 'supply_type' => 'Type' ] as $param => $param_name) {
$sql = 'SELECT DISTINCT `'.$param.'` FROM `printersupplies` WHERE 1' . $GLOBALS['cache']['where']['devices_permitted'];
if ($entries = dbFetchColumn($sql)) {
asort($entries);
}
foreach ($entries as $entry) {
if (safe_empty($entry)) { $entry = OBS_VAR_UNSET; }
$name = nicecase($entry);
$form_items[$param][$entry] = $name;
}
$form['row'][0][$param] = array(
'type' => 'multiselect',
'name' => $param_name,
'width' => '100%', //'180px',
'grid' => $param === 'supply_colour' ? 1: 2,
'value' => $vars[$param],
'values' => $form_items[$param]);
}
// Groups
foreach (get_type_groups('printersupply') as $entry)
{
$form_items['group'][$entry['group_id']] = $entry['group_name'];
}
$form['row'][0]['group'] = array(
'community' => FALSE,
'type' => 'multiselect',
'name' => 'Select Groups',
'width' => '100%', //'180px',
'grid' => 2,
'value' => $vars['group'],
'values' => $form_items['group']);
$form['row'][0]['search'] = array(
'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 = array('type' => 'rows',
'title' => 'Search Sensors',
'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]['group'] = $form['row'][0]['group'];
$panel_form['row'][1]['supply_colour'] = $form['row'][0]['supply_colour'];
$panel_form['row'][1]['supply_type'] = $form['row'][0]['supply_type'];
//$panel_form['row'][2]['measured_state'] = $form['row'][0]['measured_state'];
//$panel_form['row'][2]['group'] = $form['row'][1]['group'];
$panel_form['row'][3]['supply_descr'] = $form['row'][0]['supply_descr'];
//$panel_form['row'][5]['sort'] = $form['row'][0]['sort'];
$panel_form['row'][5]['search'] = $form['row'][0]['search'];
// Register custom panel
register_html_panel(generate_form($panel_form));
}
// EOF

View File

@ -0,0 +1,338 @@
<?php
/**
* Observium
*
* This file is part of Observium.
*
* @package observium
* @subpackage web
* @copyright (C) 2006-2013 Adam Armstrong, (C) 2013-2021 Observium Limited
*
*/
function generate_processor_query($vars)
{
$sql = "SELECT * FROM `processors`";
if(!isset($vars['sort']) || $vars['sort'] == 'hostname' || $vars['sort'] == 'device' || $vars['sort'] == 'device_id')
{
$sql .= ' LEFT JOIN `devices` USING(`device_id`)';
}
$sql .= ' WHERE 1' . generate_query_permitted(array('device'));
// Build query
foreach($vars as $var => $value)
{
switch ($var)
{
case "group":
case "group_id":
$values = get_group_entities($value);
$sql .= generate_query_values($values, 'processor_id');
break;
case 'device_group_id':
case 'device_group':
$values = get_group_entities($value, 'device');
$sql .= generate_query_values($values, 'processors.device_id');
break;
case "device":
case "device_id":
$sql .= generate_query_values($value, 'processors.device_id');
break;
case "descr":
case "processor_descr";
$sql .= generate_query_values($value, 'processor_descr', '%LIKE%');
break;
}
}
switch ($vars['sort_order'])
{
case 'descr':
$sort_order = 'DESC';
$sort_neg = 'ASC';
break;
case 'reset':
unset($vars['sort'], $vars['sort_order']);
// no break here
default:
$sort_order = 'ASC';
$sort_neg = 'DESC';
}
switch($vars['sort'])
{
case 'usage':
$sql .= ' ORDER BY `processor_usage` '.$sort_neg;
break;
case 'descr':
$sql .= ' ORDER BY `processor_descr` '.$sort_order;
break;
default:
$sql .= ' ORDER BY `hostname` '.$sort_order.', `processor_descr` '.$sort_order;
break;
}
return $sql;
}
function print_processor_table($vars)
{
global $cache;
$sql = generate_processor_query($vars);
$processors = array();
foreach(dbFetchRows($sql) as $proc)
{
if (isset($cache['devices']['id'][$proc['device_id']]))
{
$proc['hostname'] = $cache['devices']['id'][$proc['device_id']]['hostname'];
$proc['html_row_class'] = $cache['devices']['id'][$proc['device_id']]['html_row_class'];
$processors[] = $proc;
}
}
$processors_count = count($processors);
// Pagination
$pagination_html = pagination($vars, $processors_count);
echo $pagination_html;
if ($vars['pageno'])
{
$processors = array_chunk($processors, $vars['pagesize']);
$processors = $processors[$vars['pageno']-1];
}
// End Pagination
echo generate_box_open();
print_processor_table_header($vars);
foreach($processors as $processor)
{
print_processor_row($processor, $vars);
}
echo("</tbody></table>");
echo generate_box_close();
echo $pagination_html;
}
function print_processor_table_header($vars)
{
if ($vars['view'] == "graphs")
{
$table_class = OBS_CLASS_TABLE_STRIPED_TWO;
} else {
$table_class = OBS_CLASS_TABLE_STRIPED;
}
echo('<table class="' . $table_class . '">' . PHP_EOL);
$cols = array(
array(NULL, 'class="state-marker"'),
'device' => array('Device', 'style="width: 200px;"'),
'descr' => array('Processor'),
array('', 'style="width: 100px;"'),
'usage' => array('Usage', 'style="width: 250px;"'),
);
if ($vars['page'] == "device")
{
unset($cols['device']);
}
echo(get_table_header($cols, $vars));
echo('<tbody>' . PHP_EOL);
}
function print_processor_row($processor, $vars)
{
echo generate_processor_row($processor, $vars);
}
function generate_processor_row($processor, $vars)
{
global $config;
$table_cols = 4;
if ($vars['page'] != "device" && $vars['popup'] != TRUE) { $table_cols++; } // Add a column for device.
// FIXME should that really be done here? :-)
// FIXME - not it shouldn't. we need some per-os rewriting on discovery-time.
$text_descr = rewrite_entity_name($processor['processor_descr'], 'processor');
//$text_descr = $processor['processor_descr'];
//$text_descr = str_replace("Routing Processor", "RP", $text_descr);
//$text_descr = str_replace("Switching Processor", "SP", $text_descr);
//$text_descr = str_replace("Sub-Module", "Module ", $text_descr);
//$text_descr = str_replace("DFC Card", "DFC", $text_descr);
$graph_array = array();
$graph_array['to'] = $config['time']['now'];
$graph_array['id'] = $processor['processor_id'];
$graph_array['type'] = 'processor_usage';
$graph_array['legend'] = "no";
$link_array = $graph_array;
$link_array['page'] = "graphs";
unset($link_array['height'], $link_array['width'], $link_array['legend']);
$link_graph = generate_url($link_array);
$link = generate_url(array("page" => "device", "device" => $processor['device_id'], "tab" => "health", "metric" => 'processor'));
$overlib_content = generate_overlib_content($graph_array, $processor['hostname'] ." - " . $text_descr);
$graph_array['width'] = 80;
$graph_array['height'] = 20;
$graph_array['bg'] = 'ffffff00';
$graph_array['from'] = $config['time']['day'];
$mini_graph = generate_graph_tag($graph_array);
$perc = round($processor['processor_usage']);
$background = get_percentage_colours($perc);
$processor['html_row_class'] = $background['class'];
$row = '<tr class="' . $processor['html_row_class'] . '">
<td class="state-marker"></td>';
if ($vars['page'] != "device" && $vars['popup'] != TRUE) { $row .= '<td class="entity">' . generate_device_link($processor) . '</td>'; }
$row .= ' <td class="entity">'.generate_entity_link('processor', $processor).'</td>
<td>'.overlib_link($link_graph, $mini_graph, $overlib_content).'</td>
<td><a href="'.$link_graph.'">
'.print_percentage_bar (400, 20, $perc, $perc."%", "ffffff", $background['left'], (100 - $perc)."%" , "ffffff", $background['right']).'
</a>
</td>
</tr>
';
if ($vars['view'] == "graphs" || in_array($processor['processor_id'], (array)$vars['processor_id']))
{
$vars['graph'] = "usage";
$row .= '<tr class="' . $processor['html_row_class'] . '">';
$row .= '<td class="state-marker"></td>';
$row .= '<td colspan='.$table_cols.'>';
unset($graph_array['height'], $graph_array['width'], $graph_array['legend']);
$graph_array['to'] = $config['time']['now'];
$graph_array['id'] = $processor['processor_id'];
$graph_array['type'] = 'processor_'.$vars['graph'];
$row .= generate_graph_row($graph_array, TRUE);
$row .= '</td></tr>';
} # endif graphs
return $row;
}
function print_processor_form($vars, $single_device = FALSE)
{
//global $config;
$form = array('type' => 'rows',
'space' => '10px',
'submit_by_key' => TRUE,
'url' => generate_url($vars));
$form_items = array();
if ($single_device)
{
// Single device, just hidden field
$form['row'][0]['device_id'] = array(
'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 `processors`'));
$form['row'][0]['device_id'] = array(
'type' => 'multiselect',
'name' => 'Device',
'value' => $vars['device_id'],
'grid' => 2,
'width' => '100%', //'180px',
'values' => $form_items['devices']);
}
//$sensor_permitted = generate_query_permitted(array('device', 'sensor'));
$form['row'][0]['processor_descr'] = array(
'type' => 'text',
'placeholder' => 'Processor',
'width' => '100%', //'180px',
'grid' => 6,
'value' => $vars['processor_descr']);
// Groups
foreach (get_type_groups('storage') as $entry)
{
$form_items['group'][$entry['group_id']] = $entry['group_name'];
}
$form['row'][0]['group'] = array(
'community' => FALSE,
'type' => 'multiselect',
'name' => 'Select Groups',
'width' => '100%', //'180px',
'grid' => 2,
'value' => $vars['group'],
'values' => $form_items['group']);
$form['row'][0]['search'] = array(
'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 = array('type' => 'rows',
'title' => 'Search Processors',
'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]['group'] = $form['row'][0]['group'];
//$panel_form['row'][1]['supply_colour'] = $form['row'][0]['supply_colour'];
//$panel_form['row'][1]['supply_type'] = $form['row'][0]['supply_type'];
//$panel_form['row'][2]['measured_state'] = $form['row'][0]['measured_state'];
//$panel_form['row'][2]['group'] = $form['row'][1]['group'];
$panel_form['row'][3]['processor_descr'] = $form['row'][0]['processor_descr'];
//$panel_form['row'][5]['sort'] = $form['row'][0]['sort'];
$panel_form['row'][5]['search'] = $form['row'][0]['search'];
// Register custom panel
register_html_panel(generate_form($panel_form));
}
// EOF

View File

@ -0,0 +1,355 @@
<?php
/**
* Observium
*
* This file is part of Observium.
*
* @package observium
* @subpackage web
* @copyright (C) 2006-2013 Adam Armstrong, (C) 2013-2019 Observium Limited
*
*/
function generate_pseudowire_query($vars)
{
$sql = 'SELECT * FROM `pseudowires` ';
$sql .= ' WHERE 1';
// Build query
foreach ($vars as $var => $value)
{
switch ($var)
{
case "group":
case "group_id":
$values = get_group_entities($value);
$sql .= generate_query_values($values, 'pseudowire_id');
break;
case 'device_group_id':
case 'device_group':
$values = get_group_entities($value, 'device');
$sql .= generate_query_values($values, 'device_id');
break;
case "device":
case "device_id":
$sql .= generate_query_values($value, 'device_id');
break;
case "port":
case "port_id":
$sql .= generate_query_values($value, 'port_id');
break;
case "id":
$sql .= generate_query_values($value, 'pseudowire_id');
break;
case "pwid":
case "pwID":
$sql .= generate_query_values($value, 'pwID');
break;
case "pwtype":
$sql .= generate_query_values($value, 'pwType');
break;
case "psntype":
$sql .= generate_query_values($value, 'pwPsnType');
break;
case "peer_id":
$sql .= generate_query_values($value, 'peer_device_id');
break;
case "peer_addr":
$sql .= generate_query_values($value, 'peer_addr');
break;
case "event":
$sql .= generate_query_values($value, 'event');
break;
}
}
$sql .= $GLOBALS['cache']['where']['devices_permitted'];
return $sql;
}
function print_pseudowire_table_header($vars)
{
if ($vars['view'] == "graphs" || isset($vars['graph']) || isset($vars['id']))
{
$table_class = OBS_CLASS_TABLE_STRIPED_TWO;
} else {
$table_class = OBS_CLASS_TABLE_STRIPED;
}
echo('<table class="' . $table_class . '">' . PHP_EOL);
$cols = array(
array(NULL, 'class="state-marker"'),
'pwid' => array('pwID', 'style="width: 60px; text-align: right;"'),
'pwtype' => array('Type / PSN Type', 'style="width: 100px;"'),
'device' => array('Local Device', 'style="width: 180px;"'),
'port' => array('Local Port', 'style="width: 100px;"'),
array(NULL, 'style="width: 20px;"'), // arrow icon
'peer_addr' => array('Remote Peer', 'style="width: 180px;"'),
'peer_port' => array('Remote Port', 'style="width: 100px;"'),
array('History', 'style="width: 100px;"'),
'last_change' => array('Last&nbsp;changed', 'style="width: 60px;"'),
'event' => array('Event', 'style="width: 60px; text-align: right;"'),
'status' => array('Status', 'style="width: 60px; text-align: right;"'),
'uptime' => array('Uptime', 'style="width: 80px;"'),
);
if ($vars['page'] == "device" || $vars['popup'] == TRUE)
{
unset($cols['device']);
}
echo(get_table_header($cols, $vars));
echo('<tbody>' . PHP_EOL);
}
function get_pseudowire_table($vars)
{
$sql = generate_pseudowire_query($vars);
$entries = array();
foreach (dbFetchRows($sql) as $entry)
{
if (!isset($GLOBALS['cache']['devices']['id'][$entry['device_id']])) { continue; }
// Device hostname
$entry['hostname'] = $GLOBALS['cache']['devices']['id'][$entry['device_id']]['hostname'];
// Remote Peer
$peer_addr = $entry['peer_addr'];
$peer_addr_type = get_ip_version($peer_addr);
if ($peer_addr_type && $entry['peer_device_id'])
{
if ($peer_addr_type == 6)
{
$peer_addr = Net_IPv6::uncompress($peer_addr, TRUE);
}
$peer_addr_type = 'ipv'.$peer_addr_type;
//$entry['peer_addr'] = $peer_addr;
//$entry['peer_addr_type'] = $peer_addr_type;
if (!is_array($cache_pseudowires['ips'][$peer_addr]))
{
$cache_pseudowires['ips'][$peer_addr]['port_id'] = dbFetchCell('SELECT `port_id` FROM `'.$peer_addr_type.'_addresses` WHERE `'.$peer_addr_type.'_address` = ? '.generate_query_values($GLOBALS['cache']['ports']['pseudowires'], 'port_id').' LIMIT 1;', array($peer_addr));
if (!is_numeric($cache_pseudowires['ips'][$peer_addr]['port_id']))
{
// Separate entry for find correct port
$cache_pseudowires['ips'][$peer_addr]['port_id_fix'] = dbFetchCell('SELECT `port_id` FROM `'.$peer_addr_type.'_addresses` WHERE `'.$peer_addr_type.'_address` = ? '.$GLOBALS['cache']['where']['ports_permitted'].' LIMIT 1;', array($peer_addr));
}
//$cache_pseudowires['ips'][$peer_addr]['host'] = $entry['reverse_dns'];
}
$entry['peer_port_id'] = $cache_pseudowires['ips'][$peer_addr]['port_id'];
if (is_numeric($cache_pseudowires['ips'][$peer_addr]['port_id_fix']))
{
// If we found port on remote device, than both devices in DB and will try to fix real port
$peer_port_tmp = get_port_by_id_cache($cache_pseudowires['ips'][$peer_addr]['port_id_fix']);
$peer_port_fix = dbFetchCell('SELECT `port_id` FROM `pseudowires` WHERE `device_id` = ? AND `pwID` = ? LIMIT 1;', array($peer_port_tmp['device_id'], $entry['pwID']));
if (is_numeric($peer_port_fix))
{
$entry['peer_port_id'] = $peer_port_fix;
} else {
$entry['peer_port_id'] = $cache_pseudowires['ips'][$peer_addr]['port_id_fix'];
}
}
//r($entry['peer_port_id']);
if ($entry['peer_port_id'])
{
$entry['peer_port'] = get_port_by_id_cache($entry['peer_port_id']);
//r($entry['peer_port']);
$entry['peer_device_id'] = $entry['peer_port']['device_id'];
//r($entry['peer_device_id']);
$entry['peer_device'] = device_by_id_cache($entry['peer_device_id']);
}
}
$entry['hostname'] = $GLOBALS['cache']['devices']['id'][$entry['device_id']]['hostname']; // Attach hostname for sorting
$entries[] = $entry;
}
// Sorting
switch ($vars['sort_order'])
{
case 'desc':
$sort_order = SORT_DESC;
$sort_neg = SORT_ASC;
break;
case 'reset':
unset($vars['sort'], $vars['sort_order']);
// no break here
default:
$sort_order = SORT_ASC;
$sort_neg = SORT_DESC;
}
switch ($vars['sort'])
{
case 'device':
$entries = array_sort_by($entries, 'hostname', $sort_order, SORT_STRING);
break;
case 'pwid':
$entries = array_sort_by($entries, 'pwID', $sort_order, SORT_NUMERIC);
break;
case 'pwtype':
$entries = array_sort_by($entries, 'pwType', $sort_order, SORT_STRING, 'pwPsnType', $sort_order, SORT_STRING);
//$pws = array_sort_by($pws, 'pwType', $sort_order, SORT_STRING);
break;
case 'peer_addr':
$entries = array_sort_by($entries, 'peer_addr', $sort_order, SORT_NUMERIC);
break;
case 'event':
$entries = array_sort_by($entries, 'event', $sort_order, SORT_STRING);
break;
case 'uptime':
$entries = array_sort_by($entries, 'pwUptime', $sort_order, SORT_NUMERIC);
break;
case 'last_change':
$entries = array_sort_by($entries, 'last_change', $sort_neg, SORT_NUMERIC);
break;
case 'status':
$entries = array_sort_by($entries, 'pwOperStatus', $sort_order, SORT_STRING);
break;
default:
// Not sorted
}
return $entries;
}
function print_pseudowire_table($vars)
{
$pws = get_pseudowire_table($vars);
$pws_count = count($pws);
// Pagination
$pagination_html = pagination($vars, $pws_count);
echo $pagination_html;
if ($vars['pageno'])
{
$pws = array_chunk($pws, $vars['pagesize']);
$pws = $pws[$vars['pageno'] - 1];
}
// End Pagination
echo generate_box_open();
print_pseudowire_table_header($vars);
foreach ($pws as $pw)
{
print_pseudowire_row($pw, $vars);
}
echo '</tbody></table>';
echo generate_box_close();
echo $pagination_html;
}
function humanize_pseudowire(&$pw)
{
global $config;
if (isset($pw['humanized'])) { return; }
if (isset($config['entity_events'][$pw['event']]))
{
$pw = array_merge($pw, $config['entity_events'][$pw['event']]);
} else {
$pw['event_class'] = 'label label-primary';
$pw['row_class'] = '';
}
if ($pw['pwRowStatus'] != 'active')
{
$pw['row_class'] = 'ignore';
}
$device = &$GLOBALS['cache']['devices']['id'][$pw['device_id']];
if ((isset($device['status']) && !$device['status']) || (isset($device['disabled']) && $device['disabled']))
{
$pw['row_class'] = 'error';
}
$translate = entity_type_translate_array('pseudowire');
$pw['graph'] = $translate['graph']['type']; // Default graph
$pw['humanized'] = TRUE;
}
function print_pseudowire_row($pw, $vars)
{
echo generate_pseudowire_row($pw, $vars);
}
function generate_pseudowire_row($pw, $vars)
{
global $config;
humanize_pseudowire($pw);
$table_cols = 11;
$graph_array = array();
$graph_array['to'] = $config['time']['now'];
$graph_array['id'] = $pw['pseudowire_id'];
$graph_array['type'] = $pw['graph'];
$graph_array['legend'] = "no";
$graph_array['width'] = 80;
$graph_array['height'] = 20;
$graph_array['bg'] = 'ffffff00';
$graph_array['from'] = $config['time']['day'];
if ($pw['event'] && $pw['pwOperStatus'])
{
$mini_graph = generate_graph_tag($graph_array);
} else {
// Do not show "Draw Error" minigraph
$mini_graph = '';
}
$out = '<tr class="' . $pw['row_class'] . '"><td class="state-marker"></td>';
$out .= '<td class="entity" style="text-align: right;">'. generate_entity_link('pseudowire', $pw, NULL, NULL, TRUE, TRUE) .'</td>';
$out .= '<td>'. nicecase($pw['pwType']) . '/' . nicecase($pw['pwPsnType']) .'</td>';
if ($vars['page'] != "device" && $vars['popup'] != TRUE)
{
$out .= '<td class="entity">' . generate_device_link($pw, NULL, array('tab' => 'pseudowires')) . '</td>';
$table_cols++;
}
$out .= '<td class="entity">'. generate_entity_link('port', $pw['port_id']) .'</td>';
$out .= '<td><span class="text-success"><i class="glyphicon glyphicon-arrow-right"></i></span></td>';
if ($pw['peer_port_id'])
{
$out .= '<td class="entity">' . generate_entity_link('device', $pw['peer_device_id']) . '</td>';
$out .= '<td class="entity">' . generate_entity_link('port', $pw['peer_port_id']) . '</td>';
} else {
$out .= '<td class="entity">'. generate_popup_link('ip', $pw['peer_addr']) .'</td>';
$out .= '<td>'. $pw['pwRemoteIfString'] .'</td>';
}
$out .= '<td>' . generate_entity_link('pseudowire', $pw, $mini_graph, NULL, FALSE) . '</td>';
$out .= '<td style="white-space: nowrap">' . generate_tooltip_link(NULL, format_uptime(($config['time']['now'] - $pw['last_change']), 'short-2') . ' ago', format_unixtime($pw['last_change'])) . '</td>';
$out .= '<td style="text-align: right;"><strong>' . generate_tooltip_link('', $pw['event'], $pw['event_descr'], $pw['event_class']) . '</strong></td>';
$out .= '<td style="text-align: right;"><strong>' . generate_tooltip_link('', $pw['pwOperStatus'], $pw['event_descr'], $pw['event_class']) . '</strong></td>';
$out .= '<td>' . format_uptime($pw['pwUptime'], 'short-2') . '</td>';
$out .= '</tr>';
if ($vars['graph'] || $vars['view'] == "graphs" || $vars['id'] == $pw['pseudowire_id'])
{
// If id set in vars, display only specific graphs
$graph_array = array();
$graph_array['type'] = ($vars['graph'] ? $vars['graph'] : $pw['graph']);
$graph_array['id'] = $pw['pseudowire_id'];
$out .= '<tr class="' . $pw['row_class'] . '">';
$out .= ' <td class="state-marker"></td>';
$out .= ' <td colspan="'.$table_cols.'">';
$out .= generate_graph_row($graph_array, TRUE);
$out .= ' </td>';
$out .= '</tr>';
}
return $out;
}
// EOF

View File

@ -0,0 +1,606 @@
<?php
/**
* Observium
*
* This file is part of Observium.
*
* @package observium
* @subpackage web
* @copyright (C) 2006-2013 Adam Armstrong, (C) 2013-2021 Observium Limited
*
*/
/**
* Humanize sensor.
*
* Returns a the $sensor array with processed information:
* sensor_state (TRUE: state sensor, FALSE: normal sensor)
* human_value, sensor_symbol, state_name, state_event, state_class
*
* @param array $sensor
* @return array $sensor
*
*/
// TESTME needs unit testing
function humanize_sensor(&$sensor) {
global $config, $cache;
// Exit if already humanized
if ($sensor['humanized']) { return; }
$sensor['sensor_symbol'] = $GLOBALS['config']['sensor_types'][$sensor['sensor_class']]['symbol'];
$sensor['sensor_format'] = (string)$GLOBALS['config']['sensor_types'][$sensor['sensor_class']]['format'];
$sensor['state_class'] = ''; //'text-success';
// Generate "pretty" thresholds
if (is_numeric($sensor['sensor_limit_low'])) {
$sensor_threshold_low = format_value($sensor['sensor_limit_low'], $sensor['sensor_format']) . $sensor['sensor_symbol'];
} else {
$sensor_threshold_low = "&infin;";
}
if (is_numeric($sensor['sensor_limit_low_warn'])) {
$sensor_warn_low = format_value($sensor['sensor_limit_low_warn'], $sensor['sensor_format']) . $sensor['sensor_symbol'];
} else {
$sensor_warn_low = NULL;
}
if ($sensor_warn_low) { $sensor_threshold_low = $sensor_threshold_low . " (".$sensor_warn_low.")"; }
if (is_numeric($sensor['sensor_limit'])) {
$sensor_threshold_high = format_value($sensor['sensor_limit'], $sensor['sensor_format']) . $sensor['sensor_symbol'];
} else {
$sensor_threshold_high = "&infin;";
}
if (is_numeric($sensor['sensor_limit_warn'])) {
$sensor_warn_high = format_value($sensor['sensor_limit_warn'], $sensor['sensor_format']) . $sensor['sensor_symbol'];
} else {
$sensor_warn_high = "&infin;";
}
if ($sensor_warn_high) { $sensor_threshold_high = "(".$sensor_warn_high.") " . $sensor_threshold_high; }
$sensor['sensor_thresholds'] = $sensor_threshold_low . ' - ' . $sensor_threshold_high;
// generate pretty value
if (!is_numeric($sensor['sensor_value'])) {
$sensor['human_value'] = 'NaN';
$sensor['sensor_symbol'] = '';
} else {
$sensor['human_value'] = format_value($sensor['sensor_value'], $sensor['sensor_format'], 2, 4);
}
if (isset($config['entity_events'][$sensor['sensor_event']])) {
$sensor = array_merge($sensor, $config['entity_events'][$sensor['sensor_event']]);
} else {
$sensor['event_class'] = 'label label-primary';
$sensor['row_class'] = '';
}
if (device_is_ignored($sensor['device_id']) &&
($sensor['row_class'] === "error" || $sensor['row_class'] === "warning")) {
$sensor['row_class'] = 'suppressed';
}
if ($sensor['sensor_deleted']) {
$sensor['row_class'] = 'disabled';
}
/* We shouldn't pass through the parent status.
$device = &$GLOBALS['cache']['devices']['id'][$sensor['device_id']];
if ((isset($device['status']) && !$device['status']) || (isset($device['disabled']) && $device['disabled']))
{
//$sensor['row_class'] = 'error';
}
*/
// Set humanized entry in the array so we can tell later
$sensor['humanized'] = TRUE;
}
function build_sensor_query($vars, $query_count = FALSE) {
if ($query_count) {
$sql = "SELECT COUNT(*) FROM `sensors`";
} else {
$sql = "SELECT * FROM `sensors`";
if ($vars['sort'] === 'hostname' || $vars['sort'] === 'device' || $vars['sort'] === 'device_id') {
$sql .= ' LEFT JOIN `devices` USING(`device_id`)';
}
}
$sql .= " WHERE `sensor_deleted` = 0";
// Build query
foreach($vars as $var => $value)
{
switch ($var)
{
case "group":
case "group_id":
$values = get_group_entities($value);
$sql .= generate_query_values($values, 'sensors.sensor_id');
break;
case 'device_group_id':
case 'device_group':
$values = get_group_entities($value, 'device');
$sql .= generate_query_values($values, 'sensors.device_id');
break;
case "device":
case "device_id":
$sql .= generate_query_values($value, 'sensors.device_id');
break;
case "id":
case "sensor_id":
$sql .= generate_query_values($value, 'sensors.sensor_id');
break;
case "entity_id":
$sql .= generate_query_values($value, 'sensors.measured_entity');
break;
case "entity_type":
$sql .= generate_query_values($value, 'sensors.measured_class');
break;
case 'entity_state':
case "measured_state":
$sql .= build_entity_measured_where('sensor', ['measured_state' => $value]);
break;
case "metric":
// old metric param not allow array
if (!isset($GLOBALS['config']['sensor_types'][$value])) {
break;
}
case 'class':
case "sensor_class":
$sql .= generate_query_values($value, 'sensor_class');
break;
case "descr":
case "sensor_descr":
$sql .= generate_query_values($value, 'sensors.sensor_descr', '%LIKE%');
break;
case "type":
case "sensor_type":
$sql .= generate_query_values($value, 'sensor_type', '%LIKE%');
break;
case "event":
case "sensor_event":
$sql .= generate_query_values($value, 'sensor_event');
break;
}
}
$sql .= generate_query_permitted(array('device', 'sensor'));
// If need count, just return sql without sorting
if ($query_count) {
return $sql;
}
switch ($vars['sort_order']) {
case 'desc':
$sort_order = 'DESC';
$sort_neg = 'ASC';
break;
case 'reset':
unset($vars['sort'], $vars['sort_order']);
// no break here
default:
$sort_order = 'ASC';
$sort_neg = 'DESC';
}
switch($vars['sort'])
{
case 'device':
$sql .= ' ORDER BY `hostname` '.$sort_order;
break;
case 'descr':
case 'event':
$sql .= ' ORDER BY `sensor_'.$vars['sort'].'` '.$sort_order;
break;
case 'value':
case 'last_change':
$sql .= ' ORDER BY `sensor_'.$vars['sort'].'` '.$sort_order;
break;
default:
// $sql .= ' ORDER BY `hostname` '.$sort_order.', `sensor_descr` '.$sort_order;
}
if (isset($vars['pageno'])) {
$start = $vars['pagesize'] * ($vars['pageno'] - 1);
$sql .= ' LIMIT '.$start.','.$vars['pagesize'];
}
return $sql;
}
function print_sensor_table($vars, $default_order = []) {
pagination($vars, 0, TRUE); // Get default pagesize/pageno
$sql = build_sensor_query($vars);
//r($vars);
//r($sql);
$sensors = array();
//foreach(dbFetchRows($sql, NULL, TRUE) as $sensor)
foreach(dbFetchRows($sql) as $sensor) {
//if (isset($GLOBALS['cache']['devices']['id'][$sensor['device_id']]))
//{
$sensor['hostname'] = $GLOBALS['cache']['devices']['id'][$sensor['device_id']]['hostname'];
$sensors[$sensor['sensor_class']][] = $sensor;
//}
}
//r($sensors);
// order dom sensors always by temperature, voltage, current, dbm, power
$order = [];
if (safe_count($sensors)) {
if (safe_count($default_order)) {
$types = array_keys($sensors);
//r($types);
$order = array_intersect($default_order, $types);
$order = array_merge($order, array_diff($types, $order));
//r($order);
} else {
$order = array_keys($sensors);
}
}
//$sensors_count = count($sensors); // This is count incorrect, when pagination used!
//$sensors_count = dbFetchCell(build_sensor_query($vars, TRUE), NULL, TRUE);
$sensors_count = dbFetchCell(build_sensor_query($vars, TRUE));
// Pagination
$pagination_html = pagination($vars, $sensors_count);
echo $pagination_html;
echo generate_box_open();
print_sensor_table_header($vars);
foreach ($order as $type) {
foreach ($sensors[$type] as $sensor) {
print_sensor_row($sensor, $vars);
}
}
echo("</tbody></table>");
echo generate_box_close();
echo $pagination_html;
}
function print_sensor_table_header($vars) {
if ($vars['view'] === "graphs" || get_var_true($vars['graph']) || isset($vars['id'])) {
$stripe_class = "table-striped-two";
} else {
$stripe_class = "table-striped";
}
echo('<table class="table ' . $stripe_class . ' table-condensed ">' . PHP_EOL);
$cols = [];
$cols[] = array(NULL, 'class="state-marker"');
$cols['device'] = array('Device', 'style="width: 250px;"');
//$cols[] = array(NULL, 'class="no-width"'); // Measured entity link
$cols['descr'] = array('Description');
$cols['class'] = array('Class', 'style="width: 100px;"');
$cols['mib'] = array('MIB::Object');
$cols[] = array('Thresholds', 'style="width: 100px;"');
$cols[] = array('History');
$cols['last_change'] = array('Last&nbsp;changed', 'style="width: 80px;"');
$cols['event'] = array('Event', 'style="width: 60px; text-align: right;"');
$cols['value'] = array('Value', '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']); }
if (!$vars['show_class']) { unset($cols['class']); }
if ($vars['tab'] == "overview") { unset($cols[2]); } // Thresholds
echo(get_table_header($cols, $vars));
echo('<tbody>' . PHP_EOL);
}
function print_sensor_row($sensor, $vars)
{
echo generate_sensor_row($sensor, $vars);
}
function generate_sensor_row($sensor, $vars)
{
global $config;
humanize_sensor($sensor);
$table_cols = 4;
$graph_array = array();
$graph_array['to'] = $config['time']['now'];
$graph_array['id'] = $sensor['sensor_id'];
$graph_array['type'] = "sensor_graph";
$graph_array['width'] = 80;
$graph_array['height'] = 20;
$graph_array['bg'] = 'ffffff00';
$graph_array['from'] = $config['time']['day'];
if ($sensor['sensor_event'] && is_numeric($sensor['sensor_value']))
{
$mini_graph = generate_graph_tag($graph_array);
} else {
// Do not show "Draw Error" minigraph
$mini_graph = '';
}
$row = '
<tr class="'.$sensor['row_class'].'">
<td class="state-marker"></td>';
if ($vars['page'] != "device" && $vars['popup'] != TRUE)
{
$row .= ' <td class="entity">' . generate_device_link($sensor) . '</td>' . PHP_EOL;
$table_cols++;
}
// Measured link & icon
/* Disabled because it breaks the overview box layout
$row .= ' <td style="padding-right: 0px;" class="no-width vertical-align">'; // minify column if empty
if ($vars['entity_icon']) // this used for entity popup
{
$row .= get_icon($config['sensor_types'][$sensor['sensor_class']]['icon']);
}
else if ($sensor['measured_entity'] &&
(!isset($vars['measured_icon']) || $vars['measured_icon'])) // hide measured icon if not required
{
//$row .= generate_entity_link($sensor['measured_class'], $sensor['measured_entity'], get_icon($sensor['measured_class']));
$row .= generate_entity_icon_link($sensor['measured_class'], $sensor['measured_entity']);
}
$row .= '</td>';
$table_cols++;
*/
$row .= ' <td class="entity">' . generate_entity_link("sensor", $sensor) . '</td>';
$table_cols++;
if ($vars['show_class'])
{
$row .= ' <td>' . nicecase($sensor['sensor_class']). '</td>' . PHP_EOL;
$table_cols++;
}
// FIXME -- Generify this. It's not just for sensors.
if ($vars['page'] === "device" && $vars['tab'] !== "overview") {
$row .= ' <td>' . (!safe_empty($sensor['sensor_mib']) ? '<a href="'.OBSERVIUM_MIBS_URL.'/'.$sensor['sensor_mib'].'/" target="_blank">' .nicecase($sensor['sensor_mib']) .'</a>' : '') .
( ( !safe_empty($sensor['sensor_mib']) && !safe_empty($sensor['sensor_object'])) ? '::' : '') .
(!safe_empty($sensor['sensor_mib']) ? '<a href="'.OBSERVIUM_MIBS_URL.'/'.$sensor['sensor_mib'].'/#'.$sensor['sensor_object'].'" target="_blank">' .$sensor['sensor_object'] .'</a>' : '') .
'.'.$sensor['sensor_index'].'</td>' . PHP_EOL;
$table_cols++;
}
if ($vars['tab'] !== 'overview') {
$sensor_thresholds_class = $sensor['sensor_custom_limit'] ? ' label-suppressed' : '';
$sensor_thresholds = $sensor['sensor_custom_limit'] ? generate_tooltip_link(NULL, $sensor['sensor_thresholds'], 'Custom thresholds') : $sensor['sensor_thresholds'];
$row .= ' <td><span class="label' . $sensor_thresholds_class . '">' . $sensor_thresholds . '</span></td>' . PHP_EOL;
$table_cols++;
}
$row .= ' <td style="width: 90px; text-align: right;">' . generate_entity_link('sensor', $sensor, $mini_graph, NULL, FALSE) . '</td>';
if ($vars['tab'] !== 'overview') {
$row .= ' <td style="white-space: nowrap">' . ($sensor['sensor_last_change'] == '0' ? 'Never' : generate_tooltip_link(NULL, format_uptime(($config['time']['now'] - $sensor['sensor_last_change']), 'short-2') . ' ago', format_unixtime($sensor['sensor_last_change']))) . '</td>';
$table_cols++;
$row .= ' <td style="text-align: right;"><strong>' . generate_tooltip_link('', $sensor['sensor_event'], $sensor['event_descr'], $sensor['event_class']) . '</strong></td>';
$table_cols++;
}
$sensor_tooltip = $sensor['event_descr'];
// Append value in alternative units to tooltip
if (isset($config['sensor_types'][$sensor['sensor_class']]['alt_units']))
{
foreach (value_to_units($sensor['sensor_value'],
$config['sensor_types'][$sensor['sensor_class']]['symbol'],
$sensor['sensor_class'],
$config['sensor_types'][$sensor['sensor_class']]['alt_units']) as $unit => $unit_value)
{
if (is_numeric($unit_value)) { $sensor_tooltip .= "<br />${unit_value}${unit}"; }
}
}
$row .= ' <td style="width: 80px; text-align: right;"><strong>' . generate_tooltip_link('', $sensor['human_value'] . $sensor['sensor_symbol'], $sensor_tooltip, $sensor['event_class']) . '</strong>
</tr>' . PHP_EOL;
if ($vars['view'] == "graphs" || $vars['id'] == $sensor['sensor_id']) { $vars['graph'] = "graph"; }
if ($vars['graph'])
{
$row .= '
<tr class="'.$sensor['row_class'].'">
<td class="state-marker"></td>
<td colspan="'.$table_cols.'">';
$graph_array = array();
$graph_array['to'] = $config['time']['now'];
$graph_array['id'] = $sensor['sensor_id'];
$graph_array['type'] = 'sensor_'.$vars['graph'];
$row .= generate_graph_row($graph_array, TRUE);
$row .= '</td></tr>';
} # endif graphs
return $row;
}
function print_sensor_form($vars, $single_device = FALSE)
{
global $config;
$form = array('type' => 'rows',
'space' => '10px',
'submit_by_key' => TRUE,
'url' => generate_url($vars));
$form_items = array();
if ($single_device)
{
// Single device, just hidden field
$form['row'][0]['device_id'] = array(
'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 `sensors`'));
$form['row'][0]['device_id'] = array(
'type' => 'multiselect',
'name' => 'Device',
'value' => $vars['device_id'],
'grid' => 2,
'width' => '100%', //'180px',
'values' => $form_items['devices']);
}
$sensor_permitted = generate_query_permitted(array('device', 'sensor'));
foreach ([ 'sensor_class' => 'Sensor Class', 'sensor_event' => 'Sensor Event' ] as $param => $param_name)
{
$sql = 'SELECT DISTINCT `'.$param.'` FROM `sensors` WHERE `sensor_deleted` = ?' . $sensor_permitted;
if ($entries = dbFetchColumn($sql, [ 0 ])) {
asort($entries);
}
foreach ($entries as $entry)
{
if (safe_empty($entry)) { $entry = OBS_VAR_UNSET; }
if ($param === 'sensor_class') {
$name = nicecase($entry);
if (isset($config['sensor_types'][$entry]['icon']))
{
$name = ['name' => $name, 'icon' => $config['sensor_types'][$entry]['icon']];
} else {
$name = ['name' => $name, 'icon' => $config['icon']['sensor']];
}
} else {
$name = $entry;
}
$form_items[$param][$entry] = $name;
}
// Alternative param name, ie event
$short_param = str_replace('sensor_', '', $param);
if (!isset($vars[$param]) && isset($vars[$short_param]))
{
$vars[$param] = $vars[$short_param];
}
$form['row'][0][$param] = array(
'type' => 'multiselect',
'name' => $param_name,
'width' => '100%', //'180px',
'grid' => 2,
'value' => $vars[$param],
'values' => $form_items[$param]);
}
// Currently unused, just dumb space
$form['row'][0]['sensor_value'] = array(
'type' => 'hidden',
'name' => 'Value',
'width' => '100%', //'180px',
'grid' => 2,
'value' => $vars['sensor_value']);
// Measured entities
$form['row'][0]['measured_state'] = array(
'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]['sensor_descr'] = array(
'type' => 'text',
'placeholder' => 'Sensor description',
'width' => '100%', //'180px',
'grid' => 4,
'value' => $vars['sensor_descr']);
$form['row'][1]['sensor_type'] = array(
'type' => 'text',
'placeholder' => 'Sensor type',
'width' => '100%', //'180px',
'grid' => 4,
'value' => $vars['status_descr']);
// Groups
foreach (get_type_groups('sensor') as $entry)
{
$form_items['group'][$entry['group_id']] = $entry['group_name'];
}
$form['row'][1]['group'] = array(
'community' => FALSE,
'type' => 'multiselect',
'name' => 'Select Groups',
'width' => '100%', //'180px',
'grid' => 2,
'value' => $vars['group'],
'values' => $form_items['group']);
$form['row'][1]['search'] = array(
'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 = array('type' => 'rows',
'title' => 'Search Sensors',
'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]['sensor_class'] = $form['row'][0]['sensor_class'];
$panel_form['row'][1]['sensor_event'] = $form['row'][0]['sensor_event'];
$panel_form['row'][1]['sensor_value'] = $form['row'][0]['sensor_value'];
$panel_form['row'][2]['measured_state'] = $form['row'][0]['measured_state'];
$panel_form['row'][2]['group'] = $form['row'][1]['group'];
$panel_form['row'][3]['sensor_type'] = $form['row'][1]['sensor_type'];
$panel_form['row'][4]['sensor_descr'] = $form['row'][1]['sensor_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

View File

@ -0,0 +1,361 @@
<?php
/**
* Observium
*
* This file is part of Observium.
*
* @package observium
* @subpackage web
* @copyright (C) 2006-2013 Adam Armstrong, (C) 2013-2020 Observium Limited
*
*/
function generate_sla_query($vars)
{
$sql = 'SELECT * FROM `slas` ';
$sql .= ' WHERE `deleted` = 0';
// Build query
foreach($vars as $var => $value)
{
switch ($var)
{
case "group":
case "group_id":
$values = get_group_entities($value);
$sql .= generate_query_values($values, 'slas.sla_id');
break;
case 'device_group_id':
case 'device_group':
$values = get_group_entities($value, 'device');
$sql .= generate_query_values($values, 'storage.device_id');
break;
case "device":
case "device_id":
$sql .= generate_query_values($value, 'slas.device_id');
break;
case "id":
case "sla_id":
$sql .= generate_query_values($value, 'slas.sla_id');
break;
case "owner":
$sql .= generate_query_values($value, 'slas.sla_owner');
break;
case "target":
case "sla_target":
$sql .= generate_query_values($value, 'slas.sla_target', '%LIKE%');
break;
case "sla_tag":
$sql .= generate_query_values($value, 'slas.sla_tag');
break;
case "rtt_type":
case "rtt_sense":
$sql .= generate_query_values($value, 'slas.'.$var);
break;
case "event":
case "rtt_event":
$sql .= generate_query_values($value, 'slas.rtt_event');
break;
}
}
$sql .= $GLOBALS['cache']['where']['devices_permitted'];
return $sql;
}
function print_sla_table_header($vars)
{
if ($vars['view'] == "graphs" || isset($vars['graph']) || isset($vars['id']))
{
$stripe_class = "table-striped-two";
} else {
$stripe_class = "table-striped";
}
echo('<table class="table ' . $stripe_class . ' table-condensed ">' . PHP_EOL);
$cols = array(
array(NULL, 'class="state-marker"'),
'device' => array('Device', 'style="width: 250px;"'),
'descr' => array('Description'),
'owner' => array('Owner', 'style="width: 180px;"'),
'type' => array('Type', 'style="width: 100px;"'),
array('History', 'style="width: 100px;"'),
'last_change' => array('Last&nbsp;changed', 'style="width: 80px;"'),
'event' => array('Event', 'style="width: 60px; text-align: right;"'),
'sense' => array('Sense', 'style="width: 100px; text-align: right;"'),
'rtt' => array('RTT', 'style="width: 60px;"'),
);
if ($vars['page'] == "device" || $vars['popup'] == TRUE )
{
unset($cols['device']);
}
echo(get_table_header($cols, $vars));
echo('<tbody>' . PHP_EOL);
}
function print_sla_table($vars)
{
$sql = generate_sla_query($vars);
$slas = array();
foreach(dbFetchRows($sql) as $sla)
{
if (isset($GLOBALS['cache']['devices']['id'][$sla['device_id']]))
{
$sla['hostname'] = $GLOBALS['cache']['devices']['id'][$sla['device_id']]['hostname'];
$slas[] = $sla;
}
}
// Sorting
// FIXME. Sorting can be as function, but in must before print_table_header and after get table from db
switch ($vars['sort_order'])
{
case 'desc':
$sort_order = SORT_DESC;
$sort_neg = SORT_ASC;
break;
case 'reset':
unset($vars['sort'], $vars['sort_order']);
// no break here
default:
$sort_order = SORT_ASC;
$sort_neg = SORT_DESC;
}
switch ($vars['sort'])
{
case 'device':
$slas = array_sort_by($slas, 'hostname', $sort_order, SORT_STRING);
break;
case 'descr':
$slas = array_sort_by($slas, 'sla_index', $sort_order, SORT_STRING, 'sla_tag', $sort_order, SORT_STRING);
break;
case 'owner':
$slas = array_sort_by($slas, 'sla_owner', $sort_order, SORT_STRING);
break;
case 'type':
$slas = array_sort_by($slas, 'rtt_type', $sort_order, SORT_STRING);
break;
case 'event':
$slas = array_sort_by($slas, 'rtt_event', $sort_order, SORT_STRING);
break;
case 'sense':
$slas = array_sort_by($slas, 'rtt_sense', $sort_order, SORT_STRING);
break;
case 'last_change':
$slas = array_sort_by($slas, 'rtt_last_change', $sort_neg, SORT_NUMERIC);
break;
case 'rtt':
$slas = array_sort_by($slas, 'rtt_value', $sort_order, SORT_NUMERIC);
break;
default:
// Not sorted
}
$slas_count = count($slas);
// Pagination
$pagination_html = pagination($vars, $slas_count);
echo $pagination_html;
if ($vars['pageno'])
{
$slas = array_chunk($slas, $vars['pagesize']);
$slas = $slas[$vars['pageno'] - 1];
}
// End Pagination
echo generate_box_open();
print_sla_table_header($vars);
foreach($slas as $sla)
{
print_sla_row($sla, $vars);
}
echo '</tbody></table>';
echo generate_box_close();
echo $pagination_html;
}
function humanize_sla(&$sla)
{
global $config;
if (isset($sla['humanized'])) { return; }
$sla['sla_descr'] = 'SLA #' . $sla['sla_index'];
if (!empty($sla['sla_target']) && ($sla['sla_target'] != $sla['sla_tag']))
{
if (get_ip_version($sla['sla_target']) === 6)
{
$sla_target = Net_IPv6::compress($sla['sla_target'], TRUE);
} else {
$sla_target = $sla['sla_target'];
}
$sla['sla_descr'] .= ' (' . $sla['sla_tag'] . ': ' . $sla_target . ')';
} else {
$sla['sla_descr'] .= ' (' . $sla['sla_tag'] . ')';
}
if (isset($config['entity_events'][$sla['rtt_event']]))
{
$sla = array_merge($sla, $config['entity_events'][$sla['rtt_event']]);
} else {
$sla['event_class'] = 'label label-primary';
$sla['row_class'] = '';
}
if ($sla['sla_status'] != 'active')
{
$sla['row_class'] = 'ignore';
}
$device = &$GLOBALS['cache']['devices']['id'][$sla['device_id']];
if (isset($device['status']) && !$device['status'])
{
$sla['row_class'] = 'error';
}
else if (isset($device['disabled']) && $device['disabled'])
{
$sla['row_class'] = 'ignore';
}
if (!empty($sla['sla_graph']))
{
$sla['graph_type'] = "sla_" . $sla['sla_graph'];
} else {
if (stripos($sla['rtt_type'], 'jitter') !== FALSE)
{
$sla['graph_type'] = "sla_jitter";
} else {
$sla['graph_type'] = "sla_echo";
}
}
if (isset($GLOBALS['config']['sla_type_labels'][$sla['rtt_type']]))
{
$sla['rtt_label'] = $GLOBALS['config']['sla_type_labels'][$sla['rtt_type']];
} else {
$sla['rtt_label'] = nicecase($sla['rtt_type']);
}
if (is_numeric($sla['rtt_value']))
{
if ($sla['rtt_value'] > 950)
{
$sla['human_value'] = round($sla['rtt_value'] / 1000, 2);
$sla['human_unit'] = 's';
} else {
$sla['human_value'] = $sla['rtt_value'];
$sla['human_unit'] = 'ms';
}
$sla['human_value'] = str_replace('.00', '', $sla['human_value']);
}
/*
// FIXME, add table columns in discovery time 'rtt_high', 'rtt_warning'
if ($sla['rtt_value'] > 200)
{
$sla['sla_class'] = 'label label-error';
}
else if ($sla['rtt_value'] > 80)
{
$sla['sla_class'] = 'label label-warning';
} else {
$sla['sla_class'] = 'label';
}
*/
if ($sla['rtt_event'] == 'ok')
{
$sla['sla_class'] = 'label';
//$sla['rtt_class'] = 'label label-success';
}
else if ($sla['rtt_event'] == 'alert')
{
$sla['sla_class'] = 'label label-error';
//$sla['rtt_class'] = 'label label-error';
}
else if ($sla['rtt_event'] == 'ignore')
{
$sla['sla_class'] = 'label';
//$sla['rtt_class'] = 'label';
} else {
$sla['sla_class'] = 'label label-warning';
//$sla['rtt_class'] = 'label label-warning';
}
$sla['humanized'] = TRUE;
}
function print_sla_row($sla, $vars)
{
echo generate_sla_row($sla, $vars);
}
function generate_sla_row($sla, $vars)
{
global $config;
humanize_sla($sla);
$table_cols = "8";
$graph_array = array();
$graph_array['to'] = $config['time']['now'];
$graph_array['id'] = $sla['sla_id'];
$graph_array['type'] = $sla['graph_type'];
$graph_array['legend'] = "no";
$graph_array['width'] = 80;
$graph_array['height'] = 20;
$graph_array['bg'] = 'ffffff00';
$graph_array['from'] = $config['time']['day'];
if ($sla['rtt_event'] && $sla['rtt_sense'])
{
$mini_graph = generate_graph_tag($graph_array);
} else {
// Do not show "Draw Error" minigraph
$mini_graph = '';
}
$out = '<tr class="' . $sla['row_class'] . '"><td class="state-marker"></td>';
if ($vars['page'] != "device" && $vars['popup'] != TRUE )
{
$out .= '<td class="entity">' . generate_device_link($sla) . '</td>';
$table_cols++;
}
$out .= '<td class="entity">'. generate_entity_link('sla', $sla) .'</td>';
$out .= '<td>'. $sla['sla_owner'] .'</td>';
$out .= '<td>'. $sla['rtt_label'] .'</td>';
$out .= '<td>' . generate_entity_link('sla', $sla, $mini_graph, NULL, FALSE) . '</td>';
$out .= '<td style="white-space: nowrap">' . generate_tooltip_link(NULL, format_uptime(($config['time']['now'] - $sla['rtt_last_change']), 'short-2') . ' ago', format_unixtime($sla['rtt_last_change'])) . '</td>';
$out .= '<td style="text-align: right;"><strong>' . generate_tooltip_link('', $sla['rtt_event'], $sla['event_descr'], $sla['event_class']) . '</strong></td>';
$out .= '<td style="text-align: right;"><strong>' . generate_tooltip_link('', $sla['rtt_sense'], $sla['event_descr'], $sla['event_class']) . '</strong></td>';
$out .= '<td><span class="' . $sla['sla_class'] . '">' . $sla['human_value'] . $sla['human_unit'] . '</span></td>';
$out .= '</tr>';
if ($vars['graph'] || $vars['view'] == "graphs" || $vars['id'] == $sla['sla_id'])
{
// If id set in vars, display only specific graphs
$graph_array = array();
$graph_array['type'] = $sla['graph_type'];
$graph_array['id'] = $sla['sla_id'];
$out .= '<tr class="' . $sla['row_class'] . '">';
$out .= ' <td class="state-marker"></td>';
$out .= ' <td colspan="'.$table_cols.'">';
$out .= generate_graph_row($graph_array, TRUE);
$out .= ' </td>';
$out .= '</tr>';
}
return $out;
}
// EOF

View File

@ -0,0 +1,522 @@
<?php
/**
* Observium
*
* This file is part of Observium.
*
* @package observium
* @subpackage web
* @copyright (C) 2006-2013 Adam Armstrong, (C) 2013-2021 Observium Limited
*
*/
/**
* 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 = &$GLOBALS['cache']['devices']['id'][$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`)';
}
}
//$sql .= " WHERE 1";
$sql .= " WHERE `status_deleted` = 0";
// Build query
foreach($vars as $var => $value) {
switch ($var) {
case "group":
case "group_id":
$values = get_group_entities($value, 'status');
$sql .= generate_query_values($values, 'status.status_id');
break;
case 'device_group_id':
case 'device_group':
$values = get_group_entities($value, 'device');
$sql .= generate_query_values($values, 'status.device_id');
break;
case "device":
case "device_id":
$sql .= generate_query_values($value, 'status.device_id');
break;
case "id":
case 'status_id':
$sql .= generate_query_values($value, 'status.status_id');
break;
case "entity_id":
$sql .= generate_query_values($value, 'measured_entity');
break;
case "entity_type":
$sql .= generate_query_values($value, 'measured_class');
break;
case 'entity_state':
case "measured_state":
$sql .= build_entity_measured_where('status', [ 'measured_state' => $value ]);
break;
case "class":
case 'entPhysicalClass':
$sql .= generate_query_values($value, 'entPhysicalClass');
break;
case "event":
case "status_event":
$sql .= generate_query_values($value, 'status_event');
break;
case "status":
case "status_name":
$sql .= generate_query_values($value, 'status_name');
break;
case "descr":
case "status_descr":
$sql .= generate_query_values($value, 'status_descr', '%LIKE%');
break;
case 'type':
case "status_type":
$sql .= generate_query_values($value, 'status_type', '%LIKE%');
break;
}
}
//$sql .= $GLOBALS['cache']['where']['devices_permitted'];
$sql .= generate_query_permitted(array('device', 'status'));
// If need count, just return sql without sorting
if ($query_count) {
return $sql;
}
switch ($vars['sort_order']) {
case 'desc':
$sort_order = 'DESC';
$sort_neg = 'ASC';
break;
case 'reset':
unset($vars['sort'], $vars['sort_order']);
// no break here
default:
$sort_order = 'ASC';
$sort_neg = 'DESC';
}
switch($vars['sort']) {
case 'device':
$sql .= ' ORDER BY `hostname` '.$sort_order;
break;
case 'descr':
$sql .= ' ORDER BY `status_descr` '.$sort_order;
break;
case 'class':
$sql .= ' ORDER BY `entPhysicalClass` '.$sort_order;
break;
case 'event':
$sql .= ' ORDER BY `status_event` '.$sort_order;
break;
case 'status':
$sql .= ' ORDER BY `status_name` '.$sort_order;
break;
case 'last_change':
$sql .= ' ORDER BY `status_last_change` '.$sort_neg;
break;
default:
$sql .= ' ORDER BY `measured_entity_label`, `status_descr` '.$sort_order;
}
return $sql;
}
function print_status_table($vars)
{
pagination($vars, 0, TRUE); // Get default pagesize/pageno
$sql = generate_status_query($vars);
$status_list = array();
foreach(dbFetchRows($sql) as $status) {
//if (isset($GLOBALS['cache']['devices']['id'][$status['device_id']]))
//{
$status['hostname'] = $GLOBALS['cache']['devices']['id'][$status['device_id']]['hostname'];
$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 = array(
array(NULL, 'class="state-marker"'),
'device' => array('Device', 'style="width: 250px;"'),
//array(NULL, 'class="no-width"'), // Measure entity link
'descr' => array('Description'),
'mib' => array('MIB::Object'),
'class' => array('Physical&nbsp;Class', 'style="width: 100px;"'),
array('History', 'style="width: 90px;"'),
'last_change' => array('Last&nbsp;changed', 'style="width: 80px;"'),
'event' => array('Event', 'style="width: 60px; text-align: right;"'),
'status' => array('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 = 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>' . (!safe_empty($status['status_mib']) ? '<a href="'.OBSERVIUM_MIBS_URL.'/'.$status['status_mib'].'/" target="_blank">' .nicecase($status['status_mib']) .'</a>' : '') .
( ( !safe_empty($status['status_mib']) && !safe_empty($status['status_object'])) ? '::' : '') .
(!safe_empty($status['status_mib']) ? '<a href="'.OBSERVIUM_MIBS_URL.'/'.$status['status_mib'].'/#'.$status['status_object'].'" target="_blank">' . $status['status_object'] .'</a>' : '') .
'.'.$status['status_index'].'</td>' . PHP_EOL;
$table_cols++;
}
if ($vars['tab'] !== "overview")
{
$row .= '<td><span class="label">' . $status['entPhysicalClass'] . '</span></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_link('', format_uptime((get_time() - $status['status_last_change']), 'short-2') . ' ago', format_unixtime($status['status_last_change'])) . '</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 = array('type' => 'rows',
'space' => '10px',
'submit_by_key' => TRUE,
'url' => generate_url($vars));
$form_items = array();
if ($single_device)
{
// Single device, just hidden field
$form['row'][0]['device_id'] = array(
'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'] = array(
'type' => 'multiselect',
'name' => 'Device',
'value' => $vars['device_id'],
'grid' => 2,
'width' => '100%', //'180px',
'values' => $form_items['devices']);
}
$status_permitted = generate_query_permitted(array('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] = array(
'type' => 'multiselect',
'name' => $param_name,
'width' => '100%', //'180px',
'grid' => 2,
'value' => $vars[$param],
'values' => $form_items[$param]);
}
// Measured entities
$form['row'][0]['measured_state'] = array(
'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'] = array(
'type' => 'text',
'placeholder' => 'Status description',
'width' => '100%', //'180px',
'grid' => 4,
'value' => $vars['status_descr']);
$form['row'][1]['status_type'] = array(
'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'] = array(
'community' => FALSE,
'type' => 'multiselect',
'name' => 'Select Groups',
'width' => '100%', //'180px',
'grid' => 2,
'value' => $vars['group'],
'values' => $form_items['group']);
$form['row'][1]['search'] = array(
'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 = array('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

View File

@ -0,0 +1,370 @@
<?php
/**
* Observium
*
* This file is part of Observium.
*
* @package observium
* @subpackage web
* @copyright (C) 2006-2013 Adam Armstrong, (C) 2013-2021 Observium Limited
*
*/
function generate_storage_query($vars)
{
$sql = "SELECT * FROM `storage`";
if (in_array($vars['sort'], [ 'hostname', 'device', 'device_id' ]))
{
$sql .= ' LEFT JOIN `devices` USING(`device_id`)';
}
$sql .= ' WHERE 1' . generate_query_permitted(array('device'));
// Build query
if (!isset($vars['ignored'])) { $vars['ignored'] = 0; }
foreach($vars as $var => $value)
{
switch ($var) {
case "group":
case "group_id":
$values = get_group_entities($value);
$sql .= generate_query_values($values, 'storage.storage_id');
break;
case 'device_group_id':
case 'device_group':
$values = get_group_entities($value, 'device');
$sql .= generate_query_values($values, 'storage.device_id');
break;
case "device":
case "device_id":
$sql .= generate_query_values($value, 'storage.device_id');
break;
case "descr":
case "storage_descr";
$sql .= generate_query_values($value, 'storage_descr', '%LIKE%');
break;
case 'ignored':
$sql .= generate_query_values($value, 'storage.storage_ignore');
break;
}
}
switch ($vars['sort_order'])
{
case 'desc':
$sort_order = 'DESC';
$sort_neg = 'ASC';
break;
case 'reset':
unset($vars['sort'], $vars['sort_order']);
// no break here
default:
$sort_order = 'ASC';
$sort_neg = 'DESC';
}
switch($vars['sort'])
{
case 'usage':
$sql .= ' ORDER BY `storage_perc` '.$sort_neg;
break;
case 'descr':
case 'mountpoint':
$sql .= ' ORDER BY `storage_descr` '.$sort_order;
break;
case 'size':
case 'free':
case 'used':
$sql .= ' ORDER BY `storage_'.$vars['sort'].'` '.$sort_order;
break;
case 'device':
case 'hostname':
$sql .= ' ORDER BY `hostname` '.$sort_order;
break;
default:
$sql .= ' ORDER BY `storage_descr` '.$sort_order;
break;
}
return $sql;
}
function print_storage_table($vars)
{
global $cache, $config;
$graph_type = "storage_usage";
$sql = generate_storage_query($vars);
$storages = array();
foreach (dbFetchRows($sql) as $storage)
{
if (isset($cache['devices']['id'][$storage['device_id']]))
{
$storage['hostname'] = $cache['devices']['id'][$storage['device_id']]['hostname'];
$storage['html_row_class'] = $cache['devices']['id'][$storage['device_id']]['html_row_class'];
$storages[] = $storage;
}
}
$storages_count = count($storages);
// Pagination
$pagination_html = pagination($vars, $storages_count);
echo $pagination_html;
if ($vars['pageno'])
{
$storages = array_chunk($storages, $vars['pagesize']);
$storages = $storages[$vars['pageno']-1];
}
// End Pagination
echo generate_box_open();
print_storage_table_header($vars);
foreach ($storages as $storage)
{
print_storage_row($storage, $vars);
}
echo("</tbody></table>");
echo generate_box_close();
echo $pagination_html;
}
function print_storage_table_header($vars)
{
if ($vars['view'] === "graphs" || isset($vars['graph']))
{
$table_class = OBS_CLASS_TABLE_STRIPED_TWO;
} else {
$table_class = OBS_CLASS_TABLE_STRIPED;
}
echo('<table class="' . $table_class . '">' . PHP_EOL);
$cols = array(
array(NULL, 'class="state-marker"'),
'device' => array('Device', 'style="width: 250px;"'),
'mountpoint' => array('Mountpoint'),
'size' => array('Size', 'style="width: 100px;"'),
'used' => array('Used', 'style="width: 100px;"'),
'free' => array('Free', 'style="width: 100px;"'),
array('', 'style="width: 100px;"'),
'usage' => array('Usage %', 'style="width: 200px;"'),
);
if ($vars['page'] === "device")
{
unset($cols['device']);
}
echo(get_table_header($cols, $vars));
echo('<tbody>' . PHP_EOL);
}
function print_storage_row($storage, $vars) {
echo generate_storage_row($storage, $vars);
}
function generate_storage_row($storage, $vars) {
global $config;
$table_cols = 8;
if ($vars['page'] !== "device" && $vars['popup'] != TRUE) { $table_cols++; } // Add a column for device.
if(isset($vars['graph_type']) && $vars['graph_type'] == "perc")
$graph_array = array();
$graph_array['to'] = $config['time']['now'];
$graph_array['id'] = $storage['storage_id'];
$graph_array['type'] = 'storage_usage';
$graph_array['legend'] = "no";
$link_array = $graph_array;
$link_array['page'] = "graphs";
unset($link_array['height'], $link_array['width'], $link_array['legend']);
$link_graph = generate_url($link_array);
$link = generate_url( array("page" => "device", "device" => $storage['device_id'], "tab" => "health", "metric" => 'storage'));
$overlib_content = generate_overlib_content($graph_array, $storage['hostname'] . ' - ' . $storage['storage_descr']);
$graph_array['width'] = 80; $graph_array['height'] = 20; $graph_array['bg'] = 'ffffff00';
$graph_array['from'] = $config['time']['day'];
$mini_graph = generate_graph_tag($graph_array);
$total = formatStorage($storage['storage_size']);
$used = formatStorage($storage['storage_used']);
$free = formatStorage($storage['storage_free']);
$background = get_percentage_colours($storage['storage_perc']);
if ($storage['storage_ignore'])
{
$storage['row_class'] = 'suppressed';
} else {
$storage['row_class'] = $background['class'];
}
$row = '<tr class="ports ' . $storage['row_class'] . '">
<td class="state-marker"></td>';
if ($vars['page'] !== "device" && $vars['popup'] != TRUE) { $row .= '<td class="entity">' . generate_device_link($storage) . '</td>'; }
$row .= ' <td class="entity">'.generate_entity_link('storage', $storage).'</td>
<td>'.$total.'</td>
<td>'.$used.'</td>
<td>'.$free.'</td>
<td>'.overlib_link($link_graph, $mini_graph, $overlib_content).'</td>
<td><a href="'.$link_graph.'">
' . print_percentage_bar(400, 20, $storage['storage_perc'], $storage['storage_perc'].'%', "ffffff", $background['left'], 100-$storage['storage_perc']."%" , "ffffff", $background['right']).'
</a>
</td>
</tr>
';
if ($vars['view'] === "graphs" && !isset($vars['graph'])) { $vars['graph'] = "bytes,perc"; }
if (isset($vars['graph']))
{
$graph_types = explode(',', $vars['graph']);
foreach ($graph_types AS $graph_type) {
$graph_type = 'storage_'.$graph_type;
$row .= '<tr class="' . $storage['row_class'] . '">';
$row .= '<td class="state-marker"></td>';
$row .= '<td colspan="' . $table_cols . '">';
unset($graph_array['height'], $graph_array['width'], $graph_array['legend']);
$graph_array['to'] = $config['time']['now'];
$graph_array['id'] = $storage['storage_id'];
$graph_array['type'] = $graph_type;
$row .= generate_graph_row($graph_array, TRUE);
$row .= '</td></tr>';
}
} # endif graphs
return $row;
}
function print_storage_form($vars, $single_device = FALSE)
{
//global $config;
$form = array('type' => 'rows',
'space' => '10px',
'submit_by_key' => TRUE,
'url' => generate_url($vars));
$form_items = array();
if ($single_device)
{
// Single device, just hidden field
$form['row'][0]['device_id'] = array(
'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 `storage`'));
$form['row'][0]['device_id'] = array(
'type' => 'multiselect',
'name' => 'Device',
'value' => $vars['device_id'],
'grid' => 2,
'width' => '100%', //'180px',
'values' => $form_items['devices']);
}
//$sensor_permitted = generate_query_permitted(array('device', 'sensor'));
$form['row'][0]['storage_descr'] = array(
'type' => 'text',
'placeholder' => 'Storage',
'width' => '100%', //'180px',
'grid' => 6,
'value' => $vars['storage_descr']);
// Groups
foreach (get_type_groups('storage') as $entry)
{
$form_items['group'][$entry['group_id']] = $entry['group_name'];
}
$form['row'][0]['group'] = array(
'community' => FALSE,
'type' => 'multiselect',
'name' => 'Select Groups',
'width' => '100%', //'180px',
'grid' => 2,
'value' => $vars['group'],
'values' => $form_items['group']);
$form['row'][0]['search'] = array(
'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 = array('type' => 'rows',
'title' => 'Search Storage',
'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]['group'] = $form['row'][0]['group'];
//$panel_form['row'][1]['supply_colour'] = $form['row'][0]['supply_colour'];
//$panel_form['row'][1]['supply_type'] = $form['row'][0]['supply_type'];
//$panel_form['row'][2]['measured_state'] = $form['row'][0]['measured_state'];
//$panel_form['row'][2]['group'] = $form['row'][1]['group'];
$panel_form['row'][3]['storage_descr'] = $form['row'][0]['storage_descr'];
//$panel_form['row'][5]['sort'] = $form['row'][0]['sort'];
$panel_form['row'][5]['search'] = $form['row'][0]['search'];
// Register custom panel
register_html_panel(generate_form($panel_form));
}
// EOF

View File

@ -0,0 +1,207 @@
<?php
/**
* Observium
*
* This file is part of Observium.
*
* @package observium
* @subpackage web
* @copyright (C) 2006-2013 Adam Armstrong, (C) 2013-2019 Observium Limited
*
*/
function generate_vm_query($vars)
{
$sql = 'SELECT * FROM `vminfo` WHERE 1 ';
// Build query
foreach($vars as $var => $value)
{
switch ($var)
{
case "group":
case "group_id":
$values = get_group_entities($value);
$sql .= generate_query_values($values, 'vm_id');
break;
case 'device_group_id':
case 'device_group':
$values = get_group_entities($value, 'device');
$sql .= generate_query_values($values, 'device_id');
break;
case "device":
case "device_id":
$sql .= generate_query_values($value, 'device_id');
break;
case "os":
$sql .= generate_query_values($value, 'vm_guestos');
break;
case "state":
$sql .= generate_query_values($value, 'vm_state');
break;
case "memory":
$sql .= generate_query_values($value, 'vm_memory');
break;
case "cpu":
$sql .= generate_query_values($value, 'vm_cpucount');
break;
}
}
$sql .= $GLOBALS['cache']['where']['devices_permitted'];
return $sql;
}
function print_vm_table_header($vars)
{
$stripe_class = "table-striped";
echo('<table class="table ' . $stripe_class . ' table-condensed ">' . PHP_EOL);
$cols = array(
// array(NULL, 'class="state-marker"'), // FIXME useful when we start polling VM status
'device' => array('Device', 'style="width: 250px;"'),
'name' => array('Name'),
'state' => array('State'),
'os' => array('Operating System'),
'memory' => array('Memory'),
'cpu' => array('CPU'),
);
if ($vars['page'] == "device" || $vars['popup'] == TRUE )
{
unset($cols['device']);
}
echo(get_table_header($cols, $vars));
echo('<tbody>' . PHP_EOL);
}
function print_vm_table($vars)
{
$sql = generate_vm_query($vars);
$vms = array();
foreach(dbFetchRows($sql) as $vm)
{
if (isset($GLOBALS['cache']['devices']['id'][$vm['device_id']]))
{
$vm['hostname'] = $GLOBALS['cache']['devices']['id'][$vm['device_id']]['hostname'];
$vms[] = $vm;
}
}
// Sorting
// FIXME. Sorting can be as function, but in must before print_table_header and after get table from db
switch ($vars['sort_order'])
{
case 'desc':
$sort_order = SORT_DESC;
$sort_neg = SORT_ASC;
break;
case 'reset':
unset($vars['sort'], $vars['sort_order']);
// no break here
default:
$sort_order = SORT_ASC;
$sort_neg = SORT_DESC;
}
switch ($vars['sort'])
{
case 'name':
$vms = array_sort_by($vms, 'vm_name', $sort_order, SORT_STRING);
break;
case 'os':
$vms = array_sort_by($vms, 'vm_os', $sort_order, SORT_STRING);
break;
case 'state':
$vms = array_sort_by($vms, 'vm_state', $sort_order, SORT_STRING);
break;
case 'memory':
$vms = array_sort_by($vms, 'vm_memory', $sort_order, SORT_NUMERIC);
break;
case 'cpu':
$vms = array_sort_by($vms, 'vm_cpucount', $sort_order, SORT_NUMERIC);
break;
default:
// Not sorted
}
$vms_count = count($vms);
// Pagination
$pagination_html = pagination($vars, $vms_count);
echo $pagination_html;
if ($vars['pageno'])
{
$vms = array_chunk($vms, $vars['pagesize']);
$vms = $vms[$vars['pageno'] - 1];
}
// End Pagination
echo generate_box_open();
print_vm_table_header($vars);
foreach($vms as $vm)
{
print_vm_row($vm, $vars);
}
echo '</tbody></table>';
echo generate_box_close();
echo $pagination_html;
}
function print_vm_row($vm, $vars)
{
echo generate_vm_row($vm, $vars);
}
function generate_vm_row($vm, $vars)
{
global $config;
$table_cols = "8";
$out = '<tr class="' . $vm['row_class'] . '">'; // <td class="state-marker"></td>'; // FIXME useful when we start polling VM state
if ($vars['page'] != "device" && $vars['popup'] != TRUE )
{
$out .= '<td class="entity">' . generate_device_link($vm) . '</td>';
$table_cols++;
}
$out .= '<td class="entity">'. generate_entity_link('virtualmachine', $vm) .'</td>';
$out .= '<td>'. nicecase($vm['vm_state']) .'</td>';
switch ($vm['vm_guestos'])
{
case 'E: tools not installed':
$out .= ' <td class="small">Unknown (VMware Tools not installed)</td>';
break;
case 'E: tools not running':
$out .= ' <td class="small">Unknown (VMware Tools not running)</td>';
break;
case '':
$out .= ' <td class="small"><i>(Unknown)</i></td>';
break;
default:
if (isset($config['vmware_guestid'][$vm['vm_guestos']]))
{
$out .= ' <td>' . $config['vmware_guestid'][$vm['vm_guestos']] . '</td>';
} else {
$out .= ' <td>' . $vm['vm_guestos'] . '</td>';
}
break;
}
$out .= '<td>'. format_bi($vm['vm_memory'] * 1024 * 1024, 3, 3) .'B</td>';
$out .= '<td>'. $vm['vm_cpucount'] .'</td>';
$out .= '</tr>';
return $out;
}
// EOF