1<?php 2/* 3** Zabbix 4** Copyright (C) 2001-2021 Zabbix SIA 5** 6** This program is free software; you can redistribute it and/or modify 7** it under the terms of the GNU General Public License as published by 8** the Free Software Foundation; either version 2 of the License, or 9** (at your option) any later version. 10** 11** This program is distributed in the hope that it will be useful, 12** but WITHOUT ANY WARRANTY; without even the implied warranty of 13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14** GNU General Public License for more details. 15** 16** You should have received a copy of the GNU General Public License 17** along with this program; if not, write to the Free Software 18** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19**/ 20 21 22/** 23 * Class that handles associations for zabbix elements unique fields and their database ids. 24 * The purpose is to gather all elements that need ids from database and resolve them with one query. 25 */ 26class CImportReferencer { 27 28 /** 29 * @var array with references to interfaceid (hostid -> reference_name -> interfaceid) 30 */ 31 public $interfaces_cache = []; 32 33 protected $groups = []; 34 protected $templates = []; 35 protected $hosts = []; 36 protected $items = []; 37 protected $valuemaps = []; 38 protected $triggers = []; 39 protected $graphs = []; 40 protected $iconmaps = []; 41 protected $images = []; 42 protected $maps = []; 43 protected $template_dashboards = []; 44 protected $template_macros = []; 45 protected $host_macros = []; 46 protected $host_prototype_macros = []; 47 protected $proxies = []; 48 protected $host_prototypes = []; 49 protected $httptests = []; 50 protected $httpsteps = []; 51 52 protected $db_groups; 53 protected $db_templates; 54 protected $db_hosts; 55 protected $db_items; 56 protected $db_valuemaps; 57 protected $db_triggers; 58 protected $db_graphs; 59 protected $db_iconmaps; 60 protected $db_images; 61 protected $db_maps; 62 protected $db_template_dashboards; 63 protected $db_template_macros; 64 protected $db_host_macros; 65 protected $db_host_prototype_macros; 66 protected $db_proxies; 67 protected $db_host_prototypes; 68 protected $db_httptests; 69 protected $db_httpsteps; 70 71 /** 72 * Get group ID by group UUID. 73 * 74 * @param string $uuid 75 * 76 * @return string|null 77 */ 78 public function findGroupidByUuid(string $uuid): ?string { 79 if ($this->db_groups === null) { 80 $this->selectGroups(); 81 } 82 83 foreach ($this->db_groups as $groupid => $group) { 84 if ($group['uuid'] === $uuid) { 85 return $groupid; 86 } 87 } 88 89 return null; 90 } 91 92 /** 93 * Get group ID by group name. 94 * 95 * @param string $name 96 * 97 * @return string|null 98 */ 99 public function findGroupidByName(string $name): ?string { 100 if ($this->db_groups === null) { 101 $this->selectGroups(); 102 } 103 104 foreach ($this->db_groups as $groupid => $group) { 105 if ($group['name'] === $name) { 106 return $groupid; 107 } 108 } 109 110 return null; 111 } 112 113 /** 114 * Get template ID by group UUID. 115 * 116 * @param string $uuid 117 * 118 * @return string|null 119 */ 120 public function findTemplateidByUuid(string $uuid): ?string { 121 if ($this->db_templates === null) { 122 $this->selectTemplates(); 123 } 124 125 foreach ($this->db_templates as $templateid => $template) { 126 if ($template['uuid'] === $uuid) { 127 return $templateid; 128 } 129 } 130 131 return null; 132 } 133 134 /** 135 * Get template ID by template host. 136 * 137 * @param string $host 138 * 139 * @return string|null 140 */ 141 public function findTemplateidByHost(string $host): ?string { 142 if ($this->db_templates === null) { 143 $this->selectTemplates(); 144 } 145 146 foreach ($this->db_templates as $templateid => $template) { 147 if ($template['host'] === $host) { 148 return $templateid; 149 } 150 } 151 152 return null; 153 } 154 155 /** 156 * Get host ID by host. 157 * 158 * @param string $name 159 * 160 * @return string|bool 161 */ 162 public function findHostidByHost(string $name): ?string { 163 if ($this->db_hosts === null) { 164 $this->selectHosts(); 165 } 166 167 foreach ($this->db_hosts as $hostid => $host) { 168 if ($host['host'] === $name) { 169 return $hostid; 170 } 171 } 172 173 return null; 174 } 175 176 /** 177 * Get host ID or template ID by host. 178 * 179 * @param string $host 180 * 181 * @return string|null 182 */ 183 public function findTemplateidOrHostidByHost(string $host): ?string { 184 $templateid = $this->findTemplateidByHost($host); 185 186 if ($templateid !== null) { 187 return $templateid; 188 } 189 190 return $this->findHostidByHost($host); 191 } 192 193 /** 194 * Get interface ID by host ID and interface reference. 195 * 196 * @param string $hostid 197 * @param string $interface_ref 198 * 199 * @return string|null 200 */ 201 public function findInterfaceidByRef(string $hostid, string $interface_ref): ?string { 202 if (array_key_exists($hostid, $this->interfaces_cache) 203 && array_key_exists($interface_ref, $this->interfaces_cache[$hostid])) { 204 return $this->interfaces_cache[$hostid][$interface_ref]; 205 } 206 207 return null; 208 } 209 210 /** 211 * Initializes references for items. 212 */ 213 public function initItemsReferences(): void { 214 if ($this->db_items === null) { 215 $this->selectItems(); 216 } 217 } 218 219 /** 220 * Get item ID by uuid. 221 * 222 * @param string $uuid 223 * 224 * @return string|null 225 */ 226 public function findItemidByUuid(string $uuid): ?string { 227 if ($this->db_items === null) { 228 $this->selectItems(); 229 } 230 231 foreach ($this->db_items as $itemid => $item) { 232 if ($item['uuid'] === $uuid) { 233 return $itemid; 234 } 235 } 236 237 return null; 238 } 239 240 /** 241 * Get item ID by host ID and item key_. 242 * 243 * @param string $hostid 244 * @param string $key 245 * 246 * @return string|null 247 */ 248 public function findItemidByKey(string $hostid, string $key): ?string { 249 if ($this->db_items === null) { 250 $this->selectItems(); 251 } 252 253 foreach ($this->db_items as $itemid => $item) { 254 if ($item['hostid'] === $hostid && $item['key_'] === $key) { 255 return $itemid; 256 } 257 } 258 259 return null; 260 } 261 262 /** 263 * Get valuemap ID by valuemap name. 264 * 265 * @param string $hostid 266 * @param string $name 267 * 268 * @return string|null 269 */ 270 public function findValuemapidByName(string $hostid, string $name): ?string { 271 if ($this->db_valuemaps === null) { 272 $this->selectValuemaps(); 273 } 274 275 foreach ($this->db_valuemaps as $valuemapid => $valuemap) { 276 if ($valuemap['hostid'] === $hostid && $valuemap['name'] === $name) { 277 return $valuemapid; 278 } 279 } 280 281 return null; 282 } 283 284 /** 285 * Get image ID by image name. 286 * 287 * @param string $name 288 * 289 * @return string|null 290 */ 291 public function findImageidByName(string $name): ?string { 292 if ($this->db_images === null) { 293 $this->selectImages(); 294 } 295 296 foreach ($this->db_images as $imageid => $image) { 297 if ($image['name'] === $name) { 298 return $imageid; 299 } 300 } 301 302 return null; 303 } 304 305 /** 306 * Get trigger by trigger ID. 307 * 308 * @param string $triggerid 309 * 310 * @return array|null 311 */ 312 public function findTriggerById(string $triggerid): ?array { 313 if ($this->db_triggers === null) { 314 $this->selectTriggers(); 315 } 316 317 if (array_key_exists($triggerid, $this->db_triggers)) { 318 return $this->db_triggers[$triggerid]; 319 } 320 321 return null; 322 } 323 324 /** 325 * Get trigger ID by trigger UUID. 326 * 327 * @param string $uuid 328 * 329 * @return string|null 330 */ 331 public function findTriggeridByUuid(string $uuid): ?string { 332 if ($this->db_triggers === null) { 333 $this->selectTriggers(); 334 } 335 336 foreach ($this->db_triggers as $triggerid => $trigger) { 337 if ($trigger['uuid'] === $uuid) { 338 return $triggerid; 339 } 340 } 341 342 return null; 343 } 344 345 /** 346 * Get trigger ID by trigger name and expressions. 347 * 348 * @param string $name 349 * @param string $expression 350 * @param string $recovery_expression 351 * 352 * @return string|null 353 */ 354 public function findTriggeridByName(string $name, string $expression, string $recovery_expression): ?string { 355 if ($this->db_triggers === null) { 356 $this->selectTriggers(); 357 } 358 359 foreach ($this->db_triggers as $triggerid => $trigger) { 360 if ($trigger['description'] === $name 361 && $trigger['expression'] === $expression 362 && $trigger['recovery_expression'] === $recovery_expression) { 363 return $triggerid; 364 } 365 } 366 367 return null; 368 } 369 370 /** 371 * Get graph ID by UUID. 372 * 373 * @param string $uuid 374 * 375 * @return string|null 376 */ 377 public function findGraphidByUuid(string $uuid): ?string { 378 if ($this->db_graphs === null) { 379 $this->selectGraphs(); 380 } 381 382 foreach ($this->db_graphs as $graphid => $graph) { 383 if ($graph['uuid'] === $uuid) { 384 return $graphid; 385 } 386 } 387 388 return null; 389 } 390 391 /** 392 * Get graph ID by host ID and graph name. 393 * 394 * @param string $hostid 395 * @param string $name 396 * 397 * @return string|null 398 */ 399 public function findGraphidByName(string $hostid, string $name): ?string { 400 if ($this->db_graphs === null) { 401 $this->selectGraphs(); 402 } 403 404 foreach ($this->db_graphs as $graphid => $graph) { 405 if ($graph['name'] === $name && in_array($hostid, $graph['hosts'])) { 406 return $graphid; 407 } 408 } 409 410 return null; 411 } 412 413 /** 414 * Get iconmap ID by name. 415 * 416 * @param string $name 417 * 418 * @return string|null 419 */ 420 public function findIconmapidByName(string $name): ?string { 421 if ($this->db_iconmaps === null) { 422 $this->selectIconmaps(); 423 } 424 425 foreach ($this->db_iconmaps as $iconmapid => $iconmap) { 426 if ($iconmap['name'] === $name) { 427 return $iconmapid; 428 } 429 } 430 431 return null; 432 } 433 434 /** 435 * Get map ID by name. 436 * 437 * @param string $name 438 * 439 * @return string|null 440 */ 441 public function findMapidByName(string $name): ?string { 442 if ($this->db_maps === null) { 443 $this->selectMaps(); 444 } 445 446 foreach ($this->db_maps as $mapid => $map) { 447 if ($map['name'] === $name) { 448 return $mapid; 449 } 450 } 451 452 return null; 453 } 454 455 /** 456 * Get template dashboard ID by dashboard UUID. 457 * 458 * @param string $uuid 459 * 460 * @return string|null 461 * 462 * @throws APIException 463 */ 464 public function findTemplateDashboardidByUuid(string $uuid): ?string { 465 if ($this->db_template_dashboards === null) { 466 $this->selectTemplateDashboards(); 467 } 468 469 foreach ($this->db_template_dashboards as $dashboardid => $dashboard) { 470 if ($dashboard['uuid'] === $uuid) { 471 return $dashboardid; 472 } 473 } 474 475 return null; 476 } 477 478 /** 479 * Get macro ID by template ID and macro name. 480 * 481 * @param string $templateid 482 * @param string $macro 483 * 484 * @return string|null 485 */ 486 public function findTemplateMacroid(string $templateid, string $macro): ?string { 487 if ($this->db_template_macros === null) { 488 $this->selectTemplateMacros(); 489 } 490 491 return (array_key_exists($templateid, $this->db_template_macros) 492 && array_key_exists($macro, $this->db_template_macros[$templateid])) 493 ? $this->db_template_macros[$templateid][$macro] 494 : null; 495 } 496 497 /** 498 * Get macro ID by host ID and macro name. 499 * 500 * @param string $hostid 501 * @param string $macro 502 * 503 * @return string|null 504 */ 505 public function findHostMacroid(string $hostid, string $macro): ?string { 506 if ($this->db_host_macros === null) { 507 $this->selectHostMacros(); 508 } 509 510 return (array_key_exists($hostid, $this->db_host_macros) 511 && array_key_exists($macro, $this->db_host_macros[$hostid])) 512 ? $this->db_host_macros[$hostid][$macro] 513 : null; 514 } 515 516 /** 517 * Get macro ID by host prototype ID and macro name. 518 * 519 * @param string $hostid 520 * @param string $macro 521 * 522 * @return string|null 523 */ 524 public function findHostPrototypeMacroid(string $hostid, string $macro): ?string { 525 if ($this->db_host_prototype_macros === null) { 526 $this->selectHostPrototypeMacros(); 527 } 528 529 return (array_key_exists($hostid, $this->db_host_prototype_macros) 530 && array_key_exists($macro, $this->db_host_prototype_macros[$hostid])) 531 ? $this->db_host_prototype_macros[$hostid][$macro] 532 : null; 533 } 534 535 /** 536 * Get proxy ID by name. 537 * 538 * @param string $host 539 * 540 * @return string|null 541 */ 542 public function findProxyidByHost(string $host): ?string { 543 if ($this->db_proxies === null) { 544 $this->selectProxies(); 545 } 546 547 foreach ($this->db_proxies as $proxyid => $proxy) { 548 if ($proxy['host'] === $host) { 549 return $proxyid; 550 } 551 } 552 553 return null; 554 } 555 556 /** 557 * Get host prototype ID by UUID. 558 * 559 * @param string $uuid 560 * 561 * @return string|null 562 */ 563 public function findHostPrototypeidByUuid(string $uuid): ?string { 564 if ($this->db_host_prototypes === null) { 565 $this->selectHostPrototypes(); 566 } 567 568 foreach ($this->db_host_prototypes as $host_prototypeid => $host_prototype) { 569 if ($host_prototype['uuid'] === $uuid) { 570 return $host_prototypeid; 571 } 572 } 573 574 return null; 575 } 576 577 /** 578 * Get host prototype ID by host. 579 * 580 * @param string $parent_hostid 581 * @param string $discovery_ruleid 582 * @param string $host 583 * 584 * @return string|null 585 */ 586 public function findHostPrototypeidByHost(string $parent_hostid, string $discovery_ruleid, string $host): ?string { 587 if ($this->db_host_prototypes === null) { 588 $this->selectHostPrototypes(); 589 } 590 591 foreach ($this->db_host_prototypes as $host_prototypeid => $host_prototype) { 592 if ($host_prototype['parent_hostid'] === $parent_hostid 593 && $host_prototype['discovery_ruleid'] === $discovery_ruleid 594 && $host_prototype['host'] === $host) { 595 return $host_prototypeid; 596 } 597 } 598 599 return null; 600 } 601 602 /** 603 * Get httptest ID by web scenario UUID. 604 * 605 * @param string $uuid 606 * 607 * @return string|null 608 */ 609 public function findHttpTestidByUuid(string $uuid): ?string { 610 if ($this->db_httptests === null) { 611 $this->selectHttpTests(); 612 } 613 614 foreach ($this->db_httptests as $httptestid => $httptest) { 615 if ($httptest['uuid'] === $uuid) { 616 return $httptestid; 617 } 618 } 619 620 return null; 621 } 622 623 /** 624 * Get httptest ID by hostid and web scenario name. 625 * 626 * @param string $hostid 627 * @param string $name 628 * 629 * @return string|bool 630 */ 631 public function findHttpTestidByName(string $hostid, string $name): ?string { 632 if ($this->db_httptests === null) { 633 $this->selectHttpTests(); 634 } 635 636 foreach ($this->db_httptests as $httptestid => $httptest) { 637 if ($httptest['hostid'] === $hostid && $httptest['name'] === $name) { 638 return $httptestid; 639 } 640 } 641 642 return null; 643 } 644 645 /** 646 * Get httpstep ID by hostid, httptestid and web scenario step name. 647 * 648 * @param string $hostid 649 * @param string $httptestid 650 * @param string $name 651 * 652 * @return string|null 653 */ 654 public function findHttpStepidByName(string $hostid, string $httptestid, string $name): ?string { 655 if ($this->db_httpsteps === null) { 656 $this->selectHttpSteps(); 657 } 658 659 foreach ($this->db_httpsteps as $httpstepid => $httpstep) { 660 if ($httpstep['hostid'] === $hostid && $httpstep['name'] === $name 661 && $httpstep['httptestid'] === $httptestid) { 662 return $httpstepid; 663 } 664 } 665 666 return null; 667 } 668 669 /** 670 * Add group names that need association with a database group ID. 671 * 672 * @param array $groups 673 */ 674 public function addGroups(array $groups): void { 675 $this->groups = $groups; 676 } 677 678 /** 679 * Add group name association with group ID. 680 * 681 * @param string $groupid 682 * @param array $group 683 */ 684 public function setDbGroup(string $groupid, array $group): void { 685 $this->db_groups[$groupid] = [ 686 'uuid' => $group['uuid'], 687 'name' => $group['name'] 688 ]; 689 } 690 691 /** 692 * Add templates names that need association with a database template ID. 693 * 694 * @param array $templates 695 */ 696 public function addTemplates(array $templates): void { 697 $this->templates = $templates; 698 } 699 700 /** 701 * Add template name association with template ID. 702 * 703 * @param string $templateid 704 * @param array $template 705 */ 706 public function setDbTemplate(string $templateid, array $template): void { 707 $this->db_templates[$templateid] = [ 708 'uuid' => $template['uuid'], 709 'host' => $template['host'] 710 ]; 711 } 712 713 /** 714 * Add hosts names that need association with a database host ID. 715 * 716 * @param array $hosts 717 */ 718 public function addHosts(array $hosts): void { 719 $this->hosts = $hosts; 720 } 721 722 /** 723 * Add host name association with host ID. 724 * 725 * @param string $hostid 726 * @param array $host 727 */ 728 public function setDbHost(string $hostid, array $host): void { 729 $this->db_hosts[$hostid] = [ 730 'host' => $host['host'] 731 ]; 732 } 733 734 /** 735 * Add item keys that need association with a database item ID. 736 * 737 * @param array $items 738 */ 739 public function addItems(array $items): void { 740 $this->items = $items; 741 } 742 743 /** 744 * Add item key association with item ID. 745 * 746 * @param string $itemid 747 * @param array $item 748 */ 749 public function setDbItem(string $itemid, array $item): void { 750 $this->db_items[$itemid] = [ 751 'hostid' => $item['hostid'], 752 'uuid' => array_key_exists('uuid', $item) ? $item['uuid'] : '', 753 'key_' => $item['key_'] 754 ]; 755 } 756 757 /** 758 * Add value map names that need association with a database value map ID. 759 * 760 * @param array $valuemaps 761 */ 762 public function addValuemaps(array $valuemaps): void { 763 $this->valuemaps = $valuemaps; 764 } 765 766 /** 767 * Add trigger description/expression/recovery_expression that need association with a database trigger ID. 768 * 769 * @param array $triggers 770 */ 771 public function addTriggers(array $triggers): void { 772 $this->triggers = $triggers; 773 } 774 775 /** 776 * Add graph names that need association with a database graph ID. 777 * 778 * @param array $graphs 779 */ 780 public function addGraphs(array $graphs): void { 781 $this->graphs = $graphs; 782 } 783 784 /** 785 * Add trigger name/expression association with trigger ID. 786 * 787 * @param string $triggerid 788 * @param array $trigger 789 */ 790 public function setDbTrigger(string $triggerid, array $trigger): void { 791 $this->db_triggers[$triggerid] = [ 792 'uuid' => array_key_exists('uuid', $trigger) ? $trigger['uuid'] : '', 793 'description' => $trigger['description'], 794 'expression' => $trigger['expression'], 795 'recovery_expression' => $trigger['recovery_expression'] 796 ]; 797 } 798 799 /** 800 * Add icon map names that need association with a database icon map ID. 801 * 802 * @param array $iconmaps 803 */ 804 public function addIconmaps(array $iconmaps): void { 805 $this->iconmaps = $iconmaps; 806 } 807 808 /** 809 * Add icon map names that need association with a database icon map ID. 810 * 811 * @param array $images 812 */ 813 public function addImages(array $images): void { 814 $this->images = $images; 815 } 816 817 /** 818 * Add image name association with image ID. 819 * 820 * @param string $imageid 821 * @param array $image 822 */ 823 public function setDbImage(string $imageid, array $image): void { 824 $this->db_images[$imageid] = [ 825 'name' => $image['name'] 826 ]; 827 } 828 829 /** 830 * Add map names that need association with a database map ID. 831 * 832 * @param array $maps 833 */ 834 public function addMaps(array $maps) { 835// $this->maps = array_unique(array_merge($this->maps, $maps)); 836 $this->maps = $maps; 837 } 838 839 /** 840 * Add map name association with map ID. 841 * 842 * @param string $mapid 843 * @param array $map 844 */ 845 public function setDbMap(string $mapid, array $map): void { 846 $this->db_maps[$mapid] =[ 847 'name' => $map['name'] 848 ]; 849 } 850 851 /** 852 * Add templated dashboard names that need association with a database dashboard ID. 853 * 854 * @param array $dashboards 855 */ 856 public function addTemplateDashboards(array $dashboards): void { 857 $this->template_dashboards = $dashboards; 858 } 859 860 /** 861 * Add user macro names that need association with a database macro ID. 862 * 863 * @param array $macros[<template uuid>] An array of macros by template UUID. 864 */ 865 public function addTemplateMacros(array $macros): void { 866 $this->template_macros = $macros; 867 } 868 869 /** 870 * Add user macro names that need association with a database macro ID. 871 * 872 * @param array $macros[<host name>] An array of macros by host technical name. 873 */ 874 public function addHostMacros(array $macros): void { 875 $this->host_macros = $macros; 876 } 877 878 /** 879 * Add user macro names that need association with a database macro ID. 880 * 881 * @param array $macros[<host name>] An array of macros by host technical name. 882 */ 883 public function addHostPrototypeMacros(array $macros): void { 884 $this->host_prototype_macros = $macros; 885 } 886 887 /** 888 * Add proxy names that need association with a database proxy ID. 889 * 890 * @param array $proxies 891 */ 892 public function addProxies(array $proxies): void { 893 $this->proxies = $proxies; 894 } 895 896 /** 897 * Add host prototypes that need association with a database host prototype ID. 898 * 899 * @param array $hostPrototypes 900 */ 901 public function addHostPrototypes(array $hostPrototypes): void { 902 $this->host_prototypes = $hostPrototypes; 903 } 904 905 /** 906 * Add web scenario names that need association with a database httptest ID. 907 * 908 * @param array $httptests 909 */ 910 public function addHttpTests(array $httptests): void { 911 $this->httptests = $httptests; 912 } 913 914 /** 915 * Add web scenario step names that need association with a database httpstep ID. 916 * 917 * @param array $httpsteps 918 */ 919 public function addHttpSteps(array $httpsteps): void { 920 $this->httpsteps = $httpsteps; 921 } 922 923 /** 924 * Select group ids for previously added group names. 925 */ 926 protected function selectGroups(): void { 927 $this->db_groups = []; 928 929 if (!$this->groups) { 930 return; 931 } 932 933 $this->db_groups = API::HostGroup()->get([ 934 'output' => ['name', 'uuid'], 935 'filter' => [ 936 'uuid' => array_column($this->groups, 'uuid'), 937 'name' => array_keys($this->groups) 938 ], 939 'searchByAny' => true, 940 'preservekeys' => true 941 ]); 942 943 $this->groups = []; 944 } 945 946 /** 947 * Select template ids for previously added template names. 948 */ 949 protected function selectTemplates(): void { 950 $this->db_templates = []; 951 952 if (!$this->templates) { 953 return; 954 } 955 956 $this->db_templates = API::Template()->get([ 957 'output' => ['host', 'uuid'], 958 'filter' => [ 959 'uuid' => array_column($this->templates, 'uuid'), 960 'host' => array_keys($this->templates) 961 ], 962 'searchByAny' => true, 963 'editable' => true, 964 'preservekeys' => true 965 ]); 966 967 $this->templates = []; 968 } 969 970 /** 971 * Select host ids for previously added host names. 972 */ 973 protected function selectHosts(): void { 974 $this->db_hosts = []; 975 976 if (!$this->hosts) { 977 return; 978 } 979 980 // Fetch only normal hosts, discovered hosts must not be imported. 981 $this->db_hosts = API::Host()->get([ 982 'output' => ['host'], 983 'filter' => ['host' => array_keys($this->hosts)], 984 'templated_hosts' => true, 985 'preservekeys' => true 986 ]); 987 988 $this->hosts = []; 989 } 990 991 /** 992 * Select item ids for previously added item keys. 993 */ 994 protected function selectItems(): void { 995 $this->db_items = []; 996 997 if (!$this->items) { 998 return; 999 } 1000 1001 $sql_where = []; 1002 1003 foreach ($this->items as $host => $items) { 1004 $hostid = $this->findTemplateidOrHostidByHost($host); 1005 1006 if ($hostid !== null) { 1007 $sql_where[] = '(i.hostid='.zbx_dbstr($hostid) 1008 .' AND (' 1009 .dbConditionString('i.key_', array_keys($items)) 1010 .' OR '.dbConditionString('i.uuid', array_column($items, 'uuid')) 1011 .'))'; 1012 } 1013 } 1014 1015 if ($sql_where) { 1016 $db_items = DBselect( 1017 'SELECT i.itemid,i.hostid,i.key_,i.uuid FROM items i WHERE '.implode(' OR ', $sql_where) 1018 ); 1019 1020 while ($db_item = DBfetch($db_items)) { 1021 $this->db_items[$db_item['itemid']] = [ 1022 'uuid' => $db_item['uuid'], 1023 'key_' => $db_item['key_'], 1024 'hostid' => $db_item['hostid'] 1025 ]; 1026 } 1027 } 1028 } 1029 1030 /** 1031 * Unset item refs to make referencer select them from db again. 1032 */ 1033 public function refreshItems(): void { 1034 $this->db_items = null; 1035 } 1036 1037 /** 1038 * Select value map IDs for previously added value map names. 1039 */ 1040 protected function selectValuemaps(): void { 1041 $this->db_valuemaps = []; 1042 1043 if (!$this->valuemaps) { 1044 return; 1045 } 1046 1047 $sql_where = []; 1048 1049 foreach ($this->valuemaps as $host => $valuemap_names) { 1050 $hostid = $this->findTemplateidOrHostidByHost($host); 1051 1052 if ($hostid !== null) { 1053 $sql_where[] = '(vm.hostid='.zbx_dbstr($hostid).' AND '. 1054 dbConditionString('vm.name', array_keys($valuemap_names)).')'; 1055 } 1056 } 1057 1058 if ($sql_where) { 1059 $db_valuemaps = DBselect( 1060 'SELECT vm.valuemapid,vm.hostid,vm.name'. 1061 ' FROM valuemap vm'. 1062 ' WHERE '.implode(' OR ', $sql_where) 1063 ); 1064 1065 while ($valuemap = DBfetch($db_valuemaps)) { 1066 $this->db_valuemaps[$valuemap['valuemapid']] = [ 1067 'name' => $valuemap['name'], 1068 'hostid' => $valuemap['hostid'] 1069 ]; 1070 } 1071 } 1072 1073 $this->valuemaps = []; 1074 } 1075 1076 /** 1077 * Select trigger ids for previously added trigger names/expressions. 1078 */ 1079 protected function selectTriggers(): void { 1080 $this->db_triggers = []; 1081 1082 if (!$this->triggers) { 1083 return; 1084 } 1085 1086 $uuids = []; 1087 1088 foreach ($this->triggers as $trigger) { 1089 foreach ($trigger as $expression) { 1090 $uuids += array_flip(array_column($expression, 'uuid')); 1091 } 1092 } 1093 1094 $db_triggers = API::Trigger()->get([ 1095 'output' => ['uuid', 'description', 'expression', 'recovery_expression'], 1096 'filter' => [ 1097 'uuid' => array_keys($uuids), 1098 'flags' => [ 1099 ZBX_FLAG_DISCOVERY_NORMAL, 1100 ZBX_FLAG_DISCOVERY_PROTOTYPE, 1101 ZBX_FLAG_DISCOVERY_CREATED 1102 ] 1103 ], 1104 'preservekeys' => true 1105 ]); 1106 1107 $db_triggers += API::Trigger()->get([ 1108 'output' => ['uuid', 'description', 'expression', 'recovery_expression'], 1109 'filter' => [ 1110 'description' => array_keys($this->triggers), 1111 'flags' => [ 1112 ZBX_FLAG_DISCOVERY_NORMAL, 1113 ZBX_FLAG_DISCOVERY_PROTOTYPE, 1114 ZBX_FLAG_DISCOVERY_CREATED 1115 ] 1116 ], 1117 'preservekeys' => true 1118 ]); 1119 1120 if (!$db_triggers) { 1121 return; 1122 } 1123 1124 $db_triggers = CMacrosResolverHelper::resolveTriggerExpressions($db_triggers, 1125 ['sources' => ['expression', 'recovery_expression']] 1126 ); 1127 1128 foreach ($db_triggers as $db_trigger) { 1129 $uuid = $db_trigger['uuid']; 1130 $description = $db_trigger['description']; 1131 $expression = $db_trigger['expression']; 1132 $recovery_expression = $db_trigger['recovery_expression']; 1133 1134 if (array_key_exists($uuid, $uuids) 1135 || (array_key_exists($description, $this->triggers) 1136 && array_key_exists($expression, $this->triggers[$description]) 1137 && array_key_exists($recovery_expression, $this->triggers[$description][$expression]))) { 1138 $this->db_triggers[$db_trigger['triggerid']] = $db_trigger; 1139 } 1140 } 1141 } 1142 1143 /** 1144 * Unset trigger refs to make referencer select them from db again. 1145 */ 1146 public function refreshTriggers(): void { 1147 $this->db_triggers = null; 1148 } 1149 1150 /** 1151 * Select graph IDs for previously added graph names. 1152 */ 1153 protected function selectGraphs(): void { 1154 $this->db_graphs = []; 1155 1156 if (!$this->graphs) { 1157 return; 1158 } 1159 1160 $graph_uuids = []; 1161 $graph_names = []; 1162 1163 foreach ($this->graphs as $graph) { 1164 $graph_uuids += array_flip(array_column($graph, 'uuid')); 1165 $graph_names += array_flip(array_keys($graph)); 1166 } 1167 1168 $db_graphs = API::Graph()->get([ 1169 'output' => ['uuid', 'name'], 1170 'selectHosts' => ['hostid'], 1171 'filter' => [ 1172 'uuid' => array_keys($graph_uuids), 1173 'flags' => null 1174 ], 1175 'preservekeys' => true 1176 ]); 1177 1178 $db_graphs += API::Graph()->get([ 1179 'output' => ['uuid', 'name'], 1180 'selectHosts' => ['hostid'], 1181 'filter' => [ 1182 'name' => array_keys($graph_names), 1183 'flags' => null 1184 ], 1185 'preservekeys' => true 1186 ]); 1187 1188 foreach ($db_graphs as $graph) { 1189 $graph['hosts'] = array_column($graph['hosts'], 'hostid'); 1190 $this->db_graphs[$graph['graphid']] = $graph; 1191 } 1192 } 1193 1194 /** 1195 * Unset graph refs to make referencer select them from DB again. 1196 */ 1197 public function refreshGraphs(): void { 1198 $this->db_graphs = null; 1199 } 1200 1201 /** 1202 * Select icon map ids for previously added icon maps names. 1203 */ 1204 protected function selectIconmaps(): void { 1205 $this->db_iconmaps = []; 1206 1207 if (!$this->iconmaps) { 1208 return; 1209 } 1210 1211 $db_iconmaps = API::IconMap()->get([ 1212 'filter' => ['name' => array_keys($this->iconmaps)], 1213 'output' => ['name'], 1214 'preservekeys' => true 1215 ]); 1216 1217 foreach ($db_iconmaps as $iconmapid => $iconmap) { 1218 $this->db_iconmaps[$iconmapid] = $iconmap; 1219 } 1220 1221 $this->iconmaps = []; 1222 } 1223 1224 /** 1225 * Select icon map ids for previously added icon maps names. 1226 */ 1227 protected function selectImages(): void { 1228 $this->db_images = []; 1229 1230 if (!$this->images) { 1231 return; 1232 } 1233 1234 $db_images = API::Image()->get([ 1235 'output' => ['name'], 1236 'filter' => ['name' => array_keys($this->images)], 1237 'preservekeys' => true 1238 ]); 1239 1240 foreach ($db_images as $imageid => $image) { 1241 $this->db_images[$imageid] = $image; 1242 } 1243 1244 $this->images = []; 1245 } 1246 1247 /** 1248 * Select map ids for previously added maps names. 1249 */ 1250 protected function selectMaps(): void { 1251 $this->db_maps = []; 1252 1253 if (!$this->maps) { 1254 return; 1255 } 1256 1257 $db_maps = API::Map()->get([ 1258 'output' => ['name'], 1259 'filter' => ['name' => array_keys($this->maps)], 1260 'preservekeys' => true 1261 ]); 1262 1263 foreach ($db_maps as $mapid => $map) { 1264 $this->db_maps[$mapid] = $map; 1265 } 1266 1267 $this->maps = []; 1268 } 1269 1270 /** 1271 * Select template dashboard IDs for previously added dashboard names and template IDs. 1272 * 1273 * @throws APIException 1274 */ 1275 protected function selectTemplateDashboards(): void { 1276 $this->db_template_dashboards = []; 1277 1278 if (!$this->template_dashboards) { 1279 return; 1280 } 1281 1282 $db_template_dashboards = API::TemplateDashboard()->get([ 1283 'output' => ['uuid'], 1284 'filter' => ['uuid' => array_keys($this->template_dashboards)], 1285 'preservekeys' => true 1286 ]); 1287 1288 foreach ($db_template_dashboards as $dashboardid => $dashboard) { 1289 $this->db_template_dashboards[$dashboardid] = [ 1290 'uuid' => $dashboard['uuid'] 1291 ]; 1292 } 1293 1294 $this->template_dashboards = []; 1295 } 1296 1297 /** 1298 * Select user macro ids for previously added macro names. 1299 */ 1300 protected function selectTemplateMacros(): void { 1301 $this->db_template_macros = []; 1302 1303 $sql_where = []; 1304 1305 foreach ($this->template_macros as $uuid => $macros) { 1306 $sql_where[] = '(h.uuid='.zbx_dbstr($uuid).' AND '.dbConditionString('hm.macro', $macros).')'; 1307 } 1308 1309 if ($sql_where) { 1310 $db_macros = DBselect( 1311 'SELECT hm.hostmacroid,hm.hostid,hm.macro'. 1312 ' FROM hostmacro hm'. 1313 ' JOIN hosts h on hm.hostid=h.hostid'. 1314 ' WHERE '.implode(' OR ', $sql_where) 1315 ); 1316 1317 while ($db_macro = DBfetch($db_macros)) { 1318 $this->db_template_macros[$db_macro['hostid']][$db_macro['macro']] = $db_macro['hostmacroid']; 1319 } 1320 } 1321 1322 $this->template_macros = []; 1323 } 1324 1325 /** 1326 * Select user macro ids for previously added macro names. 1327 */ 1328 protected function selectHostMacros(): void { 1329 $this->db_host_macros = []; 1330 1331 $sql_where = []; 1332 1333 foreach ($this->host_macros as $host => $macros) { 1334 $sql_where[] = '(h.host='.zbx_dbstr($host).' AND '.dbConditionString('hm.macro', $macros).')'; 1335 } 1336 1337 if ($sql_where) { 1338 $db_macros = DBselect( 1339 'SELECT hm.hostmacroid,hm.hostid,hm.macro'. 1340 ' FROM hostmacro hm'. 1341 ' JOIN hosts h on hm.hostid=h.hostid'. 1342 ' WHERE '.implode(' OR ', $sql_where) 1343 ); 1344 1345 while ($db_macro = DBfetch($db_macros)) { 1346 $this->db_host_macros[$db_macro['hostid']][$db_macro['macro']] = $db_macro['hostmacroid']; 1347 } 1348 } 1349 1350 $this->host_macros = []; 1351 } 1352 1353 /** 1354 * Select user macro ids for previously added macro names. 1355 */ 1356 protected function selectHostPrototypeMacros(): void { 1357 $this->db_host_prototype_macros = []; 1358 1359 $sql_where = []; 1360 1361 foreach ($this->host_prototype_macros as $type => $hosts) { 1362 foreach ($hosts as $host => $discovery_rules) { 1363 foreach ($discovery_rules as $discovery_rule_key => $host_prototypes) { 1364 foreach ($host_prototypes as $host_prototype_id => $macros) { 1365 $sql_where[] = '('. 1366 'h.host='.zbx_dbstr($host). 1367 ' AND dr.key_='.zbx_dbstr($discovery_rule_key). 1368 ' AND hp.'.($type === 'uuid' ? 'uuid' : 'host').'='.zbx_dbstr($host_prototype_id). 1369 ' AND '.dbConditionString('hm.macro', $macros). 1370 ')'; 1371 } 1372 } 1373 } 1374 } 1375 1376 if ($sql_where) { 1377 $db_macros = DBselect( 1378 'SELECT hm.hostmacroid,hm.hostid,hm.macro'. 1379 ' FROM hostmacro hm'. 1380 ' JOIN hosts hp on hm.hostid=hp.hostid'. 1381 ' JOIN host_discovery hd on hp.hostid=hd.hostid'. 1382 ' JOIN items dr on hd.parent_itemid=dr.itemid'. 1383 ' JOIN hosts h on dr.hostid=h.hostid'. 1384 ' WHERE '.implode(' OR ', $sql_where) 1385 ); 1386 1387 while ($db_macro = DBfetch($db_macros)) { 1388 $this->db_host_prototype_macros[$db_macro['hostid']][$db_macro['macro']] = $db_macro['hostmacroid']; 1389 } 1390 } 1391 1392 $this->host_prototype_macros = []; 1393 } 1394 1395 /** 1396 * Select proxy ids for previously added proxy names. 1397 */ 1398 protected function selectProxies(): void { 1399 $this->db_proxies = []; 1400 1401 if (!$this->proxies) { 1402 return; 1403 } 1404 1405 $this->db_proxies = API::Proxy()->get([ 1406 'output' => ['host'], 1407 'filter' => ['host' => array_keys($this->proxies)], 1408 'preservekeys' => true 1409 ]); 1410 1411 $this->proxies = []; 1412 } 1413 1414 /** 1415 * Select host prototype ids for previously added host prototypes names. 1416 */ 1417 protected function selectHostPrototypes(): void { 1418 $this->db_host_prototypes = []; 1419 1420 $sql_where = []; 1421 1422 foreach ($this->host_prototypes as $type => $hosts) { 1423 foreach ($hosts as $host => $discovery_rules) { 1424 foreach ($discovery_rules as $discovery_rule_id => $host_prototype_ids) { 1425 $sql_where[] = '('. 1426 'h.host='.zbx_dbstr($host). 1427 ' AND dr.'.($type === 'uuid' ? 'uuid' : 'key_').'='.zbx_dbstr($discovery_rule_id). 1428 ' AND '.dbConditionString('hp.'.($type === 'uuid' ? 'uuid' : 'host'), $host_prototype_ids). 1429 ')'; 1430 } 1431 } 1432 } 1433 1434 if ($sql_where) { 1435 $db_host_prototypes = DBselect( 1436 'SELECT hp.host,hp.uuid,hp.hostid,hd.parent_itemid,dr.hostid AS parent_hostid'. 1437 ' FROM hosts hp'. 1438 ' JOIN host_discovery hd ON hp.hostid=hd.hostid'. 1439 ' JOIN items dr ON hd.parent_itemid=dr.itemid'. 1440 ' JOIN hosts h on dr.hostid=h.hostid'. 1441 ' WHERE '.implode(' OR ', $sql_where) 1442 ); 1443 while ($db_host_prototype = DBfetch($db_host_prototypes)) { 1444 $this->db_host_prototypes[$db_host_prototype['hostid']] = [ 1445 'uuid' => $db_host_prototype['uuid'], 1446 'host' => $db_host_prototype['host'], 1447 'parent_hostid' => $db_host_prototype['parent_hostid'], 1448 'discovery_ruleid' => $db_host_prototype['parent_itemid'] 1449 ]; 1450 } 1451 } 1452 1453 $this->host_prototypes = []; 1454 } 1455 1456 /** 1457 * Select httptestids for previously added web scenario names. 1458 */ 1459 protected function selectHttpTests(): void { 1460 $this->db_httptests = []; 1461 1462 if (!$this->httptests) { 1463 return; 1464 } 1465 1466 $sql_where = []; 1467 1468 foreach ($this->httptests as $host => $httptests) { 1469 $hostid = $this->findTemplateidOrHostidByHost($host); 1470 1471 if ($hostid !== false) { 1472 $sql_where[] = '(ht.hostid='.zbx_dbstr($hostid) 1473 .' AND (' 1474 .dbConditionString('ht.name', array_keys($httptests)) 1475 .' OR '.dbConditionString('ht.uuid', array_column($httptests, 'uuid')) 1476 .'))'; 1477 } 1478 } 1479 1480 if ($sql_where) { 1481 $db_httptests = DBselect( 1482 'SELECT ht.hostid,ht.name,ht.httptestid,ht.uuid FROM httptest ht WHERE '.implode(' OR ', $sql_where) 1483 ); 1484 1485 while ($db_httptest = DBfetch($db_httptests)) { 1486 $this->db_httptests[$db_httptest['httptestid']] = [ 1487 'uuid' => $db_httptest['uuid'], 1488 'name' => $db_httptest['name'], 1489 'hostid' => $db_httptest['hostid'] 1490 ]; 1491 } 1492 } 1493 } 1494 1495 /** 1496 * Unset web scenario refs to make referencer select them from db again. 1497 */ 1498 public function refreshHttpTests(): void { 1499 $this->db_httptests = null; 1500 } 1501 1502 /** 1503 * Select httpstepids for previously added web scenario step names. 1504 */ 1505 protected function selectHttpSteps(): void { 1506 $this->db_httpsteps = []; 1507 1508 if (!$this->httpsteps) { 1509 return; 1510 } 1511 1512 $sql_where = []; 1513 1514 foreach ($this->httpsteps as $host => $httptests) { 1515 $hostid = $this->findTemplateidOrHostidByHost($host); 1516 1517 if ($hostid !== null) { 1518 foreach ($httptests as $httpstep_names) { 1519 $sql_where[] = dbConditionString('hs.name', array_keys($httpstep_names)); 1520 } 1521 } 1522 } 1523 1524 if ($sql_where) { 1525 $db_httpsteps = DBselect( 1526 'SELECT ht.hostid,hs.httptestid,hs.name,hs.httpstepid'. 1527 ' FROM httptest ht,httpstep hs'. 1528 ' WHERE ht.httptestid=hs.httptestid'. 1529 ' AND ('.implode(' OR ', $sql_where).')' 1530 ); 1531 1532 while ($db_httpstep = DBfetch($db_httpsteps)) { 1533 $this->db_httpsteps[$db_httpstep['httpstepid']] = [ 1534 'name' => $db_httpstep['name'], 1535 'hostid' => $db_httpstep['hostid'], 1536 'httptestid' => $db_httpstep['httptestid'] 1537 ]; 1538 } 1539 } 1540 } 1541} 1542