/** * Get data for item edit page. * * @param array $item item, item prototype or LLD rule to take the data from * @param bool $options['is_discovery_rule'] * * @return array */ function getItemFormData(array $item = array(), array $options = array()) { $data = array('form' => getRequest('form'), 'form_refresh' => getRequest('form_refresh'), 'is_discovery_rule' => !empty($options['is_discovery_rule']), 'parent_discoveryid' => getRequest('parent_discoveryid', !empty($options['is_discovery_rule']) ? getRequest('itemid') : null), 'itemid' => getRequest('itemid'), 'limited' => false, 'interfaceid' => getRequest('interfaceid', 0), 'name' => getRequest('name', ''), 'description' => getRequest('description', ''), 'key' => getRequest('key', ''), 'hostname' => getRequest('hostname'), 'delay' => getRequest('delay', ZBX_ITEM_DELAY_DEFAULT), 'history' => getRequest('history', 90), 'status' => getRequest('status', isset($_REQUEST['form_refresh']) ? 1 : 0), 'type' => getRequest('type', 0), 'snmp_community' => getRequest('snmp_community', 'public'), 'snmp_oid' => getRequest('snmp_oid', 'interfaces.ifTable.ifEntry.ifInOctets.1'), 'port' => getRequest('port', ''), 'value_type' => getRequest('value_type', ITEM_VALUE_TYPE_UINT64), 'data_type' => getRequest('data_type', ITEM_DATA_TYPE_DECIMAL), 'trapper_hosts' => getRequest('trapper_hosts', ''), 'units' => getRequest('units', ''), 'valuemapid' => getRequest('valuemapid', 0), 'params' => getRequest('params', ''), 'multiplier' => getRequest('multiplier', 0), 'delta' => getRequest('delta', 0), 'trends' => getRequest('trends', DAY_IN_YEAR), 'new_application' => getRequest('new_application', ''), 'applications' => getRequest('applications', array()), 'delay_flex' => getRequest('delay_flex', array()), 'new_delay_flex' => getRequest('new_delay_flex', array('delay' => 50, 'period' => ZBX_DEFAULT_INTERVAL)), 'snmpv3_contextname' => getRequest('snmpv3_contextname', ''), 'snmpv3_securityname' => getRequest('snmpv3_securityname', ''), 'snmpv3_securitylevel' => getRequest('snmpv3_securitylevel', 0), 'snmpv3_authprotocol' => getRequest('snmpv3_authprotocol', ITEM_AUTHPROTOCOL_MD5), 'snmpv3_authpassphrase' => getRequest('snmpv3_authpassphrase', ''), 'snmpv3_privprotocol' => getRequest('snmpv3_privprotocol', ITEM_PRIVPROTOCOL_DES), 'snmpv3_privpassphrase' => getRequest('snmpv3_privpassphrase', ''), 'ipmi_sensor' => getRequest('ipmi_sensor', ''), 'authtype' => getRequest('authtype', 0), 'username' => getRequest('username', ''), 'password' => getRequest('password', ''), 'publickey' => getRequest('publickey', ''), 'privatekey' => getRequest('privatekey', ''), 'formula' => getRequest('formula', 1), 'logtimefmt' => getRequest('logtimefmt', ''), 'add_groupid' => getRequest('add_groupid', getRequest('groupid', 0)), 'valuemaps' => null, 'possibleHostInventories' => null, 'alreadyPopulated' => null, 'initial_item_type' => null, 'templates' => array()); // hostid if (!empty($data['parent_discoveryid'])) { $discoveryRule = API::DiscoveryRule()->get(array('itemids' => $data['parent_discoveryid'], 'output' => API_OUTPUT_EXTEND, 'editable' => true)); $discoveryRule = reset($discoveryRule); $data['hostid'] = $discoveryRule['hostid']; } else { $data['hostid'] = getRequest('hostid', 0); } // types, http items only for internal processes $data['types'] = item_type2str(); unset($data['types'][ITEM_TYPE_HTTPTEST]); if (!empty($options['is_discovery_rule'])) { unset($data['types'][ITEM_TYPE_AGGREGATE], $data['types'][ITEM_TYPE_CALCULATED], $data['types'][ITEM_TYPE_SNMPTRAP]); } // item if ($item) { $data['item'] = $item; $data['hostid'] = !empty($data['hostid']) ? $data['hostid'] : $data['item']['hostid']; $data['limited'] = $data['item']['templateid'] != 0; // get templates $itemid = $item['itemid']; do { $params = array('itemids' => $itemid, 'output' => array('itemid', 'templateid'), 'selectHosts' => array('name')); if ($data['is_discovery_rule']) { $item = API::DiscoveryRule()->get($params); } else { $params['selectDiscoveryRule'] = array('itemid'); $params['filter'] = array('flags' => null); $item = API::Item()->get($params); } $item = reset($item); if (!empty($item)) { $host = reset($item['hosts']); if (!empty($item['hosts'])) { $host['name'] = CHtml::encode($host['name']); if (bccomp($data['itemid'], $itemid) == 0) { } elseif ($data['is_discovery_rule']) { $data['templates'][] = new CLink($host['name'], 'host_discovery.php?form=update&itemid=' . $item['itemid'], 'highlight underline weight_normal'); $data['templates'][] = SPACE . '⇒' . SPACE; } elseif ($item['discoveryRule']) { $data['templates'][] = new CLink($host['name'], 'disc_prototypes.php?form=update&itemid=' . $item['itemid'] . '&parent_discoveryid=' . $item['discoveryRule']['itemid'], 'highlight underline weight_normal'); $data['templates'][] = SPACE . '⇒' . SPACE; } else { $data['templates'][] = new CLink($host['name'], 'items.php?form=update&itemid=' . $item['itemid'], 'highlight underline weight_normal'); $data['templates'][] = SPACE . '⇒' . SPACE; } } $itemid = $item['templateid']; } else { break; } } while ($itemid != 0); $data['templates'] = array_reverse($data['templates']); array_shift($data['templates']); } // caption if (!empty($data['is_discovery_rule'])) { $data['caption'] = _('Discovery rule'); } else { $data['caption'] = !empty($data['parent_discoveryid']) ? _('Item prototype') : _('Item'); } // hostname if (empty($data['is_discovery_rule']) && empty($data['hostname'])) { if (!empty($data['hostid'])) { $hostInfo = API::Host()->get(array('hostids' => $data['hostid'], 'output' => array('name'), 'templated_hosts' => true)); $hostInfo = reset($hostInfo); $data['hostname'] = $hostInfo['name']; } else { $data['hostname'] = _('not selected'); } } // fill data from item if (!hasRequest('form_refresh') && ($item || $data['limited'])) { $data['name'] = $data['item']['name']; $data['description'] = $data['item']['description']; $data['key'] = $data['item']['key_']; $data['interfaceid'] = $data['item']['interfaceid']; $data['type'] = $data['item']['type']; $data['snmp_community'] = $data['item']['snmp_community']; $data['snmp_oid'] = $data['item']['snmp_oid']; $data['port'] = $data['item']['port']; $data['value_type'] = $data['item']['value_type']; $data['data_type'] = $data['item']['data_type']; $data['trapper_hosts'] = $data['item']['trapper_hosts']; $data['units'] = $data['item']['units']; $data['valuemapid'] = $data['item']['valuemapid']; $data['multiplier'] = $data['item']['multiplier']; $data['hostid'] = $data['item']['hostid']; $data['params'] = $data['item']['params']; $data['snmpv3_contextname'] = $data['item']['snmpv3_contextname']; $data['snmpv3_securityname'] = $data['item']['snmpv3_securityname']; $data['snmpv3_securitylevel'] = $data['item']['snmpv3_securitylevel']; $data['snmpv3_authprotocol'] = $data['item']['snmpv3_authprotocol']; $data['snmpv3_authpassphrase'] = $data['item']['snmpv3_authpassphrase']; $data['snmpv3_privprotocol'] = $data['item']['snmpv3_privprotocol']; $data['snmpv3_privpassphrase'] = $data['item']['snmpv3_privpassphrase']; $data['ipmi_sensor'] = $data['item']['ipmi_sensor']; $data['authtype'] = $data['item']['authtype']; $data['username'] = $data['item']['username']; $data['password'] = $data['item']['password']; $data['publickey'] = $data['item']['publickey']; $data['privatekey'] = $data['item']['privatekey']; $data['logtimefmt'] = $data['item']['logtimefmt']; $data['new_application'] = getRequest('new_application', ''); if (!$data['is_discovery_rule']) { $data['formula'] = $data['item']['formula']; } if (!$data['limited'] || !isset($_REQUEST['form_refresh'])) { $data['delay'] = $data['item']['delay']; if (($data['type'] == ITEM_TYPE_TRAPPER || $data['type'] == ITEM_TYPE_SNMPTRAP) && $data['delay'] == 0) { $data['delay'] = ZBX_ITEM_DELAY_DEFAULT; } $data['history'] = $data['item']['history']; $data['status'] = $data['item']['status']; $data['delta'] = $data['item']['delta']; $data['trends'] = $data['item']['trends']; $db_delay_flex = $data['item']['delay_flex']; if (isset($db_delay_flex)) { $arr_of_dellays = explode(';', $db_delay_flex); foreach ($arr_of_dellays as $one_db_delay) { $arr_of_delay = explode('/', $one_db_delay); if (!isset($arr_of_delay[0]) || !isset($arr_of_delay[1])) { continue; } array_push($data['delay_flex'], array('delay' => $arr_of_delay[0], 'period' => $arr_of_delay[1])); } } $data['applications'] = array_unique(zbx_array_merge($data['applications'], get_applications_by_itemid($data['itemid']))); } } // applications if (count($data['applications']) == 0) { array_push($data['applications'], 0); } $data['db_applications'] = DBfetchArray(DBselect('SELECT DISTINCT a.applicationid,a.name' . ' FROM applications a' . ' WHERE a.hostid=' . zbx_dbstr($data['hostid']))); order_result($data['db_applications'], 'name'); // interfaces $data['interfaces'] = API::HostInterface()->get(array('hostids' => $data['hostid'], 'output' => API_OUTPUT_EXTEND)); // valuemapid if ($data['limited']) { if (!empty($data['valuemapid'])) { if ($map_data = DBfetch(DBselect('SELECT v.name FROM valuemaps v WHERE v.valuemapid=' . zbx_dbstr($data['valuemapid'])))) { $data['valuemaps'] = $map_data['name']; } } } else { $data['valuemaps'] = DBfetchArray(DBselect('SELECT v.* FROM valuemaps v')); order_result($data['valuemaps'], 'name'); } // possible host inventories if (empty($data['parent_discoveryid'])) { $data['possibleHostInventories'] = getHostInventories(); // get already populated fields by other items $data['alreadyPopulated'] = API::item()->get(array('output' => array('inventory_link'), 'filter' => array('hostid' => $data['hostid']), 'nopermissions' => true)); $data['alreadyPopulated'] = zbx_toHash($data['alreadyPopulated'], 'inventory_link'); } // template $data['is_template'] = isTemplate($data['hostid']); // unset snmpv3 fields if ($data['type'] != ITEM_TYPE_SNMPV3) { $data['snmpv3_contextname'] = ''; $data['snmpv3_securityname'] = ''; $data['snmpv3_securitylevel'] = ITEM_SNMPV3_SECURITYLEVEL_NOAUTHNOPRIV; $data['snmpv3_authprotocol'] = ITEM_AUTHPROTOCOL_MD5; $data['snmpv3_authpassphrase'] = ''; $data['snmpv3_privprotocol'] = ITEM_PRIVPROTOCOL_DES; $data['snmpv3_privpassphrase'] = ''; } // unset ssh auth fields if ($data['type'] != ITEM_TYPE_SSH) { $data['authtype'] = ITEM_AUTHTYPE_PASSWORD; $data['publickey'] = ''; $data['privatekey'] = ''; } return $data; }
protected function addRelatedObjects(array $options, array $result) { $result = parent::addRelatedObjects($options, $result); $hostids = array_keys($result); // adding inventories if ($options['selectInventory'] !== null) { $relationMap = $this->createRelationMap($result, 'hostid', 'hostid'); $inventory = API::getApiService()->select('host_inventory', ['output' => $options['selectInventory'], 'filter' => ['hostid' => $hostids]]); $result = $relationMap->mapOne($result, zbx_toHash($inventory, 'hostid'), 'inventory'); } // adding hostinterfaces if ($options['selectInterfaces'] !== null) { if ($options['selectInterfaces'] != API_OUTPUT_COUNT) { $interfaces = API::HostInterface()->get(['output' => $this->outputExtend($options['selectInterfaces'], ['hostid', 'interfaceid']), 'hostids' => $hostids, 'nopermissions' => true, 'preservekeys' => true]); // we need to order interfaces for proper linkage and viewing order_result($interfaces, 'interfaceid', ZBX_SORT_UP); $relationMap = $this->createRelationMap($interfaces, 'hostid', 'interfaceid'); $interfaces = $this->unsetExtraFields($interfaces, ['hostid', 'interfaceid'], $options['selectInterfaces']); $result = $relationMap->mapMany($result, $interfaces, 'interfaces', $options['limitSelects']); } else { $interfaces = API::HostInterface()->get(['hostids' => $hostids, 'nopermissions' => true, 'countOutput' => true, 'groupCount' => true]); $interfaces = zbx_toHash($interfaces, 'hostid'); foreach ($result as $hostid => $host) { $result[$hostid]['interfaces'] = isset($interfaces[$hostid]) ? $interfaces[$hostid]['rowscount'] : 0; } } } // adding screens if ($options['selectScreens'] !== null) { if ($options['selectScreens'] != API_OUTPUT_COUNT) { $screens = API::TemplateScreen()->get(['output' => $this->outputExtend($options['selectScreens'], ['hostid']), 'hostids' => $hostids, 'nopermissions' => true]); if (!is_null($options['limitSelects'])) { order_result($screens, 'name'); } // inherited screens do not have a unique screenid, so we're building a map using array keys $relationMap = new CRelationMap(); foreach ($screens as $key => $screen) { $relationMap->addRelation($screen['hostid'], $key); } $screens = $this->unsetExtraFields($screens, ['hostid'], $options['selectScreens']); $result = $relationMap->mapMany($result, $screens, 'screens', $options['limitSelects']); } else { $screens = API::TemplateScreen()->get(['hostids' => $hostids, 'nopermissions' => true, 'countOutput' => true, 'groupCount' => true]); $screens = zbx_toHash($screens, 'hostid'); foreach ($result as $hostid => $host) { $result[$hostid]['screens'] = isset($screens[$hostid]) ? $screens[$hostid]['rowscount'] : 0; } } } // adding discovery rule if ($options['selectDiscoveryRule'] !== null && $options['selectDiscoveryRule'] != API_OUTPUT_COUNT) { // discovered items $discoveryRules = DBFetchArray(DBselect('SELECT hd.hostid,hd2.parent_itemid' . ' FROM host_discovery hd,host_discovery hd2' . ' WHERE ' . dbConditionInt('hd.hostid', $hostids) . ' AND hd.parent_hostid=hd2.hostid')); $relationMap = $this->createRelationMap($discoveryRules, 'hostid', 'parent_itemid'); $discoveryRules = API::DiscoveryRule()->get(['output' => $options['selectDiscoveryRule'], 'itemids' => $relationMap->getRelatedIds(), 'preservekeys' => true]); $result = $relationMap->mapOne($result, $discoveryRules, 'discoveryRule'); } // adding host discovery if ($options['selectHostDiscovery'] !== null) { $hostDiscoveries = API::getApiService()->select('host_discovery', ['output' => $this->outputExtend($options['selectHostDiscovery'], ['hostid']), 'filter' => ['hostid' => $hostids], 'preservekeys' => true]); $relationMap = $this->createRelationMap($hostDiscoveries, 'hostid', 'hostid'); $hostDiscoveries = $this->unsetExtraFields($hostDiscoveries, ['hostid'], $options['selectHostDiscovery']); $result = $relationMap->mapOne($result, $hostDiscoveries, 'hostDiscovery'); } return $result; }
/** * For existing hosts we need to set an interfaceid for existing interfaces or they will be added. * * @param array $xmlHosts hosts from XML for which interfaces will be added * * @return array */ protected function addInterfaceIds(array $xmlHosts) { $dbInterfaces = API::HostInterface()->get(array('hostids' => zbx_objectValues($xmlHosts, 'hostid'), 'output' => API_OUTPUT_EXTEND, 'preservekeys' => true)); // build lookup maps for: // - interfaces per host // - default (primary) interface ids per host per interface type $dbHostInterfaces = array(); $dbHostMainInterfaceIds = array(); foreach ($dbInterfaces as $dbInterface) { $dbHostId = $dbInterface['hostid']; $dbHostInterfaces[$dbHostId][] = $dbInterface; if ($dbInterface['main'] == INTERFACE_PRIMARY) { $dbHostMainInterfaceIds[$dbHostId][$dbInterface['type']] = $dbInterface['interfaceid']; } } foreach ($xmlHosts as &$xmlHost) { // if interfaces in XML are empty then do not touch existing interfaces if (!$xmlHost['interfaces']) { unset($xmlHost['interfaces']); continue; } $xmlHostId = $xmlHost['hostid']; $currentDbHostMainInterfaceIds = isset($dbHostMainInterfaceIds[$xmlHostId]) ? $dbHostMainInterfaceIds[$xmlHostId] : array(); $reusedInterfaceIds = array(); foreach ($xmlHost['interfaces'] as &$xmlHostInterface) { $xmlHostInterfaceType = $xmlHostInterface['type']; // check if an existing interfaceid from current host can be reused // in case there is default (primary) interface in current host with same type if ($xmlHostInterface['main'] == INTERFACE_PRIMARY && isset($currentDbHostMainInterfaceIds[$xmlHostInterfaceType])) { $dbHostInterfaceId = $currentDbHostMainInterfaceIds[$xmlHostInterfaceType]; $xmlHostInterface['interfaceid'] = $dbHostInterfaceId; $reusedInterfaceIds[$dbHostInterfaceId] = true; } } unset($xmlHostInterface); // loop through all interfaces of current host and take interfaceids from ones that // match completely, ignoring hosts from XML with set interfaceids and ignoring hosts // from DB with reused interfaceids foreach ($xmlHost['interfaces'] as &$xmlHostInterface) { foreach ($dbHostInterfaces[$xmlHostId] as $dbHostInterface) { $dbHostInterfaceId = $dbHostInterface['interfaceid']; if (!isset($xmlHostInterface['interfaceid']) && !isset($reusedInterfaceIds[$dbHostInterfaceId]) && $dbHostInterface['ip'] == $xmlHostInterface['ip'] && $dbHostInterface['dns'] == $xmlHostInterface['dns'] && $dbHostInterface['useip'] == $xmlHostInterface['useip'] && $dbHostInterface['port'] == $xmlHostInterface['port'] && $dbHostInterface['type'] == $xmlHostInterface['type'] && $dbHostInterface['bulk'] == $xmlHostInterface['bulk']) { $xmlHostInterface['interfaceid'] = $dbHostInterfaceId; $reusedInterfaceIds[$dbHostInterfaceId] = true; break; } } } unset($xmlHostInterface); } unset($xmlHost); return $xmlHosts; }
/** * Check items data. * * Any system field passed to the function will be unset. * * @throw APIException * * @param array $items passed by reference * @param bool $update * * @return void */ protected function checkInput(array &$items, $update = false) { if ($update) { $itemDbFields = array('itemid' => null); $dbItemsFields = array('itemid', 'templateid'); foreach ($this->fieldRules as $field => $rule) { if (!isset($rule['system'])) { $dbItemsFields[] = $field; } } $dbItems = $this->get(array('output' => $dbItemsFields, 'itemids' => zbx_objectValues($items, 'itemid'), 'editable' => true, 'preservekeys' => true)); $dbHosts = API::Host()->get(array('output' => array('hostid', 'status', 'name'), 'hostids' => zbx_objectValues($dbItems, 'hostid'), 'templated_hosts' => true, 'editable' => true, 'selectApplications' => API_OUTPUT_REFER, 'preservekeys' => true)); } else { $itemDbFields = array('name' => null, 'key_' => null, 'hostid' => null, 'type' => null, 'value_type' => null, 'delay' => '0', 'delay_flex' => ''); $dbHosts = API::Host()->get(array('output' => array('hostid', 'status', 'name'), 'hostids' => zbx_objectValues($items, 'hostid'), 'templated_hosts' => true, 'editable' => true, 'selectApplications' => API_OUTPUT_REFER, 'preservekeys' => true)); } // interfaces $interfaces = API::HostInterface()->get(array('output' => array('interfaceid', 'hostid', 'type'), 'hostids' => zbx_objectValues($dbHosts, 'hostid'), 'nopermissions' => true, 'preservekeys' => true)); if ($update) { $updateDiscoveredValidator = new CUpdateDiscoveredValidator(array('allowed' => array('itemid', 'status'), 'messageAllowedField' => _('Cannot update "%1$s" for a discovered item.'))); foreach ($items as $item) { // check permissions if (!isset($dbItems[$item['itemid']])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('No permissions to referred object or it does not exist!')); } // discovered fields, except status, cannot be updated $this->checkPartialValidator($item, $updateDiscoveredValidator, $dbItems[$item['itemid']]); } $items = $this->extendObjects($this->tableName(), $items, array('name')); } foreach ($items as $inum => &$item) { $item = $this->clearValues($item); $fullItem = $items[$inum]; if (!check_db_fields($itemDbFields, $item)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function.')); } if ($update) { check_db_fields($dbItems[$item['itemid']], $fullItem); $this->checkNoParameters($item, array('templateid', 'state'), _('Cannot update "%1$s" for item "%2$s".'), $item['name']); // apply rules foreach ($this->fieldRules as $field => $rules) { if (0 != $fullItem['templateid'] && isset($rules['template']) || isset($rules['system'])) { unset($item[$field]); } } if (!isset($item['key_'])) { $item['key_'] = $fullItem['key_']; } if (!isset($item['hostid'])) { $item['hostid'] = $fullItem['hostid']; } // if a templated item is being assigned to an interface with a different type, ignore it $itemInterfaceType = itemTypeInterface($dbItems[$item['itemid']]['type']); if ($fullItem['templateid'] && isset($item['interfaceid']) && isset($interfaces[$item['interfaceid']]) && $itemInterfaceType !== INTERFACE_TYPE_ANY && $interfaces[$item['interfaceid']]['type'] != $itemInterfaceType) { unset($item['interfaceid']); } } else { if (!isset($dbHosts[$item['hostid']])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('No permissions to referred object or it does not exist!')); } check_db_fields($itemDbFields, $fullItem); $this->checkNoParameters($item, array('templateid', 'state'), _('Cannot set "%1$s" for item "%2$s".'), $item['name']); } $host = $dbHosts[$fullItem['hostid']]; if ($fullItem['type'] == ITEM_TYPE_ZABBIX_ACTIVE) { $item['delay_flex'] = ''; } if ($fullItem['value_type'] == ITEM_VALUE_TYPE_STR) { $item['delta'] = 0; } if ($fullItem['value_type'] != ITEM_VALUE_TYPE_UINT64) { $item['data_type'] = 0; } // check if the item requires an interface $itemInterfaceType = itemTypeInterface($fullItem['type']); if ($itemInterfaceType !== false && $host['status'] != HOST_STATUS_TEMPLATE) { if (!$fullItem['interfaceid']) { self::exception(ZBX_API_ERROR_PARAMETERS, _('No interface found.')); } elseif (!isset($interfaces[$fullItem['interfaceid']]) || bccomp($interfaces[$fullItem['interfaceid']]['hostid'], $fullItem['hostid']) != 0) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Item uses host interface from non-parent host.')); } elseif ($itemInterfaceType !== INTERFACE_TYPE_ANY && $interfaces[$fullItem['interfaceid']]['type'] != $itemInterfaceType) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Item uses incorrect interface type.')); } } else { $item['interfaceid'] = 0; } // item key if ($fullItem['type'] == ITEM_TYPE_DB_MONITOR && strcmp($fullItem['key_'], ZBX_DEFAULT_KEY_DB_MONITOR) == 0 || $fullItem['type'] == ITEM_TYPE_SSH && strcmp($fullItem['key_'], ZBX_DEFAULT_KEY_SSH) == 0 || $fullItem['type'] == ITEM_TYPE_TELNET && strcmp($fullItem['key_'], ZBX_DEFAULT_KEY_TELNET) == 0 || $fullItem['type'] == ITEM_TYPE_JMX && strcmp($fullItem['key_'], ZBX_DEFAULT_KEY_JMX) == 0) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Check the key, please. Default example was passed.')); } // key $itemKey = new CItemKey($fullItem['key_']); if (!$itemKey->isValid()) { self::exception(ZBX_API_ERROR_PARAMETERS, _params($this->getErrorMsg(self::ERROR_INVALID_KEY), array($fullItem['key_'], $fullItem['name'], $host['name'], $itemKey->getError()))); } // parameters if ($fullItem['type'] == ITEM_TYPE_AGGREGATE) { $params = $itemKey->getParameters(); if (!str_in_array($itemKey->getKeyId(), array('grpmax', 'grpmin', 'grpsum', 'grpavg')) || count($params) != 4 || !str_in_array($params[2], array('last', 'min', 'max', 'avg', 'sum', 'count'))) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Key "%1$s" does not match <grpmax|grpmin|grpsum|grpavg>["Host group(s)", "Item key",' . ' "<last|min|max|avg|sum|count>", "parameter"].', $itemKey->getKeyId())); } } // type of information if ($fullItem['type'] == ITEM_TYPE_AGGREGATE && $fullItem['value_type'] != ITEM_VALUE_TYPE_FLOAT && $fullItem['value_type'] != ITEM_VALUE_TYPE_UINT64) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Type of information must be "Numeric (float)" for aggregate items.')); } // log if ($fullItem['value_type'] != ITEM_VALUE_TYPE_LOG && str_in_array($itemKey->getKeyId(), array('log', 'logrt', 'eventlog'))) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Type of information must be "Log" for log key.')); } // update interval if ($fullItem['type'] != ITEM_TYPE_TRAPPER && $fullItem['type'] != ITEM_TYPE_SNMPTRAP) { $res = calculateItemNextcheck(0, $fullItem['type'], $fullItem['delay'], $fullItem['delay_flex'], time()); if ($res == ZBX_JAN_2038) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Item will not be refreshed. Please enter a correct update interval.')); } } // ssh, telnet if ($fullItem['type'] == ITEM_TYPE_SSH || $fullItem['type'] == ITEM_TYPE_TELNET) { if (zbx_empty($fullItem['username'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('No authentication user name specified.')); } if ($fullItem['type'] == ITEM_TYPE_SSH && $fullItem['authtype'] == ITEM_AUTHTYPE_PUBLICKEY) { if (zbx_empty($fullItem['publickey'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('No public key file specified.')); } if (zbx_empty($fullItem['privatekey'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('No private key file specified.')); } } } // snmp trap if ($fullItem['type'] == ITEM_TYPE_SNMPTRAP && strcmp($fullItem['key_'], 'snmptrap.fallback') != 0 && strcmp($itemKey->getKeyId(), 'snmptrap') != 0) { self::exception(ZBX_API_ERROR_PARAMETERS, _('SNMP trap key is invalid.')); } // snmp oid if (in_array($fullItem['type'], array(ITEM_TYPE_SNMPV1, ITEM_TYPE_SNMPV2C, ITEM_TYPE_SNMPV3)) && zbx_empty($fullItem['snmp_oid'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('No SNMP OID specified.')); } // snmp community if (in_array($fullItem['type'], array(ITEM_TYPE_SNMPV1, ITEM_TYPE_SNMPV2C)) && zbx_empty($fullItem['snmp_community'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('No SNMP community specified.')); } // snmp port if (isset($fullItem['port']) && !zbx_empty($fullItem['port']) && !validatePortNumberOrMacro($fullItem['port'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Item "%1$s:%2$s" has invalid port: "%3$s".', $fullItem['name'], $fullItem['key_'], $fullItem['port'])); } if (isset($fullItem['snmpv3_securitylevel']) && $fullItem['snmpv3_securitylevel'] != ITEM_SNMPV3_SECURITYLEVEL_NOAUTHNOPRIV) { // snmpv3 authprotocol if (str_in_array($fullItem['snmpv3_securitylevel'], array(ITEM_SNMPV3_SECURITYLEVEL_AUTHNOPRIV, ITEM_SNMPV3_SECURITYLEVEL_AUTHPRIV))) { if (isset($fullItem['snmpv3_authprotocol']) && (zbx_empty($fullItem['snmpv3_authprotocol']) || !str_in_array($fullItem['snmpv3_authprotocol'], array(ITEM_AUTHPROTOCOL_MD5, ITEM_AUTHPROTOCOL_SHA)))) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect authentication protocol for item "%1$s".', $fullItem['name'])); } } // snmpv3 privprotocol if ($fullItem['snmpv3_securitylevel'] == ITEM_SNMPV3_SECURITYLEVEL_AUTHPRIV) { if (isset($fullItem['snmpv3_privprotocol']) && (zbx_empty($fullItem['snmpv3_privprotocol']) || !str_in_array($fullItem['snmpv3_privprotocol'], array(ITEM_PRIVPROTOCOL_DES, ITEM_PRIVPROTOCOL_AES)))) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect privacy protocol for item "%1$s".', $fullItem['name'])); } } } // check that the given applications belong to the item's host if (isset($item['applications']) && $item['applications']) { $dbApplicationIds = zbx_objectValues($host['applications'], 'applicationid'); foreach ($item['applications'] as $appId) { if (!in_array($appId, $dbApplicationIds)) { $error = _s('Application with ID "%1$s" is not available on "%2$s".', $appId, $host['name']); self::exception(ZBX_API_ERROR_PARAMETERS, $error); } } } $this->checkDelayFlex($fullItem); $this->checkSpecificFields($fullItem); } unset($item); $this->checkExistingItems($items); }
if (!empty($data['templates'])) { $getLinkedTemplates = API::Template()->get(array('templateids' => $data['templates'], 'output' => array('templateid', 'name'))); foreach ($getLinkedTemplates as $getLinkedTemplate) { $data['linkedTemplates'][] = array('id' => $getLinkedTemplate['templateid'], 'name' => $getLinkedTemplate['name']); } } $hostForm = new CView('configuration.host.massupdate', $data); $hostsWidget->addItem($hostForm->render()); } elseif (isset($_REQUEST['form'])) { $hostsWidget->addPageHeader(_('CONFIGURATION OF HOSTS')); $data = array(); if ($hostId = get_request('hostid', 0)) { $hostsWidget->addItem(get_header_host_table('', $_REQUEST['hostid'])); $dbHosts = API::Host()->get(array('hostids' => $hostId, 'selectGroups' => API_OUTPUT_EXTEND, 'selectParentTemplates' => array('templateid', 'name'), 'selectMacros' => API_OUTPUT_EXTEND, 'selectInventory' => true, 'selectDiscoveryRule' => array('name', 'itemid'), 'output' => API_OUTPUT_EXTEND)); $dbHost = reset($dbHosts); $dbHost['interfaces'] = API::HostInterface()->get(array('hostids' => $hostId, 'output' => API_OUTPUT_EXTEND, 'selectItems' => array('type'), 'sortfield' => 'interfaceid', 'preservekeys' => true)); $data['dbHost'] = $dbHost; } $hostForm = new CView('configuration.host.edit', $data); $hostsWidget->addItem($hostForm->render()); $rootClass = 'host-edit'; if (get_request('hostid') && $dbHost['flags'] == ZBX_FLAG_DISCOVERY_CREATED) { $rootClass .= ' host-edit-discovered'; } $hostsWidget->setRootClass($rootClass); } else { $displayNodes = is_array(get_current_nodeid()) && $pageFilter->groupid == 0; $frmForm = new CForm(); $frmForm->cleanItems(); $frmForm->addItem(new CDiv(array(new CSubmit('form', _('Create host')), new CButton('form', _('Import'), 'redirect("conf.import.php?rules_preset=host")')))); $frmForm->addItem(new CVar('groupid', $_REQUEST['groupid'], 'filter_groupid_id'));
/** * For existing hosts we need to set an interfaceid for existing interfaces or they will be added. * * @param array $hosts * * @return array */ protected function addInterfaceIds(array $hosts) { $dbInterfaces = API::HostInterface()->get(array('hostids' => zbx_objectValues($hosts, 'hostid'), 'output' => API_OUTPUT_EXTEND, 'preservekeys' => true)); foreach ($dbInterfaces as $dbInterface) { foreach ($hosts as $hnum => $host) { if (!empty($host['interfaces']) && idcmp($host['hostid'], $dbInterface['hostid'])) { foreach ($host['interfaces'] as $inum => $interface) { if ($dbInterface['ip'] == $interface['ip'] && $dbInterface['dns'] == $interface['dns'] && $dbInterface['useip'] == $interface['useip'] && $dbInterface['port'] == $interface['port'] && $dbInterface['type'] == $interface['type'] && $dbInterface['main'] == $interface['main']) { $hosts[$hnum]['interfaces'][$inum]['interfaceid'] = $dbInterface['interfaceid']; break; } } } if (empty($hosts[$hnum]['interfaces'])) { unset($hosts[$hnum]['interfaces']); } } } return $hosts; }
/** * Additionally allows to remove interfaces from hosts. * * Checks write permissions for hosts. * * Additional supported $data parameters are: * - interfaces - an array of interfaces to delete from the hosts * * @param array $data * * @return array */ public function massRemove(array $data) { $hostids = zbx_toArray($data['hostids']); // check permissions if (!$this->isWritable($hostids)) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('You do not have permission to perform this operation.')); } if (isset($data['interfaces'])) { $options = array('hostids' => $hostids, 'interfaces' => zbx_toArray($data['interfaces'])); API::HostInterface()->massRemove($options); } // rename the "templates" parameter to the common "templates_link" if (isset($data['templateids'])) { $data['templateids_link'] = $data['templateids']; unset($data['templateids']); } $data['templateids'] = array(); return parent::massRemove($data); }
/** * Get items data. * * @param array $options * @param array $options['itemids'] * @param array $options['hostids'] * @param array $options['groupids'] * @param array $options['triggerids'] * @param array $options['applicationids'] * @param boolean $options['status'] * @param boolean $options['templated_items'] * @param boolean $options['editable'] * @param boolean $options['count'] * @param string $options['pattern'] * @param int $options['limit'] * @param string $options['order'] * * @return array|int item data as array or false if error */ public function get($options = array()) { $result = array(); $userType = self::$userData['type']; $userid = self::$userData['userid']; // allowed columns for sorting $sortColumns = array('itemid', 'name', 'key_', 'delay', 'history', 'trends', 'type', 'status'); // allowed output options for [ select_* ] params $subselectsAllowedOutputs = array(API_OUTPUT_REFER, API_OUTPUT_EXTEND, API_OUTPUT_CUSTOM); $sqlParts = array('select' => array('items' => 'i.itemid'), 'from' => array('items' => 'items i'), 'where' => array('webtype' => 'i.type<>' . ITEM_TYPE_HTTPTEST, 'flags' => 'i.flags IN (' . ZBX_FLAG_DISCOVERY_NORMAL . ',' . ZBX_FLAG_DISCOVERY_CREATED . ')'), 'group' => array(), 'order' => array(), 'limit' => null); $defOptions = array('nodeids' => null, 'groupids' => null, 'templateids' => null, 'hostids' => null, 'proxyids' => null, 'itemids' => null, 'interfaceids' => null, 'graphids' => null, 'triggerids' => null, 'applicationids' => null, 'webitems' => null, 'inherited' => null, 'templated' => null, 'monitored' => null, 'editable' => null, 'nopermissions' => null, 'group' => null, 'host' => null, 'application' => null, 'with_triggers' => null, 'filter' => null, 'search' => null, 'searchByAny' => null, 'startSearch' => null, 'excludeSearch' => null, 'searchWildcardsEnabled' => null, 'output' => API_OUTPUT_REFER, 'selectHosts' => null, 'selectInterfaces' => null, 'selectTriggers' => null, 'selectGraphs' => null, 'selectApplications' => null, 'selectDiscoveryRule' => null, 'selectItemDiscovery' => null, 'countOutput' => null, 'groupCount' => null, 'preservekeys' => null, 'sortfield' => '', 'sortorder' => '', 'limit' => null, 'limitSelects' => null); $options = zbx_array_merge($defOptions, $options); if (is_array($options['output'])) { unset($sqlParts['select']['items']); $dbTable = DB::getSchema('items'); $sqlParts['select']['itemid'] = 'i.itemid'; foreach ($options['output'] as $field) { if (isset($dbTable['fields'][$field])) { $sqlParts['select'][$field] = 'i.' . $field; } } $options['output'] = API_OUTPUT_CUSTOM; } // editable + permission check if ($userType != USER_TYPE_SUPER_ADMIN && !$options['nopermissions']) { $permission = $options['editable'] ? PERM_READ_WRITE : PERM_READ_ONLY; $userGroups = getUserGroupsByUserId($userid); $sqlParts['where'][] = 'EXISTS (' . 'SELECT NULL' . ' FROM hosts_groups hgg' . ' JOIN rights r' . ' ON r.id=hgg.groupid' . ' AND ' . dbConditionInt('r.groupid', $userGroups) . ' WHERE i.hostid=hgg.hostid' . ' GROUP BY hgg.hostid' . ' HAVING MIN(r.permission)>=' . $permission . ')'; } // itemids if (!is_null($options['itemids'])) { zbx_value2array($options['itemids']); $sqlParts['where']['itemid'] = dbConditionInt('i.itemid', $options['itemids']); } // templateids if (!is_null($options['templateids'])) { zbx_value2array($options['templateids']); if (!is_null($options['hostids'])) { zbx_value2array($options['hostids']); $options['hostids'] = array_merge($options['hostids'], $options['templateids']); } else { $options['hostids'] = $options['templateids']; } } // hostids if (!is_null($options['hostids'])) { zbx_value2array($options['hostids']); if ($options['output'] != API_OUTPUT_EXTEND) { $sqlParts['select']['hostid'] = 'i.hostid'; } $sqlParts['where']['hostid'] = dbConditionInt('i.hostid', $options['hostids']); if (!is_null($options['groupCount'])) { $sqlParts['group']['i'] = 'i.hostid'; } } // interfaceids if (!is_null($options['interfaceids'])) { zbx_value2array($options['interfaceids']); if ($options['output'] != API_OUTPUT_EXTEND) { $sqlParts['select']['interfaceid'] = 'i.interfaceid'; } $sqlParts['where']['interfaceid'] = dbConditionInt('i.interfaceid', $options['interfaceids']); if (!is_null($options['groupCount'])) { $sqlParts['group']['i'] = 'i.interfaceid'; } } // groupids if (!is_null($options['groupids'])) { zbx_value2array($options['groupids']); if ($options['output'] != API_OUTPUT_SHORTEN) { $sqlParts['select']['groupid'] = 'hg.groupid'; } $sqlParts['from']['hosts_groups'] = 'hosts_groups hg'; $sqlParts['where'][] = dbConditionInt('hg.groupid', $options['groupids']); $sqlParts['where'][] = 'hg.hostid=i.hostid'; if (!is_null($options['groupCount'])) { $sqlParts['group']['hg'] = 'hg.groupid'; } } // proxyids if (!is_null($options['proxyids'])) { zbx_value2array($options['proxyids']); if ($options['output'] != API_OUTPUT_EXTEND) { $sqlParts['select']['proxyid'] = 'h.proxy_hostid'; } $sqlParts['from']['hosts'] = 'hosts h'; $sqlParts['where'][] = dbConditionInt('h.proxy_hostid', $options['proxyids']); $sqlParts['where'][] = 'h.hostid=i.hostid'; if (!is_null($options['groupCount'])) { $sqlParts['group']['h'] = 'h.proxy_hostid'; } } // triggerids if (!is_null($options['triggerids'])) { zbx_value2array($options['triggerids']); if ($options['output'] != API_OUTPUT_SHORTEN) { $sqlParts['select']['triggerid'] = 'f.triggerid'; } $sqlParts['from']['functions'] = 'functions f'; $sqlParts['where'][] = dbConditionInt('f.triggerid', $options['triggerids']); $sqlParts['where']['if'] = 'i.itemid=f.itemid'; } // applicationids if (!is_null($options['applicationids'])) { zbx_value2array($options['applicationids']); if ($options['output'] != API_OUTPUT_SHORTEN) { $sqlParts['select']['applicationid'] = 'ia.applicationid'; } $sqlParts['from']['items_applications'] = 'items_applications ia'; $sqlParts['where'][] = dbConditionInt('ia.applicationid', $options['applicationids']); $sqlParts['where']['ia'] = 'ia.itemid=i.itemid'; } // graphids if (!is_null($options['graphids'])) { zbx_value2array($options['graphids']); if ($options['output'] != API_OUTPUT_SHORTEN) { $sqlParts['select']['graphid'] = 'gi.graphid'; } $sqlParts['from']['graphs_items'] = 'graphs_items gi'; $sqlParts['where'][] = dbConditionInt('gi.graphid', $options['graphids']); $sqlParts['where']['igi'] = 'i.itemid=gi.itemid'; } // webitems if (!is_null($options['webitems'])) { unset($sqlParts['where']['webtype']); } // inherited if (!is_null($options['inherited'])) { if ($options['inherited']) { $sqlParts['where'][] = 'i.templateid IS NOT NULL'; } else { $sqlParts['where'][] = 'i.templateid IS NULL'; } } // templated if (!is_null($options['templated'])) { $sqlParts['from']['hosts'] = 'hosts h'; $sqlParts['where']['hi'] = 'h.hostid=i.hostid'; if ($options['templated']) { $sqlParts['where'][] = 'h.status=' . HOST_STATUS_TEMPLATE; } else { $sqlParts['where'][] = 'h.status<>' . HOST_STATUS_TEMPLATE; } } // monitored if (!is_null($options['monitored'])) { $sqlParts['from']['hosts'] = 'hosts h'; $sqlParts['where']['hi'] = 'h.hostid=i.hostid'; if ($options['monitored']) { $sqlParts['where'][] = 'h.status=' . HOST_STATUS_MONITORED; $sqlParts['where'][] = 'i.status=' . ITEM_STATUS_ACTIVE; } else { $sqlParts['where'][] = '(h.status<>' . HOST_STATUS_MONITORED . ' OR i.status<>' . ITEM_STATUS_ACTIVE . ')'; } } // search if (is_array($options['search'])) { zbx_db_search('items i', $options, $sqlParts); } // filter if (is_array($options['filter'])) { $this->dbFilter('items i', $options, $sqlParts); if (isset($options['filter']['host'])) { zbx_value2array($options['filter']['host']); $sqlParts['from']['hosts'] = 'hosts h'; $sqlParts['where']['hi'] = 'h.hostid=i.hostid'; $sqlParts['where']['h'] = dbConditionString('h.host', $options['filter']['host'], false, true); } if (array_key_exists('flags', $options['filter']) && ($options['filter']['flags'] === null || !zbx_empty($options['filter']['flags']))) { unset($sqlParts['where']['flags']); } } // group if (!is_null($options['group'])) { $sqlParts['from']['groups'] = 'groups g'; $sqlParts['from']['hosts_groups'] = 'hosts_groups hg'; $sqlParts['where']['ghg'] = 'g.groupid=hg.groupid'; $sqlParts['where']['hgi'] = 'hg.hostid=i.hostid'; $sqlParts['where'][] = ' g.name=' . zbx_dbstr($options['group']); } // host if (!is_null($options['host'])) { if ($options['output'] != API_OUTPUT_SHORTEN) { $sqlParts['select']['host'] = 'h.host'; } $sqlParts['from']['hosts'] = 'hosts h'; $sqlParts['where']['hi'] = 'h.hostid=i.hostid'; $sqlParts['where'][] = ' h.host=' . zbx_dbstr($options['host']); } // application if (!is_null($options['application'])) { if ($options['output'] != API_OUTPUT_SHORTEN) { $sqlParts['select']['application'] = 'a.name as application'; } $sqlParts['from']['applications'] = 'applications a'; $sqlParts['from']['items_applications'] = 'items_applications ia'; $sqlParts['where']['aia'] = 'a.applicationid = ia.applicationid'; $sqlParts['where']['iai'] = 'ia.itemid=i.itemid'; $sqlParts['where'][] = ' a.name=' . zbx_dbstr($options['application']); } // with_triggers if (!is_null($options['with_triggers'])) { if ($options['with_triggers'] == 1) { $sqlParts['where'][] = ' EXISTS (SELECT NULL FROM functions ff WHERE ff.itemid=i.itemid)'; } else { $sqlParts['where'][] = 'NOT EXISTS (SELECT NULL FROM functions ff WHERE ff.itemid=i.itemid)'; } } // output if ($options['output'] == API_OUTPUT_EXTEND) { $sqlParts['select']['items'] = 'i.*'; } // countOutput if (!is_null($options['countOutput'])) { $options['sortfield'] = ''; $sqlParts['select'] = array('COUNT(DISTINCT i.itemid) AS rowscount'); // groupCount if (!is_null($options['groupCount'])) { foreach ($sqlParts['group'] as $key => $fields) { $sqlParts['select'][$key] = $fields; } } } // sorting zbx_db_sorting($sqlParts, $options, $sortColumns, 'i'); // limit if (zbx_ctype_digit($options['limit']) && $options['limit']) { $sqlParts['limit'] = $options['limit']; } $itemids = array(); $sqlParts = $this->applyQueryNodeOptions($this->tableName(), $this->tableAlias(), $options, $sqlParts); $res = DBselect($this->createSelectQueryFromParts($sqlParts), $sqlParts['limit']); while ($item = DBfetch($res)) { if (!is_null($options['countOutput'])) { if (!is_null($options['groupCount'])) { $result[] = $item; } else { $result = $item['rowscount']; } } else { $itemids[$item['itemid']] = $item['itemid']; if ($options['output'] == API_OUTPUT_SHORTEN) { $result[$item['itemid']] = array('itemid' => $item['itemid']); } else { if (!isset($result[$item['itemid']])) { $result[$item['itemid']] = array(); } if (!is_null($options['selectHosts']) && !isset($result[$item['itemid']]['hosts'])) { $result[$item['itemid']]['hosts'] = array(); } if (!is_null($options['selectTriggers']) && !isset($result[$item['itemid']]['triggers'])) { $result[$item['itemid']]['triggers'] = array(); } if (!is_null($options['selectGraphs']) && !isset($result[$item['itemid']]['graphs'])) { $result[$item['itemid']]['graphs'] = array(); } if (!is_null($options['selectApplications']) && !isset($result[$item['itemid']]['applications'])) { $result[$item['itemid']]['applications'] = array(); } if (!is_null($options['selectDiscoveryRule']) && !isset($result[$item['itemid']]['discoveryRule'])) { $result[$item['itemid']]['discoveryRule'] = array(); } if (!is_null($options['selectInterfaces']) && !isset($result[$item['itemid']]['interfaces'])) { $result[$item['itemid']]['interfaces'] = array(); } // triggerids if (isset($item['triggerid']) && is_null($options['selectTriggers'])) { if (!isset($result[$item['itemid']]['triggers'])) { $result[$item['itemid']]['triggers'] = array(); } $result[$item['itemid']]['triggers'][] = array('triggerid' => $item['triggerid']); unset($item['triggerid']); } // graphids if (isset($item['graphid']) && is_null($options['selectGraphs'])) { if (!isset($result[$item['itemid']]['graphs'])) { $result[$item['itemid']]['graphs'] = array(); } $result[$item['itemid']]['graphs'][] = array('graphid' => $item['graphid']); unset($item['graphid']); } // applicationids if (isset($item['applicationid']) && is_null($options['selectApplications'])) { if (!isset($result[$item['itemid']]['applications'])) { $result[$item['itemid']]['applications'] = array(); } $result[$item['itemid']]['applications'][] = array('applicationid' => $item['applicationid']); unset($item['applicationid']); } $result[$item['itemid']] += $item; } } } if (!is_null($options['countOutput'])) { return $result; } /* * Adding objects */ // adding hosts if (!is_null($options['selectHosts'])) { if (is_array($options['selectHosts']) || str_in_array($options['selectHosts'], $subselectsAllowedOutputs)) { $objParams = array('nodeids' => $options['nodeids'], 'itemids' => $itemids, 'templated_hosts' => true, 'output' => $options['selectHosts'], 'nopermissions' => true, 'preservekeys' => true); $hosts = API::Host()->get($objParams); foreach ($hosts as $host) { $hitems = $host['items']; unset($host['items']); foreach ($hitems as $item) { $result[$item['itemid']]['hosts'][] = $host; } } $templates = API::Template()->get($objParams); foreach ($templates as $template) { $titems = $template['items']; unset($template['items']); foreach ($titems as $item) { $result[$item['itemid']]['hosts'][] = $template; } } } } // adding interfaces if (!is_null($options['selectInterfaces'])) { if (is_array($options['selectInterfaces']) || str_in_array($options['selectInterfaces'], $subselectsAllowedOutputs)) { $interfaces = API::HostInterface()->get(array('nodeids' => $options['nodeids'], 'itemids' => $itemids, 'output' => $options['selectInterfaces'], 'nopermissions' => true, 'preservekeys' => true)); foreach ($interfaces as $interface) { $hitems = $interface['items']; unset($interface['items']); foreach ($hitems as $item) { $result[$item['itemid']]['interfaces'][] = $interface; } } } } // adding triggers if (!is_null($options['selectTriggers'])) { $objParams = array('nodeids' => $options['nodeids'], 'itemids' => $itemids, 'preservekeys' => true); if (in_array($options['selectTriggers'], $subselectsAllowedOutputs)) { $objParams['output'] = $options['selectTriggers']; $triggers = API::Trigger()->get($objParams); if (!is_null($options['limitSelects'])) { order_result($triggers, 'description'); } foreach ($triggers as $triggerid => $trigger) { unset($triggers[$triggerid]['items']); $count = array(); foreach ($trigger['items'] as $item) { // skip trigger assignment for unwanted items from other hosts if (!isset($result[$item['itemid']])) { continue; } if (!is_null($options['limitSelects'])) { if (!isset($count[$item['itemid']])) { $count[$item['itemid']] = 0; } $count[$item['itemid']]++; if ($count[$item['itemid']] > $options['limitSelects']) { continue; } } $result[$item['itemid']]['triggers'][] =& $triggers[$triggerid]; } } } elseif (API_OUTPUT_COUNT == $options['selectTriggers']) { $objParams['countOutput'] = 1; $objParams['groupCount'] = 1; $triggers = API::Trigger()->get($objParams); $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'])) { $objParams = array('nodeids' => $options['nodeids'], 'itemids' => $itemids, 'preservekeys' => true); if (in_array($options['selectGraphs'], $subselectsAllowedOutputs)) { $objParams['output'] = $options['selectGraphs']; $graphs = API::Graph()->get($objParams); if (!is_null($options['limitSelects'])) { order_result($graphs, 'name'); } foreach ($graphs as $graphid => $graph) { unset($graphs[$graphid]['items']); $count = array(); foreach ($graph['items'] as $item) { if (!is_null($options['limitSelects'])) { if (!isset($count[$item['itemid']])) { $count[$item['itemid']] = 0; } $count[$item['itemid']]++; if ($count[$item['itemid']] > $options['limitSelects']) { continue; } } $result[$item['itemid']]['graphs'][] =& $graphs[$graphid]; } } } elseif (API_OUTPUT_COUNT == $options['selectGraphs']) { $objParams['countOutput'] = 1; $objParams['groupCount'] = 1; $graphs = API::Graph()->get($objParams); $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 applications if (!is_null($options['selectApplications']) && str_in_array($options['selectApplications'], $subselectsAllowedOutputs)) { $applications = API::Application()->get(array('nodeids' => $options['nodeids'], 'output' => $options['selectApplications'], 'itemids' => $itemids, 'preservekeys' => true)); foreach ($applications as $application) { $aitems = $application['items']; unset($application['items']); foreach ($aitems as $item) { $result[$item['itemid']]['applications'][] = $application; } } } // adding discoveryrule if (!is_null($options['selectDiscoveryRule'])) { $ruleids = $ruleMap = array(); $dbRules = DBselect('SELECT id1.itemid,id2.parent_itemid' . ' FROM item_discovery id1,item_discovery id2,items i' . ' WHERE ' . dbConditionInt('id1.itemid', $itemids) . ' AND id1.parent_itemid=id2.itemid' . ' AND i.itemid=id1.itemid' . ' AND i.flags=' . ZBX_FLAG_DISCOVERY_CREATED); while ($rule = DBfetch($dbRules)) { $ruleids[$rule['parent_itemid']] = $rule['parent_itemid']; $ruleMap[$rule['itemid']] = $rule['parent_itemid']; } $dbRules = DBselect('SELECT id.parent_itemid,id.itemid' . ' FROM item_discovery id,items i' . ' WHERE ' . dbConditionInt('id.itemid', $itemids) . ' AND i.itemid=id.itemid' . ' AND i.flags=' . ZBX_FLAG_DISCOVERY_CHILD); while ($rule = DBfetch($dbRules)) { $ruleids[$rule['parent_itemid']] = $rule['parent_itemid']; $ruleMap[$rule['itemid']] = $rule['parent_itemid']; } $objParams = array('nodeids' => $options['nodeids'], 'itemids' => $ruleids, 'filter' => array('flags' => null), 'nopermissions' => true, 'preservekeys' => true); if (is_array($options['selectDiscoveryRule']) || str_in_array($options['selectDiscoveryRule'], $subselectsAllowedOutputs)) { $objParams['output'] = $options['selectDiscoveryRule']; $discoveryRules = $this->get($objParams); foreach ($result as $itemid => $item) { if (isset($ruleMap[$itemid]) && isset($discoveryRules[$ruleMap[$itemid]])) { $result[$itemid]['discoveryRule'] = $discoveryRules[$ruleMap[$itemid]]; } } } } // add other related objects if ($result) { $result = $this->addRelatedObjects($options, $result); } // removing keys (hash -> array) if (is_null($options['preservekeys'])) { $result = zbx_cleanHashes($result); } return $result; }
private function checkMainInterfacesOnDelete(array $interfaceIds) { $this->checkIfInterfaceHasItems($interfaceIds); $hostids = array(); $dbResult = DBselect('SELECT DISTINCT i.hostid FROM interface i WHERE ' . dbConditionInt('i.interfaceid', $interfaceIds)); while ($hostData = DBfetch($dbResult)) { $hostids[$hostData['hostid']] = $hostData['hostid']; } $dbInterfaces = API::HostInterface()->get(array('hostids' => $hostids, 'output' => array('hostid', 'main', 'type'), 'preservekeys' => true, 'nopermissions' => true)); foreach ($interfaceIds as $interfaceId) { unset($dbInterfaces[$interfaceId]); } $this->checkMainInterfaces($dbInterfaces); }
/** * Check items data. * * Any system field passed to the function will be unset. * * @throw APIException * * @param array $items passed by reference * @param bool $update * * @return void */ protected function checkInput(array &$items, $update = false) { if ($update) { $itemDbFields = ['itemid' => null]; $dbItemsFields = ['itemid', 'templateid']; foreach ($this->fieldRules as $field => $rule) { if (!isset($rule['system'])) { $dbItemsFields[] = $field; } } $dbItems = $this->get(['output' => $dbItemsFields, 'itemids' => zbx_objectValues($items, 'itemid'), 'editable' => true, 'preservekeys' => true]); $dbHosts = API::Host()->get(['output' => ['hostid', 'status', 'name'], 'hostids' => zbx_objectValues($dbItems, 'hostid'), 'templated_hosts' => true, 'editable' => true, 'selectApplications' => ['applicationid', 'flags'], 'preservekeys' => true]); } else { $itemDbFields = ['name' => null, 'key_' => null, 'hostid' => null, 'type' => null, 'value_type' => null, 'delay' => '0', 'delay_flex' => '']; $dbHosts = API::Host()->get(['output' => ['hostid', 'status', 'name'], 'hostids' => zbx_objectValues($items, 'hostid'), 'templated_hosts' => true, 'editable' => true, 'selectApplications' => ['applicationid', 'flags'], 'preservekeys' => true]); } // interfaces $interfaces = API::HostInterface()->get(['output' => ['interfaceid', 'hostid', 'type'], 'hostids' => zbx_objectValues($dbHosts, 'hostid'), 'nopermissions' => true, 'preservekeys' => true]); if ($update) { $updateDiscoveredValidator = new CUpdateDiscoveredValidator(['allowed' => ['itemid', 'status'], 'messageAllowedField' => _('Cannot update "%2$s" for a discovered item "%1$s".')]); foreach ($items as $item) { // check permissions if (!isset($dbItems[$item['itemid']])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('No permissions to referred object or it does not exist!')); } $dbItem = $dbItems[$item['itemid']]; $itemName = isset($item['name']) ? $item['name'] : $dbItem['name']; // discovered fields, except status, cannot be updated $updateDiscoveredValidator->setObjectName($itemName); $this->checkPartialValidator($item, $updateDiscoveredValidator, $dbItem); } $items = $this->extendObjects($this->tableName(), $items, ['name', 'flags']); } $item_key_parser = new CItemKey(); foreach ($items as $inum => &$item) { $item = $this->clearValues($item); $fullItem = $items[$inum]; if (!check_db_fields($itemDbFields, $item)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function.')); } if ($update) { check_db_fields($dbItems[$item['itemid']], $fullItem); $this->checkNoParameters($item, ['templateid', 'state'], _('Cannot update "%1$s" for item "%2$s".'), $item['name']); // apply rules foreach ($this->fieldRules as $field => $rules) { if (0 != $fullItem['templateid'] && isset($rules['template']) || isset($rules['system'])) { unset($item[$field]); // For templated item and fields that should not be modified, use the value from DB. if (array_key_exists($field, $dbItems[$item['itemid']]) && array_key_exists($field, $fullItem)) { $fullItem[$field] = $dbItems[$item['itemid']][$field]; } } } if (!isset($item['key_'])) { $item['key_'] = $fullItem['key_']; } if (!isset($item['hostid'])) { $item['hostid'] = $fullItem['hostid']; } // if a templated item is being assigned to an interface with a different type, ignore it $itemInterfaceType = itemTypeInterface($dbItems[$item['itemid']]['type']); if ($fullItem['templateid'] && isset($item['interfaceid']) && isset($interfaces[$item['interfaceid']]) && $itemInterfaceType !== INTERFACE_TYPE_ANY && $interfaces[$item['interfaceid']]['type'] != $itemInterfaceType) { unset($item['interfaceid']); } } else { if (!isset($dbHosts[$item['hostid']])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('No permissions to referred object or it does not exist!')); } check_db_fields($itemDbFields, $fullItem); $this->checkNoParameters($item, ['templateid', 'state'], _('Cannot set "%1$s" for item "%2$s".'), $item['name']); } $host = $dbHosts[$fullItem['hostid']]; if ($fullItem['type'] == ITEM_TYPE_ZABBIX_ACTIVE) { $item['delay_flex'] = ''; } if ($fullItem['value_type'] == ITEM_VALUE_TYPE_STR) { $item['delta'] = 0; } if ($fullItem['value_type'] != ITEM_VALUE_TYPE_UINT64) { $item['data_type'] = 0; } // For non-numeric types, whichever value was entered in trends field, is overwritten to zero. if ($fullItem['value_type'] == ITEM_VALUE_TYPE_STR || $fullItem['value_type'] == ITEM_VALUE_TYPE_LOG || $fullItem['value_type'] == ITEM_VALUE_TYPE_TEXT) { $item['trends'] = 0; } // check if the item requires an interface $itemInterfaceType = itemTypeInterface($fullItem['type']); if ($itemInterfaceType !== false && $host['status'] != HOST_STATUS_TEMPLATE) { if (!$fullItem['interfaceid']) { self::exception(ZBX_API_ERROR_PARAMETERS, _('No interface found.')); } elseif (!isset($interfaces[$fullItem['interfaceid']]) || bccomp($interfaces[$fullItem['interfaceid']]['hostid'], $fullItem['hostid']) != 0) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Item uses host interface from non-parent host.')); } elseif ($itemInterfaceType !== INTERFACE_TYPE_ANY && $interfaces[$fullItem['interfaceid']]['type'] != $itemInterfaceType) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Item uses incorrect interface type.')); } } else { $item['interfaceid'] = 0; } // item key if ($fullItem['type'] == ITEM_TYPE_DB_MONITOR) { if (!isset($fullItem['flags']) || $fullItem['flags'] != ZBX_FLAG_DISCOVERY_RULE) { if (strcmp($fullItem['key_'], ZBX_DEFAULT_KEY_DB_MONITOR) == 0) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Check the key, please. Default example was passed.')); } } elseif ($fullItem['flags'] == ZBX_FLAG_DISCOVERY_RULE) { if (strcmp($fullItem['key_'], ZBX_DEFAULT_KEY_DB_MONITOR_DISCOVERY) == 0) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Check the key, please. Default example was passed.')); } } } elseif ($fullItem['type'] == ITEM_TYPE_SSH && strcmp($fullItem['key_'], ZBX_DEFAULT_KEY_SSH) == 0 || $fullItem['type'] == ITEM_TYPE_TELNET && strcmp($fullItem['key_'], ZBX_DEFAULT_KEY_TELNET) == 0 || $fullItem['type'] == ITEM_TYPE_JMX && strcmp($fullItem['key_'], ZBX_DEFAULT_KEY_JMX) == 0) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Check the key, please. Default example was passed.')); } // key if ($item_key_parser->parse($fullItem['key_']) != CParser::PARSE_SUCCESS) { self::exception(ZBX_API_ERROR_PARAMETERS, _params($this->getErrorMsg(self::ERROR_INVALID_KEY), [$fullItem['key_'], $fullItem['name'], $host['name'], $item_key_parser->getError()])); } // parameters if ($fullItem['type'] == ITEM_TYPE_AGGREGATE) { $params_num = $item_key_parser->getParamsNum(); if (!str_in_array($item_key_parser->getKey(), ['grpmax', 'grpmin', 'grpsum', 'grpavg']) || $params_num > 4 || $params_num < 3 || $params_num == 3 && $item_key_parser->getParam(2) !== 'last' || !str_in_array($item_key_parser->getParam(2), ['last', 'min', 'max', 'avg', 'sum', 'count'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Key "%1$s" does not match <grpmax|grpmin|grpsum|grpavg>["Host group(s)", "Item key",' . ' "<last|min|max|avg|sum|count>", "parameter"].', $item_key_parser->getKey())); } } // type of information if ($fullItem['type'] == ITEM_TYPE_AGGREGATE && $fullItem['value_type'] != ITEM_VALUE_TYPE_UINT64 && $fullItem['value_type'] != ITEM_VALUE_TYPE_FLOAT) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Type of information must be "Numeric (unsigned)" or "Numeric (float)" for aggregate items.')); } // update interval if ($fullItem['type'] != ITEM_TYPE_TRAPPER && $fullItem['type'] != ITEM_TYPE_SNMPTRAP) { // delay must be between 0 and 86400, if delay is 0, delay_flex interval must be set. if ($fullItem['delay'] < 0 || $fullItem['delay'] > SEC_PER_DAY || $fullItem['delay'] == 0 && $fullItem['delay_flex'] === '') { self::exception(ZBX_API_ERROR_PARAMETERS, _('Item will not be refreshed. Please enter a correct update interval.')); } // Don't parse empty strings, they will not be valid. if ($fullItem['delay_flex'] === '') { continue; } // Validate item delay_flex string. First check syntax with parser, then validate time ranges. $item_delay_flex_parser = new CItemDelayFlexParser($fullItem['delay_flex']); if ($item_delay_flex_parser->isValid()) { $delay_flex_validator = new CItemDelayFlexValidator(); if ($delay_flex_validator->validate($item_delay_flex_parser->getIntervals())) { // Some valid intervals exist at this point. $flexible_intervals = $item_delay_flex_parser->getFlexibleIntervals(); // If there are no flexible intervals, skip the next check calculation. if (!$flexible_intervals) { continue; } $nextCheck = calculateItemNextCheck(0, $fullItem['delay'], $item_delay_flex_parser->getFlexibleIntervals($flexible_intervals), time()); if ($nextCheck == ZBX_JAN_2038) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Item will not be refreshed. Please enter a correct update interval.')); } } else { self::exception(ZBX_API_ERROR_PARAMETERS, $delay_flex_validator->getError()); } } else { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Invalid interval "%1$s": %2$s.', $fullItem['delay_flex'], $item_delay_flex_parser->getError())); } } // ssh, telnet if ($fullItem['type'] == ITEM_TYPE_SSH || $fullItem['type'] == ITEM_TYPE_TELNET) { if (zbx_empty($fullItem['username'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('No authentication user name specified.')); } if ($fullItem['type'] == ITEM_TYPE_SSH && $fullItem['authtype'] == ITEM_AUTHTYPE_PUBLICKEY) { if (zbx_empty($fullItem['publickey'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('No public key file specified.')); } if (zbx_empty($fullItem['privatekey'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('No private key file specified.')); } } } // snmp trap if ($fullItem['type'] == ITEM_TYPE_SNMPTRAP && $fullItem['key_'] !== 'snmptrap.fallback' && $item_key_parser->getKey() !== 'snmptrap') { self::exception(ZBX_API_ERROR_PARAMETERS, _('SNMP trap key is invalid.')); } // snmp oid if (in_array($fullItem['type'], [ITEM_TYPE_SNMPV1, ITEM_TYPE_SNMPV2C, ITEM_TYPE_SNMPV3]) && zbx_empty($fullItem['snmp_oid'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('No SNMP OID specified.')); } // snmp community if (in_array($fullItem['type'], [ITEM_TYPE_SNMPV1, ITEM_TYPE_SNMPV2C]) && zbx_empty($fullItem['snmp_community'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('No SNMP community specified.')); } // snmp port if (isset($fullItem['port']) && !zbx_empty($fullItem['port']) && !validatePortNumberOrMacro($fullItem['port'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Item "%1$s:%2$s" has invalid port: "%3$s".', $fullItem['name'], $fullItem['key_'], $fullItem['port'])); } if (isset($fullItem['snmpv3_securitylevel']) && $fullItem['snmpv3_securitylevel'] != ITEM_SNMPV3_SECURITYLEVEL_NOAUTHNOPRIV) { // snmpv3 authprotocol if (str_in_array($fullItem['snmpv3_securitylevel'], [ITEM_SNMPV3_SECURITYLEVEL_AUTHNOPRIV, ITEM_SNMPV3_SECURITYLEVEL_AUTHPRIV])) { if (isset($fullItem['snmpv3_authprotocol']) && (zbx_empty($fullItem['snmpv3_authprotocol']) || !str_in_array($fullItem['snmpv3_authprotocol'], [ITEM_AUTHPROTOCOL_MD5, ITEM_AUTHPROTOCOL_SHA]))) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect authentication protocol for item "%1$s".', $fullItem['name'])); } } // snmpv3 privprotocol if ($fullItem['snmpv3_securitylevel'] == ITEM_SNMPV3_SECURITYLEVEL_AUTHPRIV) { if (isset($fullItem['snmpv3_privprotocol']) && (zbx_empty($fullItem['snmpv3_privprotocol']) || !str_in_array($fullItem['snmpv3_privprotocol'], [ITEM_PRIVPROTOCOL_DES, ITEM_PRIVPROTOCOL_AES]))) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect privacy protocol for item "%1$s".', $fullItem['name'])); } } } if (isset($item['applications']) && $item['applications']) { /* * 'flags' is available for update and item prototypes. * Don't allow discovered or any other application types for item prototypes in 'applications' option. */ if (array_key_exists('flags', $fullItem) && $fullItem['flags'] == ZBX_FLAG_DISCOVERY_PROTOTYPE) { foreach ($host['applications'] as $num => $application) { if ($application['flags'] != ZBX_FLAG_DISCOVERY_NORMAL) { unset($host['applications'][$num]); } } } // check that the given applications belong to the item's host $dbApplicationIds = zbx_objectValues($host['applications'], 'applicationid'); foreach ($item['applications'] as $appId) { if (!in_array($appId, $dbApplicationIds)) { $error = _s('Application with ID "%1$s" is not available on "%2$s".', $appId, $host['name']); self::exception(ZBX_API_ERROR_PARAMETERS, $error); } } } $this->checkSpecificFields($fullItem); } unset($item); $this->checkExistingItems($items); }
$hostView = new CView('configuration.host.massupdate', $data); } elseif (hasRequest('form')) { $data = ['form' => getRequest('form', ''), 'hostid' => getRequest('hostid', 0), 'clone_hostid' => getRequest('clone_hostid', 0), 'groupid' => getRequest('groupid', 0), 'flags' => getRequest('flags', ZBX_FLAG_DISCOVERY_NORMAL), 'host' => getRequest('host', ''), 'visiblename' => getRequest('visiblename', ''), 'groups' => getRequest('groups', []), 'newgroup' => getRequest('newgroup', ''), 'interfaces' => getRequest('interfaces', []), 'mainInterfaces' => getRequest('mainInterfaces', []), 'description' => getRequest('description', ''), 'proxy_hostid' => getRequest('proxy_hostid', 0), 'status' => getRequest('status', HOST_STATUS_NOT_MONITORED), 'templates' => getRequest('templates', []), 'clear_templates' => getRequest('clear_templates', []), 'original_templates' => [], 'linked_templates' => [], 'ipmi_authtype' => getRequest('ipmi_authtype', IPMI_AUTHTYPE_DEFAULT), 'ipmi_privilege' => getRequest('ipmi_privilege', IPMI_PRIVILEGE_USER), 'ipmi_username' => getRequest('ipmi_username', ''), 'ipmi_password' => getRequest('ipmi_password', ''), 'macros' => $macros, 'show_inherited_macros' => getRequest('show_inherited_macros', 0), 'inventory_mode' => getRequest('inventory_mode', $config['default_inventory_mode']), 'host_inventory' => getRequest('host_inventory', []), 'inventory_items' => [], 'tls_connect' => getRequest('tls_connect', HOST_ENCRYPTION_NONE), 'tls_accept' => getRequest('tls_accept', HOST_ENCRYPTION_NONE), 'tls_issuer' => getRequest('tls_issuer', ''), 'tls_subject' => getRequest('tls_subject', ''), 'tls_psk_identity' => getRequest('tls_psk_identity', ''), 'tls_psk' => getRequest('tls_psk', '')]; if (!hasRequest('form_refresh')) { if ($data['hostid'] != 0) { $dbHosts = API::Host()->get(['output' => ['hostid', 'proxy_hostid', 'host', 'name', 'status', 'ipmi_authtype', 'ipmi_privilege', 'ipmi_username', 'ipmi_password', 'flags', 'description', 'tls_connect', 'tls_accept', 'tls_issuer', 'tls_subject', 'tls_psk_identity', 'tls_psk'], 'selectGroups' => ['groupid'], 'selectParentTemplates' => ['templateid'], 'selectMacros' => ['hostmacroid', 'macro', 'value'], 'selectDiscoveryRule' => ['itemid', 'name'], 'selectInventory' => true, 'hostids' => [$data['hostid']]]); $dbHost = reset($dbHosts); $data['flags'] = $dbHost['flags']; if ($data['flags'] == ZBX_FLAG_DISCOVERY_CREATED) { $data['discoveryRule'] = $dbHost['discoveryRule']; } // Host $data['host'] = $dbHost['host']; $data['visiblename'] = $dbHost['name']; $data['groups'] = zbx_objectValues($dbHost['groups'], 'groupid'); $data['interfaces'] = API::HostInterface()->get(['output' => ['interfaceid', 'main', 'type', 'useip', 'ip', 'dns', 'port', 'bulk'], 'selectItems' => ['type'], 'hostids' => [$data['hostid']], 'sortfield' => 'interfaceid']); $data['description'] = $dbHost['description']; $data['proxy_hostid'] = $dbHost['proxy_hostid']; $data['status'] = $dbHost['status']; // Templates $data['templates'] = zbx_objectValues($dbHost['parentTemplates'], 'templateid'); $data['original_templates'] = array_combine($data['templates'], $data['templates']); // IPMI $data['ipmi_authtype'] = $dbHost['ipmi_authtype']; $data['ipmi_privilege'] = $dbHost['ipmi_privilege']; $data['ipmi_username'] = $dbHost['ipmi_username']; $data['ipmi_password'] = $dbHost['ipmi_password']; // Macros $data['macros'] = $dbHost['macros']; // Interfaces foreach ($data['interfaces'] as &$interface) {
public static function parseMain($rules) { $triggerExpressionConverter = new C24TriggerConverter(new CFunctionMacroParser(), new CMacroParser('#')); $triggersForDependencies = array(); if ($rules['hosts']['updateExisting'] || $rules['hosts']['createMissing'] || $rules['templates']['createMissing'] || $rules['templates']['updateExisting']) { $xpath = new DOMXPath(self::$xml); $hosts = $xpath->query('hosts/host'); // stores parsed host and template IDs $processedHostIds = array(); // stores converted trigger expressions for each host $triggerExpressions = array(); // stores converted item keys for each host $itemKeys = array(); // process hosts foreach ($hosts as $host) { $host_db = self::mapXML2arr($host, XML_TAG_HOST); if (!isset($host_db['status'])) { $host_db['status'] = HOST_STATUS_TEMPLATE; } if ($host_db['status'] == HOST_STATUS_TEMPLATE) { $current_host = API::Template()->get(array('output' => array('templateid'), 'filter' => array('host' => $host_db['host']), 'nopermissions' => true, 'limit' => 1)); } else { $current_host = API::Host()->get(array('output' => array('hostid'), 'filter' => array('host' => $host_db['host']), 'nopermissions' => true, 'limit' => 1)); } if (!$current_host && ($host_db['status'] == HOST_STATUS_TEMPLATE && !$rules['templates']['createMissing'] || $host_db['status'] != HOST_STATUS_TEMPLATE && !$rules['hosts']['createMissing'])) { continue; } if ($current_host && ($host_db['status'] == HOST_STATUS_TEMPLATE && !$rules['templates']['updateExisting'] || $host_db['status'] != HOST_STATUS_TEMPLATE && !$rules['hosts']['updateExisting'])) { continue; } // there were no host visible names in 1.8 if (!isset($host_db['name'])) { $host_db['name'] = $host_db['host']; } // host will have no interfaces - we will be creating them separately $host_db['interfaces'] = null; // it is possible, that data is imported from 1.8, where there was only one network interface per host /** * @todo when new XML format will be introduced, this check should be changed to XML version check */ $oldVersionInput = $host_db['status'] != HOST_STATUS_TEMPLATE; $interfaces = array(); // rearranging host structure, so it would look more like 2.0 host if ($oldVersionInput) { // the main interface is always "agent" type if (!is_null($host_db['ip'])) { $interfaces[] = array('main' => INTERFACE_PRIMARY, 'type' => INTERFACE_TYPE_AGENT, 'useip' => $host_db['useip'], 'ip' => $host_db['ip'], 'dns' => $host_db['dns'], 'port' => $host_db['port']); } // now we need to check if host had SNMP items. If it had, we need an SNMP interface for every different port. $items = $xpath->query('items/item', $host); $snmp_interface_ports_created = array(); foreach ($items as $item) { $item_db = self::mapXML2arr($item, XML_TAG_ITEM); if (($item_db['type'] == ITEM_TYPE_SNMPV1 || $item_db['type'] == ITEM_TYPE_SNMPV2C || $item_db['type'] == ITEM_TYPE_SNMPV3) && !isset($snmp_interface_ports_created[$item_db['snmp_port']])) { $interfaces[] = array('main' => $snmp_interface_ports_created ? INTERFACE_SECONDARY : INTERFACE_PRIMARY, 'type' => INTERFACE_TYPE_SNMP, 'useip' => $host_db['useip'], 'ip' => $host_db['ip'], 'dns' => $host_db['dns'], 'port' => $item_db['snmp_port']); $snmp_interface_ports_created[$item_db['snmp_port']] = 1; } } unset($snmp_interface_ports_created); // it was a temporary variable // we need to add ipmi interface if at least one ipmi item exists foreach ($items as $item) { $item_db = self::mapXML2arr($item, XML_TAG_ITEM); if ($item_db['type'] == ITEM_TYPE_IPMI) { // when saving a host in 1.8, it's possible to set useipmi=1 and not to fill an IP address // we were not really sure what to do with this host, // and decided to take host IP address instead and show info message about this if ($host_db['ipmi_ip'] === '') { $ipmi_ip = $host_db['ip']; info(_s('Host "%s" has "useipmi" parameter checked, but has no "ipmi_ip" parameter! Using host IP address as an address for IPMI interface.', $host_db['host'])); } else { $ipmi_ip = $host_db['ipmi_ip']; } $interfaces[] = array('main' => INTERFACE_PRIMARY, 'type' => INTERFACE_TYPE_IPMI, 'useip' => INTERFACE_USE_IP, 'ip' => $ipmi_ip, 'dns' => '', 'port' => $host_db['ipmi_port']); // we need only one ipmi interface break; } } } if ($current_host) { $options = array('filter' => array('host' => $host_db['host']), 'output' => API_OUTPUT_EXTEND, 'editable' => true, 'selectInterfaces' => API_OUTPUT_EXTEND); if ($host_db['status'] == HOST_STATUS_TEMPLATE) { $current_host = API::Template()->get($options); } else { $current_host = API::Host()->get($options); } if (empty($current_host)) { throw new Exception(_s('No permission for host "%1$s".', $host_db['host'])); } else { $current_host = reset($current_host); } // checking if host already exists - then some of the interfaces may not need to be created if ($host_db['status'] != HOST_STATUS_TEMPLATE) { $currentMainInterfaces = array(); $currentInterfacesByType = array(); // group existing main interfaces by interface type into $currentMainInterfaces // and group interfaces by type into $currentInterfacesByType foreach ($current_host['interfaces'] as $currentInterface) { if ($currentInterface['main'] == INTERFACE_PRIMARY) { $currentMainInterfaces[$currentInterface['type']] = $currentInterface; } $currentInterfacesByType[$currentInterface['type']][] = $currentInterface; } // loop through all interfaces we got from XML foreach ($interfaces as &$interfaceXml) { $interfaceXmlType = $interfaceXml['type']; // if this is the primary interface of some type and we have default interface of same type // in current (target) host, re-use "interfaceid" of the matching default interface // in current host if ($interfaceXml['main'] == INTERFACE_PRIMARY && isset($currentMainInterfaces[$interfaceXmlType])) { $interfaceXml['interfaceid'] = $currentMainInterfaces[$interfaceXmlType]['interfaceid']; } else { // otherwise, loop through all current (target) host interfaces with type of current // imported interface and re-use "interfaceid" in case if all interface parameters match if (isset($currentInterfacesByType[$interfaceXmlType])) { foreach ($currentInterfacesByType[$interfaceXmlType] as $currentInterface) { if ($currentInterface['ip'] == $interfaceXml['ip'] && $currentInterface['dns'] == $interfaceXml['dns'] && $currentInterface['port'] == $interfaceXml['port'] && $currentInterface['useip'] == $interfaceXml['useip']) { $interfaceXml['interfaceid'] = $currentInterface['interfaceid']; break; } } } } } unset($interfaceXml); $host_db['interfaces'] = $interfaces; } } elseif ($host_db['status'] != HOST_STATUS_TEMPLATE) { $host_db['interfaces'] = $interfaces; } // HOST GROUPS {{{ $groups = $xpath->query('groups/group', $host); $host_db['groups'] = array(); $groups_to_parse = array(); foreach ($groups as $group) { $groups_to_parse[] = array('name' => $group->nodeValue); } if (empty($groups_to_parse)) { $groups_to_parse[] = array('name' => ZBX_DEFAULT_IMPORT_HOST_GROUP); } foreach ($groups_to_parse as $group) { $hostGroup = API::HostGroup()->get(array('output' => API_OUTPUT_EXTEND, 'filter' => $group, 'editable' => true, 'limit' => 1)); if ($hostGroup) { $host_db['groups'][] = reset($hostGroup); } else { if ($rules['groups']['createMissing']) { $result = API::HostGroup()->create($group); if ($result) { $newHostGroup = API::HostGroup()->get(array('output' => API_OUTPUT_EXTEND, 'groupids' => $result['groupids'], 'limit' => 1)); $host_db['groups'][] = reset($newHostGroup); } } else { throw new Exception(_s('No permissions for host group "%1$s".', $group['name'])); } } } // }}} HOST GROUPS // MACROS $macros = $xpath->query('macros/macro', $host); if ($macros->length > 0) { $host_db['macros'] = array(); foreach ($macros as $macro) { $host_db['macros'][] = self::mapXML2arr($macro, XML_TAG_MACRO); } } // }}} MACROS // host inventory if ($oldVersionInput) { if (!isset($host_db['inventory'])) { $host_db['inventory'] = array(); } $inventoryNode = $xpath->query('host_profile/*', $host); if ($inventoryNode->length > 0) { foreach ($inventoryNode as $field) { $newInventoryName = self::mapInventoryName($field->nodeName); $host_db['inventory'][$newInventoryName] = $field->nodeValue; } } $inventoryNodeExt = $xpath->query('host_profiles_ext/*', $host); if ($inventoryNodeExt->length > 0) { foreach ($inventoryNodeExt as $field) { $newInventoryName = self::mapInventoryName($field->nodeName); if (isset($host_db['inventory'][$newInventoryName]) && $field->nodeValue !== '') { $host_db['inventory'][$newInventoryName] .= "\r\n\r\n"; $host_db['inventory'][$newInventoryName] .= $field->nodeValue; } else { $host_db['inventory'][$newInventoryName] = $field->nodeValue; } } } $host_db['inventory_mode'] = isset($host_db['inventory']) ? HOST_INVENTORY_MANUAL : HOST_INVENTORY_DISABLED; } if (isset($host_db['proxy_hostid'])) { $proxy_exists = API::Proxy()->get(array('output' => array('proxyid'), 'proxyids' => $host_db['proxy_hostid'])); if (empty($proxy_exists)) { $host_db['proxy_hostid'] = 0; } } if ($current_host && ($rules['hosts']['updateExisting'] || $rules['templates']['updateExisting'])) { if ($host_db['status'] == HOST_STATUS_TEMPLATE) { $host_db['templateid'] = $current_host['templateid']; $result = API::Template()->update($host_db); $current_hostid = $current_host['templateid']; } else { $host_db['hostid'] = $current_host['hostid']; $result = API::Host()->update($host_db); $current_hostid = $current_host['hostid']; } } if (!$current_host && ($rules['hosts']['createMissing'] || $rules['templates']['createMissing'])) { if ($host_db['status'] == HOST_STATUS_TEMPLATE) { $result = API::Template()->create($host_db); $current_hostid = reset($result['templateids']); } else { $result = API::Host()->create($host_db); $current_hostid = reset($result['hostids']); } } // store parsed host IDs $processedHostIds[$host_db['host']] = $current_hostid; } // gather triggers and convert old expressions $triggersXML = array(); // cycle each host and gather trigger descriptions and expressions foreach ($hosts as $host) { $host_db = self::mapXML2arr($host, XML_TAG_HOST); $current_hostid = isset($processedHostIds[$host_db['host']]) ? $processedHostIds[$host_db['host']] : false; if ($current_hostid) { $triggersXML[$current_hostid] = array(); $triggerExpressions[$host_db['host']] = array(); $oldVersionInput = $host_db['status'] != HOST_STATUS_TEMPLATE; $triggers = $xpath->query('triggers/trigger', $host); foreach ($triggers as $trigger) { $trigger_db = self::mapXML2arr($trigger, XML_TAG_TRIGGER); $oldExpression = $trigger_db['expression']; if (!isset($triggerExpressions[$host_db['host']][$trigger_db['description']])) { $triggerExpressions[$host_db['host']][$trigger_db['description']] = array(); } if ($oldVersionInput) { $expressionPart = explode(':', $trigger_db['expression']); $keyName = explode(',', $expressionPart[1], 2); if (count($keyName) == 2) { $keyValue = explode('.', $keyName[1], 2); $key = $keyName[0] . "," . $keyValue[0]; if (in_array($keyName[0], self::$oldKeys) || in_array($keyName[0], self::$oldKeysPref)) { $trigger_db['expression'] = str_replace($key, self::convertOldSimpleKey($key), $trigger_db['expression']); } } } // {HOSTNAME} is here for backward compatibility $trigger_db['expression'] = str_replace('{{HOSTNAME}:', '{' . $host_db['host'] . ':', $trigger_db['expression']); $trigger_db['expression'] = str_replace('{{HOST.HOST}:', '{' . $host_db['host'] . ':', $trigger_db['expression']); $trigger_db['expression'] = $triggerExpressionConverter->convert($trigger_db['expression']); $triggersXML[$current_hostid][$trigger_db['description']][$trigger_db['expression']] = $trigger_db['expression']; $triggerExpressions[$host_db['host']][$trigger_db['description']][$oldExpression] = $trigger_db['expression']; } } } // delete missing triggers if ($rules['triggers']['deleteMissing']) { // select triggers from parsed hosts $dbTriggers = API::Trigger()->get(array('output' => array('triggerid', 'description', 'expression'), 'expandExpression' => true, 'hostids' => $processedHostIds, 'selectHosts' => array('hostid'), 'preservekeys' => true, 'nopermissions' => true, 'inherited' => false, 'filter' => array('flags' => ZBX_FLAG_DISCOVERY_NORMAL))); // find corresponding trigger ID by description and expression $triggerIdsXML = array(); foreach ($dbTriggers as $dbTrigger) { $hostId = reset($dbTrigger['hosts']); if (isset($triggersXML[$hostId['hostid']][$dbTrigger['description']][$dbTrigger['expression']])) { $triggerIdsXML[$dbTrigger['triggerid']] = $dbTrigger['triggerid']; } } $triggersToDelete = array_diff_key($dbTriggers, $triggerIdsXML); $triggerIdsToDelete = array(); // check that potentially deletable trigger belongs to same hosts that are in XML // if some triggers belong to more hosts than current XML contains, don't delete them foreach ($triggersToDelete as $triggerId => $trigger) { $triggerHostIds = array_flip(zbx_objectValues($trigger['hosts'], 'hostid')); if (!array_diff_key($triggerHostIds, array_flip($processedHostIds))) { $triggerIdsToDelete[] = $triggerId; } } if ($triggerIdsToDelete) { API::Trigger()->delete($triggerIdsToDelete); } } // delete missing graphs if ($rules['graphs']['deleteMissing']) { $graphsXML = array(); // cycle each host and gather all graph names foreach ($hosts as $host) { $host_db = self::mapXML2arr($host, XML_TAG_HOST); $current_hostid = isset($processedHostIds[$host_db['host']]) ? $processedHostIds[$host_db['host']] : false; if ($current_hostid) { $graphsXML[$current_hostid] = array(); $graphs = $xpath->query('graphs/graph', $host); foreach ($graphs as $graph) { $graph_db = self::mapXML2arr($graph, XML_TAG_GRAPH); $graphsXML[$current_hostid][$graph_db['name']] = $graph_db['name']; } } } // select graphs from already parsed hosts $dbGraphs = API::Graph()->get(array('output' => array('graphid', 'name'), 'hostids' => $processedHostIds, 'selectHosts' => array('hostid'), 'preservekeys' => true, 'nopermissions' => true, 'inherited' => false, 'filter' => array('flags' => ZBX_FLAG_DISCOVERY_NORMAL))); $graphIdsXML = array(); foreach ($dbGraphs as $dbGraph) { $hostId = reset($dbGraph['hosts']); if (isset($graphsXML[$hostId['hostid']][$dbGraph['name']])) { $graphIdsXML[$dbGraph['graphid']] = $dbGraph['graphid']; } } $graphsToDelete = array_diff_key($dbGraphs, $graphIdsXML); $graphsIdsToDelete = array(); // check that potentially deletable graph belongs to same hosts that are in XML // if some graphs belong to more hosts than current XML contains, don't delete them foreach ($graphsToDelete as $graphId => $graph) { $graphHostIds = array_flip(zbx_objectValues($graph['hosts'], 'hostid')); if (!array_diff_key($graphHostIds, array_flip($processedHostIds))) { $graphsIdsToDelete[] = $graphId; } } if ($graphsIdsToDelete) { API::Graph()->delete($graphsIdsToDelete); } } // gather items and convert old keys $itemsXML = array(); foreach ($hosts as $host) { $host_db = self::mapXML2arr($host, XML_TAG_HOST); $current_hostid = isset($processedHostIds[$host_db['host']]) ? $processedHostIds[$host_db['host']] : false; if ($current_hostid) { $itemsXML[$current_hostid] = array(); $itemKeys[$host_db['host']] = array(); $oldVersionInput = $host_db['status'] != HOST_STATUS_TEMPLATE; $items = $xpath->query('items/item', $host); foreach ($items as $item) { $item_db = self::mapXML2arr($item, XML_TAG_ITEM); if ($oldVersionInput) { $oldKey = $item_db['key_']; $item_db['key_'] = self::convertOldSimpleKey($item_db['key_']); $itemKeys[$host_db['host']][$oldKey] = $item_db['key_']; } $itemsXML[$current_hostid][$item_db['key_']] = $item_db['key_']; } } } // delete missing items if ($rules['items']['deleteMissing']) { $dbItems = API::Item()->get(array('output' => array('itemid', 'key_', 'hostid'), 'hostids' => $processedHostIds, 'preservekeys' => true, 'nopermissions' => true, 'inherited' => false, 'filter' => array('flags' => ZBX_FLAG_DISCOVERY_NORMAL))); $itemIdsXML = array(); foreach ($dbItems as $dbItem) { if (isset($itemsXML[$dbItem['hostid']][$dbItem['key_']])) { $itemIdsXML[$dbItem['itemid']] = $dbItem['itemid']; } } $itemsToDelete = array_diff_key($dbItems, $itemIdsXML); if ($itemsToDelete) { API::Item()->delete(array_keys($itemsToDelete)); } } // delete missing applications if ($rules['applications']['deleteMissing']) { $applicationsXML = array(); foreach ($hosts as $host) { $host_db = self::mapXML2arr($host, XML_TAG_HOST); $current_hostid = isset($processedHostIds[$host_db['host']]) ? $processedHostIds[$host_db['host']] : false; if ($current_hostid) { $items = $xpath->query('items/item', $host); foreach ($items as $item) { $applications = $xpath->query('applications/application', $item); foreach ($applications as $application) { $applicationsXML[$current_hostid][$application->nodeValue] = $application->nodeValue; } } } } $dbApplications = API::Application()->get(array('output' => array('applicationid', 'hostid', 'name'), 'hostids' => $processedHostIds, 'preservekeys' => true, 'nopermissions' => true, 'inherited' => false)); $applicationsIdsXML = array(); foreach ($dbApplications as $dbApplication) { if (isset($applicationsXML[$dbApplication['hostid']][$dbApplication['name']])) { $applicationsIdsXML[$dbApplication['applicationid']] = $dbApplication['applicationid']; } } $applicationsToDelete = array_diff_key($dbApplications, $applicationsIdsXML); if ($applicationsToDelete) { API::Application()->delete(array_keys($applicationsToDelete)); } } // cycle each host again and create/update other objects foreach ($hosts as $host) { $host_db = self::mapXML2arr($host, XML_TAG_HOST); if (!isset($host_db['status'])) { $host_db['status'] = HOST_STATUS_TEMPLATE; } $current_hostid = isset($processedHostIds[$host_db['host']]) ? $processedHostIds[$host_db['host']] : false; if (!$current_hostid) { continue; } $oldVersionInput = $host_db['status'] != HOST_STATUS_TEMPLATE; // TEMPLATES {{{ if (!empty($rules['templateLinkage']['createMissing'])) { $templates = $xpath->query('templates/template', $host); $templateLinkage = array(); foreach ($templates as $template) { $options = array('filter' => array('host' => $template->nodeValue), 'output' => array('templateid'), 'editable' => true); $current_template = API::Template()->get($options); if (empty($current_template)) { throw new Exception(_s('No permission for template "%1$s".', $template->nodeValue)); } $current_template = reset($current_template); $templateLinkage[] = $current_template; } if ($templateLinkage) { $result = API::Template()->massAdd(array('hosts' => array('hostid' => $current_hostid), 'templates' => $templateLinkage)); if (!$result) { throw new Exception(); } } } // }}} TEMPLATES // ITEMS {{{ if ($rules['items']['updateExisting'] || $rules['items']['createMissing'] || $rules['applications']['createMissing']) { // applications are located under items in version 1.8, // so we need to get item list in any of these cases $items = $xpath->query('items/item', $host); if ($oldVersionInput) { $interfaces = API::HostInterface()->get(array('hostids' => $current_hostid, 'output' => API_OUTPUT_EXTEND)); // we must know interface ids to assign them to items $agent_interface_id = null; $ipmi_interface_id = null; $snmp_interfaces = array(); // hash 'port' => 'interfaceid' foreach ($interfaces as $interface) { switch ($interface['type']) { case INTERFACE_TYPE_AGENT: $agent_interface_id = $interface['interfaceid']; break; case INTERFACE_TYPE_IPMI: $ipmi_interface_id = $interface['interfaceid']; break; case INTERFACE_TYPE_SNMP: $snmp_interfaces[$interface['port']] = $interface['interfaceid']; break; } } } // if this is an export from 1.8, we need to make some adjustments to items // cycle each XML item foreach ($items as $item) { if ($rules['items']['updateExisting'] || $rules['items']['createMissing']) { $item_db = self::mapXML2arr($item, XML_TAG_ITEM); $item_db['hostid'] = $current_hostid; // item needs interfaces if ($oldVersionInput) { // 'snmp_port' column was renamed to 'port' if ($item_db['snmp_port'] != 0) { // zabbix agent items have no ports $item_db['port'] = $item_db['snmp_port']; } unset($item_db['snmp_port']); // assigning appropriate interface depending on item type switch ($item_db['type']) { // zabbix agent interface case ITEM_TYPE_ZABBIX: case ITEM_TYPE_SIMPLE: case ITEM_TYPE_EXTERNAL: case ITEM_TYPE_SSH: case ITEM_TYPE_TELNET: $item_db['interfaceid'] = $agent_interface_id; break; // snmp interface // snmp interface case ITEM_TYPE_SNMPV1: case ITEM_TYPE_SNMPV2C: case ITEM_TYPE_SNMPV3: // for an item with different port - different interface $item_db['interfaceid'] = $snmp_interfaces[$item_db['port']]; break; case ITEM_TYPE_IPMI: $item_db['interfaceid'] = $ipmi_interface_id; break; // no interfaces required for these item types // no interfaces required for these item types case ITEM_TYPE_HTTPTEST: case ITEM_TYPE_CALCULATED: case ITEM_TYPE_AGGREGATE: case ITEM_TYPE_INTERNAL: case ITEM_TYPE_ZABBIX_ACTIVE: case ITEM_TYPE_TRAPPER: case ITEM_TYPE_DB_MONITOR: $item_db['interfaceid'] = null; break; } $item_db['key_'] = $itemKeys[$host_db['host']][$item_db['key_']]; } $current_item = API::Item()->get(array('filter' => array('hostid' => $item_db['hostid'], 'key_' => $item_db['key_']), 'webitems' => true, 'editable' => true, 'output' => array('itemid'))); $current_item = reset($current_item); } // create applications independently of create or update item options // in case we update items, we need to assign items to applications, // so we also gather application IDs independetly of selected application options $applications = $xpath->query('applications/application', $item); $itemApplications = array(); $applicationsToAdd = array(); $applicationsIds = array(); foreach ($applications as $application) { $application_db = array('name' => $application->nodeValue, 'hostid' => $current_hostid); $current_application = API::Application()->get(array('filter' => $application_db, 'output' => API_OUTPUT_EXTEND)); $applicationValue = reset($current_application); if ($current_application) { if (!$itemApplications) { $itemApplications = $current_application; } elseif (!in_array($applicationValue['applicationid'], $applicationsIds)) { $itemApplications = array_merge($itemApplications, $current_application); } $applicationsIds[] = $applicationValue['applicationid']; } else { $applicationsToAdd[] = $application_db; } } if ($applicationsToAdd && $rules['applications']['createMissing']) { $result = API::Application()->create($applicationsToAdd); $newApplications = API::Application()->get(array('applicationids' => $result['applicationids'], 'output' => API_OUTPUT_EXTEND)); $itemApplications = array_merge($itemApplications, $newApplications); } if ($rules['items']['updateExisting'] || $rules['items']['createMissing']) { // if item does not exist and there is no need to create it, skip item creation if (!$current_item && !$rules['items']['createMissing']) { info(_s('Item "%1$s" skipped - user rule.', $item_db['key_'])); continue; } // if item exists, but there there is no need for update, skip item update if ($current_item && !$rules['items']['updateExisting']) { info(_s('Item "%1$s" skipped - user rule.', $item_db['key_'])); continue; } if ($current_item && $rules['items']['updateExisting']) { $item_db['itemid'] = $current_item['itemid']; $result = API::Item()->update($item_db); $current_item = API::Item()->get(array('itemids' => $result['itemids'], 'webitems' => true, 'output' => array('itemid'))); } if (!$current_item && $rules['items']['createMissing']) { $result = API::Item()->create($item_db); $current_item = API::Item()->get(array('itemids' => $result['itemids'], 'webitems' => true, 'output' => array('itemid'))); } // after items are created or updated, see to if items need to assigned to applications if (isset($itemApplications) && $itemApplications) { API::Application()->massAdd(array('applications' => $itemApplications, 'items' => $current_item)); } } } } // }}} ITEMS // TRIGGERS {{{ if ($rules['triggers']['updateExisting'] || $rules['triggers']['createMissing']) { $triggers = $xpath->query('triggers/trigger', $host); $triggersToCreate = array(); $triggersToUpdate = array(); foreach ($triggers as $trigger) { $trigger_db = self::mapXML2arr($trigger, XML_TAG_TRIGGER); $trigger_db['expression'] = $triggerExpressions[$host_db['host']][$trigger_db['description']][$trigger_db['expression']]; $trigger_db['hostid'] = $current_hostid; $currentTrigger = API::Trigger()->get(array('output' => array('triggerid'), 'filter' => array('description' => $trigger_db['description']), 'hostids' => array($current_hostid), 'selectHosts' => array('hostid'), 'nopermissions' => true, 'limit' => 1)); $currentTrigger = reset($currentTrigger); if ($currentTrigger) { $dbTriggers = API::Trigger()->get(array('output' => API_OUTPUT_EXTEND, 'filter' => array('description' => $trigger_db['description']), 'hostids' => array($current_hostid), 'editable' => true)); foreach ($dbTriggers as $dbTrigger) { $expression = explode_exp($dbTrigger['expression']); if (strcmp($trigger_db['expression'], $expression) == 0) { $currentTrigger = $dbTrigger; break; } if (!$currentTrigger) { throw new Exception(_s('No permission for trigger "%1$s".', $trigger_db['description'])); } } } unset($trigger_db['hostid']); if (!$currentTrigger && !$rules['triggers']['createMissing']) { info(_s('Trigger "%1$s" skipped - user rule.', $trigger_db['description'])); continue; } if ($currentTrigger && !$rules['triggers']['updateExisting']) { info(_s('Trigger "%1$s" skipped - user rule.', $trigger_db['description'])); continue; } if (!$currentTrigger && $rules['triggers']['createMissing']) { $triggersToCreate[] = $trigger_db; } if ($currentTrigger && $rules['triggers']['updateExisting']) { $trigger_db['triggerid'] = $currentTrigger['triggerid']; $triggersToUpdate[] = $trigger_db; } } if ($triggersToUpdate) { $result = API::Trigger()->update($triggersToUpdate); $triggersUpdated = API::Trigger()->get(array('output' => API_OUTPUT_EXTEND, 'triggerids' => $result['triggerids'])); $triggersForDependencies = array_merge($triggersForDependencies, $triggersUpdated); } if ($triggersToCreate) { $result = API::Trigger()->create($triggersToCreate); $triggersCreated = API::Trigger()->get(array('output' => API_OUTPUT_EXTEND, 'triggerids' => $result['triggerids'])); $triggersForDependencies = array_merge($triggersForDependencies, $triggersCreated); } } // }}} TRIGGERS // GRAPHS {{{ if ($rules['graphs']['updateExisting'] || $rules['graphs']['createMissing']) { $graphs = $xpath->query('graphs/graph', $host); $graphs_to_add = array(); $graphs_to_upd = array(); foreach ($graphs as $graph) { // GRAPH ITEMS {{{ $gitems = $xpath->query('graph_elements/graph_element', $graph); $graph_hostids = array(); $graph_items = array(); foreach ($gitems as $gitem) { $gitem_db = self::mapXML2arr($gitem, XML_TAG_GRAPH_ELEMENT); $data = explode(':', $gitem_db['host_key_']); $gitem_host = array_shift($data); // {HOSTNAME} is here for backward compatibility $gitem_db['host'] = $gitem_host == '{HOSTNAME}' ? $host_db['host'] : $gitem_host; $gitem_db['host'] = $gitem_host == '{HOST.HOST}' ? $host_db['host'] : $gitem_host; if ($oldVersionInput) { $data[0] = self::convertOldSimpleKey($data[0]); } $gitem_db['key_'] = implode(':', $data); $itemExists = API::Item()->get(array('output' => array('itemid'), 'filter' => array('key_' => $gitem_db['key_']), 'webitems' => true, 'nopermissions' => true, 'limit' => 1)); if ($itemExists) { $current_item = API::Item()->get(array('filter' => array('key_' => $gitem_db['key_']), 'webitems' => true, 'editable' => true, 'host' => $gitem_db['host'], 'output' => array('itemid', 'hostid'))); if (empty($current_item)) { throw new Exception(_s('No permission for item "%1$s".', $gitem_db['key_'])); } $current_item = reset($current_item); $graph_hostids[] = $current_item['hostid']; $gitem_db['itemid'] = $current_item['itemid']; $graph_items[] = $gitem_db; } else { throw new Exception(_s('Item "%1$s" does not exist.', $gitem_db['host_key_'])); } } // }}} GRAPH ITEMS $graph_db = self::mapXML2arr($graph, XML_TAG_GRAPH); $graph_db['hostids'] = $graph_hostids; // do we need to show the graph legend, after it is imported? // in 1.8, this setting was present only for pie and exploded graphs // for other graph types we are always showing the legend if ($graph_db['graphtype'] != GRAPH_TYPE_PIE && $graph_db['graphtype'] != GRAPH_TYPE_EXPLODED) { $graph_db['show_legend'] = 1; } $current_graph = API::Graph()->get(array('output' => array('graphid'), 'selectHosts' => array('hostid', 'host'), 'hostids' => $graph_db['hostids'], 'filter' => array('name' => $graph_db['name']), 'nopermissions' => true, 'limit' => 1)); if ($current_graph) { $current_graph = API::Graph()->get(array('output' => API_OUTPUT_EXTEND, 'hostids' => $graph_db['hostids'], 'filter' => array('name' => $graph_db['name']), 'editable' => true)); if (empty($current_graph)) { throw new Exception(_s('No permission for graph "%1$s".', $graph_db['name'])); } $current_graph = reset($current_graph); } if (!$current_graph && empty($rules['graphs']['createMissing'])) { info(_s('Graph "%1$s" skipped - user rule.', $graph_db['name'])); continue; // break if not update updateExisting } if ($current_graph && empty($rules['graphs']['updateExisting'])) { info(_s('Graph "%1$s" skipped - user rule.', $graph_db['name'])); continue; // break if not update updateExisting } if (!isset($graph_db['ymin_type'])) { throw new Exception(_s('No "ymin_type" field for graph "%s".', $graph_db['name'])); } if (!isset($graph_db['ymax_type'])) { throw new Exception(_s('No "ymax_type" field for graph "%s".', $graph_db['name'])); } if ($graph_db['ymin_type'] == GRAPH_YAXIS_TYPE_ITEM_VALUE) { $item_data = explode(':', $graph_db['ymin_item_key'], 2); if (count($item_data) < 2) { throw new Exception(_s('Incorrect y min item for graph "%1$s".', $graph_db['name'])); } if (!($item = get_item_by_key($item_data[1], $item_data[0]))) { throw new Exception(_s('Missing item "%1$s" for host "%2$s".', $graph_db['ymin_item_key'], $host_db['host'])); } $graph_db['ymin_itemid'] = $item['itemid']; } if ($graph_db['ymax_type'] == GRAPH_YAXIS_TYPE_ITEM_VALUE) { $item_data = explode(':', $graph_db['ymax_item_key'], 2); if (count($item_data) < 2) { throw new Exception(_s('Incorrect y max item for graph "%1$s".', $graph_db['name'])); } if (!($item = get_item_by_key($item_data[1], $item_data[0]))) { throw new Exception(_s('Missing item "%1$s" for host "%2$s".', $graph_db['ymax_item_key'], $host_db['host'])); } $graph_db['ymax_itemid'] = $item['itemid']; } $graph_db['gitems'] = $graph_items; if ($current_graph) { $graph_db['graphid'] = $current_graph['graphid']; $graphs_to_upd[] = $graph_db; } else { $graphs_to_add[] = $graph_db; } } if (!empty($graphs_to_add)) { API::Graph()->create($graphs_to_add); } if (!empty($graphs_to_upd)) { API::Graph()->update($graphs_to_upd); } } } // DEPENDENCIES $dependencies = $xpath->query('dependencies/dependency'); if ($dependencies->length > 0) { $triggersForDependencies = zbx_objectValues($triggersForDependencies, 'triggerid'); $triggersForDependencies = array_flip($triggersForDependencies); $triggerDependencies = array(); foreach ($dependencies as $dependency) { $triggerDescription = $dependency->getAttribute('description'); $currentTrigger = get_trigger_by_description($triggerDescription); if ($currentTrigger && isset($triggersForDependencies[$currentTrigger['triggerid']])) { $dependsOnList = $xpath->query('depends', $dependency); foreach ($dependsOnList as $dependsOn) { $depTrigger = get_trigger_by_description($dependsOn->nodeValue); if ($depTrigger) { if (!isset($triggerDependencies[$currentTrigger['triggerid']])) { $triggerDependencies[$currentTrigger['triggerid']] = array('triggerid' => $currentTrigger['triggerid'], 'dependencies' => array()); } $triggerDependencies[$currentTrigger['triggerid']]['dependencies'][] = array('triggerid' => $depTrigger['triggerid']); } } } } if ($triggerDependencies) { API::Trigger()->update($triggerDependencies); } } } }
public function update($proxies) { $proxies = zbx_toArray($proxies); $proxyids = array(); $this->checkInput($proxies, __FUNCTION__); $proxyUpdate = array(); $hostUpdate = array(); foreach ($proxies as $proxy) { $proxyids[] = $proxy['proxyid']; $proxyUpdate[] = array('values' => $proxy, 'where' => array('hostid' => $proxy['proxyid'])); if (!isset($proxy['hosts'])) { continue; } $hostUpdate[] = array('values' => array('proxy_hostid' => 0), 'where' => array('proxy_hostid' => $proxy['proxyid'])); $hostids = zbx_objectValues($proxy['hosts'], 'hostid'); $hostUpdate[] = array('values' => array('proxy_hostid' => $proxy['proxyid']), 'where' => array('hostid' => $hostids)); // if this is an active proxy - delete it's interface; if (isset($proxy['status']) && $proxy['status'] == HOST_STATUS_PROXY_ACTIVE) { $interfaces = API::HostInterface()->get(array('output' => API_OUTPUT_REFER, 'hostids' => $proxy['hostid'])); $interfaceids = zbx_objectValues($interfaces, 'interfaceid'); if ($interfaceids) { API::HostInterface()->delete($interfaceids); } } elseif (isset($proxy['interfaces']) && is_array($proxy['interfaces'])) { $proxy['interfaces'][0]['hostid'] = $proxy['hostid']; if (isset($proxy['interfaces'][0]['interfaceid'])) { $result = API::HostInterface()->update($proxy['interfaces']); } else { $result = API::HostInterface()->create($proxy['interfaces']); } if (!$result) { self::exception(ZBX_API_ERROR_INTERNAL, _('Proxy interface update failed.')); } } } DB::update('hosts', $proxyUpdate); DB::update('hosts', $hostUpdate); return array('proxyids' => $proxyids); }
protected function addRelatedObjects(array $options, array $result) { $result = parent::addRelatedObjects($options, $result); $proxyIds = array_keys($result); // selectHosts if ($options['selectHosts'] !== null && $options['selectHosts'] != API_OUTPUT_COUNT) { $hosts = API::Host()->get(array('output' => $this->outputExtend('hosts', array('hostid', 'proxy_hostid'), $options['selectHosts']), 'nodeids' => $options['nodeids'], 'proxyids' => $proxyIds, 'preservekeys' => true)); $relationMap = $this->createRelationMap($hosts, 'proxy_hostid', 'hostid'); $hosts = $this->unsetExtraFields($hosts, array('proxy_hostid', 'hostid'), $options['selectHosts']); $result = $relationMap->mapMany($result, $hosts, 'hosts'); } // adding host interface if ($options['selectInterface'] !== null && $options['selectInterface'] != API_OUTPUT_COUNT) { $interfaces = API::HostInterface()->get(array('output' => $this->outputExtend('interface', array('interfaceid', 'hostid'), $options['selectInterface']), 'nodeids' => $options['nodeids'], 'hostids' => $proxyIds, 'nopermissions' => true, 'preservekeys' => true)); $relationMap = $this->createRelationMap($interfaces, 'hostid', 'interfaceid'); $interfaces = $this->unsetExtraFields($interfaces, array('hostid', 'interfaceid'), $options['selectInterface']); $result = $relationMap->mapOne($result, $interfaces, 'interface'); foreach ($result as $key => $proxy) { if (!empty($proxy['interface'])) { $result[$key]['interface'] = $proxy['interface']; } } } // adding host interfaces (deprecated) if ($options['selectInterfaces'] !== null && $options['selectInterfaces'] != API_OUTPUT_COUNT) { $interfaces = API::HostInterface()->get(array('output' => $this->outputExtend('interface', array('interfaceid', 'hostid'), $options['selectInterfaces']), 'nodeids' => $options['nodeids'], 'hostids' => $proxyIds, 'nopermissions' => true, 'preservekeys' => true)); $relationMap = $this->createRelationMap($interfaces, 'hostid', 'interfaceid'); $interfaces = $this->unsetExtraFields($interfaces, array('hostid', 'interfaceid'), $options['selectInterfaces']); $result = $relationMap->mapOne($result, $interfaces, 'interfaces'); foreach ($result as $key => $proxy) { if (!empty($proxy['interfaces'])) { $result[$key]['interfaces'] = array($proxy['interfaces']); } } } return $result; }
public static function parseMain($rules) { $triggersForDependencies = array(); if (!empty($rules['hosts']['updateExisting']) || !empty($rules['hosts']['createMissing']) || !empty($rules['templates']['createMissing']) || !empty($rules['templates']['updateExisting'])) { $xpath = new DOMXPath(self::$xml); $hosts = $xpath->query('hosts/host'); foreach ($hosts as $host) { $host_db = self::mapXML2arr($host, XML_TAG_HOST); if (!isset($host_db['status'])) { $host_db['status'] = HOST_STATUS_TEMPLATE; } $current_host = $host_db['status'] == HOST_STATUS_TEMPLATE ? API::Template()->exists($host_db) : API::Host()->exists($host_db); if (!$current_host && ($host_db['status'] == HOST_STATUS_TEMPLATE && empty($rules['templates']['createMissing']) || $host_db['status'] != HOST_STATUS_TEMPLATE && empty($rules['hosts']['createMissing']))) { continue; } if ($current_host && ($host_db['status'] == HOST_STATUS_TEMPLATE && empty($rules['templates']['updateExisting']) || $host_db['status'] != HOST_STATUS_TEMPLATE && empty($rules['hosts']['updateExisting']))) { continue; } // there were no host visible names in 1.8 if (!isset($host_db['name'])) { $host_db['name'] = $host_db['host']; } // host will have no interfaces - we will be creating them separately $host_db['interfaces'] = null; // it is possible, that data is imported from 1.8, where there was only one network interface per host /** * @todo when new XML format will be introduced, this check should be changed to XML version check */ $old_version_input = $host_db['status'] != HOST_STATUS_TEMPLATE; if ($old_version_input) { // rearranging host structure, so it would look more like 2.0 host $interfaces = array(); // the main interface is always "agent" type if (!is_null($host_db['ip'])) { $interfaces[] = array('main' => INTERFACE_PRIMARY, 'type' => INTERFACE_TYPE_AGENT, 'useip' => $host_db['useip'], 'ip' => $host_db['ip'], 'dns' => $host_db['dns'], 'port' => $host_db['port']); } // now we need to check if host had SNMP items. If it had, we need and SNMP interface for every different port. $items = $xpath->query('items/item', $host); $snmp_interface_ports_created = array(); foreach ($items as $item) { $item_db = self::mapXML2arr($item, XML_TAG_ITEM); if (($item_db['type'] == ITEM_TYPE_SNMPV1 || $item_db['type'] == ITEM_TYPE_SNMPV2C || $item_db['type'] == ITEM_TYPE_SNMPV3) && !isset($snmp_interface_ports_created[$item_db['snmp_port']])) { $interfaces[] = array('main' => INTERFACE_PRIMARY, 'type' => INTERFACE_TYPE_SNMP, 'useip' => $host_db['useip'], 'ip' => $host_db['ip'], 'dns' => $host_db['dns'], 'port' => $item_db['snmp_port']); $snmp_interface_ports_created[$item_db['snmp_port']] = 1; } } unset($snmp_interface_ports_created); // it was a temporary variable // we ned to add ipmi interface if at least one ipmi item exists foreach ($items as $item) { $item_db = self::mapXML2arr($item, XML_TAG_ITEM); if ($item_db['type'] == ITEM_TYPE_IPMI) { // when saving a host in 1.8, it's possible to set useipmi=1 and not to fill an IP address // we were not really sure what to do with this host, // and decided to take host IP address instead and show info message about this if ($host_db['ipmi_ip'] == '') { $ipmi_ip = $host_db['ip']; info(_s('Host "%s" has "useipmi" parameter checked, but has no "ipmi_ip" parameter! Using host IP address as an address for IPMI interface.', $host_db['host'])); } else { $ipmi_ip = $host_db['ipmi_ip']; } $interfaces[] = array('main' => INTERFACE_PRIMARY, 'type' => INTERFACE_TYPE_IPMI, 'useip' => INTERFACE_USE_DNS, 'ip' => '', 'dns' => $ipmi_ip, 'port' => $host_db['ipmi_port']); // we need only one ipmi interface break; } } } if ($current_host) { $options = array('filter' => array('host' => $host_db['host']), 'output' => API_OUTPUT_EXTEND, 'editable' => 1, 'selectInterfaces' => API_OUTPUT_EXTEND); if ($host_db['status'] == HOST_STATUS_TEMPLATE) { $current_host = API::Template()->get($options); } else { $current_host = API::Host()->get($options); } if (empty($current_host)) { throw new Exception(_s('No permission for host "%1$s".', $host_db['host'])); } else { $current_host = reset($current_host); } // checking if host already exists - then some of the interfaces may not need to be created if ($host_db['status'] != HOST_STATUS_TEMPLATE) { // for every interface we got based on XML foreach ($interfaces as $i => $interface_db) { // checking every interface of current host foreach ($current_host['interfaces'] as $interface) { // if all parameters of interface are identical if ($interface['type'] == $interface_db['type'] && $interface['ip'] == $interface_db['ip'] && $interface['dns'] == $interface_db['dns'] && $interface['port'] == $interface_db['port'] && $interface['useip'] == $interface_db['useip']) { // this interface is the same as existing one! $interfaces[$i]['interfaceid'] = $interface['interfaceid']; break; } } } } $interfaces_created_with_host = false; } else { if ($host_db['status'] != HOST_STATUS_TEMPLATE) { $host_db['interfaces'] = $interfaces; $interfaces_created_with_host = true; } } // HOST GROUPS {{{ $groups = $xpath->query('groups/group', $host); $host_db['groups'] = array(); $groups_to_parse = array(); foreach ($groups as $group) { $groups_to_parse[] = array('name' => $group->nodeValue); } if (empty($groups_to_parse)) { $groups_to_parse[] = array('name' => ZBX_DEFAULT_IMPORT_HOST_GROUP); } foreach ($groups_to_parse as $group) { $current_group = API::HostGroup()->exists($group); if ($current_group) { $options = array('filter' => $group, 'output' => API_OUTPUT_EXTEND, 'editable' => 1); $current_group = API::HostGroup()->get($options); if (empty($current_group)) { throw new Exception(_s('No permissions for group "%1$s".', $group['name'])); } $host_db['groups'][] = reset($current_group); } else { $result = API::HostGroup()->create($group); if (!$result) { throw new Exception(); } $options = array('groupids' => $result['groupids'], 'output' => API_OUTPUT_EXTEND); $new_group = API::HostGroup()->get($options); $host_db['groups'][] = reset($new_group); } } // }}} HOST GROUPS // MACROS $macros = $xpath->query('macros/macro', $host); if ($macros->length > 0) { $host_db['macros'] = array(); foreach ($macros as $macro) { $host_db['macros'][] = self::mapXML2arr($macro, XML_TAG_MACRO); } } // }}} MACROS // host inventory if ($old_version_input) { if (!isset($host_db['inventory'])) { $host_db['inventory'] = array(); } $inventoryNode = $xpath->query('host_profile/*', $host); if ($inventoryNode->length > 0) { foreach ($inventoryNode as $field) { $newInventoryName = self::mapInventoryName($field->nodeName); $host_db['inventory'][$newInventoryName] = $field->nodeValue; } } $inventoryNodeExt = $xpath->query('host_profiles_ext/*', $host); if ($inventoryNodeExt->length > 0) { foreach ($inventoryNodeExt as $field) { $newInventoryName = self::mapInventoryName($field->nodeName); if (isset($host_db['inventory'][$newInventoryName]) && $field->nodeValue !== '') { $host_db['inventory'][$newInventoryName] .= "\r\n\r\n"; $host_db['inventory'][$newInventoryName] .= $field->nodeValue; } else { $host_db['inventory'][$newInventoryName] = $field->nodeValue; } } } $host_db['inventory_mode'] = isset($host_db['inventory']) ? HOST_INVENTORY_MANUAL : HOST_INVENTORY_DISABLED; } // HOSTS if (isset($host_db['proxy_hostid'])) { $proxy_exists = API::Proxy()->get(array('proxyids' => $host_db['proxy_hostid'])); if (empty($proxy_exists)) { $host_db['proxy_hostid'] = 0; } } if ($current_host && (!empty($rules['hosts']['updateExisting']) || !empty($rules['templates']['updateExisting']))) { if ($host_db['status'] == HOST_STATUS_TEMPLATE) { $host_db['templateid'] = $current_host['templateid']; $result = API::Template()->update($host_db); $current_hostid = $current_host['templateid']; } else { $host_db['hostid'] = $current_host['hostid']; $result = API::Host()->update($host_db); $current_hostid = $current_host['hostid']; } if (!$result) { throw new Exception(); } } if (!$current_host && (!empty($rules['hosts']['createMissing']) || !empty($rules['templates']['createMissing']))) { if ($host_db['status'] == HOST_STATUS_TEMPLATE) { $result = API::Template()->create($host_db); if (!$result) { throw new Exception(); } $current_hostid = reset($result['templateids']); } else { $result = API::Host()->create($host_db); if (!$result) { throw new Exception(); } $current_hostid = reset($result['hostids']); } } $current_hostname = $host_db['host']; // TEMPLATES {{{ if (!empty($rules['templateLinkage']['createMissing'])) { $templates = $xpath->query('templates/template', $host); $templateLinkage = array(); foreach ($templates as $template) { $options = array('filter' => array('host' => $template->nodeValue), 'output' => array('templateid'), 'editable' => true); $current_template = API::Template()->get($options); if (empty($current_template)) { throw new Exception(_s('No permission for template "%1$s".', $template->nodeValue)); } $current_template = reset($current_template); $templateLinkage[] = $current_template; } if ($templateLinkage) { $result = API::Template()->massAdd(array('hosts' => array('hostid' => $current_hostid), 'templates' => $templateLinkage)); if (!$result) { throw new Exception(); } } } // }}} TEMPLATES // ITEMS {{{ if (!empty($rules['items']['updateExisting']) || !empty($rules['items']['createMissing'])) { $items = $xpath->query('items/item', $host); // if this is an export from 1.8, we need to make some adjustments to items if ($old_version_input) { if (!$interfaces_created_with_host) { // if host had another interfaces, we are not touching them: they remain as is foreach ($interfaces as $i => $interface) { // interface was not already created if (!isset($interface['interfaceid'])) { // creating interface $interface['hostid'] = $current_hostid; $ids = API::HostInterface()->create($interface); if ($ids === false) { throw new Exception(); } $interfaces[$i]['interfaceid'] = reset($ids['interfaceids']); } } } else { $options = array('hostids' => $current_hostid, 'output' => API_OUTPUT_EXTEND); $interfaces = API::HostInterface()->get($options); } // we must know interface ids to assign them to items $agent_interface_id = null; $ipmi_interface_id = null; $snmp_interfaces = array(); // hash 'port' => 'iterfaceid' foreach ($interfaces as $interface) { switch ($interface['type']) { case INTERFACE_TYPE_AGENT: $agent_interface_id = $interface['interfaceid']; break; case INTERFACE_TYPE_IPMI: $ipmi_interface_id = $interface['interfaceid']; break; case INTERFACE_TYPE_SNMP: $snmp_interfaces[$interface['port']] = $interface['interfaceid']; break; } } } foreach ($items as $item) { $item_db = self::mapXML2arr($item, XML_TAG_ITEM); $item_db['hostid'] = $current_hostid; // item needs interfaces if ($old_version_input) { // 'snmp_port' column was renamed to 'port' if ($item_db['snmp_port'] != 0) { // zabbix agent items have no ports $item_db['port'] = $item_db['snmp_port']; } unset($item_db['snmp_port']); // assigning appropriate interface depending on item type switch ($item_db['type']) { // zabbix agent interface case ITEM_TYPE_ZABBIX: case ITEM_TYPE_SIMPLE: case ITEM_TYPE_EXTERNAL: case ITEM_TYPE_SSH: case ITEM_TYPE_TELNET: $item_db['interfaceid'] = $agent_interface_id; break; // snmp interface // snmp interface case ITEM_TYPE_SNMPV1: case ITEM_TYPE_SNMPV2C: case ITEM_TYPE_SNMPV3: // for an item with different port - different interface $item_db['interfaceid'] = $snmp_interfaces[$item_db['port']]; break; case ITEM_TYPE_IPMI: $item_db['interfaceid'] = $ipmi_interface_id; break; // no interfaces required for these item types // no interfaces required for these item types case ITEM_TYPE_HTTPTEST: case ITEM_TYPE_CALCULATED: case ITEM_TYPE_AGGREGATE: case ITEM_TYPE_INTERNAL: case ITEM_TYPE_ZABBIX_ACTIVE: case ITEM_TYPE_TRAPPER: case ITEM_TYPE_DB_MONITOR: $item_db['interfaceid'] = null; break; } $item_db['key_'] = self::convertOldSimpleKey($item_db['key_']); } $options = array('filter' => array('hostid' => $item_db['hostid'], 'key_' => $item_db['key_']), 'webitems' => 1, 'output' => API_OUTPUT_EXTEND, 'editable' => 1); $current_item = API::Item()->get($options); $current_item = reset($current_item); if (!$current_item && empty($rules['items']['createMissing'])) { info(_s('Item "%1$s" skipped - user rule.', $item_db['key_'])); continue; // break if not update updateExisting } if ($current_item && empty($rules['items']['updateExisting'])) { info(_s('Item "%1$s" skipped - user rule.', $item_db['key_'])); continue; // break if not update updateExisting } // ITEM APPLICATIONS {{{ $applications = $xpath->query('applications/application', $item); $item_applications = array(); $applications_to_add = array(); $applicationsIds = array(); foreach ($applications as $application) { $application_db = array('name' => $application->nodeValue, 'hostid' => $current_hostid); $current_application = API::Application()->get(array('filter' => $application_db, 'output' => API_OUTPUT_EXTEND)); $applicationValue = reset($current_application); if ($current_application) { if (empty($item_applications)) { $item_applications = $current_application; $applicationsIds[] = $applicationValue['applicationid']; } else { if (!in_array($applicationValue['applicationid'], $applicationsIds)) { $item_applications = array_merge($item_applications, $current_application); $applicationsIds[] = $applicationValue['applicationid']; } } } else { $applications_to_add[] = $application_db; } } if (!empty($applications_to_add)) { $result = API::Application()->create($applications_to_add); if (!$result) { throw new Exception(); } $options = array('applicationids' => $result['applicationids'], 'output' => API_OUTPUT_EXTEND); $new_applications = API::Application()->get($options); $item_applications = array_merge($item_applications, $new_applications); } // }}} ITEM APPLICATIONS if ($current_item && !empty($rules['items']['updateExisting'])) { $item_db['itemid'] = $current_item['itemid']; $result = API::Item()->update($item_db); if (!$result) { throw new Exception(); } $options = array('itemids' => $result['itemids'], 'webitems' => 1, 'output' => API_OUTPUT_EXTEND); $current_item = API::Item()->get($options); } if (!$current_item && !empty($rules['items']['createMissing'])) { $result = API::Item()->create($item_db); if (!$result) { throw new Exception(); } $options = array('itemids' => $result['itemids'], 'webitems' => 1, 'output' => API_OUTPUT_EXTEND); $current_item = API::Item()->get($options); } if (!empty($item_applications)) { $r = API::Application()->massAdd(array('applications' => $item_applications, 'items' => $current_item)); if ($r === false) { throw new Exception(); } } } } // }}} ITEMS // TRIGGERS {{{ if (!empty($rules['triggers']['updateExisting']) || !empty($rules['triggers']['createMissing'])) { $triggers = $xpath->query('triggers/trigger', $host); $triggers_to_add = array(); $triggers_to_upd = array(); foreach ($triggers as $trigger) { $trigger_db = self::mapXML2arr($trigger, XML_TAG_TRIGGER); if ($old_version_input) { $expressionPart = explode(':', $trigger_db['expression']); $keyName = explode(',', $expressionPart[1], 2); if (count($keyName) == 2) { $keyValue = explode('.', $keyName[1], 2); $key = $keyName[0] . "," . $keyValue[0]; if (in_array($keyName[0], self::$oldKeys) || in_array($keyName[0], self::$oldKeysPref)) { $trigger_db['expression'] = str_replace($key, self::convertOldSimpleKey($key), $trigger_db['expression']); } } } // {HOSTNAME} is here for backward compatibility $trigger_db['expression'] = str_replace('{{HOSTNAME}:', '{' . $host_db['host'] . ':', $trigger_db['expression']); $trigger_db['expression'] = str_replace('{{HOST.HOST}:', '{' . $host_db['host'] . ':', $trigger_db['expression']); $trigger_db['hostid'] = $current_hostid; if ($current_trigger = API::Trigger()->exists($trigger_db)) { $ctriggers = API::Trigger()->get(array('filter' => array('description' => $trigger_db['description']), 'hostids' => $current_hostid, 'output' => API_OUTPUT_EXTEND, 'editable' => 1)); $current_trigger = false; foreach ($ctriggers as $ct) { $tmp_exp = explode_exp($ct['expression']); if (strcmp($trigger_db['expression'], $tmp_exp) == 0) { $current_trigger = $ct; break; } } if (!$current_trigger) { throw new Exception(_s('No permission for trigger "%s".', $trigger_db['description'])); } } unset($trigger_db['hostid']); if (!$current_trigger && empty($rules['triggers']['createMissing'])) { info(_s('Trigger "%1$s" skipped - user rule.', $trigger_db['description'])); continue; // break if not update updateExisting } if ($current_trigger && empty($rules['triggers']['updateExisting'])) { info(_s('Trigger "%1$s" skipped - user rule.', $trigger_db['description'])); continue; // break if not update updateExisting } if ($current_trigger && !empty($rules['triggers']['updateExisting'])) { $trigger_db['triggerid'] = $current_trigger['triggerid']; $triggers_to_upd[] = $trigger_db; } if (!$current_trigger && !empty($rules['triggers']['createMissing'])) { $triggers_to_add[] = $trigger_db; } } if (!empty($triggers_to_upd)) { $result = API::Trigger()->update($triggers_to_upd); if (!$result) { throw new Exception(); } $options = array('triggerids' => $result['triggerids'], 'output' => API_OUTPUT_EXTEND); $r = API::Trigger()->get($options); $triggersForDependencies = array_merge($triggersForDependencies, $r); } if (!empty($triggers_to_add)) { $result = API::Trigger()->create($triggers_to_add); if (!$result) { throw new Exception(); } $options = array('triggerids' => $result['triggerids'], 'output' => API_OUTPUT_EXTEND); $r = API::Trigger()->get($options); $triggersForDependencies = array_merge($triggersForDependencies, $r); } } // }}} TRIGGERS // GRAPHS {{{ if (!empty($rules['graphs']['updateExisting']) || !empty($rules['graphs']['createMissing'])) { $graphs = $xpath->query('graphs/graph', $host); $graphs_to_add = array(); $graphs_to_upd = array(); foreach ($graphs as $graph) { // GRAPH ITEMS {{{ $gitems = $xpath->query('graph_elements/graph_element', $graph); $graph_hostids = array(); $graph_items = array(); foreach ($gitems as $gitem) { $gitem_db = self::mapXML2arr($gitem, XML_TAG_GRAPH_ELEMENT); $data = explode(':', $gitem_db['host_key_']); $gitem_host = array_shift($data); // {HOSTNAME} is here for backward compatibility $gitem_db['host'] = $gitem_host == '{HOSTNAME}' ? $host_db['host'] : $gitem_host; $gitem_db['host'] = $gitem_host == '{HOST.HOST}' ? $host_db['host'] : $gitem_host; if ($old_version_input) { $data[0] = self::convertOldSimpleKey($data[0]); } $gitem_db['key_'] = implode(':', $data); if ($current_item = API::Item()->exists($gitem_db)) { $current_item = API::Item()->get(array('filter' => array('key_' => $gitem_db['key_']), 'webitems' => 1, 'host' => $gitem_db['host'], 'output' => API_OUTPUT_EXTEND, 'editable' => 1)); if (empty($current_item)) { throw new Exception(_s('No permission for item "%1$s".', $gitem_db['key_'])); } $current_item = reset($current_item); $graph_hostids[] = $current_item['hostid']; $gitem_db['itemid'] = $current_item['itemid']; $graph_items[] = $gitem_db; } else { throw new Exception(_s('Item "%1$s" does not exist.', $gitem_db['host_key_'])); } } // }}} GRAPH ITEMS $graph_db = self::mapXML2arr($graph, XML_TAG_GRAPH); $graph_db['hostids'] = $graph_hostids; // do we need to show the graph legend, after it is imported? // in 1.8, this setting was present only for pie and exploded graphs // for other graph types we are always showing the legend if ($graph_db['graphtype'] != GRAPH_TYPE_PIE && $graph_db['graphtype'] != GRAPH_TYPE_EXPLODED) { $graph_db['show_legend'] = 1; } $current_graph = API::Graph()->exists($graph_db); if ($current_graph) { $current_graph = API::Graph()->get(array('filter' => array('name' => $graph_db['name']), 'hostids' => $graph_db['hostids'], 'output' => API_OUTPUT_EXTEND, 'editable' => 1)); if (empty($current_graph)) { throw new Exception(_s('No permission for graph "%1$s".', $graph_db['name'])); } $current_graph = reset($current_graph); } if (!$current_graph && empty($rules['graphs']['createMissing'])) { info(_s('Graph "%1$s" skipped - user rule.', $graph_db['name'])); continue; // break if not update updateExisting } if ($current_graph && empty($rules['graphs']['updateExisting'])) { info(_s('Graph "%1$s" skipped - user rule.', $graph_db['name'])); continue; // break if not update updateExisting } if (!isset($graph_db['ymin_type'])) { throw new Exception(_s('No "ymin_type" field for graph "%s".', $graph_db['name'])); } if (!isset($graph_db['ymax_type'])) { throw new Exception(_s('No "ymax_type" field for graph "%s".', $graph_db['name'])); } if ($graph_db['ymin_type'] == GRAPH_YAXIS_TYPE_ITEM_VALUE) { $item_data = explode(':', $graph_db['ymin_item_key'], 2); if (count($item_data) < 2) { throw new Exception(_s('Incorrect y min item for graph "%1$s".', $graph_db['name'])); } if (!($item = get_item_by_key($item_data[1], $item_data[0]))) { throw new Exception(_s('Missing item "%1$s" for host "%2$s".', $graph_db['ymin_item_key'], $host_db['host'])); } $graph_db['ymin_itemid'] = $item['itemid']; } if ($graph_db['ymax_type'] == GRAPH_YAXIS_TYPE_ITEM_VALUE) { $item_data = explode(':', $graph_db['ymax_item_key'], 2); if (count($item_data) < 2) { throw new Exception(_s('Incorrect y max item for graph "%1$s".', $graph_db['name'])); } if (!($item = get_item_by_key($item_data[1], $item_data[0]))) { throw new Exception(_s('Missing item "%1$s" for host "%2$s".', $graph_db['ymax_item_key'], $host_db['host'])); } $graph_db['ymax_itemid'] = $item['itemid']; } $graph_db['gitems'] = $graph_items; if ($current_graph) { $graph_db['graphid'] = $current_graph['graphid']; $graphs_to_upd[] = $graph_db; } else { $graphs_to_add[] = $graph_db; } } if (!empty($graphs_to_add)) { $r = API::Graph()->create($graphs_to_add); if ($r === false) { throw new Exception(); } } if (!empty($graphs_to_upd)) { $r = API::Graph()->update($graphs_to_upd); if ($r === false) { throw new Exception(); } } } // SCREENS if (!empty($rules['screens']['updateExisting']) || !empty($rules['screens']['createMissing'])) { $screens_node = $xpath->query('screens', $host); if ($screens_node->length > 0) { $importScreens = self::XMLtoArray($screens_node->item(0)); foreach ($importScreens as $screen) { $current_screen = API::TemplateScreen()->get(array('filter' => array('name' => $screen['name']), 'templateids' => $current_hostid, 'output' => API_OUTPUT_EXTEND, 'editable' => 1)); $current_screen = reset($current_screen); if (!$current_screen && empty($rules['screens']['createMissing'])) { info(_s('Screen "%1$s" skipped - user rule.', $screen['name'])); continue; } if ($current_screen && empty($rules['screens']['updateExisting'])) { info(_s('Screen "%1$s" skipped - user rule.', $screen['name'])); continue; } if (isset($screen['screenitems'])) { foreach ($screen['screenitems'] as &$screenitem) { $nodeCaption = isset($screenitem['resourceid']['node']) ? $screenitem['resourceid']['node'] . ':' : ''; if (!isset($screenitem['resourceid'])) { $screenitem['resourceid'] = 0; } if (is_array($screenitem['resourceid'])) { switch ($screenitem['resourcetype']) { case SCREEN_RESOURCE_GRAPH: $db_graphs = API::Graph()->getObjects($screenitem['resourceid']); if (empty($db_graphs)) { $error = _s('Cannot find graph "%1$s" used in screen "%2$s".', $nodeCaption . $screenitem['resourceid']['host'] . ':' . $screenitem['resourceid']['name'], $screen['name']); throw new Exception($error); } $tmp = reset($db_graphs); $screenitem['resourceid'] = $tmp['graphid']; break; case SCREEN_RESOURCE_SIMPLE_GRAPH: case SCREEN_RESOURCE_PLAIN_TEXT: $db_items = API::Item()->getObjects($screenitem['resourceid']); if (empty($db_items)) { $error = _s('Cannot find item "%1$s" used in screen "%2$s".', $nodeCaption . $screenitem['resourceid']['host'] . ':' . $screenitem['resourceid']['key_'], $screen['name']); throw new Exception($error); } $tmp = reset($db_items); $screenitem['resourceid'] = $tmp['itemid']; break; default: $screenitem['resourceid'] = 0; break; } } } } $screen['templateid'] = $current_hostid; if ($current_screen) { $screen['screenid'] = $current_screen['screenid']; $result = API::TemplateScreen()->update($screen); if (!$result) { throw new Exception(_('Cannot update screen.')); } info('[' . $current_hostname . '] ' . _s('Screen "%1$s" updated.', $screen['name'])); } else { $result = API::TemplateScreen()->create($screen); if (!$result) { throw new Exception(_('Cannot create screen.')); } info('[' . $current_hostname . '] ' . _s('Screen "%1$s" added.', $screen['name'])); } } } } } // DEPENDENCIES $dependencies = $xpath->query('dependencies/dependency'); if ($dependencies->length > 0) { $triggersForDependencies = zbx_objectValues($triggersForDependencies, 'triggerid'); $triggersForDependencies = array_flip($triggersForDependencies); $newDependencies = array(); foreach ($dependencies as $dependency) { $triggerDescription = $dependency->getAttribute('description'); $currentTrigger = get_trigger_by_description($triggerDescription); if ($currentTrigger && isset($triggersForDependencies[$currentTrigger['triggerid']])) { $dependsOnList = $xpath->query('depends', $dependency); foreach ($dependsOnList as $dependsOn) { $depTrigger = get_trigger_by_description($dependsOn->nodeValue); if ($depTrigger['triggerid']) { $newDependencies[] = array('triggerid' => $currentTrigger['triggerid'], 'dependsOnTriggerid' => $depTrigger['triggerid']); } } } } if ($newDependencies) { API::Trigger()->addDependencies($newDependencies); } } } }
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 interfaces if ($options['selectInterfaces'] !== null && $options['selectInterfaces'] != API_OUTPUT_COUNT) { $relationMap = $this->createRelationMap($result, 'itemid', 'interfaceid'); $interfaces = API::HostInterface()->get(array('output' => $options['selectInterfaces'], 'interfaceids' => $relationMap->getRelatedIds(), 'nopermissions' => true, 'preservekeys' => true)); $result = $relationMap->mapMany($result, $interfaces, 'interfaces'); } // adding triggers if (!is_null($options['selectTriggers'])) { if ($options['selectTriggers'] != API_OUTPUT_COUNT) { $relationMap = $this->createRelationMap($result, 'itemid', 'triggerid', 'functions'); $triggers = API::Trigger()->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::Trigger()->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::Graph()->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::Graph()->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 = new CRelationMap(); // discovered items $dbRules = DBselect('SELECT id1.itemid,id2.parent_itemid' . ' FROM item_discovery id1,item_discovery id2,items i' . ' WHERE ' . dbConditionInt('id1.itemid', $itemids) . ' AND id1.parent_itemid=id2.itemid' . ' AND i.itemid=id1.itemid' . ' AND i.flags=' . ZBX_FLAG_DISCOVERY_CREATED); while ($rule = DBfetch($dbRules)) { $relationMap->addRelation($rule['itemid'], $rule['parent_itemid']); } // item prototypes // TODO: this should not be in the item API $dbRules = DBselect('SELECT id.parent_itemid,id.itemid' . ' FROM item_discovery id,items i' . ' WHERE ' . dbConditionInt('id.itemid', $itemids) . ' AND i.itemid=id.itemid' . ' AND i.flags=' . ZBX_FLAG_DISCOVERY_PROTOTYPE); while ($rule = DBfetch($dbRules)) { $relationMap->addRelation($rule['itemid'], $rule['parent_itemid']); } $discoveryRules = API::DiscoveryRule()->get(array('output' => $options['selectDiscoveryRule'], 'itemids' => $relationMap->getRelatedIds(), 'nopermissions' => true, 'preservekeys' => true)); $result = $relationMap->mapOne($result, $discoveryRules, 'discoveryRule'); } // adding item discovery if ($options['selectItemDiscovery'] !== null) { $itemDiscoveries = API::getApiService()->select('item_discovery', array('output' => $this->outputExtend($options['selectItemDiscovery'], array('itemdiscoveryid', 'itemid')), 'filter' => array('itemid' => array_keys($result)), 'preservekeys' => true)); $relationMap = $this->createRelationMap($itemDiscoveries, 'itemid', 'itemdiscoveryid'); $itemDiscoveries = $this->unsetExtraFields($itemDiscoveries, array('itemid', 'itemdiscoveryid'), $options['selectItemDiscovery']); $result = $relationMap->mapOne($result, $itemDiscoveries, 'itemDiscovery'); } // adding history data $requestedOutput = array(); if ($this->outputIsRequested('lastclock', $options['output'])) { $requestedOutput['lastclock'] = true; } if ($this->outputIsRequested('lastns', $options['output'])) { $requestedOutput['lastns'] = true; } if ($this->outputIsRequested('lastvalue', $options['output'])) { $requestedOutput['lastvalue'] = true; } if ($this->outputIsRequested('prevvalue', $options['output'])) { $requestedOutput['prevvalue'] = true; } if ($requestedOutput) { $history = Manager::History()->getLast($result, 2, ZBX_HISTORY_PERIOD); foreach ($result as &$item) { $lastHistory = isset($history[$item['itemid']][0]) ? $history[$item['itemid']][0] : null; $prevHistory = isset($history[$item['itemid']][1]) ? $history[$item['itemid']][1] : null; if (isset($requestedOutput['lastclock'])) { $item['lastclock'] = $lastHistory ? $lastHistory['clock'] : '0'; } if (isset($requestedOutput['lastns'])) { $item['lastns'] = $lastHistory ? $lastHistory['ns'] : '0'; } if (isset($requestedOutput['lastvalue'])) { $item['lastvalue'] = $lastHistory ? $lastHistory['value'] : '0'; } if (isset($requestedOutput['prevvalue'])) { $item['prevvalue'] = $prevHistory ? $prevHistory['value'] : '0'; } } unset($item); } return $result; }
/** * Get data for item edit page. * * @param array $item item, item prototype or LLD rule to take the data from * @param bool $options['is_discovery_rule'] * * @return array */ function getItemFormData(array $item = [], array $options = []) { $data = ['form' => getRequest('form'), 'form_refresh' => getRequest('form_refresh'), 'is_discovery_rule' => !empty($options['is_discovery_rule']), 'parent_discoveryid' => getRequest('parent_discoveryid', !empty($options['is_discovery_rule']) ? getRequest('itemid') : null), 'itemid' => getRequest('itemid'), 'limited' => false, 'interfaceid' => getRequest('interfaceid', 0), 'name' => getRequest('name', ''), 'description' => getRequest('description', ''), 'key' => getRequest('key', ''), 'hostname' => getRequest('hostname'), 'delay' => getRequest('delay', ZBX_ITEM_DELAY_DEFAULT), 'history' => getRequest('history', 90), 'status' => getRequest('status', isset($_REQUEST['form_refresh']) ? 1 : 0), 'type' => getRequest('type', 0), 'snmp_community' => getRequest('snmp_community', 'public'), 'snmp_oid' => getRequest('snmp_oid', 'interfaces.ifTable.ifEntry.ifInOctets.1'), 'port' => getRequest('port', ''), 'value_type' => getRequest('value_type', ITEM_VALUE_TYPE_UINT64), 'data_type' => getRequest('data_type', ITEM_DATA_TYPE_DECIMAL), 'trapper_hosts' => getRequest('trapper_hosts', ''), 'units' => getRequest('units', ''), 'valuemapid' => getRequest('valuemapid', 0), 'params' => getRequest('params', ''), 'multiplier' => getRequest('multiplier', 0), 'delta' => getRequest('delta', 0), 'trends' => getRequest('trends', DAY_IN_YEAR), 'new_application' => getRequest('new_application', ''), 'applications' => getRequest('applications', []), 'delay_flex' => getRequest('delay_flex', []), 'snmpv3_contextname' => getRequest('snmpv3_contextname', ''), 'snmpv3_securityname' => getRequest('snmpv3_securityname', ''), 'snmpv3_securitylevel' => getRequest('snmpv3_securitylevel', 0), 'snmpv3_authprotocol' => getRequest('snmpv3_authprotocol', ITEM_AUTHPROTOCOL_MD5), 'snmpv3_authpassphrase' => getRequest('snmpv3_authpassphrase', ''), 'snmpv3_privprotocol' => getRequest('snmpv3_privprotocol', ITEM_PRIVPROTOCOL_DES), 'snmpv3_privpassphrase' => getRequest('snmpv3_privpassphrase', ''), 'ipmi_sensor' => getRequest('ipmi_sensor', ''), 'authtype' => getRequest('authtype', 0), 'username' => getRequest('username', ''), 'password' => getRequest('password', ''), 'publickey' => getRequest('publickey', ''), 'privatekey' => getRequest('privatekey', ''), 'formula' => getRequest('formula', 1), 'logtimefmt' => getRequest('logtimefmt', ''), 'add_groupid' => getRequest('add_groupid', getRequest('groupid', 0)), 'valuemaps' => null, 'possibleHostInventories' => null, 'alreadyPopulated' => null, 'initial_item_type' => null, 'templates' => []]; // hostid if (!empty($data['parent_discoveryid'])) { $discoveryRule = API::DiscoveryRule()->get(['itemids' => $data['parent_discoveryid'], 'output' => API_OUTPUT_EXTEND, 'editable' => true]); $discoveryRule = reset($discoveryRule); $data['hostid'] = $discoveryRule['hostid']; $data['new_application_prototype'] = getRequest('new_application_prototype', ''); $data['application_prototypes'] = getRequest('application_prototypes', array()); } else { $data['hostid'] = getRequest('hostid', 0); } // types, http items only for internal processes $data['types'] = item_type2str(); unset($data['types'][ITEM_TYPE_HTTPTEST]); if (!empty($options['is_discovery_rule'])) { unset($data['types'][ITEM_TYPE_AGGREGATE], $data['types'][ITEM_TYPE_CALCULATED], $data['types'][ITEM_TYPE_SNMPTRAP]); } // item if ($item) { $data['item'] = $item; $data['hostid'] = !empty($data['hostid']) ? $data['hostid'] : $data['item']['hostid']; $data['limited'] = $data['item']['templateid'] != 0; // get templates $itemid = $item['itemid']; do { $params = ['itemids' => $itemid, 'output' => ['itemid', 'templateid'], 'selectHosts' => ['name']]; if ($data['is_discovery_rule']) { $item = API::DiscoveryRule()->get($params); } else { $params['selectDiscoveryRule'] = ['itemid']; $params['filter'] = ['flags' => null]; $item = API::Item()->get($params); } $item = reset($item); if (!empty($item)) { $host = reset($item['hosts']); if (!empty($item['hosts'])) { $host['name'] = CHtml::encode($host['name']); if (bccomp($data['itemid'], $itemid) == 0) { } elseif ($data['is_discovery_rule']) { $data['templates'][] = new CLink($host['name'], 'host_discovery.php?form=update&itemid=' . $item['itemid']); $data['templates'][] = SPACE . '⇒' . SPACE; } elseif ($item['discoveryRule']) { $data['templates'][] = new CLink($host['name'], 'disc_prototypes.php?form=update' . '&itemid=' . $item['itemid'] . '&parent_discoveryid=' . $item['discoveryRule']['itemid']); $data['templates'][] = SPACE . '⇒' . SPACE; } else { $data['templates'][] = new CLink($host['name'], 'items.php?form=update&itemid=' . $item['itemid']); $data['templates'][] = SPACE . '⇒' . SPACE; } } $itemid = $item['templateid']; } else { break; } } while ($itemid != 0); $data['templates'] = array_reverse($data['templates']); array_shift($data['templates']); } // caption if (!empty($data['is_discovery_rule'])) { $data['caption'] = _('Discovery rule'); } else { $data['caption'] = !empty($data['parent_discoveryid']) ? _('Item prototype') : _('Item'); } // hostname if (empty($data['is_discovery_rule']) && empty($data['hostname'])) { if (!empty($data['hostid'])) { $hostInfo = API::Host()->get(['hostids' => $data['hostid'], 'output' => ['name'], 'templated_hosts' => true]); $hostInfo = reset($hostInfo); $data['hostname'] = $hostInfo['name']; } else { $data['hostname'] = _('not selected'); } } // fill data from item if (!hasRequest('form_refresh') && ($item || $data['limited'])) { $data['name'] = $data['item']['name']; $data['description'] = $data['item']['description']; $data['key'] = $data['item']['key_']; $data['interfaceid'] = $data['item']['interfaceid']; $data['type'] = $data['item']['type']; $data['snmp_community'] = $data['item']['snmp_community']; $data['snmp_oid'] = $data['item']['snmp_oid']; $data['port'] = $data['item']['port']; $data['value_type'] = $data['item']['value_type']; $data['data_type'] = $data['item']['data_type']; $data['trapper_hosts'] = $data['item']['trapper_hosts']; $data['units'] = $data['item']['units']; $data['valuemapid'] = $data['item']['valuemapid']; $data['multiplier'] = $data['item']['multiplier']; $data['hostid'] = $data['item']['hostid']; $data['params'] = $data['item']['params']; $data['snmpv3_contextname'] = $data['item']['snmpv3_contextname']; $data['snmpv3_securityname'] = $data['item']['snmpv3_securityname']; $data['snmpv3_securitylevel'] = $data['item']['snmpv3_securitylevel']; $data['snmpv3_authprotocol'] = $data['item']['snmpv3_authprotocol']; $data['snmpv3_authpassphrase'] = $data['item']['snmpv3_authpassphrase']; $data['snmpv3_privprotocol'] = $data['item']['snmpv3_privprotocol']; $data['snmpv3_privpassphrase'] = $data['item']['snmpv3_privpassphrase']; $data['ipmi_sensor'] = $data['item']['ipmi_sensor']; $data['authtype'] = $data['item']['authtype']; $data['username'] = $data['item']['username']; $data['password'] = $data['item']['password']; $data['publickey'] = $data['item']['publickey']; $data['privatekey'] = $data['item']['privatekey']; $data['logtimefmt'] = $data['item']['logtimefmt']; $data['new_application'] = getRequest('new_application', ''); if ($data['parent_discoveryid'] != 0) { $data['new_application_prototype'] = getRequest('new_application_prototype', ''); } if (!$data['is_discovery_rule']) { $data['formula'] = $data['item']['formula']; } if (!$data['limited'] || !isset($_REQUEST['form_refresh'])) { $data['delay'] = $data['item']['delay']; if (($data['type'] == ITEM_TYPE_TRAPPER || $data['type'] == ITEM_TYPE_SNMPTRAP) && $data['delay'] == 0) { $data['delay'] = ZBX_ITEM_DELAY_DEFAULT; } $data['history'] = $data['item']['history']; $data['status'] = $data['item']['status']; $data['delta'] = $data['item']['delta']; $data['trends'] = $data['item']['trends']; $parser = new CItemDelayFlexParser($data['item']['delay_flex']); if ($parser->isValid()) { foreach ($parser->getIntervals() as $interval) { if ($interval['type'] == ITEM_DELAY_FLEX_TYPE_FLEXIBLE) { $interval_parts = explode('/', $interval['interval']); $data['delay_flex'][] = ['delay' => $interval_parts[0], 'period' => $interval_parts[1], 'type' => ITEM_DELAY_FLEX_TYPE_FLEXIBLE]; } else { $data['delay_flex'][] = ['schedule' => $interval['interval'], 'type' => ITEM_DELAY_FLEX_TYPE_SCHEDULING]; } } } $data['applications'] = array_unique(zbx_array_merge($data['applications'], get_applications_by_itemid($data['itemid']))); if ($data['parent_discoveryid'] != 0) { /* * Get a list of application prototypes assigned to item prototype. Don't select distinct names, * since database can be accidentally created case insensitive. */ $application_prototypes = DBfetchArray(DBselect('SELECT ap.name' . ' FROM application_prototype ap,item_application_prototype iap' . ' WHERE ap.application_prototypeid=iap.application_prototypeid' . ' AND ap.itemid=' . zbx_dbstr($data['parent_discoveryid']) . ' AND iap.itemid=' . zbx_dbstr($data['itemid']))); // Merge form submitted data with data existing in DB to find diff and correctly display ListBox. $data['application_prototypes'] = array_unique(zbx_array_merge($data['application_prototypes'], zbx_objectValues($application_prototypes, 'name'))); } } } if (!$data['delay_flex']) { $data['delay_flex'][] = ['delay' => '', 'period' => '', 'type' => ITEM_DELAY_FLEX_TYPE_FLEXIBLE]; } // applications if (count($data['applications']) == 0) { array_push($data['applications'], 0); } $data['db_applications'] = DBfetchArray(DBselect('SELECT DISTINCT a.applicationid,a.name' . ' FROM applications a' . ' WHERE a.hostid=' . zbx_dbstr($data['hostid']) . ($data['parent_discoveryid'] ? ' AND a.flags=' . ZBX_FLAG_DISCOVERY_NORMAL : ''))); order_result($data['db_applications'], 'name'); if ($data['parent_discoveryid'] != 0) { // Make the application prototype list no appearing empty, but filling it with "-None-" as first element. if (count($data['application_prototypes']) == 0) { $data['application_prototypes'][] = 0; } // Get a list of application prototypes by discovery rule. $data['db_application_prototypes'] = DBfetchArray(DBselect('SELECT ap.application_prototypeid,ap.name' . ' FROM application_prototype ap' . ' WHERE ap.itemid=' . zbx_dbstr($data['parent_discoveryid']))); order_result($data['db_application_prototypes'], 'name'); } // interfaces $data['interfaces'] = API::HostInterface()->get(['hostids' => $data['hostid'], 'output' => API_OUTPUT_EXTEND]); // valuemapid if ($data['limited']) { if ($data['valuemapid'] != 0) { $valuemaps = API::ValueMap()->get(['output' => ['name'], 'valuemapids' => [$data['valuemapid']]]); if ($valuemaps) { $data['valuemaps'] = $valuemaps[0]['name']; } } } else { $data['valuemaps'] = API::ValueMap()->get(['output' => ['valemapid', 'name']]); CArrayHelper::sort($data['valuemaps'], ['name']); } // possible host inventories if (empty($data['parent_discoveryid'])) { $data['possibleHostInventories'] = getHostInventories(); // get already populated fields by other items $data['alreadyPopulated'] = API::item()->get(['output' => ['inventory_link'], 'filter' => ['hostid' => $data['hostid']], 'nopermissions' => true]); $data['alreadyPopulated'] = zbx_toHash($data['alreadyPopulated'], 'inventory_link'); } // unset snmpv3 fields if ($data['type'] != ITEM_TYPE_SNMPV3) { $data['snmpv3_contextname'] = ''; $data['snmpv3_securityname'] = ''; $data['snmpv3_securitylevel'] = ITEM_SNMPV3_SECURITYLEVEL_NOAUTHNOPRIV; $data['snmpv3_authprotocol'] = ITEM_AUTHPROTOCOL_MD5; $data['snmpv3_authpassphrase'] = ''; $data['snmpv3_privprotocol'] = ITEM_PRIVPROTOCOL_DES; $data['snmpv3_privpassphrase'] = ''; } // unset ssh auth fields if ($data['type'] != ITEM_TYPE_SSH) { $data['authtype'] = ITEM_AUTHTYPE_PASSWORD; $data['publickey'] = ''; $data['privatekey'] = ''; } return $data; }