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 22require_once dirname(__FILE__).'/include/config.inc.php'; 23require_once dirname(__FILE__).'/include/hosts.inc.php'; 24require_once dirname(__FILE__).'/include/items.inc.php'; 25require_once dirname(__FILE__).'/include/forms.inc.php'; 26 27$page['title'] = _('Configuration of item prototypes'); 28$page['file'] = 'disc_prototypes.php'; 29$page['scripts'] = ['effects.js', 'class.cviewswitcher.js', 'items.js']; 30 31require_once dirname(__FILE__).'/include/page_header.php'; 32 33$paramsFieldName = getParamFieldNameByType(getRequest('type', 0)); 34 35// VAR TYPE OPTIONAL FLAGS VALIDATION EXCEPTION 36$fields = [ 37 'parent_discoveryid' => [T_ZBX_INT, O_MAND, P_SYS, DB_ID, null], 38 'itemid' => [T_ZBX_INT, O_OPT, P_SYS, DB_ID, '(isset({form}) && ({form} == "update"))'], 39 'interfaceid' => [T_ZBX_INT, O_OPT, P_SYS, DB_ID, null, _('Interface')], 40 'name' => [T_ZBX_STR, O_OPT, null, NOT_EMPTY, 'isset({add}) || isset({update})', 41 _('Name') 42 ], 43 'description' => [T_ZBX_STR, O_OPT, null, null, 'isset({add}) || isset({update})'], 44 'key' => [T_ZBX_STR, O_OPT, null, NOT_EMPTY, 'isset({add}) || isset({update})', 45 _('Key') 46 ], 47 'master_itemid' => [T_ZBX_STR, O_OPT, null, null, 48 '(isset({add}) || isset({update})) && isset({type}) && {type}=='.ITEM_TYPE_DEPENDENT, _('Master item')], 49 'delay' => [T_ZBX_TU, O_OPT, P_ALLOW_USER_MACRO | P_ALLOW_LLD_MACRO, null, 50 '(isset({add}) || isset({update}))'. 51 ' && (isset({type}) && ({type} != '.ITEM_TYPE_TRAPPER.' && {type} != '.ITEM_TYPE_SNMPTRAP.')'. 52 ' && {type}!='.ITEM_TYPE_DEPENDENT.')', 53 _('Update interval') 54 ], 55 'delay_flex' => [T_ZBX_STR, O_OPT, null, null, null], 56 'status' => [T_ZBX_INT, O_OPT, null, IN(ITEM_STATUS_ACTIVE), null], 57 'type' => [T_ZBX_INT, O_OPT, null, 58 IN([-1, ITEM_TYPE_ZABBIX, ITEM_TYPE_SNMPV1, ITEM_TYPE_TRAPPER, ITEM_TYPE_SIMPLE, ITEM_TYPE_SNMPV2C, 59 ITEM_TYPE_INTERNAL, ITEM_TYPE_SNMPV3, ITEM_TYPE_ZABBIX_ACTIVE, ITEM_TYPE_AGGREGATE, ITEM_TYPE_EXTERNAL, 60 ITEM_TYPE_DB_MONITOR, ITEM_TYPE_IPMI, ITEM_TYPE_SSH, ITEM_TYPE_TELNET, ITEM_TYPE_JMX, ITEM_TYPE_CALCULATED, 61 ITEM_TYPE_SNMPTRAP, ITEM_TYPE_DEPENDENT, ITEM_TYPE_HTTPAGENT 62 ]), 63 'isset({add}) || isset({update})' 64 ], 65 'value_type' => [T_ZBX_INT, O_OPT, null, IN('0,1,2,3,4'), 'isset({add}) || isset({update})'], 66 'valuemapid' => [T_ZBX_INT, O_OPT, null, DB_ID, 67 '(isset({add}) || isset({update})) && isset({value_type})'. 68 ' && '.IN(ITEM_VALUE_TYPE_FLOAT.','.ITEM_VALUE_TYPE_UINT64, 'value_type') 69 ], 70 'authtype' => [T_ZBX_INT, O_OPT, null, IN(ITEM_AUTHTYPE_PASSWORD.','.ITEM_AUTHTYPE_PUBLICKEY), 71 '(isset({add}) || isset({update})) && isset({type}) && ({type} == '.ITEM_TYPE_SSH.')' 72 ], 73 'username' => [T_ZBX_STR, O_OPT, null, NOT_EMPTY, 74 '(isset({add}) || isset({update})) && isset({type}) && '.IN(ITEM_TYPE_SSH.','.ITEM_TYPE_TELNET, 'type'), 75 _('User name') 76 ], 77 'password' => [T_ZBX_STR, O_OPT, null, null, 78 '(isset({add}) || isset({update})) && isset({type}) && '.IN(ITEM_TYPE_SSH.','.ITEM_TYPE_TELNET, 'type') 79 ], 80 'publickey' => [T_ZBX_STR, O_OPT, null, null, 81 '(isset({add}) || isset({update})) && isset({type})'. 82 ' && ({type}) == '.ITEM_TYPE_SSH.' && ({authtype}) == '.ITEM_AUTHTYPE_PUBLICKEY 83 ], 84 'privatekey' => [T_ZBX_STR, O_OPT, null, null, 85 '(isset({add}) || isset({update})) && isset({type})'. 86 ' && ({type}) == '.ITEM_TYPE_SSH.' && ({authtype}) == '.ITEM_AUTHTYPE_PUBLICKEY 87 ], 88 $paramsFieldName => [T_ZBX_STR, O_OPT, null, NOT_EMPTY, 89 '(isset({add}) || isset({update})) && isset({type})'. 90 ' && '.IN(ITEM_TYPE_SSH.','.ITEM_TYPE_DB_MONITOR.','.ITEM_TYPE_TELNET.','.ITEM_TYPE_CALCULATED, 'type'), 91 getParamFieldLabelByType(getRequest('type', 0)) 92 ], 93 'snmp_community' => [T_ZBX_STR, O_OPT, null, NOT_EMPTY, 94 '(isset({add}) || isset({update})) && isset({type}) && '.IN(ITEM_TYPE_SNMPV1.','.ITEM_TYPE_SNMPV2C, 'type'), 95 _('SNMP community') 96 ], 97 'snmp_oid' => [T_ZBX_STR, O_OPT, null, NOT_EMPTY, 98 '(isset({add}) || isset({update})) && isset({type})'. 99 ' && '.IN(ITEM_TYPE_SNMPV1.','.ITEM_TYPE_SNMPV2C.','.ITEM_TYPE_SNMPV3, 'type'), 100 _('SNMP OID') 101 ], 102 'port' => [T_ZBX_STR, O_OPT, null, BETWEEN(0, 65535), 103 '(isset({add}) || isset({update})) && isset({type})'. 104 ' && '.IN(ITEM_TYPE_SNMPV1.','.ITEM_TYPE_SNMPV2C.','.ITEM_TYPE_SNMPV3, 'type'), 105 _('Port') 106 ], 107 'snmpv3_securitylevel' => [T_ZBX_INT, O_OPT, null, IN('0,1,2'), 108 '(isset({add}) || isset({update})) && (isset({type}) && ({type} == '.ITEM_TYPE_SNMPV3.'))' 109 ], 110 'snmpv3_contextname' => [T_ZBX_STR, O_OPT, null, null, 111 '(isset({add}) || isset({update})) && (isset({type}) && ({type} == '.ITEM_TYPE_SNMPV3.'))' 112 ], 113 'snmpv3_securityname' => [T_ZBX_STR, O_OPT, null, null, 114 '(isset({add}) || isset({update})) && (isset({type}) && ({type} == '.ITEM_TYPE_SNMPV3.'))' 115 ], 116 'snmpv3_authprotocol' => [T_ZBX_INT, O_OPT, null, IN(ITEM_AUTHPROTOCOL_MD5.','.ITEM_AUTHPROTOCOL_SHA), 117 '(isset({add}) || isset({update})) && (isset({type})'. 118 ' && ({type} == '.ITEM_TYPE_SNMPV3.') && ({snmpv3_securitylevel} == '.ITEM_SNMPV3_SECURITYLEVEL_AUTHPRIV. 119 ' || {snmpv3_securitylevel} == '.ITEM_SNMPV3_SECURITYLEVEL_AUTHNOPRIV.'))' 120 ], 121 'snmpv3_authpassphrase' => [T_ZBX_STR, O_OPT, null, null, 122 '(isset({add}) || isset({update})) && (isset({type})'. 123 ' && ({type} == '.ITEM_TYPE_SNMPV3.') && ({snmpv3_securitylevel} == '.ITEM_SNMPV3_SECURITYLEVEL_AUTHPRIV. 124 ' || {snmpv3_securitylevel} == '.ITEM_SNMPV3_SECURITYLEVEL_AUTHNOPRIV.'))' 125 ], 126 'snmpv3_privprotocol' => [T_ZBX_INT, O_OPT, null, IN(ITEM_PRIVPROTOCOL_DES.','.ITEM_PRIVPROTOCOL_AES), 127 '(isset({add}) || isset({update})) && (isset({type}) && ({type} == '.ITEM_TYPE_SNMPV3.')'. 128 ' && ({snmpv3_securitylevel} == '.ITEM_SNMPV3_SECURITYLEVEL_AUTHPRIV.'))' 129 ], 130 'snmpv3_privpassphrase' => [T_ZBX_STR, O_OPT, null, null, 131 '(isset({add}) || isset({update})) && (isset({type}) && ({type} == '.ITEM_TYPE_SNMPV3.')'. 132 ' && ({snmpv3_securitylevel} == '.ITEM_SNMPV3_SECURITYLEVEL_AUTHPRIV.'))' 133 ], 134 'ipmi_sensor' => [T_ZBX_STR, O_OPT, P_NO_TRIM, NOT_EMPTY, 135 '(isset({add}) || isset({update})) && (isset({type}) && ({type} == '.ITEM_TYPE_IPMI.'))', _('IPMI sensor') 136 ], 137 'trapper_hosts' => [T_ZBX_STR, O_OPT, null, null, 138 '(isset({add}) || isset({update})) && isset({type}) && ({type} == 2)' 139 ], 140 'units' => [T_ZBX_STR, O_OPT, null, null, 141 '(isset({add}) || isset({update})) && isset({value_type}) && '. 142 IN(ITEM_VALUE_TYPE_FLOAT.','.ITEM_VALUE_TYPE_UINT64, 'value_type') 143 ], 144 'logtimefmt' => [T_ZBX_STR, O_OPT, null, null, 145 '(isset({add}) || isset({update})) && (isset({value_type}) && ({value_type} == 2))' 146 ], 147 'preprocessing' => [T_ZBX_STR, O_OPT, P_NO_TRIM, null, null], 148 'group_itemid' => [T_ZBX_INT, O_OPT, null, DB_ID, null], 149 'new_application' => [T_ZBX_STR, O_OPT, null, null, 'isset({add}) || isset({update})'], 150 'applications' => [T_ZBX_INT, O_OPT, null, DB_ID, null], 151 'new_application_prototype' => [T_ZBX_STR, O_OPT, null, null, 152 'isset({parent_discoveryid}) && (isset({add}) || isset({update}))' 153 ], 154 'application_prototypes' => [T_ZBX_STR, O_OPT, null, null, null], 155 'history_mode' => [T_ZBX_INT, O_OPT, null, IN([ITEM_STORAGE_OFF, ITEM_STORAGE_CUSTOM]), null], 156 'history' => [T_ZBX_STR, O_OPT, null, null, 157 '(isset({add}) || isset({update})) && isset({history_mode}) && {history_mode}=='.ITEM_STORAGE_CUSTOM, 158 _('History storage period') 159 ], 160 'trends_mode' => [T_ZBX_INT, O_OPT, null, IN([ITEM_STORAGE_OFF, ITEM_STORAGE_CUSTOM]), null], 161 'trends' => [T_ZBX_STR, O_OPT, null, null, 162 '(isset({add}) || isset({update})) && isset({trends_mode}) && {trends_mode}=='.ITEM_STORAGE_CUSTOM. 163 ' && isset({value_type}) && '.IN(ITEM_VALUE_TYPE_FLOAT.','.ITEM_VALUE_TYPE_UINT64, 'value_type'), 164 _('Trend storage period') 165 ], 166 'jmx_endpoint' => [T_ZBX_STR, O_OPT, null, NOT_EMPTY, 167 '(isset({add}) || isset({update})) && isset({type}) && {type} == '.ITEM_TYPE_JMX 168 ], 169 'timeout' => [T_ZBX_TU, O_OPT, P_ALLOW_USER_MACRO|P_ALLOW_LLD_MACRO, null, 170 '(isset({add}) || isset({update})) && isset({type})'. 171 ' && {type} == '.ITEM_TYPE_HTTPAGENT, 172 _('Timeout') 173 ], 174 'url' => [T_ZBX_STR, O_OPT, null, NOT_EMPTY, 175 '(isset({add}) || isset({update})) && isset({type}) && {type} == '.ITEM_TYPE_HTTPAGENT, _('URL')], 176 'query_fields' => [T_ZBX_STR, O_OPT, null, null, null], 177 'posts' => [T_ZBX_STR, O_OPT, null, null, null], 178 'status_codes' => [T_ZBX_STR, O_OPT, null, null, null], 179 'follow_redirects' => [T_ZBX_INT, O_OPT, null, 180 IN([HTTPTEST_STEP_FOLLOW_REDIRECTS_OFF, HTTPTEST_STEP_FOLLOW_REDIRECTS_ON]), 181 null 182 ], 183 'post_type' => [T_ZBX_INT, O_OPT, null, 184 IN([ZBX_POSTTYPE_RAW, ZBX_POSTTYPE_JSON, ZBX_POSTTYPE_XML]), 185 null 186 ], 187 'http_proxy' => [T_ZBX_STR, O_OPT, null, null, null], 188 'headers' => [T_ZBX_STR, O_OPT, null, null, null], 189 'retrieve_mode' => [T_ZBX_INT, O_OPT, null, 190 IN([HTTPTEST_STEP_RETRIEVE_MODE_CONTENT, HTTPTEST_STEP_RETRIEVE_MODE_HEADERS, 191 HTTPTEST_STEP_RETRIEVE_MODE_BOTH 192 ]), 193 null 194 ], 195 'request_method' => [T_ZBX_INT, O_OPT, null, 196 IN([HTTPCHECK_REQUEST_GET, HTTPCHECK_REQUEST_POST, HTTPCHECK_REQUEST_PUT, 197 HTTPCHECK_REQUEST_HEAD 198 ]), 199 null 200 ], 201 'output_format' => [T_ZBX_INT, O_OPT, null, IN([HTTPCHECK_STORE_RAW, HTTPCHECK_STORE_JSON]), null], 202 'allow_traps' => [T_ZBX_INT, O_OPT, null, 203 IN([HTTPCHECK_ALLOW_TRAPS_OFF, HTTPCHECK_ALLOW_TRAPS_ON]), 204 null 205 ], 206 'ssl_cert_file' => [T_ZBX_STR, O_OPT, null, null, null], 207 'ssl_key_file' => [T_ZBX_STR, O_OPT, null, null, null], 208 'ssl_key_password' => [T_ZBX_STR, O_OPT, null, null, null], 209 'verify_peer' => [T_ZBX_INT, O_OPT, null, 210 IN([HTTPTEST_VERIFY_PEER_OFF, HTTPTEST_VERIFY_PEER_ON]), 211 null 212 ], 213 'verify_host' => [T_ZBX_INT, O_OPT, null, 214 IN([HTTPTEST_VERIFY_HOST_OFF, HTTPTEST_VERIFY_HOST_ON]), 215 null 216 ], 217 'http_authtype' => [T_ZBX_INT, O_OPT, null, 218 IN([HTTPTEST_AUTH_NONE, HTTPTEST_AUTH_BASIC, HTTPTEST_AUTH_NTLM]), 219 null 220 ], 221 'http_username' => [T_ZBX_STR, O_OPT, null, null, 222 '(isset({add}) || isset({update})) && isset({http_authtype})'. 223 ' && ({http_authtype} == '.HTTPTEST_AUTH_BASIC. 224 ' || {http_authtype} == '.HTTPTEST_AUTH_NTLM.')', 225 _('Username') 226 ], 227 'http_password' => [T_ZBX_STR, O_OPT, null, null, 228 '(isset({add}) || isset({update})) && isset({http_authtype})'. 229 ' && ({http_authtype} == '.HTTPTEST_AUTH_BASIC. 230 ' || {http_authtype} == '.HTTPTEST_AUTH_NTLM.')', 231 _('Password') 232 ], 233 // actions 234 'action' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, 235 IN('"itemprototype.massdelete","itemprototype.massdisable","itemprototype.massenable"'), null 236 ], 237 'add' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 238 'update' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 239 'clone' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 240 'delete' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 241 'cancel' => [T_ZBX_STR, O_OPT, P_SYS, null, null], 242 'form' => [T_ZBX_STR, O_OPT, P_SYS, null, null], 243 'form_refresh' => [T_ZBX_INT, O_OPT, null, null, null], 244 // filter 245 'filter_set' => [T_ZBX_STR, O_OPT, P_SYS, null, null], 246 // sort and sortorder 247 'sort' => [T_ZBX_STR, O_OPT, P_SYS, 248 IN('"delay","history","key_","name","status","trends","type"'), null 249 ], 250 'sortorder' => [T_ZBX_STR, O_OPT, P_SYS, IN('"'.ZBX_SORT_DOWN.'","'.ZBX_SORT_UP.'"'), null] 251]; 252check_fields($fields); 253 254$_REQUEST['params'] = getRequest($paramsFieldName, ''); 255unset($_REQUEST[$paramsFieldName]); 256 257// permissions 258$discoveryRule = API::DiscoveryRule()->get([ 259 'output' => ['hostid'], 260 'itemids' => getRequest('parent_discoveryid'), 261 'editable' => true 262]); 263$discoveryRule = reset($discoveryRule); 264if (!$discoveryRule) { 265 access_deny(); 266} 267 268$itemPrototypeId = getRequest('itemid'); 269if ($itemPrototypeId) { 270 $item_prorotypes = API::ItemPrototype()->get([ 271 'output' => [], 272 'itemids' => $itemPrototypeId, 273 'editable' => true 274 ]); 275 276 if (!$item_prorotypes) { 277 access_deny(); 278 } 279} 280 281/* 282 * Actions 283 */ 284if (hasRequest('delete') && hasRequest('itemid')) { 285 DBstart(); 286 $result = API::ItemPrototype()->delete([getRequest('itemid')]); 287 $result = DBend($result); 288 289 if ($result) { 290 uncheckTableRows(getRequest('parent_discoveryid')); 291 } 292 show_messages($result, _('Item prototype deleted'), _('Cannot delete item prototype')); 293 294 unset($_REQUEST['itemid'], $_REQUEST['form']); 295} 296elseif (isset($_REQUEST['clone']) && isset($_REQUEST['itemid'])) { 297 unset($_REQUEST['itemid']); 298 $_REQUEST['form'] = 'clone'; 299} 300elseif (hasRequest('add') || hasRequest('update')) { 301 $applications = getRequest('applications', []); 302 $application = reset($applications); 303 if ($application == 0) { 304 array_shift($applications); 305 } 306 307 $result = true; 308 DBstart(); 309 310 if (!zbx_empty($_REQUEST['new_application'])) { 311 $new_appid = API::Application()->create([ 312 'name' => $_REQUEST['new_application'], 313 'hostid' => $discoveryRule['hostid'] 314 ]); 315 if ($new_appid) { 316 $new_appid = reset($new_appid['applicationids']); 317 $applications[$new_appid] = $new_appid; 318 } 319 else { 320 $result = false; 321 } 322 } 323 324 $delay = getRequest('delay', DB::getDefault('items', 'delay')); 325 $type = getRequest('type', ITEM_TYPE_ZABBIX); 326 327 /* 328 * "delay_flex" is a temporary field that collects flexible and scheduling intervals separated by a semicolon. 329 * In the end, custom intervals together with "delay" are stored in the "delay" variable. 330 */ 331 if (!in_array($type, [ITEM_TYPE_ZABBIX_ACTIVE, ITEM_TYPE_TRAPPER, ITEM_TYPE_SNMPTRAP]) && hasRequest('delay_flex')) { 332 $intervals = []; 333 $simple_interval_parser = new CSimpleIntervalParser([ 334 'usermacros' => true, 335 'lldmacros' => true 336 ]); 337 $time_period_parser = new CTimePeriodParser([ 338 'usermacros' => true, 339 'lldmacros' => true 340 ]); 341 $scheduling_interval_parser = new CSchedulingIntervalParser([ 342 'usermacros' => true, 343 'lldmacros' => true 344 ]); 345 346 foreach (getRequest('delay_flex') as $interval) { 347 if ($interval['type'] == ITEM_DELAY_FLEXIBLE) { 348 if ($interval['delay'] === '' && $interval['period'] === '') { 349 continue; 350 } 351 352 if ($simple_interval_parser->parse($interval['delay']) != CParser::PARSE_SUCCESS) { 353 $result = false; 354 info(_s('Invalid interval "%1$s".', $interval['delay'])); 355 break; 356 } 357 elseif ($time_period_parser->parse($interval['period']) != CParser::PARSE_SUCCESS) { 358 $result = false; 359 info(_s('Invalid interval "%1$s".', $interval['period'])); 360 break; 361 } 362 363 $intervals[] = $interval['delay'].'/'.$interval['period']; 364 } 365 else { 366 if ($interval['schedule'] === '') { 367 continue; 368 } 369 370 if ($scheduling_interval_parser->parse($interval['schedule']) != CParser::PARSE_SUCCESS) { 371 $result = false; 372 info(_s('Invalid interval "%1$s".', $interval['schedule'])); 373 break; 374 } 375 376 $intervals[] = $interval['schedule']; 377 } 378 } 379 380 if ($intervals) { 381 $delay .= ';'.implode(';', $intervals); 382 } 383 } 384 385 if ($result) { 386 $application_prototypes = getRequest('application_prototypes', []); 387 $application_prototype = reset($application_prototypes); 388 389 if ($application_prototype === '0') { 390 array_shift($application_prototypes); 391 } 392 393 if ($application_prototypes) { 394 foreach ($application_prototypes as &$application_prototype) { 395 $application_prototype = ['name' => $application_prototype]; 396 } 397 unset($application_prototype); 398 } 399 400 $new_application_prototype = getRequest('new_application_prototype', ''); 401 if ($new_application_prototype !== '') { 402 $application_prototypes[] = ['name' => $new_application_prototype]; 403 } 404 405 $preprocessing = getRequest('preprocessing', []); 406 407 foreach ($preprocessing as &$step) { 408 switch ($step['type']) { 409 case ZBX_PREPROC_MULTIPLIER: 410 $step['params'] = trim($step['params'][0]); 411 break; 412 413 case ZBX_PREPROC_RTRIM: 414 case ZBX_PREPROC_LTRIM: 415 case ZBX_PREPROC_TRIM: 416 case ZBX_PREPROC_XPATH: 417 case ZBX_PREPROC_JSONPATH: 418 $step['params'] = $step['params'][0]; 419 break; 420 421 case ZBX_PREPROC_REGSUB: 422 $step['params'] = implode("\n", $step['params']); 423 break; 424 425 default: 426 $step['params'] = ''; 427 } 428 } 429 unset($step); 430 431 $item = [ 432 'name' => getRequest('name'), 433 'description' => getRequest('description'), 434 'key_' => getRequest('key'), 435 'hostid' => $discoveryRule['hostid'], 436 'interfaceid' => getRequest('interfaceid'), 437 'delay' => $delay, 438 'status' => getRequest('status', ITEM_STATUS_DISABLED), 439 'type' => getRequest('type'), 440 'snmp_community' => getRequest('snmp_community'), 441 'snmp_oid' => getRequest('snmp_oid'), 442 'value_type' => getRequest('value_type'), 443 'trapper_hosts' => getRequest('trapper_hosts'), 444 'port' => getRequest('port'), 445 'history' => (getRequest('history_mode', ITEM_STORAGE_CUSTOM) == ITEM_STORAGE_OFF) 446 ? ITEM_NO_STORAGE_VALUE 447 : getRequest('history'), 448 'units' => getRequest('units'), 449 'snmpv3_contextname' => getRequest('snmpv3_contextname'), 450 'snmpv3_securityname' => getRequest('snmpv3_securityname'), 451 'snmpv3_securitylevel' => getRequest('snmpv3_securitylevel'), 452 'snmpv3_authprotocol' => getRequest('snmpv3_authprotocol'), 453 'snmpv3_authpassphrase' => getRequest('snmpv3_authpassphrase'), 454 'snmpv3_privprotocol' => getRequest('snmpv3_privprotocol'), 455 'snmpv3_privpassphrase' => getRequest('snmpv3_privpassphrase'), 456 'logtimefmt' => getRequest('logtimefmt'), 457 'valuemapid' => getRequest('valuemapid'), 458 'authtype' => getRequest('authtype'), 459 'username' => getRequest('username'), 460 'password' => getRequest('password'), 461 'publickey' => getRequest('publickey'), 462 'privatekey' => getRequest('privatekey'), 463 'params' => getRequest('params'), 464 'ipmi_sensor' => getRequest('ipmi_sensor'), 465 'ruleid' => getRequest('parent_discoveryid') 466 ]; 467 468 if ($item['type'] == ITEM_TYPE_JMX) { 469 $item['jmx_endpoint'] = getRequest('jmx_endpoint', ''); 470 } 471 472 if ($item['value_type'] == ITEM_VALUE_TYPE_FLOAT || $item['value_type'] == ITEM_VALUE_TYPE_UINT64) { 473 $item['trends'] = (getRequest('trends_mode', ITEM_STORAGE_CUSTOM) == ITEM_STORAGE_OFF) 474 ? ITEM_NO_STORAGE_VALUE 475 : getRequest('trends'); 476 } 477 478 if ($item['type'] == ITEM_TYPE_DEPENDENT) { 479 $item['master_itemid'] = getRequest('master_itemid'); 480 } 481 482 if (hasRequest('update')) { 483 $itemId = getRequest('itemid'); 484 485 $db_item = API::ItemPrototype()->get([ 486 'output' => ['type', 'snmp_community', 'snmp_oid', 'hostid', 'name', 'key_', 'delay', 'history', 487 'trends', 'status', 'value_type', 'trapper_hosts', 'units', 'snmpv3_securityname', 488 'snmpv3_securitylevel', 'snmpv3_authpassphrase', 'snmpv3_privpassphrase', 'logtimefmt', 489 'templateid', 'valuemapid', 'params', 'ipmi_sensor', 'authtype', 'username', 'password', 490 'publickey', 'privatekey', 'interfaceid', 'port', 'description', 'snmpv3_authprotocol', 491 'snmpv3_privprotocol', 'snmpv3_contextname', 'jmx_endpoint', 'master_itemid', 'timeout', 'url', 492 'query_fields', 'posts', 'status_codes', 'follow_redirects', 'post_type', 'http_proxy', 'headers', 493 'retrieve_mode', 'request_method', 'output_format', 'ssl_cert_file', 'ssl_key_file', 494 'ssl_key_password', 'verify_peer', 'verify_host', 'allow_traps' 495 ], 496 'selectApplications' => ['applicationid'], 497 'selectApplicationPrototypes' => ['name'], 498 'selectPreprocessing' => ['type', 'params'], 499 'itemids' => [$itemId] 500 ]); 501 502 // unset snmpv3 fields 503 if ($item['snmpv3_securitylevel'] == ITEM_SNMPV3_SECURITYLEVEL_NOAUTHNOPRIV) { 504 $item['snmpv3_authprotocol'] = ITEM_AUTHPROTOCOL_MD5; 505 $item['snmpv3_privprotocol'] = ITEM_PRIVPROTOCOL_DES; 506 } 507 elseif ($item['snmpv3_securitylevel'] == ITEM_SNMPV3_SECURITYLEVEL_AUTHNOPRIV) { 508 $item['snmpv3_privprotocol'] = ITEM_PRIVPROTOCOL_DES; 509 } 510 511 $db_item = $db_item[0]; 512 513 if ($item['type'] == ITEM_TYPE_HTTPAGENT) { 514 $http_item = [ 515 'timeout' => getRequest('timeout', DB::getDefault('items', 'timeout')), 516 'url' => getRequest('url'), 517 'query_fields' => getRequest('query_fields', []), 518 'posts' => getRequest('posts'), 519 'status_codes' => getRequest('status_codes', DB::getDefault('items', 'status_codes')), 520 'follow_redirects' => (int) getRequest('follow_redirects'), 521 'post_type' => (int) getRequest('post_type'), 522 'http_proxy' => getRequest('http_proxy'), 523 'headers' => getRequest('headers', []), 524 'retrieve_mode' => (int) getRequest('retrieve_mode'), 525 'request_method' => (int) getRequest('request_method'), 526 'output_format' => (int) getRequest('output_format'), 527 'allow_traps' => (int) getRequest('allow_traps', HTTPCHECK_ALLOW_TRAPS_OFF), 528 'ssl_cert_file' => getRequest('ssl_cert_file'), 529 'ssl_key_file' => getRequest('ssl_key_file'), 530 'ssl_key_password' => getRequest('ssl_key_password'), 531 'verify_peer' => (int) getRequest('verify_peer'), 532 'verify_host' => (int) getRequest('verify_host'), 533 'authtype' => getRequest('http_authtype', HTTPTEST_AUTH_NONE), 534 'username' => getRequest('http_username', ''), 535 'password' => getRequest('http_password', '') 536 ]; 537 $item = prepareItemHttpAgentFormData($http_item) + $item; 538 } 539 540 $item = CArrayHelper::unsetEqualValues($item, $db_item); 541 $item['itemid'] = $itemId; 542 543 $db_item['applications'] = zbx_objectValues($db_item['applications'], 'applicationid'); 544 545 // compare applications 546 natsort($db_item['applications']); 547 natsort($applications); 548 549 if (array_values($db_item['applications']) !== array_values($applications)) { 550 $item['applications'] = $applications; 551 } 552 553 // compare application prototypes 554 $db_application_prototype_names = zbx_objectValues($db_item['applicationPrototypes'], 'name'); 555 natsort($db_application_prototype_names); 556 557 $application_prototype_names = zbx_objectValues($application_prototypes, 'name'); 558 natsort($application_prototype_names); 559 560 if (array_values($db_application_prototype_names) !== array_values($application_prototype_names)) { 561 $item['applicationPrototypes'] = $application_prototypes; 562 } 563 564 if ($db_item['preprocessing'] !== $preprocessing) { 565 $item['preprocessing'] = $preprocessing; 566 } 567 568 $result = API::ItemPrototype()->update($item); 569 } 570 else { 571 $item['applications'] = $applications; 572 $item['applicationPrototypes'] = $application_prototypes; 573 574 if (getRequest('type') == ITEM_TYPE_HTTPAGENT) { 575 $http_item = [ 576 'timeout' => getRequest('timeout', DB::getDefault('items', 'timeout')), 577 'url' => getRequest('url'), 578 'query_fields' => getRequest('query_fields', []), 579 'posts' => getRequest('posts'), 580 'status_codes' => getRequest('status_codes', DB::getDefault('items', 'status_codes')), 581 'follow_redirects' => (int) getRequest('follow_redirects'), 582 'post_type' => (int) getRequest('post_type'), 583 'http_proxy' => getRequest('http_proxy'), 584 'headers' => getRequest('headers', []), 585 'retrieve_mode' => (int) getRequest('retrieve_mode'), 586 'request_method' => (int) getRequest('request_method'), 587 'output_format' => (int) getRequest('output_format'), 588 'allow_traps' => (int) getRequest('allow_traps', HTTPCHECK_ALLOW_TRAPS_OFF), 589 'ssl_cert_file' => getRequest('ssl_cert_file'), 590 'ssl_key_file' => getRequest('ssl_key_file'), 591 'ssl_key_password' => getRequest('ssl_key_password'), 592 'verify_peer' => (int) getRequest('verify_peer'), 593 'verify_host' => (int) getRequest('verify_host'), 594 'authtype' => getRequest('http_authtype', HTTPTEST_AUTH_NONE), 595 'username' => getRequest('http_username', ''), 596 'password' => getRequest('http_password', '') 597 ]; 598 $item = prepareItemHttpAgentFormData($http_item) + $item; 599 } 600 601 if ($preprocessing) { 602 $item['preprocessing'] = $preprocessing; 603 } 604 605 $result = API::ItemPrototype()->create($item); 606 } 607 } 608 609 $result = DBend($result); 610 611 if (hasRequest('add')) { 612 show_messages($result, _('Item prototype added'), _('Cannot add item prototype')); 613 } 614 else { 615 show_messages($result, _('Item prototype updated'), _('Cannot update item prototype')); 616 } 617 618 if ($result) { 619 unset($_REQUEST['itemid'], $_REQUEST['form']); 620 uncheckTableRows(getRequest('parent_discoveryid')); 621 } 622} 623elseif (hasRequest('action') && str_in_array(getRequest('action'), ['itemprototype.massenable', 'itemprototype.massdisable']) && hasRequest('group_itemid')) { 624 $itemids = getRequest('group_itemid'); 625 $status = (getRequest('action') == 'itemprototype.massenable') ? ITEM_STATUS_ACTIVE : ITEM_STATUS_DISABLED; 626 627 $item_prototypes = []; 628 foreach ($itemids as $itemid) { 629 $item_prototypes[] = ['itemid' => $itemid, 'status' => $status]; 630 } 631 632 $result = (bool) API::ItemPrototype()->update($item_prototypes); 633 634 if ($result) { 635 uncheckTableRows(getRequest('parent_discoveryid')); 636 } 637 638 $updated = count($itemids); 639 640 $messageSuccess = _n('Item prototype updated', 'Item prototypes updated', $updated); 641 $messageFailed = _n('Cannot update item prototype', 'Cannot update item prototypes', $updated); 642 643 show_messages($result, $messageSuccess, $messageFailed); 644} 645elseif (hasRequest('action') && getRequest('action') == 'itemprototype.massdelete' && hasRequest('group_itemid')) { 646 DBstart(); 647 648 $result = API::ItemPrototype()->delete(getRequest('group_itemid')); 649 $result = DBend($result); 650 651 if ($result) { 652 uncheckTableRows(getRequest('parent_discoveryid')); 653 } 654 show_messages($result, _('Item prototypes deleted'), _('Cannot delete item prototypes')); 655} 656 657if (hasRequest('action') && hasRequest('group_itemid') && !$result) { 658 $item_prototypes = API::ItemPrototype()->get([ 659 'itemids' => getRequest('group_itemid'), 660 'output' => [], 661 'editable' => true 662 ]); 663 uncheckTableRows(getRequest('parent_discoveryid'), zbx_objectValues($item_prototypes, 'itemid')); 664} 665 666/* 667 * Display 668 */ 669if (isset($_REQUEST['form'])) { 670 $itemPrototype = []; 671 $has_errors = false; 672 673 if (hasRequest('itemid')) { 674 $itemPrototype = API::ItemPrototype()->get([ 675 'itemids' => getRequest('itemid'), 676 'output' => [ 677 'itemid', 'type', 'snmp_community', 'snmp_oid', 'hostid', 'name', 'key_', 'delay', 'history', 678 'trends', 'status', 'value_type', 'trapper_hosts', 'units', 'snmpv3_securityname', 679 'snmpv3_securitylevel', 'snmpv3_authpassphrase', 'snmpv3_privpassphrase', 'logtimefmt', 'templateid', 680 'valuemapid', 'params', 'ipmi_sensor', 'authtype', 'username', 'password', 'publickey', 'privatekey', 681 'interfaceid', 'port', 'description', 'snmpv3_authprotocol', 'snmpv3_privprotocol', 682 'snmpv3_contextname', 'jmx_endpoint', 'master_itemid', 'timeout', 'url', 'query_fields', 'posts', 683 'status_codes', 'follow_redirects', 'post_type', 'http_proxy', 'headers', 'retrieve_mode', 684 'request_method', 'output_format', 'ssl_cert_file', 'ssl_key_file', 'ssl_key_password', 685 'verify_peer', 'verify_host', 'allow_traps' 686 ], 687 'selectPreprocessing' => ['type', 'params'] 688 ]); 689 $itemPrototype = reset($itemPrototype); 690 foreach ($itemPrototype['preprocessing'] as &$step) { 691 $step['params'] = explode("\n", $step['params']); 692 } 693 unset($step); 694 695 if ($itemPrototype['type'] != ITEM_TYPE_JMX) { 696 $itemPrototype['jmx_endpoint'] = ZBX_DEFAULT_JMX_ENDPOINT; 697 } 698 699 if (getRequest('type', $itemPrototype['type']) == ITEM_TYPE_DEPENDENT) { 700 $master_prototypes = API::Item()->get([ 701 'output' => ['itemid', 'hostid', 'name', 'key_'], 702 'itemids' => [getRequest('master_itemid', $itemPrototype['master_itemid'])], 703 'hostids' => [$itemPrototype['hostid']], 704 'webitems' => true 705 ]) 706 + API::ItemPrototype()->get([ 707 'output' => ['itemid', 'hostid', 'name', 'key_'], 708 'itemids' => getRequest('master_itemid', $itemPrototype['master_itemid']) 709 ]); 710 711 if ($master_prototypes) { 712 $itemPrototype['master_item'] = reset($master_prototypes); 713 } 714 } 715 } 716 elseif (getRequest('master_itemid')) { 717 $master_prototypes = API::Item()->get([ 718 'output' => ['itemid', 'hostid', 'name', 'key_'], 719 'itemids' => getRequest('master_itemid'), 720 'webitems' => true 721 ]) 722 + API::ItemPrototype()->get([ 723 'output' => ['itemid', 'hostid', 'name', 'key_'], 724 'itemids' => getRequest('master_itemid') 725 ]); 726 727 if ($master_prototypes) { 728 $itemPrototype['master_item'] = reset($master_prototypes); 729 } 730 else { 731 show_messages(false, '', _('No permissions to referred object or it does not exist!')); 732 $has_errors = true; 733 } 734 } 735 736 $data = getItemFormData($itemPrototype); 737 $data['config'] = select_config(); 738 $data['trends_default'] = DB::getDefault('items', 'trends'); 739 740 $history_in_seconds = timeUnitToSeconds($data['history']); 741 if (!getRequest('form_refresh') && $history_in_seconds !== null && $history_in_seconds == ITEM_NO_STORAGE_VALUE) { 742 $data['history_mode'] = getRequest('history_mode', ITEM_STORAGE_OFF); 743 $data['history'] = DB::getDefault('items', 'history'); 744 } 745 else { 746 $data['history_mode'] = getRequest('history_mode', ITEM_STORAGE_CUSTOM); 747 } 748 749 $trends_in_seconds = timeUnitToSeconds($data['trends']); 750 if (!getRequest('form_refresh') && $trends_in_seconds !== null && $trends_in_seconds == ITEM_NO_STORAGE_VALUE) { 751 $data['trends_mode'] = getRequest('trends_mode', ITEM_STORAGE_OFF); 752 $data['trends'] = $data['trends_default']; 753 } 754 else { 755 $data['trends_mode'] = getRequest('trends_mode', ITEM_STORAGE_CUSTOM); 756 } 757 758 // Sort interfaces to be listed starting with one selected as 'main'. 759 CArrayHelper::sort($data['interfaces'], [ 760 ['field' => 'main', 'order' => ZBX_SORT_DOWN] 761 ]); 762 763 // render view 764 if (!$has_errors) { 765 $itemView = new CView('configuration.item.prototype.edit', $data); 766 $itemView->render(); 767 $itemView->show(); 768 } 769} 770else { 771 $sortField = getRequest('sort', CProfile::get('web.'.$page['file'].'.sort', 'name')); 772 $sortOrder = getRequest('sortorder', CProfile::get('web.'.$page['file'].'.sortorder', ZBX_SORT_UP)); 773 774 CProfile::update('web.'.$page['file'].'.sort', $sortField, PROFILE_TYPE_STR); 775 CProfile::update('web.'.$page['file'].'.sortorder', $sortOrder, PROFILE_TYPE_STR); 776 777 $config = select_config(); 778 779 $data = [ 780 'form' => getRequest('form'), 781 'parent_discoveryid' => getRequest('parent_discoveryid'), 782 'hostid' => $discoveryRule['hostid'], 783 'sort' => $sortField, 784 'sortorder' => $sortOrder 785 ]; 786 787 $data['items'] = API::ItemPrototype()->get([ 788 'discoveryids' => $data['parent_discoveryid'], 789 'output' => API_OUTPUT_EXTEND, 790 'editable' => true, 791 'selectApplications' => API_OUTPUT_EXTEND, 792 'sortfield' => $sortField, 793 'limit' => $config['search_limit'] + 1 794 ]); 795 796 $data['items'] = expandItemNamesWithMasterItems($data['items'], 'itemprototypes'); 797 798 switch ($sortField) { 799 case 'delay': 800 orderItemsByDelay($data['items'], $sortOrder, ['usermacros' => true, 'lldmacros' => true]); 801 break; 802 803 case 'history': 804 orderItemsByHistory($data['items'], $sortOrder); 805 break; 806 807 case 'trends': 808 orderItemsByTrends($data['items'], $sortOrder); 809 break; 810 811 default: 812 order_result($data['items'], $sortField, $sortOrder); 813 } 814 815 $url = (new CUrl('disc_prototypes.php')) 816 ->setArgument('parent_discoveryid', $data['parent_discoveryid']); 817 818 $data['paging'] = getPagingLine($data['items'], $sortOrder, $url); 819 $data['parent_templates'] = getItemParentTemplates($data['items'], ZBX_FLAG_DISCOVERY_PROTOTYPE); 820 821 // render view 822 $itemView = new CView('configuration.item.prototype.list', $data); 823 $itemView->render(); 824 $itemView->show(); 825} 826 827require_once dirname(__FILE__).'/include/page_footer.php'; 828