/** * Unlinks the templates from the given hosts. If $tragetids is set to null, the templates will be unlinked from * all hosts. * * @param array $templateids * @param null|array $targetids the IDs of the hosts to unlink the templates from * @param bool $clear delete all of the inherited objects from the hosts */ protected function unlink($templateids, $targetids = null, $clear = false) { $flags = $clear ? array(ZBX_FLAG_DISCOVERY_NORMAL, ZBX_FLAG_DISCOVERY_RULE) : array(ZBX_FLAG_DISCOVERY_NORMAL, ZBX_FLAG_DISCOVERY_RULE, ZBX_FLAG_DISCOVERY_PROTOTYPE); // check that all triggers on templates that we unlink, don't have items from another templates $sql = 'SELECT DISTINCT t.description' . ' FROM triggers t,functions f,items i' . ' WHERE t.triggerid=f.triggerid' . ' AND f.itemid=i.itemid' . ' AND ' . dbConditionInt('i.hostid', $templateids) . ' AND EXISTS (' . 'SELECT ff.triggerid' . ' FROM functions ff,items ii' . ' WHERE ff.itemid=ii.itemid' . ' AND ff.triggerid=t.triggerid' . ' AND ' . dbConditionInt('ii.hostid', $templateids, true) . ')' . ' AND t.flags=' . ZBX_FLAG_DISCOVERY_NORMAL; if ($dbTrigger = DBfetch(DBSelect($sql, 1))) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Cannot unlink trigger "%s", it has items from template that is left linked to host.', $dbTrigger['description'])); } $sqlFrom = ' triggers t,hosts h'; $sqlWhere = ' EXISTS (' . 'SELECT ff.triggerid' . ' FROM functions ff,items ii' . ' WHERE ff.triggerid=t.templateid' . ' AND ii.itemid=ff.itemid' . ' AND ' . dbConditionInt('ii.hostid', $templateids) . ')' . ' AND ' . dbConditionInt('t.flags', $flags); if (!is_null($targetids)) { $sqlFrom = ' triggers t,functions f,items i,hosts h'; $sqlWhere .= ' AND ' . dbConditionInt('i.hostid', $targetids) . ' AND f.itemid=i.itemid' . ' AND t.triggerid=f.triggerid' . ' AND h.hostid=i.hostid'; } $sql = 'SELECT DISTINCT t.triggerid,t.description,t.flags,t.expression,h.name as host' . ' FROM ' . $sqlFrom . ' WHERE ' . $sqlWhere; $dbTriggers = DBSelect($sql); $triggers = array(ZBX_FLAG_DISCOVERY_NORMAL => array(), ZBX_FLAG_DISCOVERY_PROTOTYPE => array()); $triggerids = array(); while ($trigger = DBfetch($dbTriggers)) { $triggers[$trigger['flags']][$trigger['triggerid']] = array('description' => $trigger['description'], 'expression' => explode_exp($trigger['expression']), 'triggerid' => $trigger['triggerid'], 'host' => $trigger['host']); if (!in_array($trigger['triggerid'], $triggerids)) { array_push($triggerids, $trigger['triggerid']); } } if (!empty($triggers[ZBX_FLAG_DISCOVERY_NORMAL])) { if ($clear) { $result = API::Trigger()->delete(array_keys($triggers[ZBX_FLAG_DISCOVERY_NORMAL]), true); if (!$result) { self::exception(ZBX_API_ERROR_INTERNAL, _('Cannot unlink and clear triggers')); } } else { DB::update('triggers', array('values' => array('templateid' => 0), 'where' => array('triggerid' => array_keys($triggers[ZBX_FLAG_DISCOVERY_NORMAL])))); foreach ($triggers[ZBX_FLAG_DISCOVERY_NORMAL] as $trigger) { info(_s('Unlinked: Trigger "%1$s" on "%2$s".', $trigger['description'], $trigger['host'])); } } } if (!empty($triggers[ZBX_FLAG_DISCOVERY_PROTOTYPE])) { if ($clear) { $result = API::TriggerPrototype()->delete(array_keys($triggers[ZBX_FLAG_DISCOVERY_PROTOTYPE]), true); if (!$result) { self::exception(ZBX_API_ERROR_INTERNAL, _('Cannot unlink and clear triggers')); } } else { DB::update('triggers', array('values' => array('templateid' => 0), 'where' => array('triggerid' => array_keys($triggers[ZBX_FLAG_DISCOVERY_PROTOTYPE])))); foreach ($triggers[ZBX_FLAG_DISCOVERY_PROTOTYPE] as $trigger) { info(_s('Unlinked: Trigger prototype "%1$s" on "%2$s".', $trigger['description'], $trigger['host'])); } } } /* ITEMS, DISCOVERY RULES {{{ */ $sqlFrom = ' items i1,items i2,hosts h'; $sqlWhere = ' i2.itemid=i1.templateid' . ' AND ' . dbConditionInt('i2.hostid', $templateids) . ' AND ' . dbConditionInt('i1.flags', $flags) . ' AND h.hostid=i1.hostid'; if (!is_null($targetids)) { $sqlWhere .= ' AND ' . dbConditionInt('i1.hostid', $targetids); } $sql = 'SELECT DISTINCT i1.itemid,i1.flags,i1.name,i1.hostid,h.name as host' . ' FROM ' . $sqlFrom . ' WHERE ' . $sqlWhere; $dbItems = DBSelect($sql); $items = array(ZBX_FLAG_DISCOVERY_NORMAL => array(), ZBX_FLAG_DISCOVERY_RULE => array(), ZBX_FLAG_DISCOVERY_PROTOTYPE => array()); while ($item = DBfetch($dbItems)) { $items[$item['flags']][$item['itemid']] = array('name' => $item['name'], 'host' => $item['host']); } if (!empty($items[ZBX_FLAG_DISCOVERY_RULE])) { if ($clear) { $result = API::DiscoveryRule()->delete(array_keys($items[ZBX_FLAG_DISCOVERY_RULE]), true); if (!$result) { self::exception(ZBX_API_ERROR_INTERNAL, _('Cannot unlink and clear discovery rules')); } } else { DB::update('items', array('values' => array('templateid' => 0), 'where' => array('itemid' => array_keys($items[ZBX_FLAG_DISCOVERY_RULE])))); foreach ($items[ZBX_FLAG_DISCOVERY_RULE] as $discoveryRule) { info(_s('Unlinked: Discovery rule "%1$s" on "%2$s".', $discoveryRule['name'], $discoveryRule['host'])); } } } if (!empty($items[ZBX_FLAG_DISCOVERY_NORMAL])) { if ($clear) { $result = API::Item()->delete(array_keys($items[ZBX_FLAG_DISCOVERY_NORMAL]), true); if (!$result) { self::exception(ZBX_API_ERROR_INTERNAL, _('Cannot unlink and clear items')); } } else { DB::update('items', array('values' => array('templateid' => 0), 'where' => array('itemid' => array_keys($items[ZBX_FLAG_DISCOVERY_NORMAL])))); foreach ($items[ZBX_FLAG_DISCOVERY_NORMAL] as $item) { info(_s('Unlinked: Item "%1$s" on "%2$s".', $item['name'], $item['host'])); } } } if (!empty($items[ZBX_FLAG_DISCOVERY_PROTOTYPE])) { if ($clear) { $result = API::Itemprototype()->delete(array_keys($items[ZBX_FLAG_DISCOVERY_PROTOTYPE]), true); if (!$result) { self::exception(ZBX_API_ERROR_INTERNAL, _('Cannot unlink and clear item prototypes')); } } else { DB::update('items', array('values' => array('templateid' => 0), 'where' => array('itemid' => array_keys($items[ZBX_FLAG_DISCOVERY_PROTOTYPE])))); foreach ($items[ZBX_FLAG_DISCOVERY_PROTOTYPE] as $item) { info(_s('Unlinked: Item prototype "%1$s" on "%2$s".', $item['name'], $item['host'])); } } } /* }}} ITEMS, DISCOVERY RULES */ // host prototypes // we need only to unlink host prototypes. in case of unlink and clear they will be deleted together with LLD rules. if (!$clear && isset($items[ZBX_FLAG_DISCOVERY_RULE])) { $discoveryRuleIds = array_keys($items[ZBX_FLAG_DISCOVERY_RULE]); $hostPrototypes = DBfetchArrayAssoc(DBSelect('SELECT DISTINCT h.hostid,h.host,h3.host AS parent_host' . ' FROM hosts h' . ' INNER JOIN host_discovery hd ON h.hostid=hd.hostid' . ' INNER JOIN hosts h2 ON h.templateid=h2.hostid' . ' INNER JOIN host_discovery hd2 ON h.hostid=hd.hostid' . ' INNER JOIN items i ON hd.parent_itemid=i.itemid' . ' INNER JOIN hosts h3 ON i.hostid=h3.hostid' . ' WHERE ' . dbConditionInt('hd.parent_itemid', $discoveryRuleIds)), 'hostid'); if ($hostPrototypes) { DB::update('hosts', array('values' => array('templateid' => 0), 'where' => array('hostid' => array_keys($hostPrototypes)))); DB::update('group_prototype', array('values' => array('templateid' => 0), 'where' => array('hostid' => array_keys($hostPrototypes)))); foreach ($hostPrototypes as $hostPrototype) { info(_s('Unlinked: Host prototype "%1$s" on "%2$s".', $hostPrototype['host'], $hostPrototype['parent_host'])); } } } /* GRAPHS {{{ */ $sqlFrom = ' graphs g,hosts h'; $sqlWhere = ' EXISTS (' . 'SELECT ggi.graphid' . ' FROM graphs_items ggi,items ii' . ' WHERE ggi.graphid=g.templateid' . ' AND ii.itemid=ggi.itemid' . ' AND ' . dbConditionInt('ii.hostid', $templateids) . ')' . ' AND ' . dbConditionInt('g.flags', $flags); if (!is_null($targetids)) { $sqlFrom = ' graphs g,graphs_items gi,items i,hosts h'; $sqlWhere .= ' AND ' . dbConditionInt('i.hostid', $targetids) . ' AND gi.itemid=i.itemid' . ' AND g.graphid=gi.graphid' . ' AND h.hostid=i.hostid'; } $sql = 'SELECT DISTINCT g.graphid,g.name,g.flags,h.name as host' . ' FROM ' . $sqlFrom . ' WHERE ' . $sqlWhere; $dbGraphs = DBSelect($sql); $graphs = array(ZBX_FLAG_DISCOVERY_NORMAL => array(), ZBX_FLAG_DISCOVERY_PROTOTYPE => array()); while ($graph = DBfetch($dbGraphs)) { $graphs[$graph['flags']][$graph['graphid']] = array('name' => $graph['name'], 'graphid' => $graph['graphid'], 'host' => $graph['host']); } if (!empty($graphs[ZBX_FLAG_DISCOVERY_PROTOTYPE])) { if ($clear) { $result = API::GraphPrototype()->delete(array_keys($graphs[ZBX_FLAG_DISCOVERY_PROTOTYPE]), true); if (!$result) { self::exception(ZBX_API_ERROR_INTERNAL, _('Cannot unlink and clear graph prototypes')); } } else { DB::update('graphs', array('values' => array('templateid' => 0), 'where' => array('graphid' => array_keys($graphs[ZBX_FLAG_DISCOVERY_PROTOTYPE])))); foreach ($graphs[ZBX_FLAG_DISCOVERY_PROTOTYPE] as $graph) { info(_s('Unlinked: Graph prototype "%1$s" on "%2$s".', $graph['name'], $graph['host'])); } } } if (!empty($graphs[ZBX_FLAG_DISCOVERY_NORMAL])) { if ($clear) { $result = API::Graph()->delete(array_keys($graphs[ZBX_FLAG_DISCOVERY_NORMAL]), true); if (!$result) { self::exception(ZBX_API_ERROR_INTERNAL, _('Cannot unlink and clear graphs.')); } } else { DB::update('graphs', array('values' => array('templateid' => 0), 'where' => array('graphid' => array_keys($graphs[ZBX_FLAG_DISCOVERY_NORMAL])))); foreach ($graphs[ZBX_FLAG_DISCOVERY_NORMAL] as $graph) { info(_s('Unlinked: Graph "%1$s" on "%2$s".', $graph['name'], $graph['host'])); } } } /* }}} GRAPHS */ // http tests $sqlWhere = ''; if (!is_null($targetids)) { $sqlWhere = ' AND ' . dbConditionInt('ht1.hostid', $targetids); } $sql = 'SELECT DISTINCT ht1.httptestid,ht1.name,h.name as host' . ' FROM httptest ht1' . ' INNER JOIN httptest ht2 ON ht2.httptestid=ht1.templateid' . ' INNER JOIN hosts h ON h.hostid=ht1.hostid' . ' WHERE ' . dbConditionInt('ht2.hostid', $templateids) . $sqlWhere; $dbHttpTests = DBSelect($sql); $httpTests = array(); while ($httpTest = DBfetch($dbHttpTests)) { $httpTests[$httpTest['httptestid']] = array('name' => $httpTest['name'], 'host' => $httpTest['host']); } if (!empty($httpTests)) { if ($clear) { $result = API::HttpTest()->delete(array_keys($httpTests), true); if (!$result) { self::exception(ZBX_API_ERROR_INTERNAL, _('Cannot unlink and clear Web scenarios.')); } } else { DB::update('httptest', array('values' => array('templateid' => 0), 'where' => array('httptestid' => array_keys($httpTests)))); foreach ($httpTests as $httpTest) { info(_s('Unlinked: Web scenario "%1$s" on "%2$s".', $httpTest['name'], $httpTest['host'])); } } } /* APPLICATIONS {{{ */ $sql = 'SELECT at.application_templateid,at.applicationid,h.name,h.host,h.hostid' . ' FROM applications a1,application_template at,applications a2,hosts h' . ' WHERE a1.applicationid=at.applicationid' . ' AND at.templateid=a2.applicationid' . ' AND ' . dbConditionInt('a2.hostid', $templateids) . ' AND a1.hostid=h.hostid'; if ($targetids) { $sql .= ' AND ' . dbConditionInt('a1.hostid', $targetids); } $query = DBselect($sql); $applicationTemplates = array(); while ($applicationTemplate = DBfetch($query)) { $applicationTemplates[] = array('applicationid' => $applicationTemplate['applicationid'], 'application_templateid' => $applicationTemplate['application_templateid'], 'name' => $applicationTemplate['name'], 'hostid' => $applicationTemplate['hostid'], 'host' => $applicationTemplate['host']); } if ($applicationTemplates) { // unlink applications from templates DB::delete('application_template', array('application_templateid' => zbx_objectValues($applicationTemplates, 'application_templateid'))); if ($clear) { // delete inherited applications that are no longer linked to any templates $applications = DBfetchArray(DBselect('SELECT a.applicationid' . ' FROM applications a' . ' LEFT JOIN application_template at ON a.applicationid=at.applicationid ' . ' WHERE ' . dbConditionInt('a.applicationid', zbx_objectValues($applicationTemplates, 'applicationid')) . ' AND at.applicationid IS NULL')); $result = API::Application()->delete(zbx_objectValues($applications, 'applicationid'), true); if (!$result) { self::exception(ZBX_API_ERROR_INTERNAL, _('Cannot unlink and clear applications.')); } } else { foreach ($applicationTemplates as $application) { info(_s('Unlinked: Application "%1$s" on "%2$s".', $application['name'], $application['host'])); } } } /* }}} APPLICATIONS */ parent::unlink($templateids, $targetids); }
/** * Get discovery rules related objects from database. * * @param array $items * * @return array */ protected function prepareDiscoveryRules(array $items) { foreach ($items as &$item) { $item['itemPrototypes'] = array(); $item['graphPrototypes'] = array(); $item['triggerPrototypes'] = array(); $item['hostPrototypes'] = array(); } unset($item); // gather item prototypes $prototypes = API::ItemPrototype()->get(array('discoveryids' => zbx_objectValues($items, 'itemid'), 'output' => $this->dataFields['discoveryrule'], 'selectApplications' => API_OUTPUT_EXTEND, 'selectDiscoveryRule' => array('itemid'), 'inherited' => false, 'preservekeys' => true)); // gather value maps $valueMapIds = zbx_objectValues($prototypes, 'valuemapid'); $DbValueMaps = DBselect('SELECT vm.valuemapid, vm.name FROM valuemaps vm WHERE ' . dbConditionInt('vm.valuemapid', $valueMapIds)); $valueMaps = array(); while ($valueMap = DBfetch($DbValueMaps)) { $valueMaps[$valueMap['valuemapid']] = $valueMap['name']; } foreach ($prototypes as $prototype) { $prototype['valuemap'] = array(); if ($prototype['valuemapid']) { $prototype['valuemap']['name'] = $valueMaps[$prototype['valuemapid']]; } $items[$prototype['discoveryRule']['itemid']]['itemPrototypes'][] = $prototype; } // gather graph prototypes $graphs = API::GraphPrototype()->get(array('discoveryids' => zbx_objectValues($items, 'itemid'), 'selectDiscoveryRule' => API_OUTPUT_EXTEND, 'selectGraphItems' => API_OUTPUT_EXTEND, 'output' => API_OUTPUT_EXTEND, 'inherited' => false, 'preservekeys' => true)); $graphs = $this->prepareGraphs($graphs); foreach ($graphs as $graph) { $items[$graph['discoveryRule']['itemid']]['graphPrototypes'][] = $graph; } // gather trigger prototypes $triggers = API::TriggerPrototype()->get(array('discoveryids' => zbx_objectValues($items, 'itemid'), 'output' => API_OUTPUT_EXTEND, 'selectDiscoveryRule' => API_OUTPUT_EXTEND, 'selectItems' => array('flags', 'type'), 'inherited' => false, 'preservekeys' => true, 'expandData' => true)); foreach ($triggers as $trigger) { foreach ($trigger['items'] as $item) { if ($item['flags'] == ZBX_FLAG_DISCOVERY_CREATED || $item['type'] == ITEM_TYPE_HTTPTEST) { continue 2; } } $trigger['expression'] = explode_exp($trigger['expression']); $items[$trigger['discoveryRule']['itemid']]['triggerPrototypes'][] = $trigger; } // gather host prototypes $hostPrototypes = API::HostPrototype()->get(array('discoveryids' => zbx_objectValues($items, 'itemid'), 'output' => API_OUTPUT_EXTEND, 'selectGroupLinks' => API_OUTPUT_EXTEND, 'selectGroupPrototypes' => API_OUTPUT_EXTEND, 'selectDiscoveryRule' => API_OUTPUT_EXTEND, 'selectTemplates' => API_OUTPUT_EXTEND, 'inherited' => false, 'preservekeys' => true)); // replace group prototype group IDs with references $groupIds = array(); foreach ($hostPrototypes as $hostPrototype) { foreach ($hostPrototype['groupLinks'] as $groupLink) { $groupIds[$groupLink['groupid']] = $groupLink['groupid']; } } $groups = $this->getGroupsReferences($groupIds); // export the groups used in group prototypes $this->data['groups'] += $groups; foreach ($hostPrototypes as $hostPrototype) { foreach ($hostPrototype['groupLinks'] as &$groupLink) { $groupLink['groupid'] = $groups[$groupLink['groupid']]; } unset($groupLink); $items[$hostPrototype['discoveryRule']['itemid']]['hostPrototypes'][] = $hostPrototype; } return $items; }
/** * Delete items. * * @param array $itemIds * @param bool $noPermissions * * @return array */ public function delete(array $itemIds, $noPermissions = false) { if (!$itemIds) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Empty input parameter.')); } $itemIds = array_keys(array_flip($itemIds)); $delItems = $this->get(array('output' => array('name', 'templateid'), 'selectHosts' => array('name'), 'itemids' => $itemIds, 'editable' => true, 'preservekeys' => true)); // TODO: remove $nopermissions hack if (!$noPermissions) { foreach ($itemIds as $itemId) { if (!isset($delItems[$itemId])) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!')); } if ($delItems[$itemId]['templateid'] != 0) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Cannot delete templated item.')); } } } // first delete child items $parentItemIds = $itemIds; do { $dbItems = DBselect('SELECT i.itemid FROM items i WHERE ' . dbConditionInt('i.templateid', $parentItemIds)); $parentItemIds = array(); while ($dbItem = DBfetch($dbItems)) { $parentItemIds[] = $dbItem['itemid']; $itemIds[$dbItem['itemid']] = $dbItem['itemid']; } } while ($parentItemIds); // delete graphs, leave if graph still have item $delGraphs = array(); $dbGraphs = DBselect('SELECT gi.graphid' . ' FROM graphs_items gi' . ' WHERE ' . dbConditionInt('gi.itemid', $itemIds) . ' AND NOT EXISTS (' . 'SELECT NULL' . ' FROM graphs_items gii' . ' WHERE gii.graphid=gi.graphid' . ' AND ' . dbConditionInt('gii.itemid', $itemIds, true) . ')'); while ($dbGraph = DBfetch($dbGraphs)) { $delGraphs[$dbGraph['graphid']] = $dbGraph['graphid']; } if ($delGraphs) { API::Graph()->delete($delGraphs, true); } // check if any graphs are referencing this item $this->checkGraphReference($itemIds); $triggers = API::Trigger()->get(array('output' => array(), 'itemids' => $itemIds, 'nopermissions' => true, 'preservekeys' => true)); if ($triggers) { API::Trigger()->delete(array_keys($triggers), true); } $triggerPrototypes = API::TriggerPrototype()->get(array('output' => array(), 'itemids' => $itemIds, 'nopermissions' => true, 'preservekeys' => true)); if ($triggerPrototypes) { API::TriggerPrototype()->delete(array_keys($triggerPrototypes), true); } DB::delete('screens_items', array('resourceid' => $itemIds, 'resourcetype' => array(SCREEN_RESOURCE_SIMPLE_GRAPH, SCREEN_RESOURCE_PLAIN_TEXT, SCREEN_RESOURCE_CLOCK))); DB::delete('items', array('itemid' => $itemIds)); DB::delete('profiles', array('idx' => 'web.favorite.graphids', 'source' => 'itemid', 'value_id' => $itemIds)); $itemDataTables = array('trends', 'trends_uint', 'history_text', 'history_log', 'history_uint', 'history_str', 'history'); $insert = array(); foreach ($itemIds as $itemId) { foreach ($itemDataTables as $table) { $insert[] = array('tablename' => $table, 'field' => 'itemid', 'value' => $itemId); } } DB::insert('housekeeper', $insert); // TODO: remove info from API foreach ($delItems as $item) { $host = reset($item['hosts']); info(_s('Deleted: Item "%1$s" on "%2$s".', $item['name'], $host['name'])); } return array('itemids' => $itemIds); }
/** * Get discovery rules related objects from database. * * @param array $items * * @return array */ protected function prepareDiscoveryRules(array $items) { foreach ($items as &$item) { $item['itemPrototypes'] = array(); $item['graphPrototypes'] = array(); $item['triggerPrototypes'] = array(); } unset($item); // gather item prototypes $prototypes = API::ItemPrototype()->get(array('discoveryids' => zbx_objectValues($items, 'itemid'), 'output' => array('hostid', 'multiplier', 'type', 'snmp_community', 'snmp_oid', 'name', 'key_', 'delay', 'history', 'trends', 'status', 'value_type', 'trapper_hosts', 'units', 'delta', 'snmpv3_securityname', 'snmpv3_securitylevel', 'snmpv3_authpassphrase', 'snmpv3_privpassphrase', 'formula', 'valuemapid', 'delay_flex', 'params', 'ipmi_sensor', 'data_type', 'authtype', 'username', 'password', 'publickey', 'privatekey', 'interfaceid', 'port', 'description', 'inventory_link', 'flags'), 'selectApplications' => API_OUTPUT_EXTEND, 'inherited' => false, 'preservekeys' => true)); // gather value maps $valueMapIds = zbx_objectValues($prototypes, 'valuemapid'); $DbValueMaps = DBselect('SELECT vm.valuemapid, vm.name FROM valuemaps vm WHERE ' . dbConditionInt('vm.valuemapid', $valueMapIds)); $valueMaps = array(); while ($valueMap = DBfetch($DbValueMaps)) { $valueMaps[$valueMap['valuemapid']] = $valueMap['name']; } foreach ($prototypes as $prototype) { $prototype['valuemap'] = array(); if ($prototype['valuemapid']) { $prototype['valuemap']['name'] = $valueMaps[$prototype['valuemapid']]; } $items[$prototype['parent_itemid']]['itemPrototypes'][] = $prototype; } // gather graph prototypes $graphs = API::GraphPrototype()->get(array('discoveryids' => zbx_objectValues($items, 'itemid'), 'selectDiscoveryRule' => API_OUTPUT_EXTEND, 'selectGraphItems' => API_OUTPUT_EXTEND, 'output' => API_OUTPUT_EXTEND, 'inherited' => false, 'preservekeys' => true)); $graphs = $this->prepareGraphs($graphs); foreach ($graphs as $graph) { $items[$graph['discoveryRule']['itemid']]['graphPrototypes'][] = $graph; } // gather trigger prototypes $triggers = API::TriggerPrototype()->get(array('discoveryids' => zbx_objectValues($items, 'itemid'), 'output' => API_OUTPUT_EXTEND, 'selectDiscoveryRule' => API_OUTPUT_EXTEND, 'selectItems' => array('flags', 'type'), 'inherited' => false, 'preservekeys' => true, 'expandData' => true)); foreach ($triggers as $trigger) { foreach ($trigger['items'] as $item) { if ($item['flags'] == ZBX_FLAG_DISCOVERY_CREATED || $item['type'] == ITEM_TYPE_HTTPTEST) { continue 2; } } $trigger['expression'] = explode_exp($trigger['expression']); $items[$trigger['discoveryRule']['itemid']]['triggerPrototypes'][] = $trigger; } return $items; }
} // item prototypes $hostItemPrototypes = API::ItemPrototype()->get(array('hostids' => $_REQUEST['hostid'], 'discoveryids' => $hostDiscoveryRuleids, 'inherited' => false, 'output' => array('itemid', 'key_', 'name'))); if (!empty($hostItemPrototypes)) { $prototypeList = array(); foreach ($hostItemPrototypes as $itemPrototype) { $prototypeList[$itemPrototype['itemid']] = itemName($itemPrototype); } order_result($prototypeList); $listBox = new CListBox('itemsPrototypes', null, 8); $listBox->setAttribute('disabled', 'disabled'); $listBox->addItems($prototypeList); $hostList->addRow(_('Item prototypes'), $listBox); } // Trigger prototypes $hostTriggerPrototypes = API::TriggerPrototype()->get(array('hostids' => $_REQUEST['hostid'], 'discoveryids' => $hostDiscoveryRuleids, 'inherited' => false, 'output' => array('triggerid', 'description'), 'selectItems' => array('type'))); if (!empty($hostTriggerPrototypes)) { $prototypeList = array(); foreach ($hostTriggerPrototypes as $triggerPrototype) { // skip trigger prototypes with web items if (httpItemExists($triggerPrototype['items'])) { continue; } $prototypeList[$triggerPrototype['triggerid']] = $triggerPrototype['description']; } if ($prototypeList) { order_result($prototypeList); $listBox = new CListBox('triggerprototypes', null, 8); $listBox->setAttribute('disabled', 'disabled'); $listBox->addItems($prototypeList); $hostList->addRow(_('Trigger prototypes'), $listBox);
/** * Delete Item prototypes. * * @param int|string|array $prototypeids * @param bool $nopermissions * * @return array */ public function delete($prototypeids, $nopermissions = false) { if (empty($prototypeids)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Empty input parameter.')); } $prototypeids = zbx_toHash($prototypeids); $options = array('itemids' => $prototypeids, 'editable' => true, 'preservekeys' => true, 'output' => API_OUTPUT_EXTEND, 'selectHosts' => array('name')); $delItemPrototypes = $this->get($options); // TODO: remove $nopermissions hack if (!$nopermissions) { foreach ($prototypeids as $prototypeid) { if (!isset($delItemPrototypes[$prototypeid])) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!')); } if ($delItemPrototypes[$prototypeid]['templateid'] != 0) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Cannot delete templated items')); } } } // first delete child items $parentItemids = $prototypeids; $childPrototypeids = array(); do { $dbItems = DBselect('SELECT itemid FROM items WHERE ' . dbConditionInt('templateid', $parentItemids)); $parentItemids = array(); while ($dbItem = DBfetch($dbItems)) { $parentItemids[$dbItem['itemid']] = $dbItem['itemid']; $childPrototypeids[$dbItem['itemid']] = $dbItem['itemid']; } } while (!empty($parentItemids)); $options = array('output' => API_OUTPUT_EXTEND, 'itemids' => $childPrototypeids, 'nopermissions' => true, 'preservekeys' => true, 'selectHosts' => array('name')); $delItemPrototypesChilds = $this->get($options); $delItemPrototypes = array_merge($delItemPrototypes, $delItemPrototypesChilds); $prototypeids = array_merge($prototypeids, $childPrototypeids); // delete graphs with this item prototype $delGraphPrototypes = API::GraphPrototype()->get(array('itemids' => $prototypeids, 'output' => API_OUTPUT_SHORTEN, 'nopermissions' => true, 'preservekeys' => true)); if (!empty($delGraphPrototypes)) { $result = API::GraphPrototype()->delete(zbx_objectValues($delGraphPrototypes, 'graphid'), true); if (!$result) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Cannot delete graph prototype')); } } // check if any graphs are referencing this item $this->checkGraphReference($prototypeids); // CREATED ITEMS $createdItems = array(); $sql = 'SELECT itemid FROM item_discovery WHERE ' . dbConditionInt('parent_itemid', $prototypeids); $dbItems = DBselect($sql); while ($item = DBfetch($dbItems)) { $createdItems[$item['itemid']] = $item['itemid']; } if (!empty($createdItems)) { $result = API::Item()->delete($createdItems, true); if (!$result) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Cannot delete items created by low level discovery.')); } } // TRIGGER PROTOTYPES $delTriggerPrototypes = API::TriggerPrototype()->get(array('itemids' => $prototypeids, 'output' => API_OUTPUT_SHORTEN, 'nopermissions' => true, 'preservekeys' => true)); if (!empty($delTriggerPrototypes)) { $result = API::TriggerPrototype()->delete(zbx_objectValues($delTriggerPrototypes, 'triggerid'), true); if (!$result) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Cannot delete trigger prototype')); } } // ITEM PROTOTYPES DB::delete('items', array('itemid' => $prototypeids)); // TODO: remove info from API foreach ($delItemPrototypes as $item) { $host = reset($item['hosts']); info(_s('Deleted: Item prototype "%1$s" on "%2$s".', $item['name'], $host['name'])); } return array('prototypeids' => $prototypeids); }
} // item prototypes $hostItemPrototypes = API::ItemPrototype()->get(array('hostids' => $_REQUEST['hostid'], 'discoveryids' => $hostDiscoveryRuleids, 'inherited' => false, 'output' => API_OUTPUT_EXTEND)); if (!empty($hostItemPrototypes)) { $prototypeList = array(); foreach ($hostItemPrototypes as $itemPrototype) { $prototypeList[$itemPrototype['itemid']] = itemName($itemPrototype); } order_result($prototypeList); $listBox = new CListBox('itemsPrototypes', null, 8); $listBox->setAttribute('disabled', 'disabled'); $listBox->addItems($prototypeList); $hostList->addRow(_('Item prototypes'), $listBox); } // Trigger prototypes $hostTriggerPrototypes = API::TriggerPrototype()->get(array('hostids' => $_REQUEST['hostid'], 'discoveryids' => $hostDiscoveryRuleids, 'inherited' => false, 'output' => API_OUTPUT_EXTEND, 'selectItems' => API_OUTPUT_EXTEND)); if (!empty($hostTriggerPrototypes)) { $prototypeList = array(); foreach ($hostTriggerPrototypes as $triggerPrototype) { // skip trigger prototypes with web items if (httpItemExists($triggerPrototype['items'])) { continue; } $prototypeList[$triggerPrototype['triggerid']] = $triggerPrototype['description']; } if ($prototypeList) { order_result($prototypeList); $listBox = new CListBox('triggerprototypes', null, 8); $listBox->setAttribute('disabled', 'disabled'); $listBox->addItems($prototypeList); $hostList->addRow(_('Trigger prototypes'), $listBox);
/** * Copies all of the triggers from the source discovery to the target discovery rule. * * @throws APIException if trigger saving fails * * @param array $srcDiscovery The source discovery rule to copy from * @param array $dstDiscovery The target discovery rule to copy to * @param array $srcHost The host the source discovery belongs to * @param array $dstHost The host the target discovery belongs to * * @return array */ protected function copyTriggerPrototypes(array $srcDiscovery, array $dstDiscovery, array $srcHost, array $dstHost) { $srcTriggers = API::TriggerPrototype()->get(array('discoveryids' => $srcDiscovery['itemid'], 'output' => API_OUTPUT_EXTEND, 'selectHosts' => API_OUTPUT_EXTEND, 'selectItems' => API_OUTPUT_EXTEND, 'selectDiscoveryRule' => API_OUTPUT_EXTEND, 'selectFunctions' => API_OUTPUT_EXTEND, 'preservekeys' => true)); if (!$srcTriggers) { return array(); } foreach ($srcTriggers as $id => $trigger) { // skip triggers with web items if (httpItemExists($trigger['items'])) { unset($srcTriggers[$id]); continue; } } // save new triggers $dstTriggers = $srcTriggers; foreach ($dstTriggers as $id => $trigger) { unset($dstTriggers[$id]['templateid']); unset($dstTriggers[$id]['triggerid']); // update expression $dstTriggers[$id]['expression'] = explode_exp($trigger['expression'], false, false, $srcHost['host'], $dstHost['host']); } $rs = API::TriggerPrototype()->create($dstTriggers); if (!$rs) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Cannot clone trigger prototypes.')); } return $rs; }
public function addRelatedObjects(array $options, array $result) { $result = parent::addRelatedObjects($options, $result); $itemids = array_keys($result); // adding applications if ($options['selectApplications'] !== null && $options['selectApplications'] != API_OUTPUT_COUNT) { $relationMap = $this->createRelationMap($result, 'itemid', 'applicationid', 'items_applications'); $applications = API::Application()->get(['output' => $options['selectApplications'], 'applicationids' => $relationMap->getRelatedIds(), 'preservekeys' => true]); $result = $relationMap->mapMany($result, $applications, 'applications'); } // adding application prototypes if ($options['selectApplicationPrototypes'] !== null && $options['selectApplicationPrototypes'] != API_OUTPUT_COUNT) { $pkFieldId = $this->pk('application_prototype'); $outputFields = [$pkFieldId => $this->fieldId($pkFieldId, 'ap')]; if (is_array($options['selectApplicationPrototypes'])) { foreach ($options['selectApplicationPrototypes'] as $field) { if ($this->hasField($field, 'application_prototype')) { $outputFields[$field] = $this->fieldId($field, 'ap'); } } $outputFields = implode(',', $outputFields); } else { $outputFields = 'ap.*'; } $relationMap = $this->createRelationMap($result, 'itemid', 'application_prototypeid', 'item_application_prototype'); $application_prototypes = DBfetchArray(DBselect('SELECT ' . $outputFields . ' FROM application_prototype ap' . ' WHERE ' . dbConditionInt('ap.application_prototypeid', $relationMap->getRelatedIds()))); $application_prototypes = zbx_toHash($application_prototypes, 'application_prototypeid'); $result = $relationMap->mapMany($result, $application_prototypes, 'applicationPrototypes'); } // adding triggers if (!is_null($options['selectTriggers'])) { if ($options['selectTriggers'] != API_OUTPUT_COUNT) { $relationMap = $this->createRelationMap($result, 'itemid', 'triggerid', 'functions'); $triggers = API::TriggerPrototype()->get(['output' => $options['selectTriggers'], 'triggerids' => $relationMap->getRelatedIds(), 'preservekeys' => true]); if (!is_null($options['limitSelects'])) { order_result($triggers, 'description'); } $result = $relationMap->mapMany($result, $triggers, 'triggers', $options['limitSelects']); } else { $triggers = API::TriggerPrototype()->get(['countOutput' => true, 'groupCount' => true, 'itemids' => $itemids]); $triggers = zbx_toHash($triggers, 'itemid'); foreach ($result as $itemid => $item) { if (isset($triggers[$itemid])) { $result[$itemid]['triggers'] = $triggers[$itemid]['rowscount']; } else { $result[$itemid]['triggers'] = 0; } } } } // adding graphs if (!is_null($options['selectGraphs'])) { if ($options['selectGraphs'] != API_OUTPUT_COUNT) { $relationMap = $this->createRelationMap($result, 'itemid', 'graphid', 'graphs_items'); $graphs = API::GraphPrototype()->get(['output' => $options['selectGraphs'], 'graphids' => $relationMap->getRelatedIds(), 'preservekeys' => true]); if (!is_null($options['limitSelects'])) { order_result($graphs, 'name'); } $result = $relationMap->mapMany($result, $graphs, 'graphs', $options['limitSelects']); } else { $graphs = API::GraphPrototype()->get(['countOutput' => true, 'groupCount' => true, 'itemids' => $itemids]); $graphs = zbx_toHash($graphs, 'itemid'); foreach ($result as $itemid => $item) { if (isset($graphs[$itemid])) { $result[$itemid]['graphs'] = $graphs[$itemid]['rowscount']; } else { $result[$itemid]['graphs'] = 0; } } } } // adding discoveryrule if ($options['selectDiscoveryRule'] !== null && $options['selectDiscoveryRule'] != API_OUTPUT_COUNT) { $relationMap = $this->createRelationMap($result, 'itemid', 'parent_itemid', 'item_discovery'); $discoveryRules = API::DiscoveryRule()->get(['output' => $options['selectDiscoveryRule'], 'itemids' => $relationMap->getRelatedIds(), 'nopermissions' => true, 'preservekeys' => true]); $result = $relationMap->mapOne($result, $discoveryRules, 'discoveryRule'); } return $result; }
function getTriggerFormData() { $data = array('form' => get_request('form'), 'form_refresh' => get_request('form_refresh'), 'parent_discoveryid' => get_request('parent_discoveryid'), 'dependencies' => get_request('dependencies', array()), 'db_dependencies' => array(), 'triggerid' => get_request('triggerid'), 'expression' => get_request('expression', ''), 'expr_temp' => get_request('expr_temp', ''), 'description' => get_request('description', ''), 'type' => get_request('type', 0), 'priority' => get_request('priority', 0), 'status' => get_request('status', 0), 'comments' => get_request('comments', ''), 'url' => get_request('url', ''), 'input_method' => get_request('input_method', IM_ESTABLISHED), 'limited' => null, 'templates' => array(), 'hostid' => get_request('hostid', 0)); if (!empty($data['triggerid'])) { // get trigger $options = array('output' => API_OUTPUT_EXTEND, 'selectHosts' => array('hostid'), 'triggerids' => $data['triggerid']); $trigger = $data['parent_discoveryid'] ? API::TriggerPrototype()->get($options) : API::Trigger()->get($options); $data['trigger'] = reset($trigger); // get templates $tmp_triggerid = $data['triggerid']; do { $db_triggers = DBfetch(DBselect('SELECT t.triggerid,t.templateid,id.parent_itemid,h.name,h.hostid' . ' FROM triggers t' . ' LEFT JOIN functions f ON t.triggerid=f.triggerid' . ' LEFT JOIN items i ON f.itemid=i.itemid' . ' LEFT JOIN hosts h ON i.hostid=h.hostid' . ' LEFT JOIN item_discovery id ON i.itemid=id.itemid' . ' WHERE t.triggerid=' . zbx_dbstr($tmp_triggerid))); if (bccomp($data['triggerid'], $tmp_triggerid) != 0) { // parent trigger prototype link if ($data['parent_discoveryid']) { $link = 'trigger_prototypes.php?form=update&triggerid=' . $db_triggers['triggerid'] . '&parent_discoveryid=' . $db_triggers['parent_itemid'] . '&hostid=' . $db_triggers['hostid']; } else { $link = 'triggers.php?form=update&triggerid=' . $db_triggers['triggerid'] . '&hostid=' . $db_triggers['hostid']; } $data['templates'][] = new CLink($db_triggers['name'], $link, 'highlight underline weight_normal'); $data['templates'][] = SPACE . RARR . SPACE; } $tmp_triggerid = $db_triggers['templateid']; } while ($tmp_triggerid != 0); $data['templates'] = array_reverse($data['templates']); array_shift($data['templates']); $data['limited'] = $data['trigger']['templateid'] ? 'yes' : null; // if no host has been selected for the navigation panel, use the first trigger host if (!$data['hostid']) { $hosts = reset($data['trigger']['hosts']); $data['hostid'] = $hosts['hostid']; } } if (!empty($data['triggerid']) && !isset($_REQUEST['form_refresh']) || !empty($data['limited'])) { $data['expression'] = explode_exp($data['trigger']['expression']); if (empty($data['limited']) || !isset($_REQUEST['form_refresh'])) { $data['description'] = $data['trigger']['description']; $data['type'] = $data['trigger']['type']; $data['priority'] = $data['trigger']['priority']; $data['status'] = $data['trigger']['status']; $data['comments'] = $data['trigger']['comments']; $data['url'] = $data['trigger']['url']; $db_triggers = DBselect('SELECT t.triggerid,t.description' . ' FROM triggers t,trigger_depends d' . ' WHERE t.triggerid=d.triggerid_up' . ' AND d.triggerid_down=' . zbx_dbstr($data['triggerid'])); while ($trigger = DBfetch($db_triggers)) { if (uint_in_array($trigger['triggerid'], $data['dependencies'])) { continue; } array_push($data['dependencies'], $trigger['triggerid']); } } } if ($data['input_method'] == IM_TREE) { $analyze = analyzeExpression($data['expression']); if ($analyze !== false) { list($data['outline'], $data['eHTMLTree']) = $analyze; if (isset($_REQUEST['expr_action']) && $data['eHTMLTree'] != null) { $new_expr = remakeExpression($data['expression'], $_REQUEST['expr_target_single'], $_REQUEST['expr_action'], $data['expr_temp']); if ($new_expr !== false) { $data['expression'] = $new_expr; $analyze = analyzeExpression($data['expression']); if ($analyze !== false) { list($data['outline'], $data['eHTMLTree']) = $analyze; } else { show_messages(false, '', _('Expression Syntax Error.')); } $data['expr_temp'] = ''; } else { show_messages(false, '', _('Expression Syntax Error.')); } } $data['expression_field_name'] = 'expr_temp'; $data['expression_field_value'] = $data['expr_temp']; $data['expression_field_readonly'] = 'yes'; $data['expression_field_params'] = 'this.form.elements["' . $data['expression_field_name'] . '"].value'; $data['expression_macro_button'] = new CButton('insert_macro', _('Insert macro'), 'return call_ins_macro_menu(event);', 'formlist'); if ($data['limited'] == 'yes') { $data['expression_macro_button']->setAttribute('disabled', 'disabled'); } } else { show_messages(false, '', _('Expression Syntax Error.')); $data['input_method'] = IM_ESTABLISHED; } } if ($data['input_method'] != IM_TREE) { $data['expression_field_name'] = 'expression'; $data['expression_field_value'] = $data['expression']; $data['expression_field_readonly'] = $data['limited']; } if (empty($data['parent_discoveryid'])) { $data['db_dependencies'] = API::Trigger()->get(array('triggerids' => $data['dependencies'], 'output' => array('triggerid', 'description'), 'preservekeys' => true, 'selectHosts' => array('name'))); foreach ($data['db_dependencies'] as &$dependency) { if (!empty($dependency['hosts'][0]['name'])) { $dependency['host'] = $dependency['hosts'][0]['name']; } unset($dependency['hosts']); } order_result($data['db_dependencies'], 'description'); } return $data; }
* Display */ if ($_REQUEST['go'] == 'massupdate' && isset($_REQUEST['g_triggerid'])) { $triggersView = new CView('configuration.triggers.massupdate', getTriggerMassupdateFormData()); $triggersView->render(); $triggersView->show(); } elseif (isset($_REQUEST['form'])) { $triggersView = new CView('configuration.triggers.edit', getTriggerFormData()); $triggersView->render(); $triggersView->show(); } else { $data = array('parent_discoveryid' => get_request('parent_discoveryid'), 'discovery_rule' => $discovery_rule, 'hostid' => get_request('hostid'), 'showdisabled' => get_request('showdisabled', 1), 'triggers' => array()); CProfile::update('web.triggers.showdisabled', $data['showdisabled'], PROFILE_TYPE_INT); // get triggers $sortfield = getPageSortField('description'); $options = array('editable' => true, 'output' => API_OUTPUT_SHORTEN, 'discoveryids' => $data['parent_discoveryid'], 'sortfield' => $sortfield, 'limit' => $config['search_limit'] + 1); if (empty($data['showdisabled'])) { $options['filter']['status'] = TRIGGER_STATUS_ENABLED; } $data['triggers'] = API::TriggerPrototype()->get($options); $data['paging'] = getPagingLine($data['triggers']); $data['triggers'] = API::TriggerPrototype()->get(array('triggerids' => zbx_objectValues($data['triggers'], 'triggerid'), 'output' => API_OUTPUT_EXTEND, 'selectHosts' => API_OUTPUT_EXTEND, 'selectItems' => API_OUTPUT_EXTEND, 'selectFunctions' => API_OUTPUT_EXTEND)); order_result($data['triggers'], $sortfield, getPageSortOrder()); // get real hosts $data['realHosts'] = getParentHostsByTriggers($data['triggers']); // render view $triggersView = new CView('configuration.triggers.list', $data); $triggersView->render(); $triggersView->show(); } require_once dirname(__FILE__) . '/include/page_footer.php';
$listBox = (new CListBox('discoveryRules', null, 8))->setAttribute('disabled', 'disabled')->addItems($discoveryRuleList); $templateList->addRow(_('Discovery rules'), $listBox); // item prototypes $hostItemPrototypes = API::ItemPrototype()->get(['hostids' => $data['templateId'], 'discoveryids' => $hostDiscoveryRuleids, 'inherited' => false, 'output' => API_OUTPUT_EXTEND]); if ($hostItemPrototypes) { $hostItemPrototypes = CMacrosResolverHelper::resolveItemNames($hostItemPrototypes); $prototypeList = []; foreach ($hostItemPrototypes as $itemPrototype) { $prototypeList[$itemPrototype['itemid']] = $itemPrototype['name_expanded']; } order_result($prototypeList); $listBox = (new CListBox('itemsPrototypes', null, 8))->setAttribute('disabled', 'disabled')->addItems($prototypeList); $templateList->addRow(_('Item prototypes'), $listBox); } // Trigger prototypes $hostTriggerPrototypes = API::TriggerPrototype()->get(['hostids' => $data['templateId'], 'discoveryids' => $hostDiscoveryRuleids, 'inherited' => false, 'output' => API_OUTPUT_EXTEND]); if (!empty($hostTriggerPrototypes)) { $prototypeList = []; foreach ($hostTriggerPrototypes as $triggerPrototype) { $prototypeList[$triggerPrototype['triggerid']] = $triggerPrototype['description']; } order_result($prototypeList); $listBox = (new CListBox('triggerprototypes', null, 8))->setAttribute('disabled', 'disabled')->addItems($prototypeList); $templateList->addRow(_('Trigger prototypes'), $listBox); } // Graph prototypes $hostGraphPrototypes = API::GraphPrototype()->get(['hostids' => $data['templateId'], 'discoveryids' => $hostDiscoveryRuleids, 'inherited' => false, 'output' => API_OUTPUT_EXTEND]); if (!empty($hostGraphPrototypes)) { $prototypeList = []; foreach ($hostGraphPrototypes as $graphPrototype) { $prototypeList[$graphPrototype['graphid']] = $graphPrototype['name'];
$form = (new CForm())->setName('triggerform')->setId('triggers'); $table = (new CTableInfo())->setHeader([$multiselect ? (new CColHeader((new CCheckBox('all_triggers'))->onClick("checkAll('" . $form->getName() . "', 'all_triggers', 'triggers');")))->addClass(ZBX_STYLE_CELL_WIDTH) : null, _('Name'), _('Severity'), _('Status')]); $options = ['output' => ['triggerid', 'expression', 'description', 'status', 'priority', 'state'], 'selectHosts' => ['name'], 'selectDependencies' => ['triggerid', 'expression', 'description'], 'expandDescription' => true]; if ($srctbl === 'trigger_prototypes') { if ($parentDiscoveryId) { $options['discoveryids'] = [$parentDiscoveryId]; } else { $options['hostids'] = [$hostid]; } if ($writeonly !== null) { $options['editable'] = true; } if ($templated !== null) { $options['templated'] = $templated; } $triggers = API::TriggerPrototype()->get($options); } else { if ($hostid === null) { $options['groupids'] = $groupid; } else { $options['hostids'] = [$hostid]; } if ($writeonly !== null) { $options['editable'] = true; } if ($templated !== null) { $options['templated'] = $templated; } if ($withMonitoredTriggers) { $options['monitored'] = true; }
// item prototypes $hostItemPrototypes = API::ItemPrototype()->get(array('hostids' => $templateid, 'discoveryids' => $hostDiscoveryRuleids, 'inherited' => false, 'output' => API_OUTPUT_EXTEND)); if ($hostItemPrototypes) { $hostItemPrototypes = CMacrosResolverHelper::resolveItemNames($hostItemPrototypes); $prototypeList = array(); foreach ($hostItemPrototypes as $itemPrototype) { $prototypeList[$itemPrototype['itemid']] = $itemPrototype['name_expanded']; } order_result($prototypeList); $listBox = new CListBox('itemsPrototypes', null, 8); $listBox->setAttribute('disabled', 'disabled'); $listBox->addItems($prototypeList); $templateList->addRow(_('Item prototypes'), $listBox); } // Trigger prototypes $hostTriggerPrototypes = API::TriggerPrototype()->get(array('hostids' => $templateid, 'discoveryids' => $hostDiscoveryRuleids, 'inherited' => false, 'output' => API_OUTPUT_EXTEND)); if (!empty($hostTriggerPrototypes)) { $prototypeList = array(); foreach ($hostTriggerPrototypes as $triggerPrototype) { $prototypeList[$triggerPrototype['triggerid']] = $triggerPrototype['description']; } order_result($prototypeList); $listBox = new CListBox('triggerprototypes', null, 8); $listBox->setAttribute('disabled', 'disabled'); $listBox->addItems($prototypeList); $templateList->addRow(_('Trigger prototypes'), $listBox); } // Graph prototypes $hostGraphPrototypes = API::GraphPrototype()->get(array('hostids' => $templateid, 'discoveryids' => $hostDiscoveryRuleids, 'inherited' => false, 'output' => API_OUTPUT_EXTEND)); if (!empty($hostGraphPrototypes)) { $prototypeList = array();
protected function addRelatedObjects(array $options, array $result) { $result = parent::addRelatedObjects($options, $result); $itemIds = array_keys($result); // adding items if (!is_null($options['selectItems'])) { if ($options['selectItems'] != API_OUTPUT_COUNT) { $relationMap = $this->createRelationMap($result, 'parent_itemid', 'itemid', 'item_discovery'); $items = API::ItemPrototype()->get(array('output' => $options['selectItems'], 'itemids' => $relationMap->getRelatedIds(), 'nopermissions' => true, 'preservekeys' => true)); $result = $relationMap->mapMany($result, $items, 'items', $options['limitSelects']); } else { $items = API::ItemPrototype()->get(array('discoveryids' => $itemIds, 'nopermissions' => true, 'countOutput' => true, 'groupCount' => true)); $items = zbx_toHash($items, 'parent_itemid'); foreach ($result as $itemid => $item) { $result[$itemid]['items'] = isset($items[$itemid]) ? $items[$itemid]['rowscount'] : 0; } } } // adding triggers if (!is_null($options['selectTriggers'])) { if ($options['selectTriggers'] != API_OUTPUT_COUNT) { $relationMap = new CRelationMap(); $res = DBselect('SELECT id.parent_itemid,f.triggerid' . ' FROM item_discovery id,items i,functions f' . ' WHERE ' . dbConditionInt('id.parent_itemid', $itemIds) . ' AND id.itemid=i.itemid' . ' AND i.itemid=f.itemid'); while ($relation = DBfetch($res)) { $relationMap->addRelation($relation['parent_itemid'], $relation['triggerid']); } $triggers = API::TriggerPrototype()->get(array('output' => $options['selectTriggers'], 'triggerids' => $relationMap->getRelatedIds(), 'preservekeys' => true)); $result = $relationMap->mapMany($result, $triggers, 'triggers', $options['limitSelects']); } else { $triggers = API::TriggerPrototype()->get(array('discoveryids' => $itemIds, 'countOutput' => true, 'groupCount' => true)); $triggers = zbx_toHash($triggers, 'parent_itemid'); foreach ($result as $itemid => $item) { $result[$itemid]['triggers'] = isset($triggers[$itemid]) ? $triggers[$itemid]['rowscount'] : 0; } } } // adding graphs if (!is_null($options['selectGraphs'])) { if ($options['selectGraphs'] != API_OUTPUT_COUNT) { $relationMap = new CRelationMap(); $res = DBselect('SELECT id.parent_itemid,gi.graphid' . ' FROM item_discovery id,items i,graphs_items gi' . ' WHERE ' . dbConditionInt('id.parent_itemid', $itemIds) . ' AND id.itemid=i.itemid' . ' AND i.itemid=gi.itemid'); while ($relation = DBfetch($res)) { $relationMap->addRelation($relation['parent_itemid'], $relation['graphid']); } $graphs = API::GraphPrototype()->get(array('output' => $options['selectGraphs'], 'graphids' => $relationMap->getRelatedIds(), 'preservekeys' => true)); $result = $relationMap->mapMany($result, $graphs, 'graphs', $options['limitSelects']); } else { $graphs = API::GraphPrototype()->get(array('discoveryids' => $itemIds, 'countOutput' => true, 'groupCount' => true)); $graphs = zbx_toHash($graphs, 'parent_itemid'); foreach ($result as $itemid => $item) { $result[$itemid]['graphs'] = isset($graphs[$itemid]) ? $graphs[$itemid]['rowscount'] : 0; } } } // adding hosts if ($options['selectHostPrototypes'] !== null) { if ($options['selectHostPrototypes'] != API_OUTPUT_COUNT) { $relationMap = $this->createRelationMap($result, 'parent_itemid', 'hostid', 'host_discovery'); $hostPrototypes = API::HostPrototype()->get(array('output' => $options['selectHostPrototypes'], 'hostids' => $relationMap->getRelatedIds(), 'nopermissions' => true, 'preservekeys' => true)); $result = $relationMap->mapMany($result, $hostPrototypes, 'hostPrototypes', $options['limitSelects']); } else { $hostPrototypes = API::HostPrototype()->get(array('discoveryids' => $itemIds, 'nopermissions' => true, 'countOutput' => true, 'groupCount' => true)); $hostPrototypes = zbx_toHash($hostPrototypes, 'parent_itemid'); foreach ($result as $itemid => $item) { $result[$itemid]['hostPrototypes'] = isset($hostPrototypes[$itemid]) ? $hostPrototypes[$itemid]['rowscount'] : 0; } } } if ($options['selectFilter'] !== null) { $formulaRequested = $this->outputIsRequested('formula', $options['selectFilter']); $evalFormulaRequested = $this->outputIsRequested('eval_formula', $options['selectFilter']); $conditionsRequested = $this->outputIsRequested('conditions', $options['selectFilter']); $filters = array(); foreach ($result as $rule) { $filters[$rule['itemid']] = array('evaltype' => $rule['evaltype'], 'formula' => isset($rule['formula']) ? $rule['formula'] : ''); } // adding conditions if ($formulaRequested || $evalFormulaRequested || $conditionsRequested) { $conditions = API::getApiService()->select('item_condition', array('output' => array('item_conditionid', 'macro', 'value', 'itemid', 'operator'), 'filter' => array('itemid' => $itemIds), 'preservekeys' => true, 'sortfield' => 'item_conditionid')); $relationMap = $this->createRelationMap($conditions, 'itemid', 'item_conditionid'); $filters = $relationMap->mapMany($filters, $conditions, 'conditions'); foreach ($filters as &$filter) { // in case of a custom expression - use the given formula if ($filter['evaltype'] == CONDITION_EVAL_TYPE_EXPRESSION) { $formula = $filter['formula']; } else { // sort the conditions by macro before generating the formula $conditions = zbx_toHash($filter['conditions'], 'item_conditionid'); $conditions = order_macros($conditions, 'macro'); $formulaConditions = array(); foreach ($conditions as $condition) { $formulaConditions[$condition['item_conditionid']] = $condition['macro']; } $formula = CConditionHelper::getFormula($formulaConditions, $filter['evaltype']); } // generate formulaids from the effective formula $formulaIds = CConditionHelper::getFormulaIds($formula); foreach ($filter['conditions'] as &$condition) { $condition['formulaid'] = $formulaIds[$condition['item_conditionid']]; } unset($condition); // generated a letter based formula only for rules with custom expressions if ($formulaRequested && $filter['evaltype'] == CONDITION_EVAL_TYPE_EXPRESSION) { $filter['formula'] = CConditionHelper::replaceNumericIds($formula, $formulaIds); } if ($evalFormulaRequested) { $filter['eval_formula'] = CConditionHelper::replaceNumericIds($formula, $formulaIds); } } unset($filter); } // add filters to the result foreach ($result as &$rule) { $rule['filter'] = $filters[$rule['itemid']]; } unset($rule); } return $result; }
$triggersView->render(); $triggersView->show(); } elseif (isset($_REQUEST['form'])) { $triggersView = new CView('configuration.triggers.edit', getTriggerFormData($exprAction)); $triggersView->render(); $triggersView->show(); } else { $sortField = getRequest('sort', CProfile::get('web.' . $page['file'] . '.sort', 'description')); $sortOrder = getRequest('sortorder', CProfile::get('web.' . $page['file'] . '.sortorder', ZBX_SORT_UP)); CProfile::update('web.' . $page['file'] . '.sort', $sortField, PROFILE_TYPE_STR); CProfile::update('web.' . $page['file'] . '.sortorder', $sortOrder, PROFILE_TYPE_STR); $data = array('parent_discoveryid' => getRequest('parent_discoveryid'), 'showInfoColumn' => false, 'discovery_rule' => $discovery_rule, 'hostid' => getRequest('hostid'), 'showdisabled' => getRequest('showdisabled', 1), 'triggers' => array(), 'sort' => $sortField, 'sortorder' => $sortOrder); CProfile::update('web.triggers.showdisabled', $data['showdisabled'], PROFILE_TYPE_INT); // get triggers $options = array('editable' => true, 'output' => array('triggerid'), 'discoveryids' => $data['parent_discoveryid'], 'sortfield' => $sortField, 'limit' => $config['search_limit'] + 1); if (empty($data['showdisabled'])) { $options['filter']['status'] = TRIGGER_STATUS_ENABLED; } $data['triggers'] = API::TriggerPrototype()->get($options); // paging $data['paging'] = getPagingLine($data['triggers']); $data['triggers'] = API::TriggerPrototype()->get(array('triggerids' => zbx_objectValues($data['triggers'], 'triggerid'), 'output' => API_OUTPUT_EXTEND, 'selectHosts' => API_OUTPUT_EXTEND, 'selectItems' => array('itemid', 'hostid', 'key_', 'type', 'flags', 'status'), 'selectFunctions' => API_OUTPUT_EXTEND)); order_result($data['triggers'], $sortField, $sortOrder); // get real hosts $data['realHosts'] = getParentHostsByTriggers($data['triggers']); // render view $triggersView = new CView('configuration.triggers.list', $data); $triggersView->render(); $triggersView->show(); } require_once dirname(__FILE__) . '/include/page_footer.php';
$url = (new CUrl('trigger_prototypes.php'))->setArgument('parent_discoveryid', $data['parent_discoveryid']); $data['paging'] = getPagingLine($data['triggers'], $sortOrder, $url); $data['triggers'] = API::TriggerPrototype()->get(['output' => ['triggerid', 'expression', 'description', 'status', 'priority', 'templateid'], 'selectHosts' => ['hostid', 'host'], 'selectDependencies' => ['triggerid', 'description'], 'triggerids' => zbx_objectValues($data['triggers'], 'triggerid')]); order_result($data['triggers'], $sortField, $sortOrder); $depTriggerIds = []; foreach ($data['triggers'] as $trigger) { foreach ($trigger['dependencies'] as $depTrigger) { $depTriggerIds[$depTrigger['triggerid']] = true; } } if ($depTriggerIds) { $dependencyTriggers = []; $dependencyTriggerPrototypes = []; $depTriggerIds = array_keys($depTriggerIds); $dependencyTriggers = API::Trigger()->get(['output' => ['triggerid', 'description', 'status', 'flags'], 'selectHosts' => ['hostid', 'name'], 'triggerids' => $depTriggerIds, 'filter' => ['flags' => [ZBX_FLAG_DISCOVERY_NORMAL]], 'preservekeys' => true]); $dependencyTriggerPrototypes = API::TriggerPrototype()->get(['output' => ['triggerid', 'description', 'status', 'flags'], 'selectHosts' => ['hostid', 'name'], 'triggerids' => $depTriggerIds, 'preservekeys' => true]); $data['dependencyTriggers'] = $dependencyTriggers + $dependencyTriggerPrototypes; foreach ($data['triggers'] as &$trigger) { order_result($trigger['dependencies'], 'description', ZBX_SORT_UP); } unset($trigger); foreach ($data['dependencyTriggers'] as &$dependencyTrigger) { order_result($dependencyTrigger['hosts'], 'name', ZBX_SORT_UP); } unset($dependencyTrigger); } // get real hosts $data['realHosts'] = getParentHostsByTriggers($data['triggers']); // render view $triggersView = new CView('configuration.trigger.prototype.list', $data); $triggersView->render();
/** * Deletes discovery rules and prototypes from DB that are missing in XML. * * @return null */ protected function deleteMissingDiscoveryRules() { if (!$this->options['discoveryRules']['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; } $discoveryRuleIdsXML = array(); $allDiscoveryRules = $this->getFormattedDiscoveryRules(); if ($allDiscoveryRules) { foreach ($allDiscoveryRules as $host => $discoveryRules) { $hostId = $this->referencer->resolveHostOrTemplate($host); foreach ($discoveryRules as $discoveryRule) { $discoveryRuleId = $this->referencer->resolveItem($hostId, $discoveryRule['key_']); if ($discoveryRuleId) { $discoveryRuleIdsXML[$discoveryRuleId] = $discoveryRuleId; } } } } $dbDiscoveryRuleIds = API::DiscoveryRule()->get(array('output' => array('itemid'), 'hostids' => $processedHostIds, 'preservekeys' => true, 'nopermissions' => true, 'inherited' => false)); $discoveryRulesToDelete = array_diff_key($dbDiscoveryRuleIds, $discoveryRuleIdsXML); if ($discoveryRulesToDelete) { API::DiscoveryRule()->delete(array_keys($discoveryRulesToDelete)); } // refresh discovery rules because templated ones can be inherited to host and used for prototypes $this->referencer->refreshItems(); $hostPrototypeIdsXML = array(); $triggerPrototypeIdsXML = array(); $itemPrototypeIdsXML = array(); $graphPrototypeIdsXML = array(); foreach ($allDiscoveryRules as $host => $discoveryRules) { $hostId = $this->referencer->resolveHostOrTemplate($host); foreach ($discoveryRules as $discoveryRule) { $discoveryRuleId = $this->referencer->resolveItem($hostId, $discoveryRule['key_']); if ($discoveryRuleId) { // gather host prototype IDs to delete foreach ($discoveryRule['host_prototypes'] as $hostPrototype) { $hostPrototypeId = $this->referencer->resolveHostPrototype($hostId, $discoveryRuleId, $hostPrototype['host']); if ($hostPrototypeId) { $hostPrototypeIdsXML[$hostPrototypeId] = $hostPrototypeId; } } // gather trigger prototype IDs to delete foreach ($discoveryRule['trigger_prototypes'] as $triggerPrototype) { $triggerPrototypeId = $this->referencer->resolveTrigger($triggerPrototype['description'], $triggerPrototype['expression']); if ($triggerPrototypeId) { $triggerPrototypeIdsXML[$triggerPrototypeId] = $triggerPrototypeId; } } // gather graph prototype IDs to delete foreach ($discoveryRule['graph_prototypes'] as $graphPrototype) { $graphPrototypeId = $this->referencer->resolveGraph($hostId, $graphPrototype['name']); if ($graphPrototypeId) { $graphPrototypeIdsXML[$graphPrototypeId] = $graphPrototypeId; } } // gather item prototype IDs to delete foreach ($discoveryRule['item_prototypes'] as $itemPrototype) { $itemPrototypeId = $this->referencer->resolveItem($hostId, $itemPrototype['key_']); if ($itemPrototypeId) { $itemPrototypeIdsXML[$itemPrototypeId] = $itemPrototypeId; } } } } } // delete missing host prototypes $dbHostPrototypeIds = API::HostPrototype()->get(array('output' => array('hostid'), 'discoveryids' => $discoveryRuleIdsXML, 'preservekeys' => true, 'nopermissions' => true, 'inherited' => false)); $hostPrototypesToDelete = array_diff_key($dbHostPrototypeIds, $hostPrototypeIdsXML); if ($hostPrototypesToDelete) { API::HostPrototype()->delete(array_keys($hostPrototypesToDelete)); } // delete missing trigger prototypes $dbTriggerPrototypeIds = API::TriggerPrototype()->get(array('output' => array('triggerid'), 'hostids' => $processedHostIds, 'preservekeys' => true, 'nopermissions' => true, 'inherited' => false)); $triggerPrototypesToDelete = array_diff_key($dbTriggerPrototypeIds, $triggerPrototypeIdsXML); // unlike triggers that belong to multiple hosts, trigger prototypes do not, so we just delete them if ($triggerPrototypesToDelete) { API::TriggerPrototype()->delete(array_keys($triggerPrototypesToDelete)); } // delete missing graph prototypes $dbGraphPrototypeIds = API::GraphPrototype()->get(array('output' => array('graphid'), 'hostids' => $processedHostIds, 'preservekeys' => true, 'nopermissions' => true, 'inherited' => false)); $graphPrototypesToDelete = array_diff_key($dbGraphPrototypeIds, $graphPrototypeIdsXML); // unlike graphs that belong to multiple hosts, graph prototypes do not, so we just delete them if ($graphPrototypesToDelete) { API::GraphPrototype()->delete(array_keys($graphPrototypesToDelete)); } // delete missing item prototypes $dbItemPrototypeIds = API::ItemPrototype()->get(array('output' => array('itemid'), 'hostids' => $processedHostIds, 'preservekeys' => true, 'nopermissions' => true, 'inherited' => false)); $itemPrototypesToDelete = array_diff_key($dbItemPrototypeIds, $itemPrototypeIdsXML); if ($itemPrototypesToDelete) { API::ItemPrototype()->delete(array_keys($itemPrototypesToDelete)); } }
/** * Get discovery rules related objects from database. * * @param array $items * * @return array */ protected function prepareDiscoveryRules(array $items) { foreach ($items as &$item) { $item['itemPrototypes'] = []; $item['graphPrototypes'] = []; $item['triggerPrototypes'] = []; $item['hostPrototypes'] = []; // unset unnecessary condition fields foreach ($item['filter']['conditions'] as &$condition) { unset($condition['item_conditionid'], $condition['itemid']); } unset($condition); } unset($item); // gather item prototypes $prototypes = API::ItemPrototype()->get(['output' => $this->dataFields['item_prototype'], 'selectApplications' => ['name'], 'selectApplicationPrototypes' => ['name'], 'selectDiscoveryRule' => ['itemid'], 'discoveryids' => zbx_objectValues($items, 'itemid'), 'inherited' => false, 'preservekeys' => true]); $valuemapids = []; foreach ($prototypes as $prototype) { $valuemapids[$prototype['valuemapid']] = true; } // Value map IDs that are zeroes, should be skipped. unset($valuemapids[0]); if ($this->data['valueMaps']) { /* * If there is an option "valueMaps", some value maps may already been selected. Copy the result and remove * value map IDs that should not be selected again. */ foreach ($this->data['valueMaps'] as $valuemapid => $valuemap) { if (array_key_exists($valuemapid, $valuemapids)) { unset($valuemapids[$valuemapid]); } } } if ($valuemapids) { $this->data['valueMaps'] += API::ValueMap()->get(['output' => ['valuemapid', 'name'], 'selectMappings' => ['value', 'newvalue'], 'valuemapids' => array_keys($valuemapids), 'preservekeys' => true]); } foreach ($prototypes as $prototype) { $prototype['valuemap'] = []; if ($prototype['valuemapid'] != 0) { $prototype['valuemap']['name'] = $this->data['valueMaps'][$prototype['valuemapid']]['name']; } $items[$prototype['discoveryRule']['itemid']]['itemPrototypes'][] = $prototype; } // gather graph prototypes $graphs = API::GraphPrototype()->get(['discoveryids' => zbx_objectValues($items, 'itemid'), 'selectDiscoveryRule' => API_OUTPUT_EXTEND, 'selectGraphItems' => API_OUTPUT_EXTEND, 'output' => API_OUTPUT_EXTEND, 'inherited' => false, 'preservekeys' => true]); $graphs = $this->prepareGraphs($graphs); foreach ($graphs as $graph) { $items[$graph['discoveryRule']['itemid']]['graphPrototypes'][] = $graph; } // gather trigger prototypes $triggers = API::TriggerPrototype()->get(['discoveryids' => zbx_objectValues($items, 'itemid'), 'output' => ['expression', 'description', 'url', 'status', 'priority', 'comments', 'type'], 'selectDiscoveryRule' => API_OUTPUT_EXTEND, 'selectDependencies' => ['description', 'expression'], 'selectItems' => ['itemid', 'flags', 'type'], 'inherited' => false, 'preservekeys' => true]); $triggers = $this->prepareTriggers($triggers); foreach ($triggers as $trigger) { $items[$trigger['discoveryRule']['itemid']]['triggerPrototypes'][] = $trigger; } // gather host prototypes $hostPrototypes = API::HostPrototype()->get(['discoveryids' => zbx_objectValues($items, 'itemid'), 'output' => API_OUTPUT_EXTEND, 'selectGroupLinks' => API_OUTPUT_EXTEND, 'selectGroupPrototypes' => API_OUTPUT_EXTEND, 'selectDiscoveryRule' => API_OUTPUT_EXTEND, 'selectTemplates' => API_OUTPUT_EXTEND, 'inherited' => false, 'preservekeys' => true]); // replace group prototype group IDs with references $groupIds = []; foreach ($hostPrototypes as $hostPrototype) { foreach ($hostPrototype['groupLinks'] as $groupLink) { $groupIds[$groupLink['groupid']] = true; } } $groups = $this->getGroupsReferences(array_keys($groupIds)); // export the groups used in group prototypes $this->data['groups'] += $groups; foreach ($hostPrototypes as $hostPrototype) { foreach ($hostPrototype['groupLinks'] as &$groupLink) { $groupLink['groupid'] = $groups[$groupLink['groupid']]; } unset($groupLink); $items[$hostPrototype['discoveryRule']['itemid']]['hostPrototypes'][] = $hostPrototype; } return $items; }
/** * 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); } }
// item prototypes $hostItemPrototypes = API::ItemPrototype()->get(['output' => ['itemid', 'hostid', 'key_', 'name'], 'hostids' => [$data['clone_hostid']], 'discoveryids' => $hostDiscoveryRuleIds, 'inherited' => false]); if ($hostItemPrototypes) { $hostItemPrototypes = CMacrosResolverHelper::resolveItemNames($hostItemPrototypes); $prototypeList = []; foreach ($hostItemPrototypes as $itemPrototype) { $prototypeList[$itemPrototype['itemid']] = $itemPrototype['name_expanded']; } order_result($prototypeList); $listBox = new CListBox('itemsPrototypes', null, 8); $listBox->setAttribute('disabled', 'disabled'); $listBox->addItems($prototypeList); $hostList->addRow(_('Item prototypes'), $listBox); } // Trigger prototypes $hostTriggerPrototypes = API::TriggerPrototype()->get(['output' => ['triggerid', 'description'], 'selectItems' => ['type'], 'hostids' => [$data['clone_hostid']], 'discoveryids' => $hostDiscoveryRuleIds, 'inherited' => false]); if ($hostTriggerPrototypes) { $prototypeList = []; foreach ($hostTriggerPrototypes as $triggerPrototype) { // skip trigger prototypes with web items if (httpItemExists($triggerPrototype['items'])) { continue; } $prototypeList[$triggerPrototype['triggerid']] = $triggerPrototype['description']; } if ($prototypeList) { order_result($prototypeList); $listBox = new CListBox('triggerprototypes', null, 8); $listBox->setAttribute('disabled', 'disabled'); $listBox->addItems($prototypeList); $hostList->addRow(_('Trigger prototypes'), $listBox);
/** * Generate data for the trigger configuration form. * * @param string $exprAction expression constructor action, see remakeExpression() for a list of supported values * * @return array */ function getTriggerFormData($exprAction) { $data = array('form' => getRequest('form'), 'form_refresh' => getRequest('form_refresh'), 'parent_discoveryid' => getRequest('parent_discoveryid'), 'dependencies' => getRequest('dependencies', array()), 'db_dependencies' => array(), 'triggerid' => getRequest('triggerid'), 'expression' => getRequest('expression', ''), 'expr_temp' => getRequest('expr_temp', ''), 'description' => getRequest('description', ''), 'type' => getRequest('type', 0), 'priority' => getRequest('priority', 0), 'status' => getRequest('status', 0), 'comments' => getRequest('comments', ''), 'url' => getRequest('url', ''), 'input_method' => getRequest('input_method', IM_ESTABLISHED), 'limited' => false, 'templates' => array(), 'hostid' => getRequest('hostid', 0)); if (!empty($data['triggerid'])) { // get trigger $options = array('output' => API_OUTPUT_EXTEND, 'selectHosts' => array('hostid'), 'triggerids' => $data['triggerid']); $trigger = $data['parent_discoveryid'] ? API::TriggerPrototype()->get($options) : API::Trigger()->get($options); $data['trigger'] = reset($trigger); // get templates $tmp_triggerid = $data['triggerid']; do { $db_triggers = DBfetch(DBselect('SELECT t.triggerid,t.templateid,id.parent_itemid,h.name,h.hostid' . ' FROM triggers t' . ' LEFT JOIN functions f ON t.triggerid=f.triggerid' . ' LEFT JOIN items i ON f.itemid=i.itemid' . ' LEFT JOIN hosts h ON i.hostid=h.hostid' . ' LEFT JOIN item_discovery id ON i.itemid=id.itemid' . ' WHERE t.triggerid=' . zbx_dbstr($tmp_triggerid))); if (bccomp($data['triggerid'], $tmp_triggerid) != 0) { // parent trigger prototype link if ($data['parent_discoveryid']) { $link = 'trigger_prototypes.php?form=update&triggerid=' . $db_triggers['triggerid'] . '&parent_discoveryid=' . $db_triggers['parent_itemid'] . '&hostid=' . $db_triggers['hostid']; } else { $link = 'triggers.php?form=update&triggerid=' . $db_triggers['triggerid'] . '&hostid=' . $db_triggers['hostid']; } $data['templates'][] = new CLink(CHtml::encode($db_triggers['name']), $link, 'highlight underline weight_normal'); $data['templates'][] = SPACE . '⇒' . SPACE; } $tmp_triggerid = $db_triggers['templateid']; } while ($tmp_triggerid != 0); $data['templates'] = array_reverse($data['templates']); array_shift($data['templates']); $data['limited'] = $data['trigger']['templateid'] != 0; // select first host from triggers if gived not match $hosts = $data['trigger']['hosts']; if (count($hosts) > 0 && !in_array(array('hostid' => $data['hostid']), $hosts)) { $host = reset($hosts); $data['hostid'] = $host['hostid']; } } if (!empty($data['triggerid']) && !isset($_REQUEST['form_refresh']) || $data['limited']) { $data['expression'] = explode_exp($data['trigger']['expression']); if (!$data['limited'] || !isset($_REQUEST['form_refresh'])) { $data['description'] = $data['trigger']['description']; $data['type'] = $data['trigger']['type']; $data['priority'] = $data['trigger']['priority']; $data['status'] = $data['trigger']['status']; $data['comments'] = $data['trigger']['comments']; $data['url'] = $data['trigger']['url']; $db_triggers = DBselect('SELECT t.triggerid,t.description' . ' FROM triggers t,trigger_depends d' . ' WHERE t.triggerid=d.triggerid_up' . ' AND d.triggerid_down=' . zbx_dbstr($data['triggerid'])); while ($trigger = DBfetch($db_triggers)) { if (uint_in_array($trigger['triggerid'], $data['dependencies'])) { continue; } array_push($data['dependencies'], $trigger['triggerid']); } } } if ($data['input_method'] == IM_TREE) { $analyze = analyzeExpression($data['expression']); if ($analyze !== false) { list($data['outline'], $data['eHTMLTree']) = $analyze; if ($exprAction !== null && $data['eHTMLTree'] != null) { $new_expr = remakeExpression($data['expression'], $_REQUEST['expr_target_single'], $exprAction, $data['expr_temp']); if ($new_expr !== false) { $data['expression'] = $new_expr; $analyze = analyzeExpression($data['expression']); if ($analyze !== false) { list($data['outline'], $data['eHTMLTree']) = $analyze; } else { show_messages(false, '', _('Expression Syntax Error.')); } $data['expr_temp'] = ''; } else { show_messages(false, '', _('Expression Syntax Error.')); } } $data['expression_field_name'] = 'expr_temp'; $data['expression_field_value'] = $data['expr_temp']; $data['expression_field_readonly'] = true; } else { show_messages(false, '', _('Expression Syntax Error.')); $data['input_method'] = IM_ESTABLISHED; } } if ($data['input_method'] != IM_TREE) { $data['expression_field_name'] = 'expression'; $data['expression_field_value'] = $data['expression']; $data['expression_field_readonly'] = $data['limited']; } if (empty($data['parent_discoveryid'])) { $data['db_dependencies'] = API::Trigger()->get(array('triggerids' => $data['dependencies'], 'output' => array('triggerid', 'flags', 'description'), 'preservekeys' => true, 'selectHosts' => array('hostid', 'name'))); foreach ($data['db_dependencies'] as &$dependency) { if (count($dependency['hosts']) > 1) { order_result($dependency['hosts'], 'name', ZBX_SORT_UP); } $dependency['hosts'] = array_values($dependency['hosts']); $dependency['hostid'] = $dependency['hosts'][0]['hostid']; } unset($dependency); order_result($data['db_dependencies'], 'description'); } return $data; }
protected function addRelatedObjects(array $options, array $result) { $result = parent::addRelatedObjects($options, $result); $itemIds = array_keys($result); // adding items if (!is_null($options['selectItems'])) { if ($options['selectItems'] != API_OUTPUT_COUNT) { $relationMap = $this->createRelationMap($result, 'parent_itemid', 'itemid', 'item_discovery'); $items = API::ItemPrototype()->get(array('output' => $options['selectItems'], 'nodeids' => $options['nodeids'], 'itemids' => $relationMap->getRelatedIds(), 'nopermissions' => true, 'preservekeys' => true)); $result = $relationMap->mapMany($result, $items, 'items', $options['limitSelects']); } else { $items = API::ItemPrototype()->get(array('nodeids' => $options['nodeids'], 'discoveryids' => $itemIds, 'nopermissions' => true, 'countOutput' => true, 'groupCount' => true)); $items = zbx_toHash($items, 'parent_itemid'); foreach ($result as $itemid => $item) { $result[$itemid]['items'] = isset($items[$itemid]) ? $items[$itemid]['rowscount'] : 0; } } } // adding triggers if (!is_null($options['selectTriggers'])) { if ($options['selectTriggers'] != API_OUTPUT_COUNT) { $relationMap = new CRelationMap(); $res = DBselect('SELECT id.parent_itemid,f.triggerid' . ' FROM item_discovery id,items i,functions f' . ' WHERE ' . dbConditionInt('id.parent_itemid', $itemIds) . ' AND id.itemid=i.itemid' . ' AND i.itemid=f.itemid'); while ($relation = DBfetch($res)) { $relationMap->addRelation($relation['parent_itemid'], $relation['triggerid']); } $triggers = API::TriggerPrototype()->get(array('output' => $options['selectTriggers'], 'nodeids' => $options['nodeids'], 'triggerids' => $relationMap->getRelatedIds(), 'preservekeys' => true)); $result = $relationMap->mapMany($result, $triggers, 'triggers', $options['limitSelects']); } else { $triggers = API::TriggerPrototype()->get(array('nodeids' => $options['nodeids'], 'discoveryids' => $itemIds, 'countOutput' => true, 'groupCount' => true)); $triggers = zbx_toHash($triggers, 'parent_itemid'); foreach ($result as $itemid => $item) { $result[$itemid]['triggers'] = isset($triggers[$itemid]) ? $triggers[$itemid]['rowscount'] : 0; } } } // adding graphs if (!is_null($options['selectGraphs'])) { if ($options['selectGraphs'] != API_OUTPUT_COUNT) { $relationMap = new CRelationMap(); $res = DBselect('SELECT id.parent_itemid,gi.graphid' . ' FROM item_discovery id,items i,graphs_items gi' . ' WHERE ' . dbConditionInt('id.parent_itemid', $itemIds) . ' AND id.itemid=i.itemid' . ' AND i.itemid=gi.itemid'); while ($relation = DBfetch($res)) { $relationMap->addRelation($relation['parent_itemid'], $relation['graphid']); } $graphs = API::GraphPrototype()->get(array('output' => $options['selectGraphs'], 'nodeids' => $options['nodeids'], 'graphids' => $relationMap->getRelatedIds(), 'preservekeys' => true)); $result = $relationMap->mapMany($result, $graphs, 'graphs', $options['limitSelects']); } else { $graphs = API::GraphPrototype()->get(array('nodeids' => $options['nodeids'], 'discoveryids' => $itemIds, 'countOutput' => true, 'groupCount' => true)); $graphs = zbx_toHash($graphs, 'parent_itemid'); foreach ($result as $itemid => $item) { $result[$itemid]['graphs'] = isset($graphs[$itemid]) ? $graphs[$itemid]['rowscount'] : 0; } } } // adding hosts if ($options['selectHostPrototypes'] !== null) { if ($options['selectHostPrototypes'] != API_OUTPUT_COUNT) { $relationMap = $this->createRelationMap($result, 'parent_itemid', 'hostid', 'host_discovery'); $hostPrototypes = API::HostPrototype()->get(array('output' => $options['selectHostPrototypes'], 'nodeids' => $options['nodeids'], 'hostids' => $relationMap->getRelatedIds(), 'nopermissions' => true, 'preservekeys' => true)); $result = $relationMap->mapMany($result, $hostPrototypes, 'hostPrototypes', $options['limitSelects']); } else { $hostPrototypes = API::HostPrototype()->get(array('nodeids' => $options['nodeids'], 'discoveryids' => $itemIds, 'nopermissions' => true, 'countOutput' => true, 'groupCount' => true)); $hostPrototypes = zbx_toHash($hostPrototypes, 'parent_itemid'); foreach ($result as $itemid => $item) { $result[$itemid]['hostPrototypes'] = isset($hostPrototypes[$itemid]) ? $hostPrototypes[$itemid]['rowscount'] : 0; } } } return $result; }
public function addRelatedObjects(array $options, array $result) { $result = parent::addRelatedObjects($options, $result); $itemids = array_keys($result); // adding applications if ($options['selectApplications'] !== null && $options['selectApplications'] != API_OUTPUT_COUNT) { $relationMap = $this->createRelationMap($result, 'itemid', 'applicationid', 'items_applications'); $applications = API::Application()->get(array('output' => $options['selectApplications'], 'applicationids' => $relationMap->getRelatedIds(), 'preservekeys' => true)); $result = $relationMap->mapMany($result, $applications, 'applications'); } // adding triggers if (!is_null($options['selectTriggers'])) { if ($options['selectTriggers'] != API_OUTPUT_COUNT) { $relationMap = $this->createRelationMap($result, 'itemid', 'triggerid', 'functions'); $triggers = API::TriggerPrototype()->get(array('output' => $options['selectTriggers'], 'triggerids' => $relationMap->getRelatedIds(), 'preservekeys' => true)); if (!is_null($options['limitSelects'])) { order_result($triggers, 'description'); } $result = $relationMap->mapMany($result, $triggers, 'triggers', $options['limitSelects']); } else { $triggers = API::TriggerPrototype()->get(array('countOutput' => true, 'groupCount' => true, 'itemids' => $itemids)); $triggers = zbx_toHash($triggers, 'itemid'); foreach ($result as $itemid => $item) { if (isset($triggers[$itemid])) { $result[$itemid]['triggers'] = $triggers[$itemid]['rowscount']; } else { $result[$itemid]['triggers'] = 0; } } } } // adding graphs if (!is_null($options['selectGraphs'])) { if ($options['selectGraphs'] != API_OUTPUT_COUNT) { $relationMap = $this->createRelationMap($result, 'itemid', 'graphid', 'graphs_items'); $graphs = API::GraphPrototype()->get(array('output' => $options['selectGraphs'], 'graphids' => $relationMap->getRelatedIds(), 'preservekeys' => true)); if (!is_null($options['limitSelects'])) { order_result($graphs, 'name'); } $result = $relationMap->mapMany($result, $graphs, 'graphs', $options['limitSelects']); } else { $graphs = API::GraphPrototype()->get(array('countOutput' => true, 'groupCount' => true, 'itemids' => $itemids)); $graphs = zbx_toHash($graphs, 'itemid'); foreach ($result as $itemid => $item) { if (isset($graphs[$itemid])) { $result[$itemid]['graphs'] = $graphs[$itemid]['rowscount']; } else { $result[$itemid]['graphs'] = 0; } } } } // adding discoveryrule if ($options['selectDiscoveryRule'] !== null && $options['selectDiscoveryRule'] != API_OUTPUT_COUNT) { $relationMap = $this->createRelationMap($result, 'itemid', 'parent_itemid', 'item_discovery'); $discoveryRules = API::DiscoveryRule()->get(array('output' => $options['selectDiscoveryRule'], 'itemids' => $relationMap->getRelatedIds(), 'nopermissions' => true, 'preservekeys' => true)); $result = $relationMap->mapOne($result, $discoveryRules, 'discoveryRule'); } return $result; }
/** * Unlinks the templates from the given hosts. If $tragetids is set to null, the templates will be unlinked from * all hosts. * * @param $templateids * @param null|array $targetids the IDs of the hosts to unlink the templates from * @param bool $clear delete all of the inherited objects from the hosts * * @return void */ protected function unlink($templateids, $targetids = null, $clear = false) { $flags = $clear ? array(ZBX_FLAG_DISCOVERY_NORMAL, ZBX_FLAG_DISCOVERY) : array(ZBX_FLAG_DISCOVERY_NORMAL, ZBX_FLAG_DISCOVERY, ZBX_FLAG_DISCOVERY_CHILD); /* TRIGGERS {{{ */ // check that all triggers on templates that we unlink, don't have items from another templates $sql = 'SELECT DISTINCT t.description' . ' FROM triggers t,functions f,items i' . ' WHERE t.triggerid=f.triggerid' . ' AND f.itemid=i.itemid' . ' AND ' . dbConditionInt('i.hostid', $templateids) . ' AND EXISTS (' . 'SELECT ff.triggerid' . ' FROM functions ff,items ii' . ' WHERE ff.itemid=ii.itemid' . ' AND ff.triggerid=t.triggerid' . ' AND ' . dbConditionInt('ii.hostid', $templateids, true) . ')' . ' AND t.flags=' . ZBX_FLAG_DISCOVERY_NORMAL; if ($dbTrigger = DBfetch(DBSelect($sql, 1))) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Cannot unlink trigger "%s", it has items from template that is left linked to host.', $dbTrigger['description'])); } $sqlFrom = ' triggers t,hosts h'; $sqlWhere = ' EXISTS (' . 'SELECT ff.triggerid' . ' FROM functions ff,items ii' . ' WHERE ff.triggerid=t.templateid' . ' AND ii.itemid=ff.itemid' . ' AND ' . dbConditionInt('ii.hostid', $templateids) . ')' . ' AND ' . dbConditionInt('t.flags', $flags); if (!is_null($targetids)) { $sqlFrom = ' triggers t,functions f,items i,hosts h'; $sqlWhere .= ' AND ' . dbConditionInt('i.hostid', $targetids) . ' AND f.itemid=i.itemid' . ' AND t.triggerid=f.triggerid' . ' AND h.hostid=i.hostid'; } $sql = 'SELECT DISTINCT t.triggerid,t.description,t.flags,t.expression,h.name as host' . ' FROM ' . $sqlFrom . ' WHERE ' . $sqlWhere; $dbTriggers = DBSelect($sql); $triggers = array(ZBX_FLAG_DISCOVERY_NORMAL => array(), ZBX_FLAG_DISCOVERY_CHILD => array()); $triggerids = array(); while ($trigger = DBfetch($dbTriggers)) { $triggers[$trigger['flags']][$trigger['triggerid']] = array('description' => $trigger['description'], 'expression' => explode_exp($trigger['expression']), 'triggerid' => $trigger['triggerid'], 'host' => $trigger['host']); if (!in_array($trigger['triggerid'], $triggerids)) { array_push($triggerids, $trigger['triggerid']); } } if (!empty($triggers[ZBX_FLAG_DISCOVERY_NORMAL])) { if ($clear) { $result = API::Trigger()->delete(array_keys($triggers[ZBX_FLAG_DISCOVERY_NORMAL]), true); if (!$result) { self::exception(ZBX_API_ERROR_INTERNAL, _('Cannot unlink and clear triggers')); } } else { DB::update('triggers', array('values' => array('templateid' => 0), 'where' => array('triggerid' => array_keys($triggers[ZBX_FLAG_DISCOVERY_NORMAL])))); foreach ($triggers[ZBX_FLAG_DISCOVERY_NORMAL] as $trigger) { info(_s('Unlinked: Trigger "%1$s" on "%2$s".', $trigger['description'], $trigger['host'])); } } } if (!empty($triggers[ZBX_FLAG_DISCOVERY_CHILD])) { if ($clear) { $result = API::TriggerPrototype()->delete(array_keys($triggers[ZBX_FLAG_DISCOVERY_CHILD]), true); if (!$result) { self::exception(ZBX_API_ERROR_INTERNAL, _('Cannot unlink and clear triggers')); } } else { DB::update('triggers', array('values' => array('templateid' => 0), 'where' => array('triggerid' => array_keys($triggers[ZBX_FLAG_DISCOVERY_CHILD])))); foreach ($triggers[ZBX_FLAG_DISCOVERY_CHILD] as $trigger) { info(_s('Unlinked: Trigger prototype "%1$s" on "%2$s".', $trigger['description'], $trigger['host'])); } } } /* }}} TRIGGERS */ /* ITEMS, DISCOVERY RULES {{{ */ $sqlFrom = ' items i1,items i2,hosts h'; $sqlWhere = ' i2.itemid=i1.templateid' . ' AND ' . dbConditionInt('i2.hostid', $templateids) . ' AND ' . dbConditionInt('i1.flags', $flags) . ' AND h.hostid=i1.hostid'; if (!is_null($targetids)) { $sqlWhere .= ' AND ' . dbConditionInt('i1.hostid', $targetids); } $sql = 'SELECT DISTINCT i1.itemid,i1.flags,i1.name,i1.hostid,h.name as host' . ' FROM ' . $sqlFrom . ' WHERE ' . $sqlWhere; $dbItems = DBSelect($sql); $items = array(ZBX_FLAG_DISCOVERY_NORMAL => array(), ZBX_FLAG_DISCOVERY => array(), ZBX_FLAG_DISCOVERY_CHILD => array()); while ($item = DBfetch($dbItems)) { $items[$item['flags']][$item['itemid']] = array('name' => $item['name'], 'host' => $item['host']); } if (!empty($items[ZBX_FLAG_DISCOVERY])) { if ($clear) { $result = API::DiscoveryRule()->delete(array_keys($items[ZBX_FLAG_DISCOVERY]), true); if (!$result) { self::exception(ZBX_API_ERROR_INTERNAL, _('Cannot unlink and clear discovery rules')); } } else { DB::update('items', array('values' => array('templateid' => 0), 'where' => array('itemid' => array_keys($items[ZBX_FLAG_DISCOVERY])))); foreach ($items[ZBX_FLAG_DISCOVERY] as $discoveryRule) { info(_s('Unlinked: Discovery rule "%1$s" on "%2$s".', $discoveryRule['name'], $discoveryRule['host'])); } } } if (!empty($items[ZBX_FLAG_DISCOVERY_NORMAL])) { if ($clear) { $result = API::Item()->delete(array_keys($items[ZBX_FLAG_DISCOVERY_NORMAL]), true); if (!$result) { self::exception(ZBX_API_ERROR_INTERNAL, _('Cannot unlink and clear items')); } } else { DB::update('items', array('values' => array('templateid' => 0), 'where' => array('itemid' => array_keys($items[ZBX_FLAG_DISCOVERY_NORMAL])))); foreach ($items[ZBX_FLAG_DISCOVERY_NORMAL] as $item) { info(_s('Unlinked: Item "%1$s" on "%2$s".', $item['name'], $item['host'])); } } } if (!empty($items[ZBX_FLAG_DISCOVERY_CHILD])) { if ($clear) { $result = API::Itemprototype()->delete(array_keys($items[ZBX_FLAG_DISCOVERY_CHILD]), true); if (!$result) { self::exception(ZBX_API_ERROR_INTERNAL, _('Cannot unlink and clear item prototypes')); } } else { DB::update('items', array('values' => array('templateid' => 0), 'where' => array('itemid' => array_keys($items[ZBX_FLAG_DISCOVERY_CHILD])))); foreach ($items[ZBX_FLAG_DISCOVERY_CHILD] as $item) { info(_s('Unlinked: Item prototype "%1$s" on "%2$s".', $item['name'], $item['host'])); } } } /* }}} ITEMS, DISCOVERY RULES */ /* GRAPHS {{{ */ $sqlFrom = ' graphs g,hosts h'; $sqlWhere = ' EXISTS (' . 'SELECT ggi.graphid' . ' FROM graphs_items ggi,items ii' . ' WHERE ggi.graphid=g.templateid' . ' AND ii.itemid=ggi.itemid' . ' AND ' . dbConditionInt('ii.hostid', $templateids) . ')' . ' AND ' . dbConditionInt('g.flags', $flags); if (!is_null($targetids)) { $sqlFrom = ' graphs g,graphs_items gi,items i,hosts h'; $sqlWhere .= ' AND ' . dbConditionInt('i.hostid', $targetids) . ' AND gi.itemid=i.itemid' . ' AND g.graphid=gi.graphid' . ' AND h.hostid=i.hostid'; } $sql = 'SELECT DISTINCT g.graphid,g.name,g.flags,h.name as host' . ' FROM ' . $sqlFrom . ' WHERE ' . $sqlWhere; $dbGraphs = DBSelect($sql); $graphs = array(ZBX_FLAG_DISCOVERY_NORMAL => array(), ZBX_FLAG_DISCOVERY_CHILD => array()); while ($graph = DBfetch($dbGraphs)) { $graphs[$graph['flags']][$graph['graphid']] = array('name' => $graph['name'], 'graphid' => $graph['graphid'], 'host' => $graph['host']); } if (!empty($graphs[ZBX_FLAG_DISCOVERY_CHILD])) { if ($clear) { $result = API::GraphPrototype()->delete(array_keys($graphs[ZBX_FLAG_DISCOVERY_CHILD]), true); if (!$result) { self::exception(ZBX_API_ERROR_INTERNAL, _('Cannot unlink and clear graph prototypes')); } } else { DB::update('graphs', array('values' => array('templateid' => 0), 'where' => array('graphid' => array_keys($graphs[ZBX_FLAG_DISCOVERY_CHILD])))); foreach ($graphs[ZBX_FLAG_DISCOVERY_CHILD] as $graph) { info(_s('Unlinked: Graph prototype "%1$s" on "%2$s".', $graph['name'], $graph['host'])); } } } if (!empty($graphs[ZBX_FLAG_DISCOVERY_NORMAL])) { if ($clear) { $result = API::Graph()->delete(array_keys($graphs[ZBX_FLAG_DISCOVERY_NORMAL]), true); if (!$result) { self::exception(ZBX_API_ERROR_INTERNAL, _('Cannot unlink and clear graphs.')); } } else { DB::update('graphs', array('values' => array('templateid' => 0), 'where' => array('graphid' => array_keys($graphs[ZBX_FLAG_DISCOVERY_NORMAL])))); foreach ($graphs[ZBX_FLAG_DISCOVERY_NORMAL] as $graph) { info(_s('Unlinked: Graph "%1$s" on "%2$s".', $graph['name'], $graph['host'])); } } } /* }}} GRAPHS */ /* APPLICATIONS {{{ */ $sqlFrom = ' applications a1,applications a2,hosts h'; $sqlWhere = ' a2.applicationid=a1.templateid' . ' AND ' . dbConditionInt('a2.hostid', $templateids) . ' AND h.hostid=a1.hostid'; if (!is_null($targetids)) { $sqlWhere .= ' AND ' . dbConditionInt('a1.hostid', $targetids); } $sql = 'SELECT DISTINCT a1.applicationid,a1.name,a1.hostid,h.name as host' . ' FROM ' . $sqlFrom . ' WHERE ' . $sqlWhere; $dbApplications = DBSelect($sql); $applications = array(); while ($application = DBfetch($dbApplications)) { $applications[$application['applicationid']] = array('name' => $application['name'], 'hostid' => $application['hostid'], 'host' => $application['host']); } if (!empty($applications)) { if ($clear) { $result = API::Application()->delete(array_keys($applications), true); if (!$result) { self::exception(ZBX_API_ERROR_INTERNAL, _('Cannot unlink and clear applications')); } } else { DB::update('applications', array('values' => array('templateid' => 0), 'where' => array('applicationid' => array_keys($applications)))); foreach ($applications as $application) { info(_s('Unlinked: Application "%1$s" on "%2$s".', $application['name'], $application['host'])); } } } /* }}} APPLICATIONS */ $cond = array('templateid' => $templateids); if (!is_null($targetids)) { $cond['hostid'] = $targetids; } DB::delete('hosts_templates', $cond); if (!is_null($targetids)) { $hosts = API::Host()->get(array('hostids' => $targetids, 'output' => array('hostid', 'host'), 'nopermissions' => true)); } else { $hosts = API::Host()->get(array('templateids' => $templateids, 'output' => array('hostid', 'host'), 'nopermissions' => true)); } if (!empty($hosts)) { $templates = API::Template()->get(array('templateids' => $templateids, 'output' => array('hostid', 'host'), 'nopermissions' => true)); $hosts = implode(', ', zbx_objectValues($hosts, 'host')); $templates = implode(', ', zbx_objectValues($templates, 'host')); info(_s('Templates "%1$s" unlinked from hosts "%2$s".', $templates, $hosts)); } }