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?>
26
27/**
28 * Make step result UI element.
29 *
30 * @param {array} step  Step object returned from server.
31 *
32 * @return {jQuery}
33 */
34function makeStepResult(step) {
35	if (typeof step.error !== 'undefined') {
36		return jQuery(new Template(jQuery('#preprocessing-step-error-icon').html()).evaluate(
37			{error: step.error || <?= json_encode(_('<empty string>')) ?>}
38		));
39	}
40	else if (typeof step.result === 'undefined' || step.result === null) {
41		return jQuery('<span>', {'class': '<?= ZBX_STYLE_GREY ?>'}).text(<?= json_encode(_('No value')) ?>);
42	}
43	else if (step.result === '') {
44		return jQuery('<span>', {'class': '<?= ZBX_STYLE_GREY ?>'}).text(<?= json_encode(_('<empty string>')) ?>);
45	}
46	else if (step.result.indexOf("\n") != -1 || step.result.length > 25) {
47		return jQuery(new Template(jQuery('#preprocessing-step-result').html()).evaluate(
48			jQuery.extend({result: step.result})
49		));
50	}
51	else {
52		return jQuery('<span>').text(step.result);
53	}
54}
55
56/**
57 * Disable item test form.
58 */
59function disableItemTestForm() {
60	jQuery('#value, #time, [name^=macros]').prop('disabled', true);
61
62	<?php if ($data['is_item_testable']): ?>
63		jQuery('#get_value, #get_value_btn').prop('disabled', true);
64
65		<?php if ($data['interface_address_enabled']): ?>
66			jQuery('#interface_address').prop('disabled', true);
67		<?php endif ?>
68
69		<?php if ($data['interface_port_enabled']): ?>
70			jQuery('#interface_port').prop('disabled', true);
71		<?php endif ?>
72
73		<?php if ($data['proxies_enabled']): ?>
74			jQuery('#proxy_hostid').prop('disabled', true);
75		<?php endif ?>
76
77	<?php else: ?>
78		jQuery('#get_value, #get_value_btn').prop('disabled', true);
79	<?php endif ?>
80
81	<?php if ($data['show_prev']): ?>
82		jQuery('#prev_time').prop('readonly', true);
83	<?php endif ?>
84
85	jQuery('#eol input').prop('disabled', true);
86}
87
88/**
89 * Enable item test form.
90 */
91function enableItemTestForm() {
92	jQuery('#value, #time, [name^=macros]').prop('disabled', false);
93
94	<?php if ($data['is_item_testable']): ?>
95		jQuery('#get_value, #get_value_btn').prop('disabled', false);
96
97		<?php if ($data['interface_address_enabled']): ?>
98			jQuery('#interface_address').prop('disabled', false);
99		<?php endif ?>
100
101		<?php if ($data['interface_port_enabled']): ?>
102			jQuery('#interface_port').prop('disabled', false);
103		<?php endif ?>
104
105		<?php if ($data['proxies_enabled']): ?>
106			jQuery('#proxy_hostid').prop('disabled', false);
107		<?php endif ?>
108
109	<?php else: ?>
110		jQuery('#get_value, #get_value_btn').prop('disabled', false);
111	<?php endif ?>
112
113	<?php if ($data['show_prev']): ?>
114		if (!jQuery('#get_value').is(':checked')) {
115			jQuery('#prev_value').multilineInput('unsetReadOnly');
116			jQuery('#prev_time').prop('readonly', false);
117		}
118	<?php endif ?>
119
120	jQuery('#eol input').prop('disabled', false);
121}
122
123/**
124 * Clear previous test results.
125 */
126function cleanPreviousTestResults() {
127	var $form = jQuery('#preprocessing-test-form');
128
129	jQuery('[id^="preproc-test-step-"][id$="-result"]', $form).empty();
130	jQuery('[id^="preproc-test-step-"][id$="-name"] > div', $form).remove();
131	jQuery('.js-final-result', $form)
132		.hide()
133		.next()
134		.empty()
135		.hide();
136}
137
138/**
139 * Send item get value request and display retrieved results.
140 *
141 * @param {object} overlay  Overlay dialog object.
142 */
143function itemGetValueTest(overlay) {
144	var $body = overlay.$dialogue.$body,
145		$form = overlay.$dialogue.find('form'),
146		form_data = $form.serializeJSON(),
147		post_data = getItemTestProperties('#preprocessing-test-form'),
148		interface = (typeof form_data['interface'] !== 'undefined') ? form_data['interface'] : null,
149		url = new Curl('zabbix.php');
150
151	url.setArgument('action', 'popup.itemtest.getvalue');
152
153	post_data = jQuery.extend(post_data, {
154		interface: {
155			address: interface ? interface['address'].trim() : '',
156			port: (interface && interface['port']) ? interface['port'].trim() : '',
157			interfaceid: interface ? interface['interfaceid'] : null,
158			useip: interface ? interface['useip'] : null,
159			details: interface ? interface['details'] : null
160		},
161		macros: form_data['macros'],
162		proxy_hostid: form_data['proxy_hostid'],
163		test_type: <?= $data['test_type'] ?>,
164		hostid: <?= $data['hostid'] ?>,
165		value: form_data['value']
166	});
167
168	<?php if ($data['show_prev']): ?>
169		post_data['time_change'] = (form_data['upd_prev'] !== '')
170			? parseInt(form_data['upd_last']) - parseInt(form_data['upd_prev'])
171			: Math.ceil(+new Date() / 1000) - parseInt(form_data['upd_last']);
172	<?php endif ?>
173
174	delete post_data.interfaceid;
175	delete post_data.delay;
176
177	overlay.xhr = jQuery.ajax({
178		url: url.getUrl(),
179		data: post_data,
180		beforeSend: function() {
181			jQuery('#get_value_btn').blur().addClass('is-loading');
182			overlay.setLoading();
183			disableItemTestForm();
184			cleanPreviousTestResults();
185		},
186		complete: function() {
187			jQuery('#get_value_btn').removeClass('is-loading');
188			enableItemTestForm();
189			overlay.unsetLoading();
190		},
191		success: function(ret) {
192			overlay.$dialogue.find('.msg-bad, .msg-good, .msg-warning').remove();
193
194			if (typeof ret.messages !== 'undefined') {
195				jQuery($body).prepend(ret.messages);
196			}
197			else {
198				<?php if ($data['show_prev']): ?>
199					if (typeof ret.prev_value !== 'undefined') {
200						jQuery('#prev_value', $form).multilineInput('value', ret.prev_value);
201						jQuery('#prev_time', $form).val(ret.prev_time);
202						jQuery('#upd_prev', $form).val(form_data['upd_last']);
203						jQuery('#upd_last', $form).val(Math.ceil(+new Date() / 1000));
204					}
205				<?php endif ?>
206
207				jQuery('#value', $form).multilineInput('value', ret.value);
208
209				if (typeof ret.eol !== 'undefined') {
210					jQuery("input[value=" + ret.eol + "]", jQuery("#eol")).prop("checked", "checked");
211				}
212			}
213		},
214		dataType: 'json',
215		type: 'post'
216	});
217}
218
219/**
220 * Send item preprocessing test details and display results in table.
221 *
222 * @param {object} overlay  Overlay dialog object.
223 */
224function itemCompleteTest(overlay) {
225	var $body = overlay.$dialogue.$body,
226		$form = overlay.$dialogue.find('form'),
227		form_data = $form.serializeJSON(),
228		post_data = getItemTestProperties('#preprocessing-test-form'),
229		interface = (typeof form_data['interface'] !== 'undefined') ? form_data['interface'] : null,
230		url = new Curl('zabbix.php');
231
232	url.setArgument('action', 'popup.itemtest.send');
233
234	post_data = jQuery.extend(post_data, {
235		get_value: form_data['get_value'] || 0,
236		steps: form_data['steps'],
237		interface: {
238			address: interface ? interface['address'].trim() : '',
239			port: (interface && interface['port']) ? interface['port'].trim() : '',
240			interfaceid: interface ? interface['interfaceid'] : null,
241			useip: interface ? interface['useip'] : null,
242			details: interface ? interface['details'] : null
243		},
244		macros: form_data['macros'],
245		proxy_hostid: form_data['proxy_hostid'],
246		show_final_result: <?= $data['show_final_result'] ? 1 : 0 ?>,
247		test_type: <?= $data['test_type'] ?>,
248		hostid: <?= $data['hostid'] ?>,
249		valuemapid: <?= $data['valuemapid'] ?>,
250		value: form_data['value'],
251		not_supported: form_data['not_supported']
252	});
253
254	<?php if ($data['show_prev']): ?>
255		if (post_data.get_value) {
256			post_data['time_change'] = (form_data['upd_prev'] !== '')
257				? parseInt(form_data['upd_last']) - parseInt(form_data['upd_prev'])
258				: Math.ceil(+new Date() / 1000) - parseInt(form_data['upd_last']);
259		}
260
261		post_data = jQuery.extend(post_data, {
262			prev_time: form_data['prev_time'],
263			prev_value: form_data['prev_value']
264		});
265	<?php endif ?>
266
267	overlay.xhr = jQuery.ajax({
268		url: url.getUrl(),
269		data: post_data,
270		beforeSend: function() {
271			overlay.setLoading();
272			disableItemTestForm();
273			cleanPreviousTestResults();
274		},
275		complete: function() {
276			enableItemTestForm();
277			overlay.unsetLoading();
278		},
279		success: function(ret) {
280			overlay.$dialogue.find('.msg-bad, .msg-good, .msg-warning').remove();
281
282			if (typeof ret.messages !== 'undefined') {
283				jQuery($body).prepend(ret.messages);
284			}
285
286			processItemPreprocessingTestResults(ret.steps);
287
288			<?php if ($data['show_prev']): ?>
289				if (typeof ret.prev_value !== 'undefined') {
290					jQuery('#prev_value', $form).multilineInput('value', ret.prev_value);
291					jQuery('#prev_time', $form).val(ret.prev_time);
292					jQuery('#upd_prev', $form).val(post_data['upd_last']);
293					jQuery('#upd_last', $form).val(Math.ceil(+new Date() / 1000));
294				}
295			<?php endif ?>
296
297			jQuery('#value', $form).multilineInput('value', ret.value);
298
299			if (typeof ret.eol !== 'undefined') {
300				jQuery("input[value=" + ret.eol + "]", jQuery("#eol")).prop("checked", "checked");
301			}
302
303			if (typeof ret.final !== 'undefined') {
304				var result = makeStepResult(ret.final);
305				if (result !== null) {
306					$result = jQuery(result).css('float', 'right');
307				}
308
309				$result_row = jQuery('<div>', {'class': '<?= ZBX_STYLE_TABLE_FORMS_SEPARATOR ?>'})
310					.css({whiteSpace: 'normal'})
311					.append(jQuery('<div>').append(ret.final.action, $result))
312					.css({display: 'block', width: '675px'});
313
314				if (typeof ret.mapped_value !== 'undefined') {
315					$mapped_value = makeStepResult({result: ret.mapped_value});
316					$mapped_value.css('float', 'right');
317
318					$result_row.append(jQuery('<div>')
319						.append(
320							jQuery('<span>', {'class': '<?= ZBX_STYLE_GREY ?>'})
321								.text('<?= _('Result with value map applied') ?>'),
322							$mapped_value
323						)
324					);
325				}
326
327				jQuery('.js-final-result')
328					.show()
329					.next()
330					.append($result_row)
331					.show();
332			}
333		},
334		dataType: 'json',
335		type: 'post'
336	});
337
338	return false;
339}
340
341/**
342 * Process test results and make visual changes in test dialog results block.
343 *
344 * @param {array} steps  Array of objects containing details about each preprocessing step test results.
345 */
346function processItemPreprocessingTestResults(steps) {
347	var tmpl_gray_label = new Template(jQuery('#preprocessing-gray-label').html()),
348		tmpl_act_done = new Template(jQuery('#preprocessing-step-action-done').html());
349
350	steps.forEach(function(step, i) {
351		if (typeof step.action !== 'undefined') {
352			switch (step.action) {
353				case <?= ZBX_PREPROC_FAIL_DEFAULT ?>:
354					step.action = null;
355					break;
356
357				case <?= ZBX_PREPROC_FAIL_DISCARD_VALUE ?>:
358					step.action = jQuery(tmpl_gray_label.evaluate(<?= json_encode([
359						'label' => _('Discard value')
360					]) ?>));
361					break;
362
363				case <?= ZBX_PREPROC_FAIL_SET_VALUE ?>:
364					step.action = jQuery(tmpl_act_done.evaluate(jQuery.extend(<?= json_encode([
365						'action_name' => _('Set value to')
366					]) ?>, {failed: step.result})));
367					break;
368
369				case <?= ZBX_PREPROC_FAIL_SET_ERROR ?>:
370					step.action = jQuery(tmpl_act_done.evaluate(jQuery.extend(<?= json_encode([
371						'action_name' => _('Set error to')
372					]) ?>, {failed: step.failed})));
373					break;
374			}
375		}
376
377		step.result = makeStepResult(step);
378
379		if (typeof step.action !== 'undefined' && step.action !== null) {
380			jQuery('#preproc-test-step-' + i + '-name').append(jQuery(tmpl_gray_label.evaluate(<?= json_encode([
381				'label' => _('Custom on fail')
382			]) ?>)));
383		}
384
385		jQuery('#preproc-test-step-' + i + '-result').append(step.result, step.action);
386	});
387}
388
389/**
390 * Collect values from opened item test dialog and save input values for repeated use.
391 */
392function saveItemTestInputs() {
393	var $form = jQuery('#preprocessing-test-form'),
394		$test_obj,
395		input_values = {
396			value: jQuery('#value').multilineInput('value'),
397			eol: jQuery('#eol').find(':checked').val()
398		},
399		form_data = $form.serializeJSON(),
400		interface = (typeof form_data['interface'] !== 'undefined') ? form_data['interface'] : null,
401		macros = {};
402
403	<?php if ($data['is_item_testable']): ?>
404		input_values = jQuery.extend(input_values, {
405			get_value: jQuery('#get_value', $form).is(':checked') ? 1 : 0,
406			proxy_hostid: jQuery('#proxy_hostid', $form).val(),
407			interfaceid: <?= $data['interfaceid'] ?> || 0,
408			address: jQuery('#interface_address', $form).val(),
409			port: jQuery('#interface_port', $form).val(),
410			interface_details: (interface && 'details' in interface) ? interface['details'] : null
411		});
412	<?php endif ?>
413
414	<?php if ($data['show_prev']): ?>
415		input_values = jQuery.extend(input_values, {
416			prev_value: jQuery('#prev_value').multilineInput('value'),
417			prev_time: jQuery('#prev_time').val()
418		});
419	<?php endif ?>
420
421	jQuery('[name^=macros]').each(function(i, macro) {
422		var name = macro.name.toString();
423		macros[name.substr(7, name.length - 8)] = macro.value;
424	});
425	input_values.macros = macros;
426
427	<?php if ($data['step_obj'] == -2): ?>
428		$test_obj = jQuery('.tfoot-buttons');
429	<?php elseif ($data['step_obj'] == -1): ?>
430		$test_obj = jQuery('.preprocessing-list-foot', jQuery('#preprocessing'));
431	<?php else: ?>
432		$test_obj = jQuery('.preprocessing-list-item[data-step=<?= $data['step_obj'] ?>]', jQuery('#preprocessing'));
433	<?php endif ?>
434
435	$test_obj.data('test-data', input_values);
436}
437
438jQuery(document).ready(function($) {
439	$('.js-final-result').hide().next().hide();
440
441	<?php if ($data['show_prev']): ?>
442		jQuery('#upd_last').val(Math.ceil(+new Date() / 1000));
443	<?php endif ?>
444
445	$('#value').multilineInput({
446		placeholder: <?= json_encode(_('value')) ?>,
447		value: <?= json_encode($data['value']) ?>,
448		monospace_font: false,
449		autofocus: true,
450		readonly: false,
451		grow: 'auto',
452		rows: 0
453	});
454
455	$('#prev_value').multilineInput({
456		placeholder: <?= $data['show_prev'] ? json_encode(_('value')) : '""' ?>,
457		value: <?= json_encode($data['prev_value']) ?>,
458		monospace_font: false,
459		disabled: <?= $data['show_prev'] ? 'false' : 'true' ?>,
460		grow: 'auto',
461		rows: 0
462	});
463
464	<?php if ($data['is_item_testable']): ?>
465		$('#not_supported').on('change', function() {
466			var $form = $('#preprocessing-test-form');
467
468			if ($(this).is(':checked')) {
469				$('#value', $form).multilineInput('setReadOnly');
470			}
471			else {
472				$('#value', $form).multilineInput('unsetReadOnly');
473			}
474		});
475
476		$('#get_value').on('change', function() {
477			var $rows = $('.js-host-address-row, .js-proxy-hostid-row, .js-get-value-row, [class*=js-popup-row-snmp]'),
478				$form = $('#preprocessing-test-form'),
479				$submit_btn = overlays_stack.getById('item-test').$btn_submit,
480				$not_supported = $('#not_supported', $form);
481
482			if ($(this).is(':checked')) {
483				$('#value', $form).multilineInput('setReadOnly');
484				$not_supported.prop('disabled', true);
485
486				<?php if ($data['show_prev']): ?>
487					$('#prev_value', $form).multilineInput('setReadOnly');
488					$('#prev_time', $form).prop('readonly', true);
489				<?php endif ?>
490
491				<?php if ($data['proxies_enabled']): ?>
492					$('#proxy_hostid').prop('disabled', false);
493				<?php endif ?>
494
495				<?php if ($data['interface_address_enabled']): ?>
496					$('#interface_address').prop('disabled', false);
497				<?php endif ?>
498
499				<?php if ($data['interface_port_enabled']): ?>
500					$('#interface_port').prop('disabled', false);
501				<?php endif ?>
502
503				$submit_btn.html('<?= _('Get value and test') ?>');
504				$rows.show();
505
506				<?php if ($data['show_snmp_form']): ?>
507					$('#interface_details_version').on('change', function (e) {
508						$(`.js-popup-row-snmp-community, .js-popup-row-snmpv3-contextname,
509							.js-popup-row-snmpv3-securityname, .js-popup-row-snmpv3-securitylevel,
510							.js-popup-row-snmpv3-authprotocol, .js-popup-row-snmpv3-authpassphrase,
511							.js-popup-row-snmpv3-privprotocol, .js-popup-row-snmpv3-privpassphrase`).hide();
512
513						switch (e.target.value) {
514							case '<?= SNMP_V1 ?>':
515								$('#interface_details_securitylevel').off('change');
516								$('.js-popup-row-snmp-community').show();
517								break;
518							case '<?= SNMP_V2C ?>':
519								$('#interface_details_securitylevel').off('change');
520								$('.js-popup-row-snmp-community').show();
521								break;
522							case '<?= SNMP_V3 ?>':
523								$(`.js-popup-row-snmpv3-contextname, .js-popup-row-snmpv3-securityname,
524									.js-popup-row-snmpv3-securitylevel`).show();
525
526								$('#interface_details_securitylevel').on('change', function (e) {
527									$(`.js-popup-row-snmpv3-authprotocol, .js-popup-row-snmpv3-authpassphrase,
528										.js-popup-row-snmpv3-privprotocol, .js-popup-row-snmpv3-privpassphrase`).hide();
529									switch (e.target.value) {
530										case '<?= ITEM_SNMPV3_SECURITYLEVEL_AUTHNOPRIV ?>':
531											$(`.js-popup-row-snmpv3-authprotocol, .js-popup-row-snmpv3-authpassphrase`)
532												.show();
533											break;
534										case '<?= ITEM_SNMPV3_SECURITYLEVEL_AUTHPRIV ?>':
535											$(`.js-popup-row-snmpv3-authprotocol, .js-popup-row-snmpv3-authpassphrase,
536												.js-popup-row-snmpv3-privprotocol, .js-popup-row-snmpv3-privpassphrase`)
537												.show();
538											break;
539									}
540
541									overlays_stack.end().centerDialog();
542								}).trigger('change');
543								break;
544						}
545
546						overlays_stack.end().centerDialog();
547					}).trigger('change');
548				<?php endif ?>
549			}
550			else {
551				!$not_supported.is(':checked') && $('#value', $form).multilineInput('unsetReadOnly');
552				$not_supported.prop('disabled', false);
553
554				<?php if ($data['show_prev']): ?>
555					$('#prev_value', $form).multilineInput('unsetReadOnly');
556					$('#prev_time', $form).prop('readonly', false);
557				<?php endif ?>
558
559				<?php if ($data['proxies_enabled']): ?>
560					$('#proxy_hostid').prop('disabled', true);
561				<?php endif ?>
562
563				<?php if ($data['interface_address_enabled']): ?>
564					$('#interface_address').prop('disabled', false);
565				<?php endif ?>
566
567				<?php if ($data['interface_port_enabled']): ?>
568					$('#interface_port').prop('disabled', false);
569				<?php endif ?>
570
571				$submit_btn.html('<?= _('Test') ?>');
572				$rows.hide();
573			}
574		}).trigger('change');
575
576		$('#get_value_btn').on('click', function() {
577			itemGetValueTest(overlays_stack.getById('item-test'));
578		});
579	<?php endif ?>
580
581	$('#preprocessing-test-form .<?= ZBX_STYLE_TEXTAREA_FLEXIBLE ?>').textareaFlexible();
582});
583