/** * Deletes applications from DB that are missing in XML. * * @return null */ protected function deleteMissingApplications() { if (!$this->options['applications']['deleteMissing']) { return; } $processedHostIds = $this->importedObjectContainer->getHostIds(); $processedTemplateIds = $this->importedObjectContainer->getTemplateIds(); $processedHostIds = array_merge($processedHostIds, $processedTemplateIds); // no hosts or templates have been processed if (!$processedHostIds) { return; } $applicationIdsXML = array(); $allApplications = $this->getFormattedApplications(); if ($allApplications) { foreach ($allApplications as $host => $applications) { $hostId = $this->referencer->resolveHostOrTemplate($host); foreach ($applications as $application) { $applicationId = $this->referencer->resolveApplication($hostId, $application['name']); if ($applicationId) { $applicationIdsXML[$applicationId] = $applicationId; } } } } $dbApplicationIds = API::Application()->get(array('output' => array('applicationid'), 'hostids' => $processedHostIds, 'preservekeys' => true, 'nopermissions' => true, 'inherited' => false)); $applicationsToDelete = array_diff_key($dbApplicationIds, $applicationIdsXML); if ($applicationsToDelete) { API::Application()->delete(array_keys($applicationsToDelete)); } // refresh applications because templated ones can be inherited to host and used in items $this->referencer->refreshApplications(); }
/** * Import discovery rules. * * @throws Exception */ protected function processDiscoveryRules() { $allDiscoveryRules = $this->getFormattedDiscoveryRules(); if (empty($allDiscoveryRules)) { return; } // unset rules that are related to hosts we did not process foreach ($allDiscoveryRules as $host => $discoveryRules) { if (!$this->referencer->isProcessedHost($host)) { unset($allDiscoveryRules[$host]); } } $itemsToCreate = array(); $itemsToUpdate = array(); foreach ($allDiscoveryRules as $host => $discoveryRules) { $hostid = $this->referencer->resolveHostOrTemplate($host); foreach ($discoveryRules as $item) { $item['hostid'] = $hostid; if (isset($item['interface_ref'])) { $item['interfaceid'] = $this->referencer->interfacesCache[$hostid][$item['interface_ref']]; } unset($item['item_prototypes']); unset($item['trigger_prototypes']); unset($item['graph_prototypes']); unset($item['host_prototypes']); $itemId = $this->referencer->resolveItem($hostid, $item['key_']); if ($itemId) { $item['itemid'] = $itemId; $itemsToUpdate[] = $item; } else { $itemsToCreate[] = $item; } } } // create/update discovery rules and add processed rules to array $processedRules $processedRules = array(); if ($this->options['discoveryRules']['createMissing'] && $itemsToCreate) { $newItemsIds = API::DiscoveryRule()->create($itemsToCreate); foreach ($newItemsIds['itemids'] as $inum => $itemid) { $item = $itemsToCreate[$inum]; $this->referencer->addItemRef($item['hostid'], $item['key_'], $itemid); } foreach ($itemsToCreate as $item) { $processedRules[$item['hostid']][$item['key_']] = 1; } } if ($this->options['discoveryRules']['updateExisting'] && $itemsToUpdate) { API::DiscoveryRule()->update($itemsToUpdate); foreach ($itemsToUpdate as $item) { $processedRules[$item['hostid']][$item['key_']] = 1; } } // refresh discovery rules because templated ones can be inherited to host and used for prototypes $this->referencer->refreshItems(); // process prototypes $prototypesToUpdate = array(); $prototypesToCreate = array(); $hostPrototypesToUpdate = array(); $hostPrototypesToCreate = array(); foreach ($allDiscoveryRules as $host => $discoveryRules) { $hostid = $this->referencer->resolveHostOrTemplate($host); foreach ($discoveryRules as $item) { // if rule was not processed we should not create/update any of its prototypes if (!isset($processedRules[$hostid][$item['key_']])) { continue; } $item['hostid'] = $hostid; $itemId = $this->referencer->resolveItem($hostid, $item['key_']); // prototypes foreach ($item['item_prototypes'] as $prototype) { $prototype['hostid'] = $hostid; $applicationsIds = array(); foreach ($prototype['applications'] as $application) { $applicationsIds[] = $this->referencer->resolveApplication($hostid, $application['name']); } $prototype['applications'] = $applicationsIds; if (isset($prototype['interface_ref'])) { $prototype['interfaceid'] = $this->referencer->interfacesCache[$hostid][$prototype['interface_ref']]; } if ($prototype['valuemap']) { $valueMapId = $this->referencer->resolveValueMap($prototype['valuemap']['name']); if (!$valueMapId) { throw new Exception(_s('Cannot find value map "%1$s" used for item prototype "%2$s" of discovery rule "%3$s" on "%4$s".', $prototype['valuemap']['name'], $prototype['name'], $item['name'], $host)); } $prototype['valuemapid'] = $valueMapId; } $prototypeId = $this->referencer->resolveItem($hostid, $prototype['key_']); $prototype['rule'] = array('hostid' => $hostid, 'key' => $item['key_']); if ($prototypeId) { $prototype['itemid'] = $prototypeId; $prototypesToUpdate[] = $prototype; } else { $prototypesToCreate[] = $prototype; } } // host prototype foreach ($item['host_prototypes'] as $hostPrototype) { // resolve group prototypes $groupLinks = array(); foreach ($hostPrototype['group_links'] as $groupLink) { $groupId = $this->referencer->resolveGroup($groupLink['group']['name']); if (!$groupId) { throw new Exception(_s('Cannot find host group "%1$s" for host prototype "%2$s" of discovery rule "%3$s" on "%4$s".', $groupLink['group']['name'], $hostPrototype['name'], $item['name'], $host)); } $groupLinks[] = array('groupid' => $groupId); } $hostPrototype['groupLinks'] = $groupLinks; $hostPrototype['groupPrototypes'] = $hostPrototype['group_prototypes']; unset($hostPrototype['group_links'], $hostPrototype['group_prototypes']); // resolve templates $templates = array(); foreach ($hostPrototype['templates'] as $template) { $templateId = $this->referencer->resolveTemplate($template['name']); if (!$templateId) { throw new Exception(_s('Cannot find template "%1$s" for host prototype "%2$s" of discovery rule "%3$s" on "%4$s".', $template['name'], $hostPrototype['name'], $item['name'], $host)); } $templates[] = array('templateid' => $templateId); } $hostPrototype['templates'] = $templates; $hostPrototypeId = $this->referencer->resolveHostPrototype($hostid, $itemId, $hostPrototype['host']); if ($hostPrototypeId) { $hostPrototype['hostid'] = $hostPrototypeId; $hostPrototypesToUpdate[] = $hostPrototype; } else { $hostPrototype['ruleid'] = $itemId; $hostPrototypesToCreate[] = $hostPrototype; } } if (isset($item['interface_ref'])) { $item['interfaceid'] = $this->referencer->interfacesCache[$hostid][$item['interface_ref']]; } unset($item['item_prototypes']); unset($item['trigger_prototypes']); unset($item['graph_prototypes']); unset($item['host_prototypes']); $itemsId = $this->referencer->resolveItem($hostid, $item['key_']); if ($itemsId) { $item['itemid'] = $itemsId; $itemsToUpdate[] = $item; } else { $itemsToCreate[] = $item; } } } if ($prototypesToCreate) { foreach ($prototypesToCreate as &$prototype) { $prototype['ruleid'] = $this->referencer->resolveItem($prototype['rule']['hostid'], $prototype['rule']['key']); } unset($prototype); $newPrototypeIds = API::ItemPrototype()->create($prototypesToCreate); foreach ($newPrototypeIds['itemids'] as $inum => $itemid) { $item = $prototypesToCreate[$inum]; $this->referencer->addItemRef($item['hostid'], $item['key_'], $itemid); } } if ($prototypesToUpdate) { foreach ($prototypesToCreate as &$prototype) { $prototype['ruleid'] = $this->referencer->resolveItem($prototype['rule']['hostid'], $prototype['rule']['key']); } unset($prototype); API::ItemPrototype()->update($prototypesToUpdate); } if ($hostPrototypesToCreate) { API::HostPrototype()->create($hostPrototypesToCreate); } if ($hostPrototypesToUpdate) { API::HostPrototype()->update($hostPrototypesToUpdate); } // refresh prototypes because templated ones can be inherited to host and used in triggers prototypes or graph prototypes $this->referencer->refreshItems(); // first we need to create item prototypes and only then graph prototypes $triggersToCreate = array(); $triggersToUpdate = array(); $graphsToCreate = array(); $graphsToUpdate = array(); foreach ($allDiscoveryRules as $host => $discoveryRules) { $hostid = $this->referencer->resolveHostOrTemplate($host); foreach ($discoveryRules as $item) { // if rule was not processed we should not create/update any of its prototypes if (!isset($processedRules[$hostid][$item['key_']])) { continue; } // trigger prototypes foreach ($item['trigger_prototypes'] as $trigger) { $triggerId = $this->referencer->resolveTrigger($trigger['description'], $trigger['expression']); if ($triggerId) { $trigger['triggerid'] = $triggerId; $triggersToUpdate[] = $trigger; } else { $triggersToCreate[] = $trigger; } } // graph prototypes foreach ($item['graph_prototypes'] as $graph) { $graphHostIds = array(); if ($graph['ymin_item_1']) { $hostId = $this->referencer->resolveHostOrTemplate($graph['ymin_item_1']['host']); $itemId = $hostId ? $this->referencer->resolveItem($hostId, $graph['ymin_item_1']['key']) : false; if (!$itemId) { throw new Exception(_s('Cannot find item "%1$s" on "%2$s" used as the Y axis MIN value for graph prototype "%3$s" of discovery rule "%4$s" on "%5$s".', $graph['ymin_item_1']['key'], $graph['ymin_item_1']['host'], $graph['name'], $item['name'], $host)); } $graph['ymin_itemid'] = $itemId; } if ($graph['ymax_item_1']) { $hostId = $this->referencer->resolveHostOrTemplate($graph['ymax_item_1']['host']); $itemId = $hostId ? $this->referencer->resolveItem($hostId, $graph['ymax_item_1']['key']) : false; if (!$itemId) { throw new Exception(_s('Cannot find item "%1$s" on "%2$s" used as the Y axis MAX value for graph prototype "%3$s" of discovery rule "%4$s" on "%5$s".', $graph['ymax_item_1']['key'], $graph['ymax_item_1']['host'], $graph['name'], $item['name'], $host)); } $graph['ymax_itemid'] = $itemId; } foreach ($graph['gitems'] as &$gitem) { if (!($gitemHostId = $this->referencer->resolveHostOrTemplate($gitem['item']['host']))) { throw new Exception(_s('Cannot find host or template "%1$s" used in graph "%2$s".', $gitem['item']['host'], $graph['name'])); } $gitem['itemid'] = $this->referencer->resolveItem($gitemHostId, $gitem['item']['key']); $graphHostIds[$gitemHostId] = $gitemHostId; } unset($gitem); // TODO: do this for all graphs at once $sql = 'SELECT g.graphid' . ' FROM graphs g,graphs_items gi,items i' . ' WHERE g.graphid=gi.graphid' . ' AND gi.itemid=i.itemid' . ' AND g.name=' . zbx_dbstr($graph['name']) . ' AND ' . dbConditionInt('i.hostid', $graphHostIds); $graphExists = DBfetch(DBselect($sql)); if ($graphExists) { $dbGraph = API::GraphPrototype()->get(array('graphids' => $graphExists['graphid'], 'output' => array('graphid'), 'editable' => true)); if (empty($dbGraph)) { throw new Exception(_s('No permission for graph "%1$s".', $graph['name'])); } $graph['graphid'] = $graphExists['graphid']; $graphsToUpdate[] = $graph; } else { $graphsToCreate[] = $graph; } } } } if ($triggersToCreate) { API::TriggerPrototype()->create($triggersToCreate); } if ($triggersToUpdate) { API::TriggerPrototype()->update($triggersToUpdate); } if ($graphsToCreate) { API::GraphPrototype()->create($graphsToCreate); } if ($graphsToUpdate) { API::GraphPrototype()->update($graphsToUpdate); } }