Example #1
0
 /**
  * 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);
 }