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