You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

258 lines
6.9 KiB

<?php
/*
** Zabbix
** Copyright (C) 2001-2023 Zabbix SIA
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**/
/**
* A class to display discovery table as a screen element.
*/
class CScreenDiscovery extends CScreenBase {
/**
* Data
*
* @var array
*/
protected $data = [];
/**
* Init screen data.
*
* @param array $options
* @param array $options['data']
*/
public function __construct(array $options = []) {
parent::__construct($options);
$this->data = $options['data'];
}
/**
* Process screen.
*
* @return CDiv (screen inside container)
*/
public function get() {
$this->dataId = 'discovery';
$sort_field = $this->data['sort'];
$sort_order = $this->data['sortorder'];
$drules = API::DRule()->get([
'output' => ['druleid', 'name'],
'selectDHosts' => ['dhostid', 'status', 'lastup', 'lastdown'],
'druleids' => (array_key_exists('filter_druleids', $this->data) && $this->data['filter_druleids'])
? $this->data['filter_druleids']
: null,
'filter' => ['status' => DRULE_STATUS_ACTIVE],
'preservekeys' => true
]);
order_result($drules, 'name');
$dservices = API::DService()->get([
'output' => ['dserviceid', 'port', 'status', 'lastup', 'lastdown', 'dcheckid', 'ip', 'dns'],
'selectHosts' => ['hostid', 'name', 'status'],
'druleids' => array_keys($drules),
'sortfield' => $sort_field,
'sortorder' => $sort_order,
'limitSelects' => 1,
'preservekeys' => true
]);
// user macros
$macros = API::UserMacro()->get([
'output' => ['macro', 'value', 'type'],
'globalmacro' => true
]);
$macros = zbx_toHash($macros, 'macro');
$dchecks = API::DCheck()->get([
'output' => ['type', 'key_', 'allow_redirect'],
'dserviceids' => array_keys($dservices),
'preservekeys' => true
]);
// services
$services = [];
foreach ($dservices as $dservice) {
$key_ = $dchecks[$dservice['dcheckid']]['key_'];
if ($key_ !== '') {
if (array_key_exists($key_, $macros)) {
$key_ = CMacrosResolverGeneral::getMacroValue($macros[$key_]);
}
$key_ = ': '.$key_;
}
$allow_redirect = ($dchecks[$dservice['dcheckid']]['allow_redirect'] == 1)
? ' "'._('allow redirect').'"'
: '';
$service_name = discovery_check_type2str($dchecks[$dservice['dcheckid']]['type']).
discovery_port2str($dchecks[$dservice['dcheckid']]['type'], $dservice['port']).$key_.$allow_redirect;
$services[$service_name] = 1;
}
ksort($services);
$dhosts = API::DHost()->get([
'output' => ['dhostid'],
'selectDServices' => ['dserviceid'],
'druleids' => array_keys($drules),
'preservekeys' => true
]);
$header = [
make_sorting_header(_('Discovered device'), 'ip', $sort_field, $sort_order,
'zabbix.php?action=discovery.view'
),
_('Monitored host'),
_('Uptime').'/'._('Downtime')
];
foreach ($services as $name => $foo) {
$header[] = (new CColHeader($name))
->addClass('vertical_rotation')
->setTitle($name);
}
// create table
$table = (new CTableInfo())
->makeVerticalRotation()
->setHeader($header);
foreach ($drules as $drule) {
$discovery_info = [];
foreach ($drule['dhosts'] as $dhost) {
if ($dhost['status'] == DHOST_STATUS_DISABLED) {
$hclass = 'disabled';
$htime = $dhost['lastdown'];
}
else {
$hclass = 'enabled';
$htime = $dhost['lastup'];
}
// $primary_ip stores the primary host ip of the dhost
$primary_ip = '';
foreach ($dhosts[$dhost['dhostid']]['dservices'] as $dservice) {
$dservice = $dservices[$dservice['dserviceid']];
$hostName = '';
$host = reset($dservices[$dservice['dserviceid']]['hosts']);
if ($host) {
$hostName = $host['name'];
}
if ($primary_ip !== '') {
if ($primary_ip === $dservice['ip']) {
$htype = 'primary';
}
else {
$htype = 'slave';
}
}
else {
$primary_ip = $dservice['ip'];
$htype = 'primary';
}
if (!array_key_exists($dservice['ip'], $discovery_info)) {
$discovery_info[$dservice['ip']] = [
'ip' => $dservice['ip'],
'dns' => $dservice['dns'],
'type' => $htype,
'class' => $hclass,
'host' => $hostName,
'time' => $htime
];
}
if ($dservice['status'] == DSVC_STATUS_DISABLED) {
$class = ZBX_STYLE_INACTIVE_BG;
$time = 'lastdown';
}
else {
$class = null;
$time = 'lastup';
}
$key_ = $dchecks[$dservice['dcheckid']]['key_'];
if ($key_ !== '') {
if (array_key_exists($key_, $macros)) {
$key_ = CMacrosResolverGeneral::getMacroValue($macros[$key_]);
}
$key_ = NAME_DELIMITER.$key_;
}
$allow_redirect = ($dchecks[$dservice['dcheckid']]['allow_redirect'] == 1)
? ' "'._('allow redirect').'"'
: '';
$service_name = discovery_check_type2str($dchecks[$dservice['dcheckid']]['type']).
discovery_port2str($dchecks[$dservice['dcheckid']]['type'], $dservice['port']).$key_.
$allow_redirect;
$discovery_info[$dservice['ip']]['services'][$service_name] = [
'class' => $class,
'time' => $dservice[$time]
];
}
}
if ($discovery_info) {
$col = new CCol(
[bold($drule['name']), NBSP(), '('._n('%d device', '%d devices', count($discovery_info)).')']
);
$col->setColSpan(count($services) + 3);
$table->addRow($col);
}
order_result($discovery_info, $sort_field, $sort_order);
foreach ($discovery_info as $ip => $h_data) {
$dns = ($h_data['dns'] === '') ? '' : ' ('.$h_data['dns'].')';
$row = [
($h_data['type'] === 'primary')
? (new CSpan($ip.$dns))->addClass($h_data['class'])
: new CSpan([NBSP(), NBSP(), $ip.$dns]),
new CSpan(array_key_exists('host', $h_data) ? $h_data['host'] : ''),
(new CSpan((($h_data['time'] == 0 || $h_data['type'] === 'slave')
? ''
: convertUnits(['value' => time() - $h_data['time'], 'units' => 'uptime'])))
)
->addClass($h_data['class'])
];
foreach ($services as $name => $foo) {
$row[] = array_key_exists($name, $h_data['services'])
? (new CCol(zbx_date2age($h_data['services'][$name]['time'])))
->addClass($h_data['services'][$name]['class'])
: '';
}
$table->addRow($row);
}
}
return $this->getOutput($table, true, $this->data);
}
}