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('redirect("conf.import.php?rules_preset=host")')
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 = (new CTable())
50	->setId('filter-tags')
51	->addRow((new CCol(
52		(new CRadioButtonList('filter_evaltype', (int) $data['filter']['evaltype']))
53			->addValue(_('And/Or'), TAG_EVAL_TYPE_AND_OR)
54			->addValue(_('Or'), TAG_EVAL_TYPE_OR)
55			->setModern(true)
56		))->setColSpan(4)
57	);
58
59$i = 0;
60foreach ($filter_tags as $tag) {
61	$filter_tags_table->addRow([
62		(new CTextBox('filter_tags['.$i.'][tag]', $tag['tag']))
63			->setAttribute('placeholder', _('tag'))
64			->setWidth(ZBX_TEXTAREA_FILTER_SMALL_WIDTH),
65		(new CRadioButtonList('filter_tags['.$i.'][operator]', (int) $tag['operator']))
66			->addValue(_('Contains'), TAG_OPERATOR_LIKE)
67			->addValue(_('Equals'), TAG_OPERATOR_EQUAL)
68			->setModern(true),
69		(new CTextBox('filter_tags['.$i.'][value]', $tag['value']))
70			->setAttribute('placeholder', _('value'))
71			->setWidth(ZBX_TEXTAREA_FILTER_SMALL_WIDTH),
72		(new CCol(
73			(new CButton('filter_tags['.$i.'][remove]', _('Remove')))
74				->addClass(ZBX_STYLE_BTN_LINK)
75				->addClass('element-table-remove')
76		))->addClass(ZBX_STYLE_NOWRAP)
77	], 'form_row');
78
79	$i++;
80}
81$filter_tags_table->addRow(
82	(new CCol(
83		(new CButton('filter_tags_add', _('Add')))
84			->addClass(ZBX_STYLE_BTN_LINK)
85			->addClass('element-table-add')
86	))->setColSpan(3)
87);
88
89// filter
90$filter = new CFilter(new CUrl('hosts.php'));
91$filter
92	->setProfile($data['profileIdx'])
93	->setActiveTab($data['active_tab'])
94	->addFilterTab(_('Filter'), [
95		(new CFormList())
96			->addRow(
97				(new CLabel(_('Host groups'), 'filter_groups__ms')),
98				(new CMultiSelect([
99					'name' => 'filter_groups[]',
100					'object_name' => 'hostGroup',
101					'data' => $data['filter']['groups'],
102					'popup' => [
103						'parameters' => [
104							'srctbl' => 'host_groups',
105							'srcfld1' => 'groupid',
106							'dstfrm' => $filter->getName(),
107							'dstfld1' => 'filter_groups_',
108							'real_hosts' => 1,
109							'editable' => 1,
110							'enrich_parent_groups' => 1
111						]
112					]
113				]))->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH)
114			)
115			->addRow(
116				(new CLabel(_('Templates'), 'filter_templates__ms')),
117				(new CMultiSelect([
118					'name' => 'filter_templates[]',
119					'object_name' => 'templates',
120					'data' => $data['filter']['templates'],
121					'popup' => [
122						'parameters' => [
123							'srctbl' => 'templates',
124							'srcfld1' => 'hostid',
125							'srcfld2' => 'host',
126							'dstfrm' => $filter->getName(),
127							'dstfld1' => 'filter_templates_'
128						]
129					]
130				]))->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH)
131			)
132			->addRow(_('Name'),
133				(new CTextBox('filter_host', $data['filter']['host']))->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH)
134			)
135			->addRow(_('DNS'),
136				(new CTextBox('filter_dns', $data['filter']['dns']))->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH)
137			)
138			->addRow(_('IP'),
139				(new CTextBox('filter_ip', $data['filter']['ip']))->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH)
140			)
141			->addRow(_('Port'),
142				(new CTextBox('filter_port', $data['filter']['port']))->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH)
143			),
144		(new CFormList())
145			->addRow(_('Monitored by'),
146				(new CRadioButtonList('filter_monitored_by', (int) $data['filter']['monitored_by']))
147					->addValue(_('Any'), ZBX_MONITORED_BY_ANY)
148					->addValue(_('Server'), ZBX_MONITORED_BY_SERVER)
149					->addValue(_('Proxy'), ZBX_MONITORED_BY_PROXY)
150					->setModern(true)
151			)
152			->addRow(
153				(new CLabel(_('Proxy'), 'filter_proxyids__ms')),
154				(new CMultiSelect([
155					'name' => 'filter_proxyids[]',
156					'object_name' => 'proxies',
157					'data' => $data['proxies_ms'],
158					'disabled' => ($data['filter']['monitored_by'] != ZBX_MONITORED_BY_PROXY),
159					'popup' => [
160						'parameters' => [
161							'srctbl' => 'proxies',
162							'srcfld1' => 'proxyid',
163							'srcfld2' => 'host',
164							'dstfrm' => 'zbx_filter',
165							'dstfld1' => 'filter_proxyids_'
166						]
167					]
168				]))->setWidth(ZBX_TEXTAREA_MEDIUM_WIDTH)
169			)
170			->addRow(_('Tags'), $filter_tags_table)
171	]);
172
173$widget->addItem($filter);
174
175// table hosts
176$form = (new CForm())->setName('hosts');
177
178$table = (new CTableInfo())
179	->setHeader([
180		(new CColHeader(
181			(new CCheckBox('all_hosts'))->onClick("checkAll('".$form->getName()."', 'all_hosts', 'hosts');")
182		))->addClass(ZBX_STYLE_CELL_WIDTH),
183		make_sorting_header(_('Name'), 'name', $data['sortField'], $data['sortOrder'], 'hosts.php'),
184		_('Applications'),
185		_('Items'),
186		_('Triggers'),
187		_('Graphs'),
188		_('Discovery'),
189		_('Web'),
190		_('Interface'),
191		($data['filter']['monitored_by'] == ZBX_MONITORED_BY_PROXY
192				|| $data['filter']['monitored_by'] == ZBX_MONITORED_BY_ANY) ? _('Proxy') : null,
193		_('Templates'),
194		make_sorting_header(_('Status'), 'status', $data['sortField'], $data['sortOrder'], 'hosts.php'),
195		_('Availability'),
196		_('Agent encryption'),
197		_('Info'),
198		_('Tags')
199	]);
200
201$current_time = time();
202
203foreach ($data['hosts'] as $host) {
204	// Select an interface from the list with highest priority.
205	$interface = null;
206	foreach ([INTERFACE_TYPE_AGENT, INTERFACE_TYPE_SNMP, INTERFACE_TYPE_JMX, INTERFACE_TYPE_IPMI] as $interface_type) {
207		$host_interfaces = array_filter($host['interfaces'], function($host_interface) use($interface_type) {
208			return $host_interface['type'] == $interface_type;
209		});
210		if ($host_interfaces) {
211			$interface = reset($host_interfaces);
212			break;
213		}
214	}
215
216	$description = [];
217
218	if ($host['discoveryRule']) {
219		$description[] = (new CLink(CHtml::encode($host['discoveryRule']['name']),
220			(new CUrl('host_prototypes.php'))->setArgument('parent_discoveryid', $host['discoveryRule']['itemid'])
221		))
222			->addClass(ZBX_STYLE_LINK_ALT)
223			->addClass(ZBX_STYLE_ORANGE);
224		$description[] = NAME_DELIMITER;
225	}
226	elseif ($host['flags'] == ZBX_FLAG_DISCOVERY_CREATED) {
227		// Discovered host which does not contain info about parent discovery rule is inaccessible for current user.
228		$description[] = (new CSpan(_('Inaccessible discovery rule')))->addClass(ZBX_STYLE_ORANGE);
229		$description[] = NAME_DELIMITER;
230	}
231
232	$description[] = new CLink(CHtml::encode($host['name']), (new CUrl('hosts.php'))
233				->setArgument('form', 'update')
234				->setArgument('hostid', $host['hostid'])
235	);
236
237	$maintenance_icon = false;
238	$hostInterface = ($interface['useip'] == INTERFACE_USE_IP) ? $interface['ip'] : $interface['dns'];
239	$hostInterface .= empty($interface['port']) ? '' : NAME_DELIMITER.$interface['port'];
240
241	if ($host['status'] == HOST_STATUS_MONITORED) {
242		if ($host['maintenance_status'] == HOST_MAINTENANCE_STATUS_ON) {
243			if (array_key_exists($host['maintenanceid'], $data['maintenances'])) {
244				$maintenance = $data['maintenances'][$host['maintenanceid']];
245				$maintenance_icon = makeMaintenanceIcon($host['maintenance_type'], $maintenance['name'],
246					$maintenance['description']
247				);
248			}
249			else {
250				$maintenance_icon = makeMaintenanceIcon($host['maintenance_type'], _('Inaccessible maintenance'), '');
251			}
252		}
253
254		$statusCaption = _('Enabled');
255		$statusClass = ZBX_STYLE_GREEN;
256		$confirm_message = _('Disable host?');
257		$status_url = (new CUrl('hosts.php'))
258			->setArgument('action', 'host.massdisable')
259			->setArgument('hosts', [$host['hostid']]);
260	}
261	else {
262		$statusCaption = _('Disabled');
263		$status_url = (new CUrl('hosts.php'))
264			->setArgument('action', 'host.massenable')
265			->setArgument('hosts', [$host['hostid']]);
266		$confirm_message = _('Enable host?');
267		$statusClass = ZBX_STYLE_RED;
268	}
269
270	$status = (new CLink($statusCaption, $status_url->getUrl()))
271		->addClass(ZBX_STYLE_LINK_ACTION)
272		->addClass($statusClass)
273		->addConfirmation($confirm_message)
274		->addSID();
275
276	if ($maintenance_icon) {
277		$description[] = $maintenance_icon;
278	}
279
280	order_result($host['parentTemplates'], 'name');
281
282	$hostTemplates = [];
283	$i = 0;
284
285	foreach ($host['parentTemplates'] as $template) {
286		$i++;
287
288		if ($i > $data['config']['max_in_table']) {
289			$hostTemplates[] = ' &hellip;';
290
291			break;
292		}
293
294		if (array_key_exists($template['templateid'], $data['writable_templates'])) {
295			$caption = [
296				(new CLink(CHtml::encode($template['name']),
297					(new CUrl('templates.php'))
298						->setArgument('form', 'update')
299						->setArgument('templateid', $template['templateid'])
300				))
301					->addClass(ZBX_STYLE_LINK_ALT)
302					->addClass(ZBX_STYLE_GREY)
303			];
304		}
305		else {
306			$caption = [
307				(new CSpan(CHtml::encode($template['name'])))->addClass(ZBX_STYLE_GREY)
308			];
309		}
310
311		$parent_templates = $data['templates'][$template['templateid']]['parentTemplates'];
312
313		if ($parent_templates) {
314			order_result($parent_templates, 'name');
315			$caption[] = ' (';
316
317			foreach ($parent_templates as $parent_template) {
318				if (array_key_exists($parent_template['templateid'], $data['writable_templates'])) {
319					$caption[] = (new CLink(CHtml::encode($parent_template['name']),
320						(new CUrl('templates.php'))
321							->setArgument('form', 'update')
322							->setArgument('templateid', $parent_template['templateid'])
323					))
324						->addClass(ZBX_STYLE_LINK_ALT)
325						->addClass(ZBX_STYLE_GREY);
326				}
327				else {
328					$caption[] = (new CSpan(CHtml::encode($parent_template['name'])))->addClass(ZBX_STYLE_GREY);
329				}
330				$caption[] = ', ';
331			}
332			array_pop($caption);
333
334			$caption[] = ')';
335		}
336
337		if ($hostTemplates) {
338			$hostTemplates[] = ', ';
339		}
340
341		$hostTemplates[] = $caption;
342	}
343
344	$info_icons = [];
345	if ($host['flags'] == ZBX_FLAG_DISCOVERY_CREATED && $host['hostDiscovery']['ts_delete'] != 0) {
346		$info_icons[] = getHostLifetimeIndicator($current_time, $host['hostDiscovery']['ts_delete']);
347	}
348
349	if ($host['tls_connect'] == HOST_ENCRYPTION_NONE
350			&& ($host['tls_accept'] & HOST_ENCRYPTION_NONE) == HOST_ENCRYPTION_NONE
351			&& ($host['tls_accept'] & HOST_ENCRYPTION_PSK) != HOST_ENCRYPTION_PSK
352			&& ($host['tls_accept'] & HOST_ENCRYPTION_CERTIFICATE) != HOST_ENCRYPTION_CERTIFICATE) {
353		$encryption = (new CDiv((new CSpan(_('None')))->addClass(ZBX_STYLE_STATUS_GREEN)))
354			->addClass(ZBX_STYLE_STATUS_CONTAINER);
355	}
356	else {
357		// Incoming encryption.
358		if ($host['tls_connect'] == HOST_ENCRYPTION_NONE) {
359			$in_encryption = (new CSpan(_('None')))->addClass(ZBX_STYLE_STATUS_GREEN);
360		}
361		elseif ($host['tls_connect'] == HOST_ENCRYPTION_PSK) {
362			$in_encryption = (new CSpan(_('PSK')))->addClass(ZBX_STYLE_STATUS_GREEN);
363		}
364		else {
365			$in_encryption = (new CSpan(_('CERT')))->addClass(ZBX_STYLE_STATUS_GREEN);
366		}
367
368		// Outgoing encryption.
369		$out_encryption = [];
370		if (($host['tls_accept'] & HOST_ENCRYPTION_NONE) == HOST_ENCRYPTION_NONE) {
371			$out_encryption[] = (new CSpan(_('None')))->addClass(ZBX_STYLE_STATUS_GREEN);
372		}
373		else {
374			$out_encryption[] = (new CSpan(_('None')))->addClass(ZBX_STYLE_STATUS_GREY);
375		}
376
377		if (($host['tls_accept'] & HOST_ENCRYPTION_PSK) == HOST_ENCRYPTION_PSK) {
378			$out_encryption[] = (new CSpan(_('PSK')))->addClass(ZBX_STYLE_STATUS_GREEN);
379		}
380		else {
381			$out_encryption[] = (new CSpan(_('PSK')))->addClass(ZBX_STYLE_STATUS_GREY);
382		}
383
384		if (($host['tls_accept'] & HOST_ENCRYPTION_CERTIFICATE) == HOST_ENCRYPTION_CERTIFICATE) {
385			$out_encryption[] = (new CSpan(_('CERT')))->addClass(ZBX_STYLE_STATUS_GREEN);
386		}
387		else {
388			$out_encryption[] = (new CSpan(_('CERT')))->addClass(ZBX_STYLE_STATUS_GREY);
389		}
390
391		$encryption = (new CDiv([new CSpan($in_encryption), ' ', new CSpan($out_encryption)]))
392			->addClass(ZBX_STYLE_STATUS_CONTAINER)
393			->addClass(ZBX_STYLE_NOWRAP);
394	}
395
396	$table->addRow([
397		new CCheckBox('hosts['.$host['hostid'].']', $host['hostid']),
398		(new CCol($description))->addClass(ZBX_STYLE_NOWRAP),
399		[
400			new CLink(_('Applications'),
401				(new CUrl('applications.php'))
402					->setArgument('filter_set', '1')
403					->setArgument('filter_hostids', [$host['hostid']])
404			),
405			CViewHelper::showNum($host['applications'])
406		],
407		[
408			new CLink(_('Items'),
409				(new CUrl('items.php'))
410					->setArgument('filter_set', '1')
411					->setArgument('filter_hostids', [$host['hostid']])
412			),
413			CViewHelper::showNum($host['items'])
414		],
415		[
416			new CLink(_('Triggers'),
417				(new CUrl('triggers.php'))
418					->setArgument('filter_set', '1')
419					->setArgument('filter_hostids', [$host['hostid']])
420			),
421			CViewHelper::showNum($host['triggers'])
422		],
423		[
424			new CLink(_('Graphs'),
425				(new CUrl('graphs.php'))
426					->setArgument('filter_set', '1')
427					->setArgument('filter_hostids', [$host['hostid']])
428			),
429			CViewHelper::showNum($host['graphs'])
430		],
431		[
432			new CLink(_('Discovery'),
433				(new CUrl('host_discovery.php'))
434					->setArgument('filter_set', '1')
435					->setArgument('filter_hostids', [$host['hostid']])
436			),
437			CViewHelper::showNum($host['discoveries'])
438		],
439		[
440			new CLink(_('Web'),
441				(new CUrl('httpconf.php'))
442					->setArgument('filter_set', '1')
443					->setArgument('filter_hostids', [$host['hostid']])
444			),
445			CViewHelper::showNum($host['httpTests'])
446		],
447		$hostInterface,
448		($data['filter']['monitored_by'] == ZBX_MONITORED_BY_PROXY
449				|| $data['filter']['monitored_by'] == ZBX_MONITORED_BY_ANY)
450			? ($host['proxy_hostid'] != 0)
451				? $data['proxies'][$host['proxy_hostid']]['host']
452				: ''
453			: null,
454		$hostTemplates,
455		$status,
456		getHostAvailabilityTable($host),
457		$encryption,
458		makeInformationList($info_icons),
459		$data['tags'][$host['hostid']]
460	]);
461}
462
463$form->addItem([
464	$table,
465	$data['paging'],
466	new CActionButtonList('action', 'hosts',
467		[
468			'host.massenable' => ['name' => _('Enable'), 'confirm' => _('Enable selected hosts?')],
469			'host.massdisable' => ['name' => _('Disable'), 'confirm' => _('Disable selected hosts?')],
470			'host.export' => ['name' => _('Export'), 'redirect' =>
471				(new CUrl('zabbix.php'))
472					->setArgument('action', 'export.hosts.xml')
473					->setArgument('backurl', (new CUrl('hosts.php'))
474						->setArgument('page', $data['page'] == 1 ? null : $data['page'])
475						->getUrl())
476					->getUrl()
477			],
478			'host.massupdateform' => ['name' => _('Mass update')],
479			'host.massdelete' => ['name' => _('Delete'), 'confirm' => _('Delete selected hosts?')]
480		]
481	)
482]);
483
484$widget->addItem($form);
485
486$widget->show();
487