1<?php
2/*
3** Zabbix
4** Copyright (C) 2001-2021 Zabbix SIA
5**
6** This program is free software; you can redistribute it and/or modify
7** it under the terms of the GNU General Public License as published by
8** the Free Software Foundation; either version 2 of the License, or
9** (at your option) any later version.
10**
11** This program is distributed in the hope that it will be useful,
12** but WITHOUT ANY WARRANTY; without even the implied warranty of
13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14** GNU General Public License for more details.
15**
16** You should have received a copy of the GNU General Public License
17** along with this program; if not, write to the Free Software
18** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19**/
20
21
22/**
23 * @var CView $this
24 */
25
26require_once dirname(__FILE__).'/js/configuration.host.list.js.php';
27
28$widget = (new CWidget())
29	->setTitle(_('Hosts'))
30	->setControls((new CTag('nav', true, (new CList())
31			->addItem(new CRedirectButton(_('Create host'), (new CUrl('hosts.php'))
32				->setArgument('form', 'create')
33				->setArgument('groupids', array_keys($data['filter']['groups']))
34				->getUrl()
35			))
36			->addItem(
37				(new CButton('form', _('Import')))
38					->onClick('return PopUp("popup.import", {rules_preset: "host"}, null, this);')
39					->removeId()
40			)
41		))->setAttribute('aria-label', _('Content controls'))
42	);
43
44$filter_tags = $data['filter']['tags'];
45if (!$filter_tags) {
46	$filter_tags = [['tag' => '', 'value' => '', 'operator' => TAG_OPERATOR_LIKE]];
47}
48
49$filter_tags_table = CTagFilterFieldHelper::getTagFilterField([
50	'evaltype' => $data['filter']['evaltype'],
51	'tags' => $filter_tags
52]);
53
54// filter
55$filter = new CFilter(new CUrl('hosts.php'));
56$filter
57	->setProfile($data['profileIdx'])
58	->setActiveTab($data['active_tab'])
59	->addFilterTab(_('Filter'), [
60		(new CFormList())
61			->addRow(
62				(new CLabel(_('Host groups'), 'filter_groups__ms')),
63				(new CMultiSelect([
64					'name' => 'filter_groups[]',
65					'object_name' => 'hostGroup',
66					'data' => $data['filter']['groups'],
67					'popup' => [
68						'parameters' => [
69							'srctbl' => 'host_groups',
70							'srcfld1' => 'groupid',
71							'dstfrm' => $filter->getName(),
72							'dstfld1' => 'filter_groups_',
73							'real_hosts' => 1,
74							'editable' => 1,
75							'enrich_parent_groups' => 1
76						]
77					]
78				]))->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH)
79			)
80			->addRow(
81				(new CLabel(_('Templates'), 'filter_templates__ms')),
82				(new CMultiSelect([
83					'name' => 'filter_templates[]',
84					'object_name' => 'templates',
85					'data' => $data['filter']['templates'],
86					'popup' => [
87						'parameters' => [
88							'srctbl' => 'templates',
89							'srcfld1' => 'hostid',
90							'srcfld2' => 'host',
91							'dstfrm' => $filter->getName(),
92							'dstfld1' => 'filter_templates_'
93						]
94					]
95				]))->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH)
96			)
97			->addRow(_('Name'),
98				(new CTextBox('filter_host', $data['filter']['host']))->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH)
99			)
100			->addRow(_('DNS'),
101				(new CTextBox('filter_dns', $data['filter']['dns']))->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH)
102			)
103			->addRow(_('IP'),
104				(new CTextBox('filter_ip', $data['filter']['ip']))->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH)
105			)
106			->addRow(_('Port'),
107				(new CTextBox('filter_port', $data['filter']['port']))->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH)
108			),
109		(new CFormList())
110			->addRow(_('Monitored by'),
111				(new CRadioButtonList('filter_monitored_by', (int) $data['filter']['monitored_by']))
112					->addValue(_('Any'), ZBX_MONITORED_BY_ANY)
113					->addValue(_('Server'), ZBX_MONITORED_BY_SERVER)
114					->addValue(_('Proxy'), ZBX_MONITORED_BY_PROXY)
115					->setModern(true)
116			)
117			->addRow(
118				(new CLabel(_('Proxy'), 'filter_proxyids__ms')),
119				(new CMultiSelect([
120					'name' => 'filter_proxyids[]',
121					'object_name' => 'proxies',
122					'data' => $data['proxies_ms'],
123					'disabled' => ($data['filter']['monitored_by'] != ZBX_MONITORED_BY_PROXY),
124					'popup' => [
125						'parameters' => [
126							'srctbl' => 'proxies',
127							'srcfld1' => 'proxyid',
128							'srcfld2' => 'host',
129							'dstfrm' => 'zbx_filter',
130							'dstfld1' => 'filter_proxyids_'
131						]
132					]
133				]))->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH)
134			)
135			->addRow(_('Tags'), $filter_tags_table)
136	]);
137
138$widget->addItem($filter);
139
140// table hosts
141$form = (new CForm())->setName('hosts');
142
143$table = (new CTableInfo())
144	->setHeader([
145		(new CColHeader(
146			(new CCheckBox('all_hosts'))->onClick("checkAll('".$form->getName()."', 'all_hosts', 'hosts');")
147		))->addClass(ZBX_STYLE_CELL_WIDTH),
148		make_sorting_header(_('Name'), 'name', $data['sortField'], $data['sortOrder'], 'hosts.php'),
149		_('Items'),
150		_('Triggers'),
151		_('Graphs'),
152		_('Discovery'),
153		_('Web'),
154		_('Interface'),
155		($data['filter']['monitored_by'] == ZBX_MONITORED_BY_PROXY
156				|| $data['filter']['monitored_by'] == ZBX_MONITORED_BY_ANY) ? _('Proxy') : null,
157		_('Templates'),
158		make_sorting_header(_('Status'), 'status', $data['sortField'], $data['sortOrder'], 'hosts.php'),
159		_('Availability'),
160		_('Agent encryption'),
161		_('Info'),
162		_('Tags')
163	]);
164
165$current_time = time();
166
167$interface_types = [INTERFACE_TYPE_AGENT, INTERFACE_TYPE_SNMP, INTERFACE_TYPE_JMX, INTERFACE_TYPE_IPMI];
168
169foreach ($data['hosts'] as $host) {
170	// Select an interface from the list with highest priority.
171	$interface = null;
172	if ($host['interfaces']) {
173		foreach ($interface_types as $interface_type) {
174			$host_interfaces = array_filter($host['interfaces'], function(array $host_interface) use ($interface_type) {
175				return ($host_interface['type'] == $interface_type);
176			});
177			if ($host_interfaces) {
178				$interface = reset($host_interfaces);
179				break;
180			}
181		}
182	}
183
184	$description = [];
185
186	if ($host['discoveryRule']) {
187		$description[] = (new CLink(CHtml::encode($host['discoveryRule']['name']),
188			(new CUrl('host_prototypes.php'))
189				->setArgument('parent_discoveryid', $host['discoveryRule']['itemid'])
190				->setArgument('context', 'host')
191		))
192			->addClass(ZBX_STYLE_LINK_ALT)
193			->addClass(ZBX_STYLE_ORANGE);
194		$description[] = NAME_DELIMITER;
195	}
196	elseif ($host['flags'] == ZBX_FLAG_DISCOVERY_CREATED) {
197		// Discovered host which does not contain info about parent discovery rule is inaccessible for current user.
198		$description[] = (new CSpan(_('Inaccessible discovery rule')))->addClass(ZBX_STYLE_ORANGE);
199		$description[] = NAME_DELIMITER;
200	}
201
202	$description[] = new CLink(CHtml::encode($host['name']), (new CUrl('hosts.php'))
203				->setArgument('form', 'update')
204				->setArgument('hostid', $host['hostid'])
205	);
206
207	$maintenance_icon = false;
208	if ($host['status'] == HOST_STATUS_MONITORED) {
209		if ($host['maintenance_status'] == HOST_MAINTENANCE_STATUS_ON) {
210			if (array_key_exists($host['maintenanceid'], $data['maintenances'])) {
211				$maintenance = $data['maintenances'][$host['maintenanceid']];
212				$maintenance_icon = makeMaintenanceIcon($host['maintenance_type'], $maintenance['name'],
213					$maintenance['description']
214				);
215			}
216			else {
217				$maintenance_icon = makeMaintenanceIcon($host['maintenance_type'], _('Inaccessible maintenance'), '');
218			}
219		}
220
221		$statusCaption = _('Enabled');
222		$statusClass = ZBX_STYLE_GREEN;
223		$confirm_message = _('Disable host?');
224		$status_url = (new CUrl('hosts.php'))
225			->setArgument('action', 'host.massdisable')
226			->setArgument('hosts', [$host['hostid']]);
227	}
228	else {
229		$statusCaption = _('Disabled');
230		$status_url = (new CUrl('hosts.php'))
231			->setArgument('action', 'host.massenable')
232			->setArgument('hosts', [$host['hostid']]);
233		$confirm_message = _('Enable host?');
234		$statusClass = ZBX_STYLE_RED;
235	}
236
237	$status = (new CLink($statusCaption, $status_url->getUrl()))
238		->addClass(ZBX_STYLE_LINK_ACTION)
239		->addClass($statusClass)
240		->addConfirmation($confirm_message)
241		->addSID();
242
243	if ($maintenance_icon) {
244		$description[] = $maintenance_icon;
245	}
246
247	order_result($host['parentTemplates'], 'name');
248
249	$hostTemplates = [];
250	$i = 0;
251
252	foreach ($host['parentTemplates'] as $template) {
253		$i++;
254
255		if ($i > $data['config']['max_in_table']) {
256			$hostTemplates[] = ' &hellip;';
257
258			break;
259		}
260
261		if (array_key_exists($template['templateid'], $data['writable_templates'])
262				&& $data['allowed_ui_conf_templates']) {
263			$caption = [
264				(new CLink(CHtml::encode($template['name']),
265					(new CUrl('templates.php'))
266						->setArgument('form', 'update')
267						->setArgument('templateid', $template['templateid'])
268				))
269					->addClass(ZBX_STYLE_LINK_ALT)
270					->addClass(ZBX_STYLE_GREY)
271			];
272		}
273		else {
274			$caption = [
275				(new CSpan(CHtml::encode($template['name'])))->addClass(ZBX_STYLE_GREY)
276			];
277		}
278
279		$parent_templates = $data['templates'][$template['templateid']]['parentTemplates'];
280
281		if ($parent_templates) {
282			order_result($parent_templates, 'name');
283			$caption[] = ' (';
284
285			foreach ($parent_templates as $parent_template) {
286				if (array_key_exists($parent_template['templateid'], $data['writable_templates'])
287						&& $data['allowed_ui_conf_templates']) {
288					$caption[] = (new CLink(CHtml::encode($parent_template['name']),
289						(new CUrl('templates.php'))
290							->setArgument('form', 'update')
291							->setArgument('templateid', $parent_template['templateid'])
292					))
293						->addClass(ZBX_STYLE_LINK_ALT)
294						->addClass(ZBX_STYLE_GREY);
295				}
296				else {
297					$caption[] = (new CSpan(CHtml::encode($parent_template['name'])))->addClass(ZBX_STYLE_GREY);
298				}
299				$caption[] = ', ';
300			}
301			array_pop($caption);
302
303			$caption[] = ')';
304		}
305
306		if ($hostTemplates) {
307			$hostTemplates[] = ', ';
308		}
309
310		$hostTemplates[] = $caption;
311	}
312
313	$info_icons = [];
314	if ($host['flags'] == ZBX_FLAG_DISCOVERY_CREATED && $host['hostDiscovery']['ts_delete'] != 0) {
315		$info_icons[] = getHostLifetimeIndicator($current_time, $host['hostDiscovery']['ts_delete']);
316	}
317
318	if ($host['tls_connect'] == HOST_ENCRYPTION_NONE
319			&& ($host['tls_accept'] & HOST_ENCRYPTION_NONE) == HOST_ENCRYPTION_NONE
320			&& ($host['tls_accept'] & HOST_ENCRYPTION_PSK) != HOST_ENCRYPTION_PSK
321			&& ($host['tls_accept'] & HOST_ENCRYPTION_CERTIFICATE) != HOST_ENCRYPTION_CERTIFICATE) {
322		$encryption = (new CDiv((new CSpan(_('None')))->addClass(ZBX_STYLE_STATUS_GREEN)))
323			->addClass(ZBX_STYLE_STATUS_CONTAINER);
324	}
325	else {
326		// Incoming encryption.
327		if ($host['tls_connect'] == HOST_ENCRYPTION_NONE) {
328			$in_encryption = (new CSpan(_('None')))->addClass(ZBX_STYLE_STATUS_GREEN);
329		}
330		elseif ($host['tls_connect'] == HOST_ENCRYPTION_PSK) {
331			$in_encryption = (new CSpan(_('PSK')))->addClass(ZBX_STYLE_STATUS_GREEN);
332		}
333		else {
334			$in_encryption = (new CSpan(_('CERT')))->addClass(ZBX_STYLE_STATUS_GREEN);
335		}
336
337		// Outgoing encryption.
338		$out_encryption = [];
339		if (($host['tls_accept'] & HOST_ENCRYPTION_NONE) == HOST_ENCRYPTION_NONE) {
340			$out_encryption[] = (new CSpan(_('None')))->addClass(ZBX_STYLE_STATUS_GREEN);
341		}
342		else {
343			$out_encryption[] = (new CSpan(_('None')))->addClass(ZBX_STYLE_STATUS_GREY);
344		}
345
346		if (($host['tls_accept'] & HOST_ENCRYPTION_PSK) == HOST_ENCRYPTION_PSK) {
347			$out_encryption[] = (new CSpan(_('PSK')))->addClass(ZBX_STYLE_STATUS_GREEN);
348		}
349		else {
350			$out_encryption[] = (new CSpan(_('PSK')))->addClass(ZBX_STYLE_STATUS_GREY);
351		}
352
353		if (($host['tls_accept'] & HOST_ENCRYPTION_CERTIFICATE) == HOST_ENCRYPTION_CERTIFICATE) {
354			$out_encryption[] = (new CSpan(_('CERT')))->addClass(ZBX_STYLE_STATUS_GREEN);
355		}
356		else {
357			$out_encryption[] = (new CSpan(_('CERT')))->addClass(ZBX_STYLE_STATUS_GREY);
358		}
359
360		$encryption = (new CDiv([new CSpan($in_encryption), ' ', new CSpan($out_encryption)]))
361			->addClass(ZBX_STYLE_STATUS_CONTAINER)
362			->addClass(ZBX_STYLE_NOWRAP);
363	}
364
365	$table->addRow([
366		new CCheckBox('hosts['.$host['hostid'].']', $host['hostid']),
367		(new CCol($description))->addClass(ZBX_STYLE_NOWRAP),
368		[
369			new CLink(_('Items'),
370				(new CUrl('items.php'))
371					->setArgument('filter_set', '1')
372					->setArgument('filter_hostids', [$host['hostid']])
373					->setArgument('context', 'host')
374			),
375			CViewHelper::showNum($host['items'])
376		],
377		[
378			new CLink(_('Triggers'),
379				(new CUrl('triggers.php'))
380					->setArgument('filter_set', '1')
381					->setArgument('filter_hostids', [$host['hostid']])
382					->setArgument('context', 'host')
383			),
384			CViewHelper::showNum($host['triggers'])
385		],
386		[
387			new CLink(_('Graphs'),
388				(new CUrl('graphs.php'))
389					->setArgument('filter_set', '1')
390					->setArgument('filter_hostids', [$host['hostid']])
391					->setArgument('context', 'host')
392			),
393			CViewHelper::showNum($host['graphs'])
394		],
395		[
396			new CLink(_('Discovery'),
397				(new CUrl('host_discovery.php'))
398					->setArgument('filter_set', '1')
399					->setArgument('filter_hostids', [$host['hostid']])
400					->setArgument('context', 'host')
401			),
402			CViewHelper::showNum($host['discoveries'])
403		],
404		[
405			new CLink(_('Web'),
406				(new CUrl('httpconf.php'))
407					->setArgument('filter_set', '1')
408					->setArgument('filter_hostids', [$host['hostid']])
409					->setArgument('context', 'host')
410			),
411			CViewHelper::showNum($host['httpTests'])
412		],
413		getHostInterface($interface),
414		($data['filter']['monitored_by'] == ZBX_MONITORED_BY_PROXY
415				|| $data['filter']['monitored_by'] == ZBX_MONITORED_BY_ANY)
416			? ($host['proxy_hostid'] != 0)
417				? $data['proxies'][$host['proxy_hostid']]['host']
418				: ''
419			: null,
420		$hostTemplates,
421		$status,
422		getHostAvailabilityTable($host['interfaces']),
423		$encryption,
424		makeInformationList($info_icons),
425		$data['tags'][$host['hostid']]
426	]);
427}
428
429$form->addItem([
430	$table,
431	$data['paging'],
432	new CActionButtonList('action', 'hosts',
433		[
434			'host.massenable' => ['name' => _('Enable'), 'confirm' => _('Enable selected hosts?')],
435			'host.massdisable' => ['name' => _('Disable'), 'confirm' => _('Disable selected hosts?')],
436			'host.export' => [
437				'content' => new CButtonExport('export.hosts',
438					(new CUrl('hosts.php'))
439						->setArgument('page', ($data['page'] == 1) ? null : $data['page'])
440						->getUrl()
441				)
442			],
443			'popup.massupdate.host' => [
444				'content' => (new CButton('', _('Mass update')))
445					->onClick("return openMassupdatePopup(this, 'popup.massupdate.host');")
446					->addClass(ZBX_STYLE_BTN_ALT)
447					->removeAttribute('id')
448			],
449			'host.massdelete' => ['name' => _('Delete'), 'confirm' => _('Delete selected hosts?')]
450		]
451	)
452]);
453
454$widget->addItem($form);
455
456$widget->show();
457