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/forms.inc.php'; 24 25$page['title'] = _('Configuration of hosts'); 26$page['file'] = 'hosts.php'; 27$page['type'] = detect_page_type(PAGE_TYPE_HTML); 28$page['scripts'] = ['multiselect.js']; 29 30require_once dirname(__FILE__).'/include/page_header.php'; 31 32// VAR TYPE OPTIONAL FLAGS VALIDATION EXCEPTION 33$fields = [ 34 'hosts' => [T_ZBX_INT, O_OPT, P_SYS, DB_ID, null], 35 'groups' => [T_ZBX_STR, O_OPT, null, NOT_EMPTY, 'isset({add}) || isset({update})'], 36 'new_groups' => [T_ZBX_STR, O_OPT, P_SYS, null, null], 37 'remove_groups' => [T_ZBX_STR, O_OPT, P_SYS, DB_ID, null], 38 'hostids' => [T_ZBX_INT, O_OPT, P_SYS, DB_ID, null], 39 'groupids' => [T_ZBX_INT, O_OPT, P_SYS, DB_ID, null], 40 'applications' => [T_ZBX_INT, O_OPT, P_SYS, DB_ID, null], 41 'groupid' => [T_ZBX_INT, O_OPT, P_SYS, DB_ID, null], 42 'hostid' => [T_ZBX_INT, O_OPT, P_SYS, DB_ID, 'isset({form}) && {form} == "update"'], 43 'clone_hostid' => [T_ZBX_INT, O_OPT, P_SYS, DB_ID, 44 'isset({form}) && {form} == "full_clone"' 45 ], 46 'host' => [T_ZBX_STR, O_OPT, null, NOT_EMPTY, 'isset({add}) || isset({update})', 47 _('Host name') 48 ], 49 'visiblename' => [T_ZBX_STR, O_OPT, null, null, 'isset({add}) || isset({update})'], 50 'description' => [T_ZBX_STR, O_OPT, null, null, null], 51 'proxy_hostid' => [T_ZBX_INT, O_OPT, P_SYS, DB_ID, null], 52 'status' => [T_ZBX_INT, O_OPT, null, 53 IN([HOST_STATUS_MONITORED, HOST_STATUS_NOT_MONITORED]), null 54 ], 55 'interfaces' => [T_ZBX_STR, O_OPT, null, NOT_EMPTY, 56 'isset({add}) || isset({update})', _('Agent or SNMP or JMX or IPMI interface') 57 ], 58 'mainInterfaces' => [T_ZBX_INT, O_OPT, null, DB_ID, null], 59 'templates' => [T_ZBX_INT, O_OPT, null, DB_ID, null], 60 'add_template' => [T_ZBX_STR, O_OPT, null, null, null], 61 'add_templates' => [T_ZBX_INT, O_OPT, null, DB_ID, null], 62 'templates_rem' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 63 'clear_templates' => [T_ZBX_INT, O_OPT, null, DB_ID, null], 64 'ipmi_authtype' => [T_ZBX_INT, O_OPT, null, BETWEEN(-1, 6), null], 65 'ipmi_privilege' => [T_ZBX_INT, O_OPT, null, BETWEEN(0, 5), null], 66 'ipmi_username' => [T_ZBX_STR, O_OPT, null, null, null], 67 'ipmi_password' => [T_ZBX_STR, O_OPT, null, null, null], 68 'tls_connect' => [T_ZBX_INT, O_OPT, null, 69 IN([HOST_ENCRYPTION_NONE, HOST_ENCRYPTION_PSK, HOST_ENCRYPTION_CERTIFICATE]), 70 null 71 ], 72 'tls_accept' => [T_ZBX_INT, O_OPT, null, 73 BETWEEN(0, 74 (HOST_ENCRYPTION_NONE | HOST_ENCRYPTION_PSK | HOST_ENCRYPTION_CERTIFICATE) 75 ), 76 null 77 ], 78 'tls_subject' => [T_ZBX_STR, O_OPT, null, null, null], 79 'tls_issuer' => [T_ZBX_STR, O_OPT, null, null, null], 80 'tls_psk_identity' => [T_ZBX_STR, O_OPT, null, null, null], 81 'tls_psk' => [T_ZBX_STR, O_OPT, null, null, null], 82 'flags' => [T_ZBX_INT, O_OPT, null, 83 IN([ZBX_FLAG_DISCOVERY_NORMAL, ZBX_FLAG_DISCOVERY_CREATED]), null 84 ], 85 'mass_replace_tpls' => [T_ZBX_STR, O_OPT, null, null, null], 86 'mass_clear_tpls' => [T_ZBX_STR, O_OPT, null, null, null], 87 'inventory_mode' => [T_ZBX_INT, O_OPT, null, 88 IN(HOST_INVENTORY_DISABLED.','.HOST_INVENTORY_MANUAL.','.HOST_INVENTORY_AUTOMATIC), 89 null 90 ], 91 'host_inventory' => [T_ZBX_STR, O_OPT, P_UNSET_EMPTY, null, null], 92 'macros' => [T_ZBX_STR, O_OPT, P_SYS, null, null], 93 'visible' => [T_ZBX_STR, O_OPT, null, null, null], 94 'show_inherited_macros' => [T_ZBX_INT, O_OPT, null, IN([0,1]), null], 95 // actions 96 'action' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, 97 IN('"host.export","host.massdelete","host.massdisable",'. 98 '"host.massenable","host.massupdate","host.massupdateform"' 99 ), 100 null 101 ], 102 'add_to_group' => [T_ZBX_INT, O_OPT, P_SYS|P_ACT, DB_ID, null], 103 'delete_from_group' => [T_ZBX_INT, O_OPT, P_SYS|P_ACT, DB_ID, null], 104 'unlink' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 105 'unlink_and_clear' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 106 'add' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 107 'update' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 108 'masssave' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 109 'clone' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 110 'full_clone' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 111 'delete' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 112 'cancel' => [T_ZBX_STR, O_OPT, P_SYS, null, null], 113 'form' => [T_ZBX_STR, O_OPT, P_SYS, null, null], 114 'form_refresh' => [T_ZBX_INT, O_OPT, null, null, null], 115 // filter 116 'filter_set' => [T_ZBX_STR, O_OPT, P_SYS, null, null], 117 'filter_rst' => [T_ZBX_STR, O_OPT, P_SYS, null, null], 118 'filter_host' => [T_ZBX_STR, O_OPT, null, null, null], 119 'filter_templates' => [T_ZBX_INT, O_OPT, null, DB_ID, null], 120 'filter_ip' => [T_ZBX_STR, O_OPT, null, null, null], 121 'filter_dns' => [T_ZBX_STR, O_OPT, null, null, null], 122 'filter_port' => [T_ZBX_STR, O_OPT, null, null, null], 123 'filter_monitored_by' => [T_ZBX_INT, O_OPT, null, 124 IN([ZBX_MONITORED_BY_ANY, ZBX_MONITORED_BY_SERVER, ZBX_MONITORED_BY_PROXY]), 125 null 126 ], 127 'filter_proxyids' => [T_ZBX_INT, O_OPT, null, DB_ID, null], 128 // sort and sortorder 129 'sort' => [T_ZBX_STR, O_OPT, P_SYS, IN('"name","status"'), null], 130 'sortorder' => [T_ZBX_STR, O_OPT, P_SYS, IN('"'.ZBX_SORT_DOWN.'","'.ZBX_SORT_UP.'"'), null] 131]; 132check_fields($fields); 133 134/* 135 * Permissions 136 */ 137if (getRequest('groupid') && !isWritableHostGroups([getRequest('groupid')])) { 138 access_deny(); 139} 140if (getRequest('hostid')) { 141 $hosts = API::Host()->get([ 142 'output' => [], 143 'hostids' => getRequest('hostid'), 144 'editable' => true 145 ]); 146 147 if (!$hosts) { 148 access_deny(); 149 } 150} 151 152/* 153 * Filter 154 */ 155if (hasRequest('filter_set')) { 156 CProfile::update('web.hosts.filter_ip', getRequest('filter_ip', ''), PROFILE_TYPE_STR); 157 CProfile::update('web.hosts.filter_dns', getRequest('filter_dns', ''), PROFILE_TYPE_STR); 158 CProfile::update('web.hosts.filter_host', getRequest('filter_host', ''), PROFILE_TYPE_STR); 159 CProfile::update('web.hosts.filter_port', getRequest('filter_port', ''), PROFILE_TYPE_STR); 160 CProfile::update('web.hosts.filter_monitored_by', getRequest('filter_monitored_by', ZBX_MONITORED_BY_ANY), 161 PROFILE_TYPE_INT 162 ); 163 CProfile::updateArray('web.hosts.filter_templates', getRequest('filter_templates', []), PROFILE_TYPE_ID); 164 CProfile::updateArray('web.hosts.filter_proxyids', getRequest('filter_proxyids', []), PROFILE_TYPE_ID); 165} 166elseif (hasRequest('filter_rst')) { 167 DBStart(); 168 CProfile::delete('web.hosts.filter_ip'); 169 CProfile::delete('web.hosts.filter_dns'); 170 CProfile::delete('web.hosts.filter_host'); 171 CProfile::delete('web.hosts.filter_port'); 172 CProfile::delete('web.hosts.filter_monitored_by'); 173 CProfile::deleteIdx('web.hosts.filter_templates'); 174 CProfile::deleteIdx('web.hosts.filter_proxyids'); 175 DBend(); 176} 177 178$filter['ip'] = CProfile::get('web.hosts.filter_ip', ''); 179$filter['dns'] = CProfile::get('web.hosts.filter_dns', ''); 180$filter['host'] = CProfile::get('web.hosts.filter_host', ''); 181$filter['templates'] = CProfile::getArray('web.hosts.filter_templates', []); 182$filter['port'] = CProfile::get('web.hosts.filter_port', ''); 183$filter['monitored_by'] = CProfile::get('web.hosts.filter_monitored_by', ZBX_MONITORED_BY_ANY); 184$filter['proxyids'] = CProfile::getArray('web.hosts.filter_proxyids', []); 185 186// remove inherited macros data (actions: 'add', 'update' and 'form') 187$macros = cleanInheritedMacros(getRequest('macros', [])); 188 189// remove empty new macro lines 190foreach ($macros as $idx => $macro) { 191 if (!array_key_exists('hostmacroid', $macro) && $macro['macro'] === '' && $macro['value'] === '') { 192 unset($macros[$idx]); 193 } 194} 195 196/* 197 * Actions 198 */ 199if (isset($_REQUEST['add_template']) && isset($_REQUEST['add_templates'])) { 200 $_REQUEST['templates'] = getRequest('templates', []); 201 $_REQUEST['templates'] = array_merge($_REQUEST['templates'], $_REQUEST['add_templates']); 202} 203if (isset($_REQUEST['unlink']) || isset($_REQUEST['unlink_and_clear'])) { 204 $_REQUEST['clear_templates'] = getRequest('clear_templates', []); 205 206 $unlinkTemplates = []; 207 208 if (isset($_REQUEST['unlink'])) { 209 // templates_rem for old style removal in massupdate form 210 if (isset($_REQUEST['templates_rem'])) { 211 $unlinkTemplates = array_keys($_REQUEST['templates_rem']); 212 } 213 elseif (is_array($_REQUEST['unlink'])) { 214 $unlinkTemplates = array_keys($_REQUEST['unlink']); 215 } 216 } 217 else { 218 $unlinkTemplates = array_keys($_REQUEST['unlink_and_clear']); 219 220 $_REQUEST['clear_templates'] = array_merge($_REQUEST['clear_templates'], $unlinkTemplates); 221 } 222 223 foreach ($unlinkTemplates as $templateId) { 224 unset($_REQUEST['templates'][array_search($templateId, $_REQUEST['templates'])]); 225 } 226} 227elseif ((hasRequest('clone') || hasRequest('full_clone')) && hasRequest('hostid')) { 228 $_REQUEST['form'] = hasRequest('clone') ? 'clone' : 'full_clone'; 229 230 $groups = getRequest('groups', []); 231 $groupids = []; 232 233 // Remove inaccessible groups from request, but leave "new". 234 foreach ($groups as $group) { 235 if (!is_array($group)) { 236 $groupids[] = $group; 237 } 238 } 239 240 if ($groupids) { 241 $groups_allowed = API::HostGroup()->get([ 242 'output' => [], 243 'groupids' => $groupids, 244 'editable' => true, 245 'preservekeys' => true 246 ]); 247 248 foreach ($groups as $idx => $group) { 249 if (!is_array($group) && !array_key_exists($group, $groups_allowed)) { 250 unset($groups[$idx]); 251 } 252 } 253 254 $_REQUEST['groups'] = $groups; 255 } 256 257 if (hasRequest('interfaces')) { 258 $interfaceid = 1; 259 foreach ($_REQUEST['interfaces'] as &$interface) { 260 $interface['interfaceid'] = (string) $interfaceid++; 261 unset($interface['locked'], $interface['items']); 262 } 263 unset($interface); 264 } 265 266 if (hasRequest('full_clone')) { 267 $_REQUEST['clone_hostid'] = $_REQUEST['hostid']; 268 } 269 270 unset($_REQUEST['hostid'], $_REQUEST['flags']); 271} 272elseif (hasRequest('action') && getRequest('action') == 'host.massupdate' && hasRequest('masssave')) { 273 $hostIds = getRequest('hosts', []); 274 $visible = getRequest('visible', []); 275 $_REQUEST['proxy_hostid'] = getRequest('proxy_hostid', 0); 276 $_REQUEST['templates'] = getRequest('templates', []); 277 278 try { 279 DBstart(); 280 281 // filter only normal and discovery created hosts 282 $options = [ 283 'output' => ['hostid'], 284 'hostids' => $hostIds, 285 'selectInventory' => ['inventory_mode'], 286 'selectGroups' => ['groupid'], 287 'filter' => ['flags' => [ZBX_FLAG_DISCOVERY_NORMAL, ZBX_FLAG_DISCOVERY_CREATED]] 288 ]; 289 290 if (array_key_exists('templates', $visible) && !hasRequest('mass_replace_tpls')) { 291 $options['selectParentTemplates'] = ['templateid']; 292 } 293 294 $hosts = API::Host()->get($options); 295 296 $properties = [ 297 'proxy_hostid', 'ipmi_authtype', 'ipmi_privilege', 'ipmi_username', 'ipmi_password', 'description' 298 ]; 299 300 $newValues = []; 301 foreach ($properties as $property) { 302 if (isset($visible[$property])) { 303 $newValues[$property] = $_REQUEST[$property]; 304 } 305 } 306 307 if (isset($visible['status'])) { 308 $newValues['status'] = getRequest('status', HOST_STATUS_NOT_MONITORED); 309 } 310 311 if (array_key_exists('encryption', $visible)) { 312 $newValues['tls_connect'] = getRequest('tls_connect', HOST_ENCRYPTION_NONE); 313 $newValues['tls_accept'] = getRequest('tls_accept', HOST_ENCRYPTION_NONE); 314 315 if ($newValues['tls_connect'] == HOST_ENCRYPTION_PSK || ($newValues['tls_accept'] & HOST_ENCRYPTION_PSK)) { 316 $newValues['tls_psk_identity'] = getRequest('tls_psk_identity', ''); 317 $newValues['tls_psk'] = getRequest('tls_psk', ''); 318 } 319 320 if ($newValues['tls_connect'] == HOST_ENCRYPTION_CERTIFICATE 321 || ($newValues['tls_accept'] & HOST_ENCRYPTION_CERTIFICATE)) { 322 $newValues['tls_issuer'] = getRequest('tls_issuer', ''); 323 $newValues['tls_subject'] = getRequest('tls_subject', ''); 324 } 325 } 326 327 $templateids = []; 328 if (isset($visible['templates'])) { 329 $templateids = $_REQUEST['templates']; 330 } 331 332 /* 333 * Step 2. Add new host groups. This is actually done later, but before we can do that we need to check what 334 * groups will be added and first of all actually create them and get the new IDs. 335 */ 336 $new_groupids = []; 337 338 if (array_key_exists('new_groups', $visible)) { 339 if (CWebUser::getType() == USER_TYPE_SUPER_ADMIN) { 340 $ins_groups = []; 341 342 foreach (getRequest('new_groups', []) as $new_group) { 343 if (is_array($new_group) && array_key_exists('new', $new_group)) { 344 $ins_groups[] = ['name' => $new_group['new']]; 345 } 346 else { 347 $new_groupids[] = $new_group; 348 } 349 } 350 351 if ($ins_groups) { 352 if (!$result = API::HostGroup()->create($ins_groups)) { 353 throw new Exception(); 354 } 355 356 $new_groupids = array_merge($new_groupids, $result['groupids']); 357 } 358 } 359 else { 360 $new_groupids = getRequest('new_groups', []); 361 } 362 } 363 364 // Step 1. Replace existing groups. 365 if (array_key_exists('groups', $visible)) { 366 $replace_groupids = []; 367 368 if (hasRequest('groups')) { 369 // First (step 1.) we try to replace existing groups and add new groups in the process (step 2.). 370 $replace_groupids = array_unique(array_merge(getRequest('groups'), $new_groupids)); 371 } 372 elseif ($new_groupids) { 373 /* 374 * If no groups need to be replaced, use same variable as if new groups are added. This is used in 375 * step 3. The only difference is that we try to remove all existing groups by replacing with nothing 376 * since we left it empty. 377 */ 378 $replace_groupids = $new_groupids; 379 } 380 381 $newValues['groups'] = zbx_toObject($replace_groupids, 'groupid'); 382 } 383 384 if (isset($_REQUEST['mass_replace_tpls'])) { 385 if (isset($_REQUEST['mass_clear_tpls'])) { 386 $hostTemplates = API::Template()->get([ 387 'output' => ['templateid'], 388 'hostids' => $hostIds 389 ]); 390 391 $hostTemplateIds = zbx_objectValues($hostTemplates, 'templateid'); 392 $templatesToDelete = array_diff($hostTemplateIds, $templateids); 393 394 $newValues['templates_clear'] = zbx_toObject($templatesToDelete, 'templateid'); 395 } 396 397 $newValues['templates'] = $templateids; 398 } 399 400 $host_inventory = array_intersect_key(getRequest('host_inventory', []), $visible); 401 402 if (hasRequest('inventory_mode') && array_key_exists('inventory_mode', $visible)) { 403 $newValues['inventory_mode'] = getRequest('inventory_mode', HOST_INVENTORY_DISABLED); 404 405 if ($newValues['inventory_mode'] == HOST_INVENTORY_DISABLED) { 406 $host_inventory = []; 407 } 408 } 409 410 foreach ($hosts as &$host) { 411 if (array_key_exists('inventory_mode', $newValues)) { 412 $host['inventory'] = $host_inventory; 413 } 414 elseif (array_key_exists('inventory_mode', $host['inventory']) 415 && $host['inventory']['inventory_mode'] != HOST_INVENTORY_DISABLED) { 416 $host['inventory'] = $host_inventory; 417 } 418 else { 419 $host['inventory'] = []; 420 } 421 422 /* 423 * Step 3. Case when groups need to be removed. This is done inside the loop, since each host may have 424 * different existing groups. So we need to know what can we remove. 425 */ 426 if (array_key_exists('remove_groups', $visible)) { 427 $remove_groups = getRequest('remove_groups', []); 428 429 if (array_key_exists('groups', $visible)) { 430 /* 431 * Previously we determined what groups for ALL hosts will be replaced. 432 * The $replace_groupids holds both - groups to replace and new groups to add. 433 * New $replace_groupids is the difference between the replaceable groups and removable groups. 434 */ 435 $replace_groupids = array_diff($replace_groupids, $remove_groups); 436 } 437 else { 438 /* 439 * The $new_groupids holds only groups that need to be added. So $replace_groupids is 440 * the difference between the groups that already exist + groups that need to be added and 441 * removable groups. 442 */ 443 $current_groupids = zbx_objectValues($host['groups'], 'groupid'); 444 445 $replace_groupids = array_diff(array_unique(array_merge($current_groupids, $new_groupids)), 446 $remove_groups 447 ); 448 } 449 450 $newValues['groups'] = zbx_toObject($replace_groupids, 'groupid'); 451 } 452 453 // Case when we only need to add new groups to host. 454 if ($new_groupids && !array_key_exists('groups', $visible) 455 && !array_key_exists('remove_groups', $visible)) { 456 $current_groupids = zbx_objectValues($host['groups'], 'groupid'); 457 458 $host['groups'] = zbx_toObject(array_unique(array_merge($current_groupids, $new_groupids)), 'groupid'); 459 } 460 else { 461 // In all other cases we first clear out the old values. And simply replace with $newValues later. 462 unset($host['groups']); 463 } 464 465 if ($templateids && array_key_exists('parentTemplates', $host)) { 466 $host['templates'] = array_unique( 467 array_merge($templateids, zbx_objectValues($host['parentTemplates'], 'templateid')) 468 ); 469 } 470 471 unset($host['parentTemplates']); 472 473 $host = array_merge($host, $newValues); 474 } 475 unset($host); 476 477 $result = (bool) API::Host()->update($hosts); 478 479 if ($result === false) { 480 throw new Exception(); 481 } 482 483 DBend(true); 484 485 uncheckTableRows(); 486 show_message(_('Hosts updated')); 487 488 unset($_REQUEST['masssave'], $_REQUEST['form'], $_REQUEST['hosts']); 489 } 490 catch (Exception $e) { 491 DBend(false); 492 show_error_message(_('Cannot update hosts')); 493 } 494} 495elseif (hasRequest('add') || hasRequest('update')) { 496 try { 497 DBstart(); 498 499 $hostId = getRequest('hostid', 0); 500 501 if ($hostId != 0) { 502 $create = false; 503 504 $msgOk = _('Host updated'); 505 $msgFail = _('Cannot update host'); 506 507 $dbHost = API::Host()->get([ 508 'output' => ['hostid', 'host', 'name', 'status', 'description', 'proxy_hostid', 'ipmi_authtype', 509 'ipmi_privilege', 'ipmi_username', 'ipmi_password', 'tls_connect', 'tls_accept', 'tls_psk_identity', 510 'tls_psk', 'tls_issuer', 'tls_subject', 'flags' 511 ], 512 'hostids' => $hostId, 513 'editable' => true 514 ]); 515 $dbHost = reset($dbHost); 516 } 517 else { 518 $create = true; 519 520 $msgOk = _('Host added'); 521 $msgFail = _('Cannot add host'); 522 } 523 524 // host data 525 if (!$create && $dbHost['flags'] == ZBX_FLAG_DISCOVERY_CREATED) { 526 $host = [ 527 'hostid' => $hostId, 528 'status' => getRequest('status', HOST_STATUS_NOT_MONITORED), 529 'description' => getRequest('description', ''), 530 'inventory' => (getRequest('inventory_mode') == HOST_INVENTORY_DISABLED) 531 ? [] 532 : getRequest('host_inventory', []) 533 ]; 534 } 535 else { 536 // templates 537 $templates = []; 538 539 foreach (getRequest('templates', []) as $templateId) { 540 $templates[] = ['templateid' => $templateId]; 541 } 542 543 // interfaces 544 $interfaces = getRequest('interfaces', []); 545 546 foreach ($interfaces as $key => $interface) { 547 if (zbx_empty($interface['ip']) && zbx_empty($interface['dns'])) { 548 unset($interface[$key]); 549 continue; 550 } 551 552 if ($interface['type'] == INTERFACE_TYPE_SNMP && !isset($interface['bulk'])) { 553 $interfaces[$key]['bulk'] = SNMP_BULK_DISABLED; 554 } 555 else { 556 $interfaces[$key]['bulk'] = SNMP_BULK_ENABLED; 557 } 558 559 if ($interface['isNew']) { 560 unset($interfaces[$key]['interfaceid']); 561 } 562 563 unset($interfaces[$key]['isNew']); 564 $interfaces[$key]['main'] = 0; 565 } 566 567 $mainInterfaces = getRequest('mainInterfaces', []); 568 foreach ([INTERFACE_TYPE_AGENT, INTERFACE_TYPE_SNMP, INTERFACE_TYPE_JMX, INTERFACE_TYPE_IPMI] as $type) { 569 if (array_key_exists($type, $mainInterfaces)) { 570 $interfaces[$mainInterfaces[$type]]['main'] = INTERFACE_PRIMARY; 571 } 572 } 573 574 // Add new group. 575 $groups = getRequest('groups', []); 576 $new_groups = []; 577 578 foreach ($groups as $idx => $group) { 579 if (is_array($group) && array_key_exists('new', $group)) { 580 $new_groups[] = ['name' => $group['new']]; 581 unset($groups[$idx]); 582 } 583 } 584 585 if ($new_groups) { 586 $new_groupid = API::HostGroup()->create($new_groups); 587 588 if (!$new_groupid) { 589 throw new Exception(); 590 } 591 592 $groups = array_merge($groups, $new_groupid['groupids']); 593 } 594 595 // Host data. 596 $host = [ 597 'host' => getRequest('host'), 598 'name' => getRequest('visiblename'), 599 'status' => getRequest('status', HOST_STATUS_NOT_MONITORED), 600 'description' => getRequest('description'), 601 'proxy_hostid' => getRequest('proxy_hostid', 0), 602 'ipmi_authtype' => getRequest('ipmi_authtype'), 603 'ipmi_privilege' => getRequest('ipmi_privilege'), 604 'ipmi_username' => getRequest('ipmi_username'), 605 'ipmi_password' => getRequest('ipmi_password'), 606 'tls_connect' => getRequest('tls_connect', HOST_ENCRYPTION_NONE), 607 'tls_accept' => getRequest('tls_accept', HOST_ENCRYPTION_NONE), 608 'groups' => zbx_toObject($groups, 'groupid'), 609 'templates' => $templates, 610 'interfaces' => $interfaces, 611 'macros' => $macros, 612 'inventory_mode' => getRequest('inventory_mode'), 613 'inventory' => (getRequest('inventory_mode') == HOST_INVENTORY_DISABLED) 614 ? [] 615 : getRequest('host_inventory', []) 616 ]; 617 618 if ($host['tls_connect'] == HOST_ENCRYPTION_PSK || ($host['tls_accept'] & HOST_ENCRYPTION_PSK)) { 619 $host['tls_psk_identity'] = getRequest('tls_psk_identity', ''); 620 $host['tls_psk'] = getRequest('tls_psk', ''); 621 } 622 623 if ($host['tls_connect'] == HOST_ENCRYPTION_CERTIFICATE 624 || ($host['tls_accept'] & HOST_ENCRYPTION_CERTIFICATE)) { 625 $host['tls_issuer'] = getRequest('tls_issuer', ''); 626 $host['tls_subject'] = getRequest('tls_subject', ''); 627 } 628 629 if (!$create) { 630 $host['templates_clear'] = zbx_toObject(getRequest('clear_templates', []), 'templateid'); 631 } 632 } 633 634 if ($create) { 635 $hostIds = API::Host()->create($host); 636 637 if ($hostIds) { 638 $hostId = reset($hostIds['hostids']); 639 } 640 else { 641 throw new Exception(); 642 } 643 } 644 else { 645 $host['hostid'] = $hostId; 646 647 if (!API::Host()->update($host)) { 648 throw new Exception(); 649 } 650 } 651 652 // full clone 653 if (getRequest('form', '') === 'full_clone' && getRequest('clone_hostid', 0) != 0) { 654 $srcHostId = getRequest('clone_hostid'); 655 656 // copy applications 657 if (!copyApplications($srcHostId, $hostId)) { 658 throw new Exception(); 659 } 660 661 /* 662 * First copy web scenarios with web items, so that later regular items can use web item as their master 663 * item. 664 */ 665 if (!copyHttpTests($srcHostId, $hostId)) { 666 throw new Exception(); 667 } 668 669 if (!copyItems($srcHostId, $hostId)) { 670 throw new Exception(); 671 } 672 673 // copy triggers 674 $dbTriggers = API::Trigger()->get([ 675 'output' => ['triggerid'], 676 'hostids' => $srcHostId, 677 'inherited' => false, 678 'filter' => ['flags' => ZBX_FLAG_DISCOVERY_NORMAL] 679 ]); 680 681 if ($dbTriggers) { 682 if (!copyTriggersToHosts(zbx_objectValues($dbTriggers, 'triggerid'), $hostId, $srcHostId)) { 683 throw new Exception(); 684 } 685 } 686 687 // copy discovery rules 688 $dbDiscoveryRules = API::DiscoveryRule()->get([ 689 'output' => ['itemid'], 690 'hostids' => $srcHostId, 691 'inherited' => false 692 ]); 693 694 if ($dbDiscoveryRules) { 695 $copyDiscoveryRules = API::DiscoveryRule()->copy([ 696 'discoveryids' => zbx_objectValues($dbDiscoveryRules, 'itemid'), 697 'hostids' => [$hostId] 698 ]); 699 700 if (!$copyDiscoveryRules) { 701 throw new Exception(); 702 } 703 } 704 705 // copy graphs 706 $dbGraphs = API::Graph()->get([ 707 'output' => API_OUTPUT_EXTEND, 708 'selectHosts' => ['hostid'], 709 'selectItems' => ['type'], 710 'hostids' => $srcHostId, 711 'filter' => ['flags' => ZBX_FLAG_DISCOVERY_NORMAL], 712 'inherited' => false 713 ]); 714 715 foreach ($dbGraphs as $dbGraph) { 716 if (count($dbGraph['hosts']) > 1) { 717 continue; 718 } 719 720 if (httpItemExists($dbGraph['items'])) { 721 continue; 722 } 723 724 if (!copyGraphToHost($dbGraph['graphid'], $hostId)) { 725 throw new Exception(); 726 } 727 } 728 } 729 730 $result = DBend(true); 731 732 if ($result) { 733 uncheckTableRows(); 734 } 735 show_messages($result, $msgOk, $msgFail); 736 737 unset($_REQUEST['form'], $_REQUEST['hostid']); 738 } 739 catch (Exception $e) { 740 DBend(false); 741 show_messages(false, $msgOk, $msgFail); 742 } 743} 744elseif (hasRequest('delete') && hasRequest('hostid')) { 745 DBstart(); 746 747 $result = API::Host()->delete([getRequest('hostid')]); 748 $result = DBend($result); 749 750 if ($result) { 751 unset($_REQUEST['form'], $_REQUEST['hostid']); 752 uncheckTableRows(); 753 } 754 show_messages($result, _('Host deleted'), _('Cannot delete host')); 755 756 unset($_REQUEST['delete']); 757} 758elseif (hasRequest('action') && getRequest('action') == 'host.massdelete' && hasRequest('hosts')) { 759 DBstart(); 760 761 $result = API::Host()->delete(getRequest('hosts')); 762 $result = DBend($result); 763 764 if ($result) { 765 uncheckTableRows(); 766 } 767 else { 768 $hostids = API::Host()->get([ 769 'output' => [], 770 'hostids' => getRequest('hosts'), 771 'editable' => true 772 ]); 773 uncheckTableRows(getRequest('hostid'), zbx_objectValues($hostids, 'hostid')); 774 } 775 show_messages($result, _('Host deleted'), _('Cannot delete host')); 776} 777elseif (hasRequest('action') && str_in_array(getRequest('action'), ['host.massenable', 'host.massdisable']) && hasRequest('hosts')) { 778 $enable =(getRequest('action') == 'host.massenable'); 779 $status = $enable ? TRIGGER_STATUS_ENABLED : TRIGGER_STATUS_DISABLED; 780 781 $actHosts = API::Host()->get([ 782 'hostids' => getRequest('hosts'), 783 'editable' => true, 784 'templated_hosts' => true, 785 'output' => ['hostid'] 786 ]); 787 788 if ($actHosts) { 789 foreach ($actHosts as &$host) { 790 $host['status'] = $status; 791 } 792 unset($host); 793 794 $result = (bool) API::Host()->update($actHosts); 795 796 if ($result) { 797 uncheckTableRows(); 798 } 799 800 $updated = count($actHosts); 801 802 $messageSuccess = $enable 803 ? _n('Host enabled', 'Hosts enabled', $updated) 804 : _n('Host disabled', 'Hosts disabled', $updated); 805 $messageFailed = $enable 806 ? _n('Cannot enable host', 'Cannot enable hosts', $updated) 807 : _n('Cannot disable host', 'Cannot disable hosts', $updated); 808 809 show_messages($result, $messageSuccess, $messageFailed); 810 } 811} 812 813/* 814 * Display 815 */ 816$pageFilter = new CPageFilter([ 817 'groups' => [ 818 'real_hosts' => true, 819 'editable' => true 820 ], 821 'groupid' => getRequest('groupid') 822]); 823 824$_REQUEST['groupid'] = $pageFilter->groupid; 825$_REQUEST['hostid'] = getRequest('hostid', 0); 826 827$config = select_config(); 828 829if ((getRequest('action') === 'host.massupdateform' || hasRequest('masssave')) && hasRequest('hosts')) { 830 $data = [ 831 'hosts' => getRequest('hosts'), 832 'visible' => getRequest('visible', []), 833 'mass_replace_tpls' => getRequest('mass_replace_tpls'), 834 'mass_clear_tpls' => getRequest('mass_clear_tpls'), 835 'groups' => getRequest('groups', []), 836 'status' => getRequest('status', HOST_STATUS_MONITORED), 837 'description' => getRequest('description'), 838 'proxy_hostid' => getRequest('proxy_hostid', ''), 839 'ipmi_authtype' => getRequest('ipmi_authtype', IPMI_AUTHTYPE_DEFAULT), 840 'ipmi_privilege' => getRequest('ipmi_privilege', IPMI_PRIVILEGE_USER), 841 'ipmi_username' => getRequest('ipmi_username', ''), 842 'ipmi_password' => getRequest('ipmi_password', ''), 843 'inventory_mode' => getRequest('inventory_mode', HOST_INVENTORY_DISABLED), 844 'host_inventory' => getRequest('host_inventory', []), 845 'templates' => getRequest('templates', []), 846 'inventories' => zbx_toHash(getHostInventories(), 'db_field'), 847 'tls_connect' => getRequest('tls_connect', HOST_ENCRYPTION_NONE), 848 'tls_accept' => getRequest('tls_accept', HOST_ENCRYPTION_NONE), 849 'tls_issuer' => getRequest('tls_issuer', ''), 850 'tls_subject' => getRequest('tls_subject', ''), 851 'tls_psk_identity' => getRequest('tls_psk_identity', ''), 852 'tls_psk' => getRequest('tls_psk', '') 853 ]; 854 855 // sort templates 856 natsort($data['templates']); 857 858 // get groups 859 $data['all_groups'] = API::HostGroup()->get([ 860 'output' => API_OUTPUT_EXTEND, 861 'editable' => true 862 ]); 863 order_result($data['all_groups'], 'name'); 864 865 // get proxies 866 $data['proxies'] = DBfetchArray(DBselect( 867 'SELECT h.hostid,h.host'. 868 ' FROM hosts h'. 869 ' WHERE h.status IN ('.HOST_STATUS_PROXY_ACTIVE.','.HOST_STATUS_PROXY_PASSIVE.')' 870 )); 871 order_result($data['proxies'], 'host'); 872 873 // get templates data 874 $data['linkedTemplates'] = !empty($data['templates']) 875 ? CArrayHelper::renameObjectsKeys(API::Template()->get([ 876 'output' => ['templateid', 'name'], 877 'templateids' => $data['templates'] 878 ]), ['templateid' => 'id']) 879 : []; 880 881 $hostView = new CView('configuration.host.massupdate', $data); 882} 883elseif (hasRequest('form')) { 884 $data = [ 885 // Common & auxiliary 886 'form' => getRequest('form', ''), 887 'hostid' => getRequest('hostid', 0), 888 'clone_hostid' => getRequest('clone_hostid', 0), 889 'flags' => getRequest('flags', ZBX_FLAG_DISCOVERY_NORMAL), 890 891 // Host 892 'host' => getRequest('host', ''), 893 'visiblename' => getRequest('visiblename', ''), 894 'interfaces' => getRequest('interfaces', []), 895 'mainInterfaces' => getRequest('mainInterfaces', []), 896 'description' => getRequest('description', ''), 897 'proxy_hostid' => getRequest('proxy_hostid', 0), 898 'status' => getRequest('status', HOST_STATUS_NOT_MONITORED), 899 900 // Templates 901 'templates' => getRequest('templates', []), 902 'clear_templates' => getRequest('clear_templates', []), 903 'original_templates' => [], 904 'linked_templates' => [], 905 906 // IPMI 907 'ipmi_authtype' => getRequest('ipmi_authtype', IPMI_AUTHTYPE_DEFAULT), 908 'ipmi_privilege' => getRequest('ipmi_privilege', IPMI_PRIVILEGE_USER), 909 'ipmi_username' => getRequest('ipmi_username', ''), 910 'ipmi_password' => getRequest('ipmi_password', ''), 911 912 // Macros 913 'macros' => $macros, 914 'show_inherited_macros' => getRequest('show_inherited_macros', 0), 915 916 // Host inventory 917 'inventory_mode' => getRequest('inventory_mode', $config['default_inventory_mode']), 918 'host_inventory' => getRequest('host_inventory', []), 919 'inventory_items' => [], 920 921 // Encryption 922 'tls_connect' => getRequest('tls_connect', HOST_ENCRYPTION_NONE), 923 'tls_accept' => getRequest('tls_accept', HOST_ENCRYPTION_NONE), 924 'tls_issuer' => getRequest('tls_issuer', ''), 925 'tls_subject' => getRequest('tls_subject', ''), 926 'tls_psk_identity' => getRequest('tls_psk_identity', ''), 927 'tls_psk' => getRequest('tls_psk', '') 928 ]; 929 930 $groups = []; 931 932 if (!hasRequest('form_refresh')) { 933 if ($data['hostid'] != 0) { 934 $dbHosts = API::Host()->get([ 935 'output' => ['hostid', 'proxy_hostid', 'host', 'name', 'status', 'ipmi_authtype', 'ipmi_privilege', 936 'ipmi_username', 'ipmi_password', 'flags', 'description', 'tls_connect', 'tls_accept', 'tls_issuer', 937 'tls_subject', 'tls_psk_identity', 'tls_psk' 938 ], 939 'selectGroups' => ['groupid'], 940 'selectParentTemplates' => ['templateid'], 941 'selectMacros' => ['hostmacroid', 'macro', 'value'], 942 'selectDiscoveryRule' => ['itemid', 'name'], 943 'selectInventory' => true, 944 'hostids' => [$data['hostid']] 945 ]); 946 $dbHost = reset($dbHosts); 947 948 $data['flags'] = $dbHost['flags']; 949 if ($data['flags'] == ZBX_FLAG_DISCOVERY_CREATED) { 950 $data['discoveryRule'] = $dbHost['discoveryRule']; 951 } 952 953 // Host 954 $data['host'] = $dbHost['host']; 955 $data['visiblename'] = $dbHost['name']; 956 $data['interfaces'] = API::HostInterface()->get([ 957 'output' => ['interfaceid', 'main', 'type', 'useip', 'ip', 'dns', 'port', 'bulk'], 958 'selectItems' => ['type'], 959 'hostids' => [$data['hostid']], 960 'sortfield' => 'interfaceid' 961 ]); 962 $data['description'] = $dbHost['description']; 963 $data['proxy_hostid'] = $dbHost['proxy_hostid']; 964 $data['status'] = $dbHost['status']; 965 966 // Templates 967 $data['templates'] = zbx_objectValues($dbHost['parentTemplates'], 'templateid'); 968 $data['original_templates'] = array_combine($data['templates'], $data['templates']); 969 970 // IPMI 971 $data['ipmi_authtype'] = $dbHost['ipmi_authtype']; 972 $data['ipmi_privilege'] = $dbHost['ipmi_privilege']; 973 $data['ipmi_username'] = $dbHost['ipmi_username']; 974 $data['ipmi_password'] = $dbHost['ipmi_password']; 975 976 // Macros 977 $data['macros'] = $dbHost['macros']; 978 979 // Interfaces 980 foreach ($data['interfaces'] as &$interface) { 981 if ($data['flags'] == ZBX_FLAG_DISCOVERY_CREATED) { 982 $interface['locked'] = true; 983 } 984 else { 985 // check if interface has items that require specific interface type, if so type cannot be changed 986 $interface['locked'] = false; 987 foreach ($interface['items'] as $item) { 988 $type = itemTypeInterface($item['type']); 989 if ($type !== false && $type != INTERFACE_TYPE_ANY) { 990 $interface['locked'] = true; 991 break; 992 } 993 } 994 } 995 996 $interface['items'] = (bool) $interface['items']; 997 } 998 unset($interface); 999 1000 // Host inventory 1001 $data['inventory_mode'] = array_key_exists('inventory_mode', $dbHost['inventory']) 1002 ? $dbHost['inventory']['inventory_mode'] 1003 : HOST_INVENTORY_DISABLED; 1004 $data['host_inventory'] = $dbHost['inventory']; 1005 unset($data['host_inventory']['inventory_mode']); 1006 1007 // Encryption 1008 $data['tls_connect'] = $dbHost['tls_connect']; 1009 $data['tls_accept'] = $dbHost['tls_accept']; 1010 $data['tls_issuer'] = $dbHost['tls_issuer']; 1011 $data['tls_subject'] = $dbHost['tls_subject']; 1012 $data['tls_psk_identity'] = $dbHost['tls_psk_identity']; 1013 $data['tls_psk'] = $dbHost['tls_psk']; 1014 1015 // display empty visible name if equal to host name 1016 if ($data['host'] === $data['visiblename']) { 1017 $data['visiblename'] = ''; 1018 } 1019 1020 $groups = zbx_objectValues($dbHost['groups'], 'groupid'); 1021 } 1022 else { 1023 if (getRequest('groupid', 0) != 0) { 1024 $groups[] = getRequest('groupid'); 1025 } 1026 1027 $data['status'] = HOST_STATUS_MONITORED; 1028 } 1029 } 1030 else { 1031 if ($data['hostid'] != 0) { 1032 $dbHosts = API::Host()->get([ 1033 'output' => ['flags'], 1034 'selectParentTemplates' => ['templateid'], 1035 'selectDiscoveryRule' => ['itemid', 'name'], 1036 'hostids' => [$data['hostid']] 1037 ]); 1038 $dbHost = reset($dbHosts); 1039 1040 $data['flags'] = $dbHost['flags']; 1041 if ($data['flags'] == ZBX_FLAG_DISCOVERY_CREATED) { 1042 $data['discoveryRule'] = $dbHost['discoveryRule']; 1043 } 1044 1045 $templateids = zbx_objectValues($dbHost['parentTemplates'], 'templateid'); 1046 $data['original_templates'] = array_combine($templateids, $templateids); 1047 } 1048 1049 foreach ([INTERFACE_TYPE_AGENT, INTERFACE_TYPE_SNMP, INTERFACE_TYPE_JMX, INTERFACE_TYPE_IPMI] as $type) { 1050 if (array_key_exists($type, $data['mainInterfaces'])) { 1051 $interfaceid = $data['mainInterfaces'][$type]; 1052 $data['interfaces'][$interfaceid]['main'] = '1'; 1053 } 1054 } 1055 $data['interfaces'] = array_values($data['interfaces']); 1056 1057 $groups = getRequest('groups', []); 1058 } 1059 1060 if ($data['hostid'] != 0) { 1061 // get items that populate host inventory fields 1062 $data['inventory_items'] = API::Item()->get([ 1063 'output' => ['inventory_link', 'itemid', 'hostid', 'name', 'key_'], 1064 'hostids' => [$dbHost['hostid']], 1065 'filter' => ['inventory_link' => array_keys(getHostInventories())] 1066 ]); 1067 $data['inventory_items'] = zbx_toHash($data['inventory_items'], 'inventory_link'); 1068 $data['inventory_items'] = CMacrosResolverHelper::resolveItemNames($data['inventory_items']); 1069 } 1070 1071 if ($data['flags'] == ZBX_FLAG_DISCOVERY_CREATED) { 1072 if ($data['proxy_hostid'] != 0) { 1073 $data['proxies'] = API::Proxy()->get([ 1074 'output' => ['host'], 1075 'proxyids' => [$data['proxy_hostid']], 1076 'preservekeys' => true 1077 ]); 1078 } 1079 else { 1080 $data['proxies'] = []; 1081 } 1082 } 1083 else { 1084 $data['proxies'] = API::Proxy()->get([ 1085 'output' => ['host'], 1086 'preservekeys' => true 1087 ]); 1088 order_result($data['proxies'], 'host'); 1089 } 1090 1091 foreach ($data['proxies'] as &$proxy) { 1092 $proxy = $proxy['host']; 1093 } 1094 unset($proxy); 1095 1096 if ($data['show_inherited_macros']) { 1097 $data['macros'] = mergeInheritedMacros($data['macros'], getInheritedMacros($data['templates'])); 1098 } 1099 $data['macros'] = array_values(order_macros($data['macros'], 'macro')); 1100 1101 if (!$data['macros'] && $data['flags'] != ZBX_FLAG_DISCOVERY_CREATED) { 1102 $macro = ['macro' => '', 'value' => '']; 1103 if ($data['show_inherited_macros']) { 1104 $macro['type'] = MACRO_TYPE_HOSTMACRO; 1105 } 1106 $data['macros'][] = $macro; 1107 } 1108 1109 $groupids = []; 1110 1111 foreach ($groups as $group) { 1112 if (is_array($group) && array_key_exists('new', $group)) { 1113 continue; 1114 } 1115 1116 $groupids[] = $group; 1117 } 1118 1119 // Groups with R and RW permissions. 1120 $groups_all = $groupids 1121 ? API::HostGroup()->get([ 1122 'output' => ['name'], 1123 'groupids' => $groupids, 1124 'preservekeys' => true 1125 ]) 1126 : []; 1127 1128 // Groups with RW permissions. 1129 $groups_rw = $groupids && (CWebUser::getType() != USER_TYPE_SUPER_ADMIN) 1130 ? API::HostGroup()->get([ 1131 'output' => [], 1132 'groupids' => $groupids, 1133 'editable' => true, 1134 'preservekeys' => true 1135 ]) 1136 : []; 1137 1138 $data['groups_ms'] = []; 1139 1140 // Prepare data for multiselect. 1141 foreach ($groups as $group) { 1142 if (is_array($group) && array_key_exists('new', $group)) { 1143 $data['groups_ms'][] = [ 1144 'id' => $group['new'], 1145 'name' => $group['new'].' ('._x('new', 'new element in multiselect').')', 1146 'isNew' => true 1147 ]; 1148 } 1149 elseif (array_key_exists($group, $groups_all)) { 1150 $data['groups_ms'][] = [ 1151 'id' => $group, 1152 'name' => $groups_all[$group]['name'], 1153 'disabled' => (CWebUser::getType() != USER_TYPE_SUPER_ADMIN) && !array_key_exists($group, $groups_rw) 1154 ]; 1155 } 1156 } 1157 CArrayHelper::sort($data['groups_ms'], ['name']); 1158 1159 if ($data['templates']) { 1160 $data['linked_templates'] = API::Template()->get([ 1161 'output' => ['templateid', 'name'], 1162 'templateids' => $data['templates'] 1163 ]); 1164 CArrayHelper::sort($data['linked_templates'], ['name']); 1165 1166 $data['writable_templates'] = API::Template()->get([ 1167 'output' => ['templateid'], 1168 'templateids' => $data['templates'], 1169 'editable' => true, 1170 'preservekeys' => true 1171 ]); 1172 } 1173 1174 $hostView = new CView('configuration.host.edit', $data); 1175} 1176else { 1177 $sortField = getRequest('sort', CProfile::get('web.'.$page['file'].'.sort', 'name')); 1178 $sortOrder = getRequest('sortorder', CProfile::get('web.'.$page['file'].'.sortorder', ZBX_SORT_UP)); 1179 1180 CProfile::update('web.'.$page['file'].'.sort', $sortField, PROFILE_TYPE_STR); 1181 CProfile::update('web.'.$page['file'].'.sortorder', $sortOrder, PROFILE_TYPE_STR); 1182 1183 $filter['templates'] = $filter['templates'] 1184 ? CArrayHelper::renameObjectsKeys(API::Template()->get([ 1185 'output' => ['templateid', 'name'], 1186 'templateids' => $filter['templates'], 1187 'preservekeys' => true 1188 ]), ['templateid' => 'id']) 1189 : []; 1190 1191 // get Hosts 1192 $hosts = []; 1193 if ($pageFilter->groupsSelected) { 1194 switch ($filter['monitored_by']) { 1195 case ZBX_MONITORED_BY_ANY: 1196 $proxyids = null; 1197 break; 1198 1199 case ZBX_MONITORED_BY_PROXY: 1200 $proxyids = $filter['proxyids'] 1201 ? $filter['proxyids'] 1202 : array_keys(API::Proxy()->get([ 1203 'output' => [], 1204 'preservekeys' => true 1205 ])); 1206 break; 1207 1208 case ZBX_MONITORED_BY_SERVER: 1209 $proxyids = 0; 1210 break; 1211 } 1212 1213 $hosts = API::Host()->get([ 1214 'output' => ['hostid', $sortField], 1215 'groupids' => $pageFilter->groupids, 1216 'templateids' => $filter['templates'] ? array_keys($filter['templates']) : null, 1217 'editable' => true, 1218 'sortfield' => $sortField, 1219 'limit' => $config['search_limit'] + 1, 1220 'search' => [ 1221 'name' => ($filter['host'] === '') ? null : $filter['host'], 1222 'ip' => ($filter['ip'] === '') ? null : $filter['ip'], 1223 'dns' => ($filter['dns'] === '') ? null : $filter['dns'] 1224 ], 1225 'filter' => [ 1226 'port' => ($filter['port'] === '') ? null : $filter['port'] 1227 ], 1228 'proxyids' => $proxyids 1229 ]); 1230 } 1231 order_result($hosts, $sortField, $sortOrder); 1232 1233 $url = (new CUrl('hosts.php')) 1234 ->setArgument('groupid', $pageFilter->groupid); 1235 1236 $pagingLine = getPagingLine($hosts, $sortOrder, $url); 1237 1238 $hosts = API::Host()->get([ 1239 'hostids' => zbx_objectValues($hosts, 'hostid'), 1240 'output' => API_OUTPUT_EXTEND, 1241 'selectParentTemplates' => ['hostid', 'name'], 1242 'selectInterfaces' => API_OUTPUT_EXTEND, 1243 'selectItems' => API_OUTPUT_COUNT, 1244 'selectDiscoveries' => API_OUTPUT_COUNT, 1245 'selectTriggers' => API_OUTPUT_COUNT, 1246 'selectGraphs' => API_OUTPUT_COUNT, 1247 'selectApplications' => API_OUTPUT_COUNT, 1248 'selectHttpTests' => API_OUTPUT_COUNT, 1249 'selectDiscoveryRule' => ['itemid', 'name'], 1250 'selectHostDiscovery' => ['ts_delete'] 1251 ]); 1252 order_result($hosts, $sortField, $sortOrder); 1253 1254 // selecting linked templates to templates linked to hosts 1255 $templateids = []; 1256 1257 foreach ($hosts as $host) { 1258 $templateids = array_merge($templateids, zbx_objectValues($host['parentTemplates'], 'templateid')); 1259 } 1260 1261 $templateids = array_keys(array_flip($templateids)); 1262 1263 $templates = API::Template()->get([ 1264 'output' => ['templateid', 'name'], 1265 'templateids' => $templateids, 1266 'selectParentTemplates' => ['hostid', 'name'], 1267 'preservekeys' => true 1268 ]); 1269 1270 // selecting writable templates IDs 1271 $writable_templates = []; 1272 if ($templateids) { 1273 foreach ($templates as $template) { 1274 $templateids = array_merge($templateids, zbx_objectValues($template['parentTemplates'], 'templateid')); 1275 } 1276 1277 $writable_templates = API::Template()->get([ 1278 'output' => ['templateid'], 1279 'templateids' => array_keys(array_flip($templateids)), 1280 'editable' => true, 1281 'preservekeys' => true 1282 ]); 1283 } 1284 1285 // Get proxy host IDs that are not 0 and maintenance IDs. 1286 $proxyHostIds = []; 1287 $maintenanceids = []; 1288 1289 foreach ($hosts as &$host) { 1290 // Sort interfaces to be listed starting with one selected as 'main'. 1291 CArrayHelper::sort($host['interfaces'], [ 1292 ['field' => 'main', 'order' => ZBX_SORT_DOWN] 1293 ]); 1294 1295 if ($host['proxy_hostid']) { 1296 $proxyHostIds[$host['proxy_hostid']] = $host['proxy_hostid']; 1297 } 1298 1299 if ($host['status'] == HOST_STATUS_MONITORED && $host['maintenance_status'] == HOST_MAINTENANCE_STATUS_ON) { 1300 $maintenanceids[$host['maintenanceid']] = true; 1301 } 1302 } 1303 unset($host); 1304 1305 $proxies = []; 1306 if ($proxyHostIds) { 1307 $proxies = API::Proxy()->get([ 1308 'proxyids' => $proxyHostIds, 1309 'output' => ['host'], 1310 'preservekeys' => true 1311 ]); 1312 } 1313 1314 // Prepare data for multiselect and remove unexisting proxies. 1315 $proxies_ms = []; 1316 if ($filter['proxyids']) { 1317 $filter_proxies = API::Proxy()->get([ 1318 'output' => ['proxyid', 'host'], 1319 'proxyids' => $filter['proxyids'] 1320 ]); 1321 1322 $proxies_ms = CArrayHelper::renameObjectsKeys($filter_proxies, ['proxyid' => 'id', 'host' => 'name']); 1323 } 1324 1325 $db_maintenances = []; 1326 1327 if ($maintenanceids) { 1328 $db_maintenances = API::Maintenance()->get([ 1329 'output' => ['name', 'description'], 1330 'maintenanceids' => array_keys($maintenanceids), 1331 'preservekeys' => true 1332 ]); 1333 } 1334 1335 $data = [ 1336 'pageFilter' => $pageFilter, 1337 'hosts' => $hosts, 1338 'paging' => $pagingLine, 1339 'filter' => $filter, 1340 'sortField' => $sortField, 1341 'sortOrder' => $sortOrder, 1342 'groupId' => $pageFilter->groupid, 1343 'config' => $config, 1344 'templates' => $templates, 1345 'maintenances' => $db_maintenances, 1346 'writable_templates' => $writable_templates, 1347 'proxies' => $proxies, 1348 'proxies_ms' => $proxies_ms, 1349 'profileIdx' => 'web.hosts.filter', 1350 'active_tab' => CProfile::get('web.hosts.filter.active', 1) 1351 ]; 1352 1353 $hostView = new CView('configuration.host.list', $data); 1354} 1355 1356$hostView->render(); 1357$hostView->show(); 1358 1359require_once dirname(__FILE__).'/include/page_footer.php'; 1360