<?php declare(strict_types = 0); /* ** Copyright (C) 2001-2025 Zabbix SIA ** ** This program is free software: you can redistribute it and/or modify it under the terms of ** the GNU Affero General Public License as published by the Free Software Foundation, version 3. ** ** 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 Affero General Public License for more details. ** ** You should have received a copy of the GNU Affero General Public License along with this program. ** If not, see <https://www.gnu.org/licenses/>. **/ /** * @var CView $this * @var array $data */ $this->addJsFile('class.tagfilteritem.js'); $this->addJsFile('items.js'); $this->addJsFile('multilineinput.js'); $this->includeJsFile('configuration.host.list.js.php'); if ($data['uncheck']) { uncheckTableRows('hosts'); } $html_page = (new CHtmlPage()) ->setTitle(_('Hosts')) ->setDocUrl(CDocHelper::getUrl(CDocHelper::DATA_COLLECTION_HOST_LIST)) ->setControls((new CTag('nav', true, (new CList()) ->addItem( (new CSimpleButton(_('Create host'))) ->onClick('view.createHost()') ) ->addItem( (new CButton('form', _('Import'))) ->onClick( 'return PopUp("popup.import", { rules_preset: "host", '. CSRF_TOKEN_NAME.': "'.CCsrfTokenHelper::get('import'). '"}, { dialogueid: "popup_import", dialogue_class: "modal-popup-generic" });' ) ->removeId() ) ))->setAttribute('aria-label', _('Content controls')) ); $action_url = (new CUrl('zabbix.php'))->setArgument('action', $data['action']); $filter = (new CFilter()) ->setResetUrl($action_url) ->setProfile($data['profileIdx']) ->setActiveTab($data['active_tab']) ->addVar('action', $data['action'], 'filter_action') ->addFilterTab(_('Filter'), [ (new CFormGrid()) ->addClass(CFormGrid::ZBX_STYLE_FORM_GRID_LABEL_WIDTH_TRUE) ->addItem([ new CLabel(_('Host groups'), 'filter_groups__ms'), new CFormField( (new CMultiSelect([ 'name' => 'filter_groups[]', 'object_name' => 'hostGroup', 'data' => $data['filter']['groups'], 'popup' => [ 'parameters' => [ 'srctbl' => 'host_groups', 'srcfld1' => 'groupid', 'dstfrm' => 'zbx_filter', 'dstfld1' => 'filter_groups_', 'with_hosts' => true, 'editable' => true, 'enrich_parent_groups' => true ] ] ]))->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH) ) ]) ->addItem([ new CLabel(_('Templates'), 'filter_templates__ms'), new CFormField( (new CMultiSelect([ 'name' => 'filter_templates[]', 'object_name' => 'templates', 'data' => $data['filter']['templates'], 'popup' => [ 'parameters' => [ 'srctbl' => 'templates', 'srcfld1' => 'hostid', 'srcfld2' => 'host', 'dstfrm' => 'zbx_filter', 'dstfld1' => 'filter_templates_' ] ] ]))->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH) ) ]) ->addItem([ new CLabel(_('Name'), 'filter_host'), new CFormField( (new CTextBox('filter_host', $data['filter']['host']))->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH) ) ]) ->addItem([ new CLabel(_('DNS'), 'filter_dns'), new CFormField( (new CTextBox('filter_dns', $data['filter']['dns']))->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH) ) ]) ->addItem([ new CLabel(_('IP'), 'filter_ip'), new CFormField( (new CTextBox('filter_ip', $data['filter']['ip']))->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH) ) ]) ->addItem([ new CLabel(_('Port'), 'filter_port'), new CFormField( (new CTextBox('filter_port', $data['filter']['port']))->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH) ) ]), (new CFormGrid()) ->addClass(CFormGrid::ZBX_STYLE_FORM_GRID_LABEL_WIDTH_TRUE) ->addItem([ new CLabel(_('Status'), 'filter_status'), new CFormField( (new CRadioButtonList('filter_status', (int) $data['filter']['status'])) ->addValue(_('Any'), -1) ->addValue(_('Enabled'), HOST_STATUS_MONITORED) ->addValue(_('Disabled'), HOST_STATUS_NOT_MONITORED) ->setModern(true) ) ]) ->addItem([ new CLabel(_('Monitored by'), 'filter_monitored_by'), new CFormField( (new CRadioButtonList('filter_monitored_by', (int) $data['filter']['monitored_by'])) ->addValue(_('Any'), ZBX_MONITORED_BY_ANY) ->addValue(_('Server'), ZBX_MONITORED_BY_SERVER) ->addValue(_('Proxy'), ZBX_MONITORED_BY_PROXY) ->addValue(_('Proxy group'), ZBX_MONITORED_BY_PROXY_GROUP) ->setModern() ) ]) ->addItem([ (new CLabel(_('Proxies'), 'filter_proxyids__ms'))->addClass('js-filter-proxyids'), (new CFormField( (new CMultiSelect([ 'name' => 'filter_proxyids[]', 'object_name' => 'proxies', 'data' => $data['proxies_ms'], 'popup' => [ 'parameters' => [ 'srctbl' => 'proxies', 'srcfld1' => 'proxyid', 'srcfld2' => 'name', 'dstfrm' => 'zbx_filter', 'dstfld1' => 'filter_proxyids_' ] ] ]))->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH) ))->addClass('js-filter-proxyids') ]) ->addItem([ (new CLabel(_('Proxy groups'), 'filter_proxy_groupids__ms'))->addClass('js-filter-proxy-groupids'), (new CFormField( (new CMultiSelect([ 'name' => 'filter_proxy_groupids[]', 'object_name' => 'proxy_groups', 'data' => $data['proxy_groups_ms'], 'popup' => [ 'parameters' => [ 'srctbl' => 'proxy_groups', 'srcfld1' => 'proxy_groupid', 'srcfld2' => 'name', 'dstfrm' => 'zbx_filter', 'dstfld1' => 'filter_proxy_groupids_' ] ] ]))->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH) ))->addClass('js-filter-proxy-groupids') ]) ->addItem([ new CLabel(_('Tags')), new CFormField( CTagFilterFieldHelper::getTagFilterField([ 'evaltype' => $data['filter']['evaltype'], 'tags' => $data['filter']['tags'] ]) ) ]) ]); $html_page->addItem($filter); // table hosts $form = (new CForm())->setName('hosts'); $header_checkbox = (new CCheckBox('all_hosts'))->onClick("checkAll('".$form->getName()."', 'all_hosts', 'hostids');"); $show_monitored_by = $data['filter']['monitored_by'] == ZBX_MONITORED_BY_ANY || $data['filter']['monitored_by'] == ZBX_MONITORED_BY_PROXY || $data['filter']['monitored_by'] == ZBX_MONITORED_BY_PROXY_GROUP; $header_sortable_name = make_sorting_header(_('Name'), 'name', $data['sortField'], $data['sortOrder'], $action_url->getUrl() ); $header_sortable_status = make_sorting_header(_('Status'), 'status', $data['sortField'], $data['sortOrder'], $action_url->getUrl() ); $table = (new CTableInfo()) ->setHeader([ (new CColHeader($header_checkbox))->addClass(ZBX_STYLE_CELL_WIDTH), $header_sortable_name, _('Items'), _('Triggers'), _('Graphs'), _('Discovery'), _('Web'), _('Interface'), $show_monitored_by ? _('Proxy') : null, _('Templates'), $header_sortable_status, _('Availability'), _('Agent encryption'), _('Info'), _('Tags') ]) ->setPageNavigation($data['paging']); $current_time = time(); $csrf_token = CCsrfTokenHelper::get('host'); foreach ($data['hosts'] as $host) { // Select an interface from the list with highest priority. $interface = null; if ($host['interfaces']) { foreach (CItem::INTERFACE_TYPES_BY_PRIORITY as $interface_type) { $host_interfaces = array_filter($host['interfaces'], function(array $host_interface) use ($interface_type) { return ($host_interface['type'] == $interface_type); }); if ($host_interfaces) { $interface = reset($host_interfaces); break; } } } $description = []; if ($host['flags'] == ZBX_FLAG_DISCOVERY_CREATED) { if ($host['discoveryRule']) { if ($host['is_discovery_rule_editable']) { $description[] = (new CLink($host['discoveryRule']['name'], (new CUrl('host_prototypes.php')) ->setArgument('form', 'update') ->setArgument('parent_discoveryid', $host['discoveryRule']['itemid']) ->setArgument('hostid', $host['hostDiscovery']['parent_hostid']) ->setArgument('context', 'host') )) ->addClass(ZBX_STYLE_LINK_ALT) ->addClass(ZBX_STYLE_ORANGE); } else { $description[] = (new CSpan($host['discoveryRule']['name']))->addClass(ZBX_STYLE_ORANGE); } } else { $description[] = (new CSpan(_('Inaccessible discovery rule')))->addClass(ZBX_STYLE_ORANGE); } $description[] = NAME_DELIMITER; } $description[] = (new CLink($host['name'], (new CUrl('zabbix.php')) ->setArgument('action', 'host.edit') ->setArgument('hostid', $host['hostid']) )) ->setAttribute('data-hostid', $host['hostid']) ->onClick('view.editHost(event, this.dataset.hostid);'); $maintenance_icon = false; if ($host['status'] == HOST_STATUS_MONITORED) { if ($host['maintenance_status'] == HOST_MAINTENANCE_STATUS_ON) { if (array_key_exists($host['maintenanceid'], $data['maintenances'])) { $maintenance = $data['maintenances'][$host['maintenanceid']]; $maintenance_icon = makeMaintenanceIcon($host['maintenance_type'], $maintenance['name'], $maintenance['description'] ); } else { $maintenance_icon = makeMaintenanceIcon($host['maintenance_type'], _('Inaccessible maintenance'), ''); } } $toggle_status_link = (new CLinkAction(_('Enabled'))) ->addClass(ZBX_STYLE_GREEN) ->addClass('js-disable-host') ->setAttribute('data-hostid', $host['hostid']); } else { $toggle_status_link = (new CLinkAction(_('Disabled'))) ->addClass(ZBX_STYLE_RED) ->addClass('js-enable-host') ->setAttribute('data-hostid', $host['hostid']); } if ($maintenance_icon) { $description[] = $maintenance_icon; } order_result($host['parentTemplates'], 'name'); $hostTemplates = []; $i = 0; foreach ($host['parentTemplates'] as $template) { $i++; if ($i > $data['config']['max_in_table']) { $hostTemplates[] = [' ', HELLIP()]; break; } if (array_key_exists($template['templateid'], $data['writable_templates']) && $data['user']['can_edit_templates']) { $caption = [ (new CLink($template['name'])) ->addClass('js-edit-template') ->setAttribute('data-templateid', $template['templateid']) ->addClass(ZBX_STYLE_LINK_ALT) ->addClass(ZBX_STYLE_GREY) ]; } else { $caption = [ (new CSpan($template['name']))->addClass(ZBX_STYLE_GREY) ]; } $parent_templates = $data['templates'][$template['templateid']]['parentTemplates']; if ($parent_templates) { order_result($parent_templates, 'name'); $caption[] = ' ('; foreach ($parent_templates as $parent_template) { if (array_key_exists($parent_template['templateid'], $data['writable_templates']) && $data['user']['can_edit_templates']) { $caption[] = (new CLink($parent_template['name'])) ->addClass('js-edit-template') ->setAttribute('data-templateid', $parent_template['templateid']) ->addClass(ZBX_STYLE_LINK_ALT) ->addClass(ZBX_STYLE_GREY); } else { $caption[] = (new CSpan($parent_template['name']))->addClass(ZBX_STYLE_GREY); } $caption[] = ', '; } array_pop($caption); $caption[] = ')'; } if ($hostTemplates) { $hostTemplates[] = ', '; } $hostTemplates[] = $caption; } $info_icons = []; $disable_source = $host['status'] == HOST_STATUS_NOT_MONITORED && $host['hostDiscovery'] ? $host['hostDiscovery']['disable_source'] : ''; if ($host['flags'] == ZBX_FLAG_DISCOVERY_CREATED && $host['hostDiscovery']['status'] == ZBX_LLD_STATUS_LOST) { $info_icons[] = getLldLostEntityIndicator($current_time, $host['hostDiscovery']['ts_delete'], $host['hostDiscovery']['ts_disable'], $disable_source, $host['status'] == HOST_STATUS_NOT_MONITORED, _('host') ); } if ($host['tls_connect'] == HOST_ENCRYPTION_NONE && ($host['tls_accept'] & HOST_ENCRYPTION_NONE) == HOST_ENCRYPTION_NONE && ($host['tls_accept'] & HOST_ENCRYPTION_PSK) != HOST_ENCRYPTION_PSK && ($host['tls_accept'] & HOST_ENCRYPTION_CERTIFICATE) != HOST_ENCRYPTION_CERTIFICATE) { $encryption = (new CDiv((new CSpan(_('None')))->addClass(ZBX_STYLE_STATUS_GREEN))) ->addClass(ZBX_STYLE_STATUS_CONTAINER); } else { // Incoming encryption. if ($host['tls_connect'] == HOST_ENCRYPTION_NONE) { $in_encryption = (new CSpan(_('None')))->addClass(ZBX_STYLE_STATUS_GREEN); } elseif ($host['tls_connect'] == HOST_ENCRYPTION_PSK) { $in_encryption = (new CSpan(_('PSK')))->addClass(ZBX_STYLE_STATUS_GREEN); } else { $in_encryption = (new CSpan(_('CERT')))->addClass(ZBX_STYLE_STATUS_GREEN); } // Outgoing encryption. $out_encryption = []; if (($host['tls_accept'] & HOST_ENCRYPTION_NONE) == HOST_ENCRYPTION_NONE) { $out_encryption[] = (new CSpan(_('None')))->addClass(ZBX_STYLE_STATUS_GREEN); } else { $out_encryption[] = (new CSpan(_('None')))->addClass(ZBX_STYLE_STATUS_GREY); } if (($host['tls_accept'] & HOST_ENCRYPTION_PSK) == HOST_ENCRYPTION_PSK) { $out_encryption[] = (new CSpan(_('PSK')))->addClass(ZBX_STYLE_STATUS_GREEN); } else { $out_encryption[] = (new CSpan(_('PSK')))->addClass(ZBX_STYLE_STATUS_GREY); } if (($host['tls_accept'] & HOST_ENCRYPTION_CERTIFICATE) == HOST_ENCRYPTION_CERTIFICATE) { $out_encryption[] = (new CSpan(_('CERT')))->addClass(ZBX_STYLE_STATUS_GREEN); } else { $out_encryption[] = (new CSpan(_('CERT')))->addClass(ZBX_STYLE_STATUS_GREY); } $encryption = (new CDiv([new CSpan($in_encryption), ' ', new CSpan($out_encryption)])) ->addClass(ZBX_STYLE_STATUS_CONTAINER) ->addClass(ZBX_STYLE_NOWRAP); } $monitored_by = null; if ($show_monitored_by) { if ($host['monitored_by'] == ZBX_MONITORED_BY_PROXY) { $monitored_by = $data['user']['can_edit_proxies'] ? (new CLink($data['proxies'][$host['proxyid']]['name'])) ->addClass('js-edit-proxy') ->setAttribute('data-proxyid', $host['proxyid']) : $data['proxies'][$host['proxyid']]['name']; } elseif ($host['monitored_by'] == ZBX_MONITORED_BY_PROXY_GROUP) { $monitored_by = $data['user']['can_edit_proxy_groups'] ? (new CLink($data['proxy_groups'][$host['proxy_groupid']]['name'])) ->addClass(ZBX_STYLE_LINK_ALT) ->addClass(ZBX_STYLE_GREY) ->addClass('js-edit-proxy-group') ->setAttribute('data-proxy_groupid', $host['proxy_groupid']) : $data['proxy_groups'][$host['proxy_groupid']]['name']; if ($host['assigned_proxyid'] != 0) { $monitored_by = [$monitored_by]; $monitored_by[] = NAME_DELIMITER; $monitored_by[] = $data['user']['can_edit_proxies'] ? (new CLink($data['proxies'][$host['assigned_proxyid']]['name'])) ->addClass('js-edit-proxy') ->setAttribute('data-proxyid', $host['assigned_proxyid']) : $data['proxies'][$host['assigned_proxyid']]['name']; } } else { $monitored_by = ''; } } $disabled_by_lld = $disable_source == ZBX_DISABLE_SOURCE_LLD; $table->addRow([ new CCheckBox('hostids['.$host['hostid'].']', $host['hostid']), (new CCol($description))->addClass(ZBX_STYLE_WORDBREAK), [ new CLink(_('Items'), (new CUrl('zabbix.php')) ->setArgument('action', 'item.list') ->setArgument('context', 'host') ->setArgument('filter_set', '1') ->setArgument('filter_hostids', [$host['hostid']]) ), CViewHelper::showNum($host['items']) ], [ new CLink(_('Triggers'), (new CUrl('zabbix.php')) ->setArgument('action', 'trigger.list') ->setArgument('filter_set', '1') ->setArgument('filter_hostids', [$host['hostid']]) ->setArgument('context', 'host') ), CViewHelper::showNum($host['triggers']) ], [ new CLink(_('Graphs'), (new CUrl('graphs.php')) ->setArgument('filter_set', '1') ->setArgument('filter_hostids', [$host['hostid']]) ->setArgument('context', 'host') ), CViewHelper::showNum($host['graphs']) ], [ new CLink(_('Discovery'), (new CUrl('host_discovery.php')) ->setArgument('filter_set', '1') ->setArgument('filter_hostids', [$host['hostid']]) ->setArgument('context', 'host') ), CViewHelper::showNum($host['discoveries']) ], [ new CLink(_('Web'), (new CUrl('httpconf.php')) ->setArgument('filter_set', '1') ->setArgument('filter_hostids', [$host['hostid']]) ->setArgument('context', 'host') ), CViewHelper::showNum($host['httpTests']) ], (new CCol(getHostInterface($interface)))->addClass(ZBX_STYLE_WORDBREAK), (new CCol($monitored_by))->addClass(ZBX_STYLE_WORDBREAK), (new CCol($hostTemplates))->addClass(ZBX_STYLE_WORDBREAK), [ $toggle_status_link, $disabled_by_lld ? makeDescriptionIcon(_('Disabled automatically by an LLD rule.')) : null ], getHostAvailabilityTable($host['interfaces'], $host['has_passive_checks']), $encryption, makeInformationList($info_icons), $data['tags'][$host['hostid']] ]); } $status_toggle_url = (new CUrl('zabbix.php')) ->setArgument('action', 'popup.massupdate.host') ->setArgument(CSRF_TOKEN_NAME, $csrf_token) ->setArgument('visible[status]', 1) ->setArgument('update', 1) ->setArgument('backurl', (new CUrl('zabbix.php')) ->setArgument('action', 'host.list') ->setArgument('page', CPagerHelper::loadPage('host.list', null)) ->getUrl() ); $form->addItem([ $table, new CActionButtonList('action', 'hostids', [ 'host.enable' => [ 'content' => (new CSimpleButton(_('Enable'))) ->addClass(ZBX_STYLE_BTN_ALT) ->addClass('js-massenable-host') ->addClass('js-no-chkbxrange') ], 'host.disable' => [ 'content' => (new CSimpleButton(_('Disable'))) ->addClass(ZBX_STYLE_BTN_ALT) ->addClass('js-massdisable-host') ->addClass('js-no-chkbxrange') ], 'host.export' => [ 'content' => new CButtonExport('export.hosts', $action_url ->setArgument('page', ($data['page'] == 1) ? null : $data['page']) ->getUrl() ) ], 'popup.massupdate.host' => [ 'content' => (new CSimpleButton(_('Mass update'))) ->addClass(ZBX_STYLE_BTN_ALT) ->addClass('js-massupdate-host') ->addClass('js-no-chkbxrange') ], 'host.massdelete' => [ 'content' => (new CSimpleButton(_('Delete'))) ->addClass(ZBX_STYLE_BTN_ALT) ->addClass('js-massdelete-host') ->addClass('js-no-chkbxrange') ] ], 'hosts') ]); $html_page ->addItem($form) ->show(); (new CScriptTag(' view.init('.json_encode([ 'applied_filter_groupids' => array_keys($data['filter']['groups']), 'csrf_token' => $csrf_token ]).'); ')) ->setOnDocumentReady() ->show();