1<?php
2
3/**
4 * Observium
5 *
6 *   This file is part of Observium.
7 *
8 * @package    observium
9 * @subpackage web
10 * @copyright  (C) 2006-2013 Adam Armstrong, (C) 2013-2019 Observium Limited
11 *
12 */
13
14/**
15 * Display status alerts.
16 *
17 * Display pages with alerts about device troubles.
18 * Examples:
19 * print_status(array('devices' => TRUE)) - display for devices down
20 *
21 * Another statuses:
22 * devices, uptime, ports, errors, services, bgp
23 *
24 * @param array $options
25 * @return none
26 *
27 */
28function print_status_old($options)
29{
30  global $config;
31
32  $max_interval = filter_var($options['max']['interval'], FILTER_VALIDATE_INT, array('options' => array('default' => 24,  'min_range' => 1)));
33  $max_count    = filter_var($options['max']['count'],    FILTER_VALIDATE_INT, array('options' => array('default' => 200, 'min_range' => 1)));
34
35   $string  = '<table class="table  table-striped table-hover table-condensed">' . PHP_EOL;
36 /* $string .= '  <thead>' . PHP_EOL;
37  $string .= '  <tr>' . PHP_EOL;
38  $string .= '    <th>Device</th>' . PHP_EOL;
39  $string .= '    <th>Type</th>' . PHP_EOL;
40  $string .= '    <th>Status</th>' . PHP_EOL;
41  $string .= '    <th>Entity</th>' . PHP_EOL;
42  // $string .= '    <th>Location</th>' . PHP_EOL;
43  $string .= '    <th>Information</th>' . PHP_EOL;
44  $string .= '  </tr>' . PHP_EOL;
45  $string .= '  </thead>' . PHP_EOL;
46  $string .= '  <tbody>' . PHP_EOL;
47 */
48
49  $query_device_permitted = generate_query_permitted(array('device'), array('device_table' => 'D', 'hide_ignored' => TRUE));
50  $query_port_permitted   = generate_query_permitted(array('port'),   array('port_table' => 'I',   'hide_ignored' => TRUE));
51
52  // Show Device Status
53  if ($options['devices'])
54  {
55    $query = 'SELECT * FROM `devices` AS D';
56    $query .= ' WHERE D.`status` = 0' . $query_device_permitted;
57    $query .= ' ORDER BY D.`hostname` ASC';
58    $entries = dbFetchRows($query);
59    foreach ($entries as $device)
60    {
61      $string .= '  <tr>' . PHP_EOL;
62      $string .= '    <td class="entity">' . generate_device_link($device, short_hostname($device['hostname'])) . '</td>' . PHP_EOL;
63      // $string .= '    <td><span class="badge badge-inverse">Device</span></td>' . PHP_EOL;
64      $string .= '    <td><span class="label label-important">Device Down</span></td>' . PHP_EOL;
65      $string .= '    <td class="entity"><i class="'.$config['icon']['devices'].'"></i> ' . generate_device_link($device, short_hostname($device['hostname'])) . '</td>' . PHP_EOL;
66      // $string .= '    <td style="white-space: nowrap">' . escape_html(truncate($device['location'], 30)) . '</td>' . PHP_EOL;
67      $string .= '    <td style="white-space: nowrap">' . deviceUptime($device, 'short') . '</td>' . PHP_EOL;
68      $string .= '  </tr>' . PHP_EOL;
69    }
70  }
71
72  // Uptime
73  if ($options['uptime'])
74  {
75    if (filter_var($config['uptime_warning'], FILTER_VALIDATE_FLOAT) !== FALSE && $config['uptime_warning'] > 0)
76    {
77      $query = 'SELECT * FROM `devices` AS D';
78      // Since reboot event more complicated than just device uptime less than some time
79      //$query .= ' WHERE D.`status` = 1 AND D.`uptime` > 0 AND D.`uptime` < ' . $config['uptime_warning'];
80      $query .= ' WHERE D.`status` = 1 AND D.`uptime` > 0 AND D.`last_rebooted` > ?';
81      $query .= $query_device_permitted;
82      $query .= 'ORDER BY D.`hostname` ASC';
83      $entries = dbFetchRows($query, array($config['time']['now'] - $config['uptime_warning'] - 10));
84
85      foreach ($entries as $device)
86      {
87        $string .= '  <tr>' . PHP_EOL;
88        $string .= '    <td class="entity">' . generate_device_link($device, short_hostname($device['hostname'])) . '</td>' . PHP_EOL;
89        // $string .= '    <td><span class="badge badge-inverse">Device</span></td>' . PHP_EOL;
90        $string .= '    <td><span class="label label-success">Device Rebooted</span></td>' . PHP_EOL;
91        $string .= '    <td class="entity"><i class="'.$config['icon']['devices'].'"></i> ' . generate_device_link($device, short_hostname($device['hostname'])) . '</td>' . PHP_EOL;
92        // $string .= '    <td style="white-space: nowrap">' . escape_html(truncate($device['location'], 30)) . '</td>' . PHP_EOL;
93        $string .= '    <td style="white-space: nowrap">Uptime ' . format_uptime($device['uptime'], 'short') . '</td>' . PHP_EOL;
94        $string .= '  </tr>' . PHP_EOL;
95      }
96    }
97  }
98
99  // Ports Down
100  if ($options['ports'] || $options['neighbours'] || $options['links'])
101  {
102    $options['neighbours'] = $options['neighbours'] && !$options['ports']; // Disable 'neighbours' if 'ports' already enabled
103
104    $query = 'SELECT * FROM `ports` AS I ';
105    if ($options['neighbours'])
106    {
107      $query .= 'INNER JOIN `neighbours` AS L ON I.`port_id` = L.`port_id` ';
108    }
109    $query .= 'LEFT JOIN `devices` AS D ON I.`device_id` = D.`device_id` ';
110    $query .= "WHERE D.`status` = 1 AND D.ignore = 0 AND I.ignore = 0 AND I.deleted = 0 AND I.`ifAdminStatus` = 'up' AND (I.`ifOperStatus` = 'lowerLayerDown' OR I.`ifOperStatus` = 'down') ";
111    if ($options['neighbours'])
112    {
113      $query .= ' AND L.`active` = 1 ';
114    }
115    $query .= $query_port_permitted;
116    $query .= ' AND I.`ifLastChange` >= DATE_SUB(NOW(), INTERVAL '.$max_interval.' HOUR) ';
117    if ($options['neighbours']) { $query .= 'GROUP BY L.`port_id` '; }
118    $query .= 'ORDER BY I.`ifLastChange` DESC, D.`hostname` ASC, I.`ifDescr` * 1 ASC ';
119    $entries = dbFetchRows($query);
120    $i = 1;
121    foreach ($entries as $port)
122    {
123      if ($i > $max_count)
124      {
125        $string .= '  <tr><td></td><td><span class="badge badge-info">Port</span></td>';
126        $string .= '<td><span class="label label-important">Port Down</span></td>';
127        $string .= '<td colspan=3>Too many ports down. See <strong><a href="'.generate_url(array('page'=>'ports'), array('state'=>'down')).'">All DOWN ports</a></strong>.</td></tr>' . PHP_EOL;
128        break;
129      }
130      humanize_port($port);
131      $string .= '  <tr>' . PHP_EOL;
132      $string .= '    <td class="entity">' . generate_device_link($port, short_hostname($port['hostname'])) . '</td>' . PHP_EOL;
133      // $string .= '    <td><span class="badge badge-info">Port</span></td>' . PHP_EOL;
134      $string .= '    <td><span class="label label-important">Port Down</span></td>' . PHP_EOL;
135      $string .= '    <td class="entity"><i class="'.$config['icon']['port'].'"></i> ' . generate_port_link($port, short_ifname($port['port_label'])) . '</td>' . PHP_EOL;
136      // $string .= '    <td style="white-space: nowrap">' . escape_html(truncate($port['location'], 30)) . '</td>' . PHP_EOL;
137      $string .= '    <td style="white-space: nowrap">Down for ' . format_uptime($config['time']['now'] - strtotime($port['ifLastChange']), 'short'); // This is like deviceUptime()
138      if ($options['links']) { $string .= ' ('.nicecase($port['protocol']).': ' .$port['remote_hostname'].' / ' .$port['remote_port'] .')'; }
139      $string .= '</td>' . PHP_EOL;
140      $string .= '  </tr>' . PHP_EOL;
141      $i++;
142    }
143  }
144
145  // Ports Errors (only deltas)
146  if ($options['errors'])
147  {
148    $query = 'SELECT * FROM `ports` AS I ';
149    //$query .= 'LEFT JOIN `ports-state` AS E ON I.`port_id` = E.`port_id` ';
150    $query .= 'LEFT JOIN `devices` AS D ON I.`device_id` = D.`device_id` ';
151    $query .= "WHERE D.`status` = 1 AND I.`ifOperStatus` = 'up' AND (I.`ifInErrors_delta` > 0 OR I.`ifOutErrors_delta` > 0)";
152    $query .= $query_port_permitted;
153    $query .= 'ORDER BY D.`hostname` ASC, I.`ifDescr` * 1 ASC';
154    $entries = dbFetchRows($query);
155    foreach ($entries as $port)
156    {
157      humanize_port($port);
158      $string .= '  <tr>' . PHP_EOL;
159      $string .= '    <td class="entity">' . generate_device_link($port, short_hostname($port['hostname'])) . '</td>' . PHP_EOL;
160      // $string .= '    <td><span class="badge badge-info">Port</span></td>' . PHP_EOL;
161      $string .= '    <td><span class="label label-important">Port Errors</span></td>' . PHP_EOL;
162      $string .= '    <td class="entity"><i class="'.$config['icon']['port'].'"></i> '.generate_port_link($port, short_ifname($port['port_label']), 'port_errors') . '</td>' . PHP_EOL;
163      // $string .= '    <td style="white-space: nowrap">' . escape_html(truncate($port['location'], 30)) . '</td>' . PHP_EOL;
164      $string .= '    <td>Errors ';
165      if ($port['ifInErrors_delta']) { $string .= 'In: ' . $port['ifInErrors_delta']; }
166      if ($port['ifInErrors_delta'] && $port['ifOutErrors_delta']) { $string .= ', '; }
167      if ($port['ifOutErrors_delta']) { $string .= 'Out: ' . $port['ifOutErrors_delta']; }
168      $string .= '</td>' . PHP_EOL;
169      $string .= '  </tr>' . PHP_EOL;
170    }
171  }
172
173  // Services
174  if ($options['services'])
175  {
176    $query = 'SELECT * FROM `services` AS S ';
177    $query .= 'LEFT JOIN `devices` AS D ON S.`device_id` = D.`device_id` ';
178    $query .= "WHERE S.`service_status` = 'down' AND S.`service_ignore` = 0";
179    $query .= $query_device_permitted;
180    $query .= 'ORDER BY D.`hostname` ASC';
181    $entries = dbFetchRows($query);
182    foreach ($entries as $service)
183    {
184      $string .= '  <tr>' . PHP_EOL;
185      $string .= '    <td class="entity">' . generate_device_link($service, short_hostname($service['hostname'])) . '</td>' . PHP_EOL;
186      // $string .= '    <td><span class="badge">Service</span></td>' . PHP_EOL;
187      $string .= '    <td><span class="label label-important">Service Down</span></td>' . PHP_EOL;
188      $string .= '    <td>' . $service['service_type'] . '</td>' . PHP_EOL;
189      // $string .= '    <td style="white-space: nowrap">' . escape_html(truncate($service['location'], 30)) . '</td>' . PHP_EOL;
190      $string .= '    <td style="white-space: nowrap">Down for ' . format_uptime($config['time']['now'] - strtotime($service['service_changed']), 'short') . '</td>' . PHP_EOL; // This is like deviceUptime()
191      $string .= '  </tr>' . PHP_EOL;
192    }
193  }
194
195  // BGP
196  if ($options['bgp'])
197  {
198    if (isset($config['enable_bgp']) && $config['enable_bgp'])
199    {
200      // Description for BGP states
201      $bgpstates = 'IDLE - Router is searching routing table to see whether a route exists to reach the neighbor. &#xA;';
202      $bgpstates .= 'CONNECT - Router found a route to the neighbor and has completed the three-way TCP handshake. &#xA;';
203      $bgpstates .= 'OPEN SENT - Open message sent, with parameters for the BGP session. &#xA;';
204      $bgpstates .= 'OPEN CONFIRM - Router received agreement on the parameters for establishing session. &#xA;';
205      $bgpstates .= 'ACTIVE - Router did not receive agreement on parameters of establishment. &#xA;';
206      //$bgpstates .= 'ESTABLISHED - Peering is established; routing begins.';
207
208      $query = 'SELECT * FROM `devices` AS D ';
209      $query .= 'LEFT JOIN `bgpPeers` AS B ON B.`device_id` = D.`device_id` ';
210      $query .= "WHERE D.`status` = 1 AND (`bgpPeerAdminStatus` = 'start' OR `bgpPeerAdminStatus` = 'running') AND `bgpPeerState` != 'established' ";
211      $query .= $query_device_permitted;
212      $query .= 'ORDER BY D.`hostname` ASC';
213      $entries = dbFetchRows($query);
214      foreach ($entries as $peer)
215      {
216        humanize_bgp($peer);
217        $peer_ip = generate_entity_link("bgp_peer", $peer, $peer['human_remoteip']);
218
219        $string .= '  <tr>' . PHP_EOL;
220        $string .= '    <td class="entity">' . generate_device_link($peer, short_hostname($peer['hostname']), array('tab' => 'routing', 'proto' => 'bgp')) . '</td>' . PHP_EOL;
221        // $string .= '    <td><span class="badge badge-warning">BGP</span></td>' . PHP_EOL;
222        $string .= '    <td><span class="label label-warning" title="' . $bgpstates . '">BGP ' . nicecase($peer['bgpPeerState']) . '</span></td>' . PHP_EOL;
223        $string .= '    <td class="entity" style="white-space: nowrap"><i class="'.$config['icon']['bgp'].'"></i> ' . $peer_ip . '</td>' . PHP_EOL;
224        // $string .= '    <td style="white-space: nowrap">' . escape_html(truncate($peer['location'], 30)) . '</td>' . PHP_EOL;
225        $string .= '    <td><strong>AS' . $peer['human_remote_as'] . ' :</strong> ' . $peer['astext'] . '</td>' . PHP_EOL;
226        $string .= '  </tr>' . PHP_EOL;
227      }
228    }
229  }
230
231  // $string .= '  </tbody>' . PHP_EOL;
232  $string .= '</table>';
233
234  // Final print all statuses
235  echo($string);
236}
237
238function generate_alert_entries($vars)
239{
240
241  global $alert_rules;
242  global $config;
243
244  // This should be set outside, but do it here if it isn't
245  if (!is_array($alert_rules)) { $alert_rules = cache_alert_rules(); }
246  /// WARN HERE
247
248  $vars['sort'] = 'alert_last_changed';
249
250  list($query, $param, $query_count) = build_alert_table_query($vars);
251
252  // Fetch alerts
253  $count  = dbFetchCell($query_count, $param);
254  $alerts = dbFetchRows($query, $param);
255
256  foreach ($alerts as $alert)
257  {
258
259    humanize_alert_entry($alert);
260    $alert_rule = &$alert_rules[$alert['alert_test_id']];
261
262    $device = device_by_id_cache($alert['device_id']);
263
264    $array[] = array('sev' => 100,
265                     'icon_tag'    => '<i class="' . $config['entities'][$alert['entity_type']]['icon'] . '"></i>',
266                     'alert_test_id' => $alert['alert_test_id'],
267                     'event'       => '<a href="'. generate_url(array('page' => 'alert_check', 'alert_test_id' => $alert_rule['alert_test_id'])). '">'. escape_html($alert_rule['alert_name']). '</a>',
268                     'entity_type' => $alert['entity_type'],
269                     'entity_id'   => $alert['entity_id'],
270                     'entity_link' => ($alert['entity_type'] != "device" ? generate_entity_link($alert['entity_type'], $alert['entity_id'],NULL, NULL, TRUE, TRUE) : NULL),
271                     'device_id' => $device['device_id'],
272                     'device_link' => generate_device_link($device, short_hostname($device['hostname'])),
273                     'time' => $alert['changed']);
274  }
275
276  return $array;
277
278}
279
280/**
281 * Display status alerts.
282 *
283 * Display pages with alerts about device troubles.
284 * Examples:
285 * print_status(array('devices' => TRUE)) - display for devices down
286 *
287 * Another statuses:
288 * devices, uptime, ports, errors, services, bgp
289 *
290 * @param array $options
291 * @return TRUE
292 *
293 */
294function print_status_boxes($options, $limit = NULL)
295{
296  if(isset($options['widget_type']) && $options['widget_type'] == 'alert_boxes')
297  {
298    $status_array = generate_alert_entries(array('status' => 'failed')); //, 'entity_id' => '1'));
299  } else
300  {
301    $status_array = get_status_array($options);
302    $status_array = array_sort($status_array, 'sev', 'SORT_DESC');
303  }
304
305  $count = count($status_array);
306
307  if ($count == 0)
308  {
309    echo '<div class="alert statusbox alert-info" style="border-left: 1px; width: 80%; height: 75px; margin-left:10%; float:none; display: block;">';
310    echo '<div style="margin: auto; line-height: 75px; text-align: center;">There are currently no ongoing alert events.</div>';
311    echo '</div>';
312
313    return;
314  }
315
316  $i = 1;
317  foreach ($status_array as $entry)
318  {
319    if ($i >= $limit)
320    {
321      echo('<div class="alert statusbox alert-danger" style="border-left: 1px;">');
322      echo '<div style="margin: auto; line-height: 75px; text-align: center;"><b>' . $count . ' more...</b></div>';
323      echo('</div>');
324
325      return;
326    }
327
328    if ($entry['entity_link'])
329    {
330      $entry['entity_link'] = preg_replace('/(<a.*?>)(.{0,20}).*(<\/a>)/', '\\1\\2\\3', $entry['entity_link']);
331    }
332
333    if ($entry['sev'] > 51)     { $class = "alert-danger"; }
334    elseif ($entry['sev'] > 20) { $class = "alert-warning"; }
335    else                        { $class = "alert-info"; }
336
337    //if ($entry['wide']) { $class .= ' statusbox-wide'; }
338
339    echo('<div class="alert statusbox ' . $class . '" style="text-align: center;position: relative;">
340            <p style="margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">');
341
342    echo '<h4>' . $entry['device_link'] . '</h4>';
343    echo '' . $entry['event'] . '<br />';
344    echo '<h4 style="margin-bottom: 2px;">' . ($entry['entity_link'] ? $entry['icon_tag'] . $entry['entity_link'] : 'Device') . ' </h4>';
345    echo '<small>' . $entry['time'] . '</small>';
346    echo('</p></div>');
347
348    $count--;
349    $i++;
350  }
351
352  return TRUE;
353
354}
355
356function generate_status_table($options, $print = FALSE)
357{
358
359  $status_array = get_status_array($options);
360  $status_array = array_sort($status_array, 'sev', 'SORT_DESC');
361  $i = 1; $string = '';
362  $string .= '<table style="" class="table table-striped table-hover table-condensed">' . PHP_EOL;
363
364  foreach ($status_array as $entry)
365  {
366    if ($entry['sev'] > 51)     { $class = "danger"; $row_class = 'error'; }
367    elseif ($entry['sev'] > 20) { $class = "warning"; $row_class = 'warning'; }
368    else                        { $class = "info"; }
369
370    $string .= '  <tr class="'.$row_class.'">' . PHP_EOL;
371    $string .= '    <td class="state-marker"></td>';
372    $string .= '    <td class="entity">' . $entry['device_link'] . '</td>' . PHP_EOL;
373    $string .= '    <td><span class="label label-'.$class.'" title="' . $entry['event'] . '">'.$entry['class'].' '.$entry['event'].'</span></td>' . PHP_EOL;
374    $string .= '    <td class="entity" style="white-space: nowrap">'. $entry['icon_tag'] . ($entry['entity_link'] ? $entry['entity_link'] : $entry['device_link']) . '</td>' . PHP_EOL;
375    $string .= '    <td>' . $entry['time'] . '</td>' . PHP_EOL;
376    $string .= '  </tr>' . PHP_EOL;
377  }
378  $string .= '</table>';
379  if($print == TRUE)
380  {
381    echo $string;
382    return TRUE;
383  } else {
384    return $string;
385  }
386}
387
388
389// DOCME needs phpdoc block
390function get_status_array($options)
391{
392  // Mike: I know that there are duplicated variables, but later will remove global
393  global $config;
394
395  $max_interval = filter_var($options['max']['interval'], FILTER_VALIDATE_INT, array('options' => array('default' => 24, 'min_range' => 1)));
396  $max_count    = filter_var($options['max']['count'],    FILTER_VALIDATE_INT, array('options' => array('default' => 200, 'min_range' => 1)));
397  $query_device_permitted = generate_query_permitted(array('device'), array('device_table' => 'D', 'hide_ignored' => TRUE));
398  $query_port_permitted   = generate_query_permitted(array('port'),   array('port_table' => 'I',   'hide_ignored' => TRUE));
399
400  // Show Device Status
401  if ($options['devices'])
402  {
403    $query = 'SELECT * FROM `devices` AS D ';
404    $query .= 'WHERE D.`status` = 0' . $query_device_permitted;
405    $query .= 'ORDER BY D.`hostname` ASC';
406    $entries = dbFetchRows($query);
407    foreach ($entries as $device)
408    {
409      $boxes[] = array('sev' => 100,
410                       'class' => 'Device',
411                       'event' => 'Down',
412                       'device_link' => generate_device_link($device, short_hostname($device['hostname'])),
413                       'time' => deviceUptime($device, 'short-3'),
414                       'icon_tag' => '<i class="' . $config['entities']['device']['icon'] . '"></i>');
415    }
416  }
417
418  // Uptime
419  if ($options['uptime'])
420  {
421    if (filter_var($config['uptime_warning'], FILTER_VALIDATE_FLOAT) !== FALSE && $config['uptime_warning'] > 0)
422    {
423      $query = 'SELECT * FROM `devices` AS D ';
424      // Since reboot event more complicated than just device uptime less than some time
425      //$query .= ' WHERE D.`status` = 1 AND D.`uptime` > 0 AND D.`uptime` < ' . $config['uptime_warning'];
426      $query .= ' WHERE D.`status` = 1 AND D.`uptime` > 0 AND D.`last_rebooted` > ?';
427      $query .= $query_device_permitted;
428      $query .= 'ORDER BY D.`hostname` ASC';
429      $entries = dbFetchRows($query, array($config['time']['now'] - $config['uptime_warning'] - 10));
430
431      foreach ($entries as $device)
432      {
433        $boxes[] = array('sev' => 10,
434                         'class' => 'Device',
435                         'event' => 'Rebooted',
436                         'device_link' => generate_device_link($device, short_hostname($device['hostname'])),
437                         'time' => deviceUptime($device, 'short-3'),
438                         'location' => $device['location'],
439                         'icon_tag' => '<i class="' . $config['entities']['device']['icon'] . '"></i>');
440      }
441    }
442  }
443
444  // Ports Down
445  if ($options['ports'] || $options['neighbours'])
446  {
447    $options['neighbours'] = $options['neighbours'] && !$options['ports']; // Disable 'neighbours' if 'ports' already enabled
448
449    $query = 'SELECT * FROM `ports` AS I ';
450    if ($options['neighbours'])
451    {
452      $query .= 'INNER JOIN `neighbours` as L ON I.`port_id` = L.`port_id` ';
453    }
454    $query .= 'LEFT JOIN `devices` AS D ON I.`device_id` = D.`device_id` ';
455    $query .= "WHERE D.`status` = 1 AND D.ignore = 0 AND I.ignore = 0 AND I.deleted = 0 AND I.`ifAdminStatus` = 'up' AND (I.`ifOperStatus` = 'lowerLayerDown' OR I.`ifOperStatus` = 'down') ";
456    if ($options['neighbours'])
457    {
458      $query .= ' AND L.`active` = 1 ';
459    }
460    $query .= $query_port_permitted;
461    $query .= ' AND I.`ifLastChange` >= DATE_SUB(NOW(), INTERVAL '.$max_interval.' HOUR) ';
462    if ($options['neighbours'])
463    {
464      $query .= 'GROUP BY L.`port_id` ';
465    }
466    $query .= 'ORDER BY I.`ifLastChange` DESC, D.`hostname` ASC, I.`ifDescr` * 1 ASC ';
467    $entries = dbFetchRows($query);
468    $i = 1;
469    foreach ($entries as $port)
470    {
471      if ($i > $max_count)
472      {
473        // Limit to 200 ports on overview page
474        break;
475      }
476      humanize_port($port);
477      $boxes[] = array('sev' => 50,
478                       'class' => 'Port',
479                       'event' => 'Down',
480                       'device_link' => generate_device_link($port, short_hostname($port['hostname'])),
481                       'entity_link' => generate_port_link($port, short_ifname($port['port_label'], 13)),
482                       'time' => format_uptime($config['time']['now'] - strtotime($port['ifLastChange'])),
483                       'location' => $device['location'],
484                       'icon_tag' => '<i class="' . $config['entities']['port']['icon'] . '"></i>');
485    }
486  }
487
488
489  // Ports Errors (only deltas)
490  if ($options['errors'])
491  {
492
493    foreach ($GLOBALS['cache']['ports']['errored'] as $port_id)
494    {
495      if (in_array($port_id, $GLOBALS['cache']['ports']['ignored'])) { continue; } // Skip ignored ports
496      if (in_array($port['ifType'], $config['ports']['ignore_errors_iftype'])) { continue; } // Skip iftypes we ignore
497
498      $port   = get_port_by_id($port_id);
499      $device = device_by_id_cache($port['device_id']);
500      humanize_port($port);
501
502      if ($port['ifInErrors_delta'])  { $port['text'][]  = 'Rx: ' . format_number($port['ifInErrors_delta']) . ' (' . format_number($port['ifInErrors_rate']) . '/s)'; }
503      if ($port['ifOutErrors_delta']) { $port['text'][] = 'Tx: ' . format_number($port['ifOutErrors_delta']) . ' ('  . format_number($port['ifOutErrors_rate']) . '/s)'; }
504
505      $port['string'] = implode(', ', $port['text']);
506
507      if($port['ifInErrors_rate'] > 1 || $port['ifOutErrors_rate'] > 1) { $sev = 70; } else { $sev = 45; }
508
509      $boxes[] = array('sev' => $sev,
510                       'class' => 'Port',
511                       'event' => 'Errors',
512                       'device_link' => generate_device_link($device, short_hostname($device['hostname'])),
513                       'entity_link' => generate_port_link($port, short_ifname($port['port_label'], 13)),
514                       'time' => $port['string'],
515                       'location' => $device['location'],
516                       'icon_tag' => '<i class="' . $config['entities']['port']['icon'] . '"></i>');
517    }
518  }
519
520  // Services
521  if ($options['services'])
522  {
523    $query = 'SELECT * FROM `services` AS S ';
524    $query .= 'LEFT JOIN `devices` AS D ON S.`device_id` = D.`device_id` ';
525    $query .= "WHERE S.`service_status` = 'down' AND S.`service_ignore` = 0";
526    $query .= $query_device_permitted;
527    $query .= 'ORDER BY D.`hostname` ASC';
528    $entries = dbFetchRows($query);
529    foreach ($entries as $service)
530    {
531      $boxes[] = array('sev' => 50,
532                       'class' => 'Service',
533                       'event' => 'Down',
534                       'device_link' => generate_device_link($service, short_hostname($service['hostname'])),
535                       'entity_link' => $service['service_type'],
536                       'time' => format_uptime($config['time']['now'] - strtotime($service['service_changed']), 'short'),
537                       'location' => $device['location'],
538                       'icon_tag' => '<i class="' . $config['entities']['service']['icon'] . '"></i>');
539    }
540  }
541
542  // BGP
543  if ($options['bgp'])
544  {
545    if (isset($config['enable_bgp']) && $config['enable_bgp'])
546    {
547      $query = 'SELECT * FROM `bgpPeers` AS B ';
548      $query .= 'LEFT JOIN `devices` AS D ON B.`device_id` = D.`device_id` ';
549      //$query .= 'LEFT JOIN `bgpPeers-state` AS BS ON B.`bgpPeer_id` = BS.`bgpPeer_id` ';
550      $query .= "WHERE D.`status` = 1 AND (`bgpPeerAdminStatus` = 'start' OR `bgpPeerAdminStatus` = 'running') AND `bgpPeerState` != 'established' ";
551      $query .= $query_device_permitted;
552      $query .= 'ORDER BY D.`hostname` ASC';
553      $entries = dbFetchRows($query);
554      foreach ($entries as $peer)
555      {
556        humanize_bgp($peer);
557        $peer_ip = generate_entity_link("bgp_peer", $peer, $peer['human_remoteip']);
558
559        $peer['wide'] = (strstr($peer['bgpPeerRemoteAddr'], ':')) ? TRUE : FALSE;
560        $boxes[] = array('sev' => 75,
561                         'class' => 'BGP Session',
562                         'event' => 'Down',
563                         'device_link' => generate_device_link($peer, short_hostname($peer['hostname'])),
564                         'entity_link' => $peer_ip,
565                         'wide' => $peer['wide'],
566                         'time' => format_uptime($peer['bgpPeerFsmEstablishedTime'], 'short-3'),
567                         'location' => $device['location'],
568                         'icon_tag' => '<i class="' . $config['entities']['bgp_peer']['icon'] . '"></i>');
569      }
570    }
571  }
572
573  // Return boxes array
574  return $boxes;
575}
576
577// EOF
578