function add_expression($regexpid, $expression = array()) { $db_fields = array('expression' => null, 'expression_type' => null, 'case_sensitive' => 0, 'exp_delimiter' => ','); if (!check_db_fields($db_fields, $expression)) { error('Incorrect arguments pasted to function [add_expression]'); return false; } $expressionid = get_dbid('expressions', 'expressionid'); $result = DBexecute('INSERT INTO expressions (expressionid,regexpid,expression,expression_type,case_sensitive,exp_delimiter) ' . ' VALUES (' . $expressionid . ',' . $regexpid . ',' . zbx_dbstr($expression['expression']) . ',' . $expression['expression_type'] . ',' . $expression['case_sensitive'] . ',' . zbx_dbstr($expression['exp_delimiter']) . ')'); return $result ? $expressionid : false; }
function add_expression($regexpid, $expression = array()) { $db_fields = array('expression' => null, 'expression_type' => null, 'case_sensitive' => 0, 'exp_delimiter' => ','); if (!check_db_fields($db_fields, $expression)) { error(S_INCORRECT_ARGUMENTS_PASSED_TO_FUNCTION . ' [add_expression]'); return false; } $expressionid = get_dbid('expressions', 'expressionid'); $result = DBexecute('INSERT INTO expressions (expressionid,regexpid,expression,expression_type,case_sensitive,exp_delimiter) ' . ' VALUES (' . $expressionid . ',' . $regexpid . ',' . zbx_dbstr($expression['expression']) . ',' . $expression['expression_type'] . ',' . $expression['case_sensitive'] . ',' . zbx_dbstr($expression['exp_delimiter']) . ')'); return $result ? $expressionid : false; }
/** * Validate trigger prototypes to be created. * * @param array $triggerPrototypes * * @throws APIException if validation failed. */ protected function validateCreate(array $triggerPrototypes) { $triggerDbFields = ['description' => null, 'expression' => null, 'error' => _('Trigger just added. No status update so far.')]; foreach ($triggerPrototypes as $triggerPrototype) { if (!check_db_fields($triggerDbFields, $triggerPrototype)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Wrong fields for trigger.')); } if (array_key_exists('templateid', $triggerPrototype)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Cannot set "templateid" for trigger prototype "%1$s".', $triggerPrototype['description'])); } $this->checkExpression($triggerPrototype); $this->checkIfExistsOnHost($triggerPrototype); } }
/** * Validates the input parameters for the create() method. * * @throws APIException if the input is invalid * * @param array $scripts */ protected function validateCreate(array $scripts) { if (self::$userData['type'] != USER_TYPE_SUPER_ADMIN) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('You do not have permission to perform this operation.')); } $dbFields = array('command' => null, 'name' => null); $names = array(); foreach ($scripts as $script) { if (!check_db_fields($dbFields, $script)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Wrong fields for script.')); } if (zbx_empty($script['name'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Empty name for script.')); } if (isset($names[$script['name']])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Duplicate script name "%1$s".', $script['name'])); } $names[$script['name']] = $script['name']; } $dbScripts = $this->get(array('output' => array('name'), 'filter' => array('name' => $names), 'nopermissions' => true, 'limit' => 1)); if ($dbScript = reset($dbScripts)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Script "%1$s" already exists.', $dbScript['name'])); } }
function update_user($userid, $user) { $result = true; $sql = 'SELECT DISTINCT * ' . ' FROM users ' . ' WHERE ( alias=' . zbx_dbstr($user['alias']) . ' OR userid=' . $userid . ' ) ' . ' AND ' . DBin_node('userid', id2nodeid($userid)); $db_users = DBselect($sql); while ($db_user = DBfetch($db_users)) { if ($db_user['userid'] != $userid) { error('User ' . $user['alias'] . ' already exists'); return false; } $user_db_fields = $db_user; } if (!isset($user_db_fields)) { return false; } if (isset($user['passwd'])) { $user['passwd'] = md5($user['passwd']); } if (!check_db_fields($user_db_fields, $user)) { error('Incorrect arguments pasted to function [update_user]'); return false; } $sql = 'UPDATE users SET ' . ' name=' . zbx_dbstr($user['name']) . ' ,surname=' . zbx_dbstr($user['surname']) . ' ,alias=' . zbx_dbstr($user['alias']) . ' ,passwd=' . zbx_dbstr($user['passwd']) . ' ,url=' . zbx_dbstr($user['url']) . ' ,autologin='******'autologin'] . ' ,autologout=' . $user['autologout'] . ' ,lang=' . zbx_dbstr($user['lang']) . ' ,theme=' . zbx_dbstr($user['theme']) . ' ,refresh=' . $user['refresh'] . ' ,rows_per_page=' . $user['rows_per_page'] . ' ,type=' . $user['type'] . ' WHERE userid=' . $userid; $result = DBexecute($sql); if ($result && !is_null($user['user_groups'])) { $result = DBexecute('DELETE FROM users_groups WHERE userid=' . $userid); foreach ($user['user_groups'] as $groupid => $group_name) { if (!$result) { break; } $users_groups_id = get_dbid('users_groups', 'id'); $result = DBexecute('INSERT INTO users_groups (id, usrgrpid, userid)' . 'values(' . $users_groups_id . ',' . $groupid . ',' . $userid . ')'); } } if ($result && !is_null($user['user_medias'])) { $result = DBexecute('DELETE FROM media WHERE userid=' . $userid); foreach ($user['user_medias'] as $mediaid => $media_data) { if (!$result) { break; } $mediaid = get_dbid('media', 'mediaid'); $result = DBexecute('INSERT INTO media (mediaid, userid, mediatypeid, sendto, active, severity, period)' . ' values (' . $mediaid . ',' . $userid . ',' . $media_data['mediatypeid'] . ',' . zbx_dbstr($media_data['sendto']) . ',' . $media_data['active'] . ',' . $media_data['severity'] . ',' . zbx_dbstr($media_data['period']) . ')'); } } return $result; }
function addRegexpExpressions($regexpId, array $expressions) { $dbFields = array('expression' => null, 'expression_type' => null); foreach ($expressions as &$expression) { if (!check_db_fields($dbFields, $expression)) { throw new Exception(_('Incorrect arguments passed to function') . ' [add_expression]'); } $expression['regexpid'] = $regexpId; } unset($expression); DB::insert('expressions', $expressions); }
/** * Update maintenances. * * @param array $maintenances * * @return boolean */ public function update(array $maintenances) { $maintenances = zbx_toArray($maintenances); $maintenanceids = zbx_objectValues($maintenances, 'maintenanceid'); // validate maintenance permissions if (self::$userData['type'] == USER_TYPE_ZABBIX_USER) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!')); } $updMaintenances = $this->get(['maintenanceids' => zbx_objectValues($maintenances, 'maintenanceid'), 'editable' => true, 'output' => API_OUTPUT_EXTEND, 'selectGroups' => ['groupid'], 'selectHosts' => ['hostid'], 'selectTimeperiods' => API_OUTPUT_EXTEND, 'preservekeys' => true]); $maintenanceNamesChanged = []; foreach ($maintenances as $maintenance) { if (!isset($updMaintenances[$maintenance['maintenanceid']])) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!')); } if (isset($maintenance['name']) && !zbx_empty($maintenance['name']) && $updMaintenances[$maintenance['maintenanceid']]['name'] !== $maintenance['name']) { if (isset($maintenanceNamesChanged[$maintenance['name']])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Maintenance "%1$s" already exists.', $maintenance['name'])); } else { $maintenanceNamesChanged[$maintenance['name']] = $maintenance['name']; } } } // check if maintenance already exists if ($maintenanceNamesChanged) { $dbMaintenances = $this->get(['output' => ['name'], 'filter' => ['name' => $maintenanceNamesChanged], 'nopermissions' => true, 'limit' => 1]); if ($dbMaintenances) { $dbMaintenance = reset($dbMaintenances); self::exception(ZBX_API_ERROR_PARAMETERS, _s('Maintenance "%1$s" already exists.', $dbMaintenance['name'])); } } $hostids = []; $groupids = []; foreach ($maintenances as $maintenance) { // validate maintenance active since if (!validateUnixTime($maintenance['active_since'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('"%s" must be between 1970.01.01 and 2038.01.18.', _('Active since'))); } // validate maintenance active till if (!validateUnixTime($maintenance['active_till'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('"%s" must be between 1970.01.01 and 2038.01.18.', _('Active till'))); } // validate maintenance active interval if ($maintenance['active_since'] > $maintenance['active_till']) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Maintenance "Active since" value cannot be bigger than "Active till".')); } // validate timeperiods if (!array_key_exists('timeperiods', $maintenance) || !is_array($maintenance['timeperiods']) || !$maintenance['timeperiods']) { self::exception(ZBX_API_ERROR_PARAMETERS, _('At least one maintenance period must be created.')); } foreach ($maintenance['timeperiods'] as $timeperiod) { if (!is_array($timeperiod)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('At least one maintenance period must be created.')); } } $hostids = array_merge($hostids, $maintenance['hostids']); $groupids = array_merge($groupids, $maintenance['groupids']); } // validate hosts & groups if (empty($hostids) && empty($groupids)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('At least one host or group should be selected.')); } // validate hosts permissions $options = ['hostids' => $hostids, 'editable' => true, 'output' => ['hostid'], 'preservekeys' => true]; $updHosts = API::Host()->get($options); foreach ($hostids as $hostid) { if (!isset($updHosts[$hostid])) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('You do not have permission to perform this operation.')); } } // validate groups permissions $options = ['groupids' => $groupids, 'editable' => true, 'output' => ['groupid'], 'preservekeys' => true]; $updGroups = API::HostGroup()->get($options); foreach ($groupids as $groupid) { if (!isset($updGroups[$groupid])) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!')); } } $this->removeSecondsFromTimes($maintenances); $update = []; foreach ($maintenances as $mnum => $maintenance) { $dbFields = ['maintenanceid' => null]; // validate fields if (!check_db_fields($dbFields, $maintenance)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect parameters for maintenance.')); } $update[$mnum] = ['values' => $maintenance, 'where' => ['maintenanceid' => $maintenance['maintenanceid']]]; // update time periods $this->replaceTimePeriods($updMaintenances[$maintenance['maintenanceid']], $maintenance); } DB::update('maintenances', $update); // some of the hosts and groups bound to maintenance must be deleted, other inserted and others left alone $insertHosts = []; $insertGroups = []; foreach ($maintenances as $maintenance) { // putting apart those host<->maintenance connections that should be inserted, deleted and not changed // $hostDiff['first'] - new hosts, that should be inserted // $hostDiff['second'] - hosts, that should be deleted // $hostDiff['both'] - hosts, that should not be touched $hostDiff = zbx_array_diff(zbx_toObject($maintenance['hostids'], 'hostid'), $updMaintenances[$maintenance['maintenanceid']]['hosts'], 'hostid'); foreach ($hostDiff['first'] as $host) { $insertHosts[] = ['hostid' => $host['hostid'], 'maintenanceid' => $maintenance['maintenanceid']]; } foreach ($hostDiff['second'] as $host) { $deleteHosts = ['hostid' => $host['hostid'], 'maintenanceid' => $maintenance['maintenanceid']]; DB::delete('maintenances_hosts', $deleteHosts); } // now the same with the groups $groupDiff = zbx_array_diff(zbx_toObject($maintenance['groupids'], 'groupid'), $updMaintenances[$maintenance['maintenanceid']]['groups'], 'groupid'); foreach ($groupDiff['first'] as $group) { $insertGroups[] = ['groupid' => $group['groupid'], 'maintenanceid' => $maintenance['maintenanceid']]; } foreach ($groupDiff['second'] as $group) { $deleteGroups = ['groupid' => $group['groupid'], 'maintenanceid' => $maintenance['maintenanceid']]; DB::delete('maintenances_groups', $deleteGroups); } add_audit_ext(AUDIT_ACTION_UPDATE, AUDIT_RESOURCE_MAINTENANCE, $maintenance['maintenanceid'], array_key_exists('name', $maintenance) ? $maintenance['name'] : $updMaintenances[$maintenance['maintenanceid']]['name'], 'maintenances', $updMaintenances[$maintenance['maintenanceid']], $maintenance); } DB::insert('maintenances_hosts', $insertHosts); DB::insert('maintenances_groups', $insertGroups); return ['maintenanceids' => $maintenanceids]; }
/** * Create web scenario. * * @param $httpTests * * @return array */ public function create($httpTests) { $httpTests = zbx_toArray($httpTests); if (!$httpTests) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Empty input parameters.')); } // find hostid by applicationid foreach ($httpTests as &$httpTest) { unset($httpTest['templateid']); if (empty($httpTest['hostid']) && !empty($httpTest['applicationid'])) { $dbHostId = DBfetch(DBselect('SELECT a.hostid' . ' FROM applications a' . ' WHERE a.applicationid=' . zbx_dbstr($httpTest['applicationid']))); $httpTest['hostid'] = $dbHostId['hostid']; } } unset($httpTest); foreach ($httpTests as &$httpTest) { $defaultValues = array('verify_peer' => HTTPTEST_VERIFY_PEER_OFF, 'verify_host' => HTTPTEST_VERIFY_HOST_OFF); check_db_fields($defaultValues, $httpTest); } unset($httpTest); $this->validateCreate($httpTests); $httpTests = Manager::HttpTest()->persist($httpTests); return array('httptestids' => zbx_objectValues($httpTests, 'httptestid')); }
/** * Update IconMap. * @param array $iconMaps * @return array */ public function update(array $iconMaps) { if (USER_TYPE_SUPER_ADMIN != self::$userData['type']) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('Only Super Admins can update icon maps.')); } $iconMaps = zbx_toArray($iconMaps); $iconMapids = zbx_objectValues($iconMaps, 'iconmapid'); $updates = array(); $duplicates = array(); foreach ($iconMaps as $iconMap) { if (!check_db_fields(array('iconmapid' => null), $iconMap)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect parameters for icon map update method "%s".', $iconMap['name'])); } if (isset($iconMap['name'])) { if (zbx_empty($iconMap['name'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Icon map name cannot be empty.')); } elseif (isset($duplicates[$iconMap['name']])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Cannot create icon maps with identical name "%s".', $iconMap['name'])); } else { $duplicates[$iconMap['name']] = $iconMap['name']; } } } $this->validateMappings($iconMaps, false); $iconMapsUpd = API::IconMap()->get(array('iconmapids' => $iconMapids, 'output' => API_OUTPUT_EXTEND, 'preservekeys' => true, 'selectMappings' => API_OUTPUT_EXTEND)); $mappingsCreate = $mappingsUpdate = $mappingidsDelete = array(); foreach ($iconMaps as $iconMap) { if (!isset($iconMapsUpd[$iconMap['iconmapid']])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Icon map with iconmapid "%s" does not exist.', $iconMap['iconmapid'])); } // Existence if (isset($iconMap['name'])) { $iconMapExists = $this->get(array('filter' => array('name' => $iconMap['name']), 'output' => API_OUTPUT_SHORTEN, 'editable' => true, 'nopermissions' => true, 'preservekeys' => true)); if (($iconMapExists = reset($iconMapExists)) && bccomp($iconMapExists['iconmapid'], $iconMap['iconmapid']) != 0) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Icon map "%s" already exists.', $iconMap['name'])); } } if (isset($iconMap['mappings'])) { $mappingsDb = $iconMapsUpd[$iconMap['iconmapid']]['mappings']; foreach ($iconMap['mappings'] as $mapping) { $mapping['iconmapid'] = $iconMap['iconmapid']; if (isset($mapping['iconmappingid']) && isset($mappingsDb[$mapping['iconmappingid']])) { $iconmappingid = $mapping['iconmappingid']; unset($mapping['iconmappingid']); $mappingsUpdate[] = array('values' => $mapping, 'where' => array('iconmappingid' => $iconmappingid)); unset($mappingsDb[$iconmappingid]); } else { $mappingsCreate[] = $mapping; } } $mappingidsDelete = array_merge($mappingidsDelete, array_keys($mappingsDb)); } $iconMapid = $iconMap['iconmapid']; unset($iconMap['iconmapid']); if (!empty($iconMap)) { $updates[] = array('values' => $iconMap, 'where' => array('iconmapid' => $iconMapid)); } } DB::update('icon_map', $updates); DB::insert('icon_mapping', $mappingsCreate); DB::update('icon_mapping', $mappingsUpdate); if (!empty($mappingidsDelete)) { DB::delete('icon_mapping', array('iconmappingid' => $mappingidsDelete)); } return array('iconmapids' => $iconMapids); }
protected function checkInput(&$hosts, $method) { $create = $method == 'create'; $update = $method == 'update'; $delete = $method == 'delete'; // permissions $groupids = array(); foreach ($hosts as $host) { if (!isset($host['groups'])) { continue; } $groupids = array_merge($groupids, zbx_objectValues($host['groups'], 'groupid')); } if ($update || $delete) { $hostDBfields = array('hostid' => null); $dbHosts = $this->get(array('output' => array('hostid', 'host'), 'hostids' => zbx_objectValues($hosts, 'hostid'), 'editable' => true, 'preservekeys' => true)); } else { $hostDBfields = array('host' => null); } if (!empty($groupids)) { $dbGroups = API::HostGroup()->get(array('output' => API_OUTPUT_EXTEND, 'groupids' => $groupids, 'editable' => true, 'preservekeys' => true)); } $inventoryFields = getHostInventories(); $inventoryFields = zbx_objectValues($inventoryFields, 'db_field'); $hostNames = array(); foreach ($hosts as &$host) { if (!check_db_fields($hostDBfields, $host)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Wrong fields for host "%s".', isset($host['host']) ? $host['host'] : '')); } if (isset($host['inventory']) && !empty($host['inventory'])) { $fields = array_keys($host['inventory']); foreach ($fields as $field) { if (!in_array($field, $inventoryFields)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect inventory field "%s".', $field)); } } } if ($update || $delete) { if (!isset($dbHosts[$host['hostid']])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('No permissions to referred object or it does not exist!')); } if ($delete) { $host['host'] = $dbHosts[$host['hostid']]['host']; } } else { // if visible name is not given or empty it should be set to host name if (!isset($host['name']) || zbx_empty(trim($host['name']))) { $host['name'] = $host['host']; } if (!isset($host['groups'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('No groups for host "%s".', $host['host'])); } if (!isset($host['interfaces'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('No interfaces for host "%s".', $host['host'])); } } if ($delete) { continue; } if (isset($host['groups'])) { if (!is_array($host['groups']) || empty($host['groups'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('No groups for host "%s".', $host['host'])); } foreach ($host['groups'] as $group) { if (!isset($dbGroups[$group['groupid']])) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!')); } } } if (isset($host['interfaces'])) { if (!is_array($host['interfaces']) || empty($host['interfaces'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('No interfaces for host "%s".', $host['host'])); } } if (isset($host['host'])) { // Check if host name isn't longer than 64 chars if (zbx_strlen($host['host']) > 64) { self::exception(ZBX_API_ERROR_PARAMETERS, _n('Maximum host name length is %2$d characters, "%3$s" is %1$d character.', 'Maximum host name length is %2$d characters, "%3$s" is %1$d characters.', zbx_strlen($host['host']), 64, $host['host'])); } if (!preg_match('/^' . ZBX_PREG_HOST_FORMAT . '$/', $host['host'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect characters used for host name "%s".', $host['host'])); } if (isset($hostNames['host'][$host['host']])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Duplicate host. Host with the same host name "%s" already exists in data.', $host['host'])); } $hostNames['host'][$host['host']] = $update ? $host['hostid'] : 1; } if (isset($host['name'])) { if ($update) { // if visible name is empty replace it with host name if (zbx_empty(trim($host['name']))) { if (!isset($host['host'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Visible name cannot be empty if host name is missing.')); } $host['name'] = $host['host']; } } // Check if visible name isn't longer than 64 chars if (zbx_strlen($host['name']) > 64) { self::exception(ZBX_API_ERROR_PARAMETERS, _n('Maximum visible host name length is %2$d characters, "%3$s" is %1$d character.', 'Maximum visible host name length is %2$d characters, "%3$s" is %1$d characters.', zbx_strlen($host['name']), 64, $host['name'])); } if (isset($hostNames['name'][$host['name']])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Duplicate host. Host with the same visible name "%s" already exists in data.', $host['name'])); } $hostNames['name'][$host['name']] = $update ? $host['hostid'] : 1; } } unset($host); if ($update || $create) { if (isset($hostNames['host']) || isset($hostNames['name'])) { $filter = array(); if (isset($hostNames['host'])) { $filter['host'] = array_keys($hostNames['host']); } if (isset($hostNames['name'])) { $filter['name'] = array_keys($hostNames['name']); } $options = array('output' => array('hostid', 'host', 'name'), 'filter' => $filter, 'searchByAny' => true, 'nopermissions' => true, 'preservekeys' => true); $hostsExists = $this->get($options); foreach ($hostsExists as $hostExists) { if (isset($hostNames['host'][$hostExists['host']])) { if (!$update || bccomp($hostExists['hostid'], $hostNames['host'][$hostExists['host']]) != 0) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Host with the same name "%s" already exists.', $hostExists['host'])); } } if (isset($hostNames['name'][$hostExists['name']])) { if (!$update || bccomp($hostExists['hostid'], $hostNames['name'][$hostExists['name']]) != 0) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Host with the same visible name "%s" already exists.', $hostExists['name'])); } } } $templatesExists = API::Template()->get($options); foreach ($templatesExists as $templateExists) { if (isset($hostNames['host'][$templateExists['host']])) { if (!$update || bccomp($templateExists['templateid'], $hostNames['host'][$templateExists['host']]) != 0) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Template with the same name "%s" already exists.', $templateExists['host'])); } } if (isset($hostNames['name'][$templateExists['name']])) { if (!$update || bccomp($templateExists['templateid'], $hostNames['name'][$templateExists['name']]) != 0) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Template with the same visible name "%s" already exists.', $templateExists['name'])); } } } } } return $update ? $dbHosts : $hosts; }
/** * 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); }
/** * Validate web scenario parameters for update method. * - check permissions * - check if web scenario with same name already exists * - check that each web scenario object has httptestid defined * * @param array $httpTests */ protected function validateUpdate(array $httpTests, array $dbHttpTests) { $httpTestIds = zbx_objectValues($httpTests, 'httptestid'); if (!$this->isWritable($httpTestIds)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('You do not have permission to perform this operation.')); } $this->checkNames($httpTests); foreach ($httpTests as $httpTest) { $missingKeys = checkRequiredKeys($httpTest, array('httptestid')); if (!empty($missingKeys)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Web scenario missing parameters: %1$s', implode(', ', $missingKeys))); } if (isset($httpTest['name'])) { // get hostid from db if it's not provided if (isset($httpTest['hostid'])) { $hostId = $httpTest['hostid']; } else { $hostId = DBfetch(DBselect('SELECT ht.hostid FROM httptest ht' . ' WHERE ht.httptestid=' . zbx_dbstr($httpTest['httptestid']))); $hostId = $hostId['hostid']; } $nameExists = DBfetch(DBselect('SELECT ht.name FROM httptest ht' . ' WHERE ht.name=' . zbx_dbstr($httpTest['name']) . ' AND ht.hostid=' . zbx_dbstr($hostId) . ' AND ht.httptestid<>' . zbx_dbstr($httpTest['httptestid']), 1)); if ($nameExists) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Web scenario "%1$s" already exists.', $nameExists['name'])); } } if (!check_db_fields(array('httptestid' => null), $httpTest)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function.')); } if (array_key_exists('steps', $httpTest)) { $dbHttpTest = isset($httpTest['httptestid']) ? $dbHttpTests[$httpTest['httptestid']] : null; $this->checkSteps($httpTest, $dbHttpTest); $this->checkDuplicateSteps($httpTest); } } $this->checkApplicationHost($httpTests); }
/** * Add items to graph * * <code> * $items = array( * *string 'graphid' => null, * array 'items' => ( * 'item1' => array( * *int 'itemid' => null, * int 'color' => '000000', * int 'drawtype' => 0, * int 'sortorder' => 0, * int 'yaxisside' => 1, * int 'calc_fnc' => 2, * int 'type' => 0, * int 'periods_cnt' => 5, * ), ... ) * ); * </code> * * @static * @param array $items multidimensional array with items data * @return boolean */ public static function addItems($items) { $error = 'Unknown ZABBIX internal error'; $result_ids = array(); $result = false; $tpl_graph = false; $graphid = $items['graphid']; $items_tmp = $items['items']; $items = array(); $itemids = array(); foreach ($items_tmp as $item) { $graph_db_fields = array('itemid' => null, 'color' => '000000', 'drawtype' => 0, 'sortorder' => 0, 'yaxisside' => 1, 'calc_fnc' => 2, 'type' => 0, 'periods_cnt' => 5); if (!check_db_fields($graph_db_fields, $item)) { self::$error = array('error' => ZBX_API_ERROR_INTERNAL, 'data' => 'Wrong fields for item [ ' . $item['itemid'] . ' ]'); return false; } $items[$item['itemid']] = $item; $itemids[$item['itemid']] = $item['itemid']; } // check if graph is templated graph, then items cannot be added $graph = CGraph::getById(array('graphid' => $graphid)); if ($graph['templateid'] != 0) { self::$error = array('error' => ZBX_API_ERROR_INTERNAL, 'data' => 'Cannot edit templated graph : ' . $graph['name']); return false; } // check if graph belongs to template, if so, only items from same template can be added $tmp_hosts = get_hosts_by_graphid($graphid); $host = DBfetch($tmp_hosts); // if graph belongs to template, only one host is possible if ($host["status"] == HOST_STATUS_TEMPLATE) { $sql = 'SELECT DISTINCT count(i.hostid) as count FROM items i WHERE i.hostid<>' . $host['hostid'] . ' AND ' . DBcondition('i.itemid', $itemids); $host_count = DBfetch(DBselect($sql)); if ($host_count['count']) { self::$error = array('error' => ZBX_API_ERROR_INTERNAL, 'data' => 'You must use items only from host : ' . $host['host'] . ' for template graph : ' . $graph['name']); return false; } $tpl_graph = true; } DBstart(false); $result = self::addItems_rec($graphid, $items, $tpl_graph); $result = DBend($result); if ($result) { return $result; } else { self::$error = array('error' => ZBX_API_ERROR_INTERNAL, 'data' => $error); //'Internal zabbix error'); return false; } }
/** * Update UserGroups. * Checks permissions - only super admins can update usergroups. * Formats data to be used in massUpdate() method. * * @param array $usrgrps * * @return int[] array['usrgrpids'] returns passed group ids */ public function update($usrgrps) { if (USER_TYPE_SUPER_ADMIN != self::$userData['type']) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('Only Super Admins can update user groups.')); } $usrgrps = zbx_toArray($usrgrps); foreach ($usrgrps as $usrgrp) { // checks if usergroup id is present $groupDbFields = array('usrgrpid' => null); if (!check_db_fields($groupDbFields, $usrgrp)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect parameters for user group.')); } $usrgrp['usrgrpids'] = $usrgrp['usrgrpid']; unset($usrgrp['usrgrpid']); if (!$this->massUpdate($usrgrp)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Cannot update group.')); } } return array('usrgrpids' => zbx_objectValues($usrgrps, 'usrgrpid')); }
/** * Add Template * * @param array $templates multidimensional array with templates data * @param string $templates['host'] * @return boolean */ public function create($templates) { $templates = zbx_toArray($templates); $templateids = array(); // CHECK IF HOSTS HAVE AT LEAST 1 GROUP {{{ foreach ($templates as $tnum => $template) { if (empty($template['groups'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('No groups for template [ %s ]', $template['host'])); } $templates[$tnum]['groups'] = zbx_toArray($templates[$tnum]['groups']); foreach ($templates[$tnum]['groups'] as $gnum => $group) { $groupids[$group['groupid']] = $group['groupid']; } } // }}} CHECK IF HOSTS HAVE AT LEAST 1 GROUP // PERMISSIONS {{{ $options = array('groupids' => $groupids, 'editable' => 1, 'preservekeys' => 1); $updGroups = API::HostGroup()->get($options); foreach ($groupids as $gnum => $groupid) { if (!isset($updGroups[$groupid])) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('You do not have permission to perform this operation.')); } } // }}} PERMISSIONS foreach ($templates as $tnum => $template) { // If visible name is not given or empty it should be set to host name if (!isset($template['name']) || isset($template['name']) && zbx_empty(trim($template['name']))) { if (isset($template['host'])) { $template['name'] = $template['host']; } } $templateDbFields = array('host' => null); if (!check_db_fields($templateDbFields, $template)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Field "host" is mandatory')); } if (!preg_match('/^' . ZBX_PREG_HOST_FORMAT . '$/', $template['host'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect characters used for Template name [ %1$s ]', $template['host'])); } if (isset($template['host'])) { if ($this->exists(array('host' => $template['host']))) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Template "%s" already exists.', $template['host'])); } if (API::Host()->exists(array('host' => $template['host']))) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Host "%s" already exists.', $template['host'])); } } if (isset($template['name'])) { if ($this->exists(array('name' => $template['name']))) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Template with the same visible name "%s" already exists.', $template['name'])); } if (API::Host()->exists(array('name' => $template['name']))) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Host with the same visible name "%s" already exists.', $template['name'])); } } $templateid = DB::insert('hosts', array(array('host' => $template['host'], 'name' => $template['name'], 'status' => HOST_STATUS_TEMPLATE))); $templateids[] = $templateid = reset($templateid); foreach ($template['groups'] as $group) { $hostgroupid = get_dbid('hosts_groups', 'hostgroupid'); $result = DBexecute('INSERT INTO hosts_groups (hostgroupid,hostid,groupid) VALUES (' . zbx_dbstr($hostgroupid) . ',' . zbx_dbstr($templateid) . ',' . zbx_dbstr($group['groupid']) . ')'); if (!$result) { self::exception(ZBX_API_ERROR_PARAMETERS, 'DBerror'); } } $template['templateid'] = $templateid; $options = array(); $options['templates'] = $template; if (isset($template['templates']) && !is_null($template['templates'])) { $options['templates_link'] = $template['templates']; } if (isset($template['macros']) && !is_null($template['macros'])) { $options['macros'] = $template['macros']; } if (isset($template['hosts']) && !is_null($template['hosts'])) { $options['hosts'] = $template['hosts']; } $result = $this->massAdd($options); if (!$result) { self::exception(ZBX_API_ERROR_PARAMETERS); } } return array('templateids' => $templateids); }
/** * 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); }
/** * Validates the input parameters for the update() method. * * @param array $hosts hosts data array * @param array $db_hosts db hosts data array * * @throws APIException if the input is invalid. */ protected function validateUpdate(array $hosts, array $db_hosts) { $host_db_fields = ['hostid' => null]; $hosts_full = []; foreach ($hosts as $host) { // Validate mandatory fields. if (!check_db_fields($host_db_fields, $host)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Wrong fields for host "%1$s".', array_key_exists('host', $host) ? $host['host'] : '')); } // Validate host permissions. if (!array_key_exists($host['hostid'], $db_hosts)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('No permissions to referred object or it does not exist!')); } // Validate "groups" field. if (array_key_exists('groups', $host) && (!is_array($host['groups']) || !$host['groups'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('No groups for host "%1$s".', $db_hosts[$host['hostid']]['host'])); } // Permissions to host groups is validated in massUpdate(). } $inventory_fields = zbx_objectValues(getHostInventories(), 'db_field'); $status_validator = new CLimitedSetValidator(['values' => [HOST_STATUS_MONITORED, HOST_STATUS_NOT_MONITORED], 'messageInvalid' => _('Incorrect status for host "%1$s".')]); $update_discovered_validator = new CUpdateDiscoveredValidator(['allowed' => ['hostid', 'status', 'inventory', 'description'], 'messageAllowedField' => _('Cannot update "%2$s" for a discovered host "%1$s".')]); $host_names = []; foreach ($hosts as &$host) { $db_host = $db_hosts[$host['hostid']]; $host_name = array_key_exists('host', $host) ? $host['host'] : $db_host['host']; if (array_key_exists('status', $host)) { $status_validator->setObjectName($host_name); $this->checkValidator($host['status'], $status_validator); } if (array_key_exists('inventory', $host) && $host['inventory']) { if (array_key_exists('inventory_mode', $host) && $host['inventory_mode'] == HOST_INVENTORY_DISABLED) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Cannot set inventory fields for disabled inventory.')); } $fields = array_keys($host['inventory']); foreach ($fields as $field) { if (!in_array($field, $inventory_fields)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect inventory field "%s".', $field)); } } } // cannot update certain fields for discovered hosts $update_discovered_validator->setObjectName($host_name); $this->checkPartialValidator($host, $update_discovered_validator, $db_host); if (array_key_exists('interfaces', $host)) { if (!is_array($host['interfaces']) || !$host['interfaces']) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('No interfaces for host "%s".', $host['host'])); } } if (array_key_exists('host', $host)) { if (!preg_match('/^' . ZBX_PREG_HOST_FORMAT . '$/', $host['host'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect characters used for host name "%s".', $host['host'])); } if (array_key_exists('host', $host_names) && array_key_exists($host['host'], $host_names['host'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Duplicate host. Host with the same host name "%s" already exists in data.', $host['host'])); } $host_names['host'][$host['host']] = $host['hostid']; } if (array_key_exists('name', $host)) { // if visible name is empty replace it with host name if (zbx_empty(trim($host['name']))) { if (!array_key_exists('host', $host)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Visible name cannot be empty if host name is missing.')); } $host['name'] = $host['host']; } if (array_key_exists('name', $host_names) && array_key_exists($host['name'], $host_names['name'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Duplicate host. Host with the same visible name "%s" already exists in data.', $host['name'])); } $host_names['name'][$host['name']] = $host['hostid']; } $hosts_full[] = zbx_array_merge($db_host, $host); } unset($host); if (array_key_exists('host', $host_names) || array_key_exists('name', $host_names)) { $filter = []; if (array_key_exists('host', $host_names)) { $filter['host'] = array_keys($host_names['host']); } if (array_key_exists('name', $host_names)) { $filter['name'] = array_keys($host_names['name']); } $hosts_exists = $this->get(['output' => ['hostid', 'host', 'name'], 'filter' => $filter, 'searchByAny' => true, 'nopermissions' => true, 'preservekeys' => true]); foreach ($hosts_exists as $host_exists) { if (array_key_exists('host', $host_names) && array_key_exists($host_exists['host'], $host_names['host']) && bccomp($host_exists['hostid'], $host_names['host'][$host_exists['host']]) != 0) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Host with the same name "%s" already exists.', $host_exists['host'])); } if (array_key_exists('name', $host_names) && array_key_exists($host_exists['name'], $host_names['name']) && bccomp($host_exists['hostid'], $host_names['name'][$host_exists['name']]) != 0) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Host with the same visible name "%s" already exists.', $host_exists['name'])); } } $templates_exists = API::Template()->get(['output' => ['hostid', 'host', 'name'], 'filter' => $filter, 'searchByAny' => true, 'nopermissions' => true, 'preservekeys' => true]); foreach ($templates_exists as $template_exists) { if (array_key_exists('host', $host_names) && array_key_exists($template_exists['host'], $host_names['host']) && bccomp($template_exists['templateid'], $host_names['host'][$template_exists['host']]) != 0) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Template with the same name "%s" already exists.', $template_exists['host'])); } if (array_key_exists('name', $host_names) && array_key_exists($template_exists['name'], $host_names['name']) && bccomp($template_exists['templateid'], $host_names['name'][$template_exists['name']]) != 0) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Template with the same visible name "%s" already exists.', $template_exists['name'])); } } } $this->validateEncryption($hosts_full); }
/** * Delete Host * * @param string|array $hostIds * @param bool $nopermissions * * @return array|boolean */ public function delete($hostIds, $nopermissions = false) { $hostIds = zbx_toArray($hostIds); // deprecated input support if ($hostIds && is_array($hostIds[0])) { $this->deprecated('Passing objects is deprecated, use an array of IDs instead.'); foreach ($hostIds as $host) { if (!check_db_fields(array('hostid' => null), $host)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('No host ID given.')); } } $hostIds = zbx_objectValues($hostIds, 'hostid'); } $this->validateDelete($hostIds, $nopermissions); // delete the discovery rules first $delRules = API::DiscoveryRule()->get(array('hostids' => $hostIds, 'nopermissions' => true, 'preservekeys' => true)); if ($delRules) { API::DiscoveryRule()->delete(array_keys($delRules), true); } // delete the items $delItems = API::Item()->get(array('templateids' => $hostIds, 'output' => array('itemid'), 'nopermissions' => true, 'preservekeys' => true)); if ($delItems) { API::Item()->delete(array_keys($delItems), true); } // delete web tests $delHttptests = array(); $dbHttptests = get_httptests_by_hostid($hostIds); while ($dbHttptest = DBfetch($dbHttptests)) { $delHttptests[$dbHttptest['httptestid']] = $dbHttptest['httptestid']; } if (!empty($delHttptests)) { API::HttpTest()->delete($delHttptests, true); } // delete screen items DB::delete('screens_items', array('resourceid' => $hostIds, 'resourcetype' => SCREEN_RESOURCE_HOST_TRIGGERS)); // delete host from maps if (!empty($hostIds)) { DB::delete('sysmaps_elements', array('elementtype' => SYSMAP_ELEMENT_TYPE_HOST, 'elementid' => $hostIds)); } // disable actions // actions from conditions $actionids = array(); $sql = 'SELECT DISTINCT actionid' . ' FROM conditions' . ' WHERE conditiontype=' . CONDITION_TYPE_HOST . ' AND ' . dbConditionString('value', $hostIds); $dbActions = DBselect($sql); while ($dbAction = DBfetch($dbActions)) { $actionids[$dbAction['actionid']] = $dbAction['actionid']; } // actions from operations $sql = 'SELECT DISTINCT o.actionid' . ' FROM operations o, opcommand_hst oh' . ' WHERE o.operationid=oh.operationid' . ' AND ' . dbConditionInt('oh.hostid', $hostIds); $dbActions = DBselect($sql); while ($dbAction = DBfetch($dbActions)) { $actionids[$dbAction['actionid']] = $dbAction['actionid']; } if (!empty($actionids)) { $update = array(); $update[] = array('values' => array('status' => ACTION_STATUS_DISABLED), 'where' => array('actionid' => $actionids)); DB::update('actions', $update); } // delete action conditions DB::delete('conditions', array('conditiontype' => CONDITION_TYPE_HOST, 'value' => $hostIds)); // delete action operation commands $operationids = array(); $sql = 'SELECT DISTINCT oh.operationid' . ' FROM opcommand_hst oh' . ' WHERE ' . dbConditionInt('oh.hostid', $hostIds); $dbOperations = DBselect($sql); while ($dbOperation = DBfetch($dbOperations)) { $operationids[$dbOperation['operationid']] = $dbOperation['operationid']; } DB::delete('opcommand_hst', array('hostid' => $hostIds)); // delete empty operations $delOperationids = array(); $sql = 'SELECT DISTINCT o.operationid' . ' FROM operations o' . ' WHERE ' . dbConditionInt('o.operationid', $operationids) . ' AND NOT EXISTS(SELECT oh.opcommand_hstid FROM opcommand_hst oh WHERE oh.operationid=o.operationid)'; $dbOperations = DBselect($sql); while ($dbOperation = DBfetch($dbOperations)) { $delOperationids[$dbOperation['operationid']] = $dbOperation['operationid']; } DB::delete('operations', array('operationid' => $delOperationids)); $hosts = API::Host()->get(array('output' => array('hostid', 'name'), 'hostids' => $hostIds, 'nopermissions' => true)); // delete host inventory DB::delete('host_inventory', array('hostid' => $hostIds)); // delete host applications DB::delete('applications', array('hostid' => $hostIds)); // delete host DB::delete('hosts', array('hostid' => $hostIds)); // TODO: remove info from API foreach ($hosts as $host) { info(_s('Deleted: Host "%1$s".', $host['name'])); add_audit_ext(AUDIT_ACTION_DELETE, AUDIT_RESOURCE_HOST, $host['hostid'], $host['name'], 'hosts', NULL, NULL); } // remove Monitoring > Latest data toggle profile values related to given hosts CProfile::delete('web.latest.toggle_other', $hostIds); return array('hostids' => $hostIds); }
/** * Delete proxy. * * @param string|array $proxyIds * * @return array */ public function delete($proxyIds) { $proxyIds = zbx_toArray($proxyIds); // deprecated input support if ($proxyIds && is_array($proxyIds[0])) { $this->deprecated('Passing objects is deprecated, use an array of IDs instead.'); foreach ($proxyIds as $proxyId) { if (!check_db_fields(array('proxyid' => null), $proxyId)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('No proxy ID given.')); } } $proxyIds = zbx_objectValues($proxyIds, 'proxyid'); } $this->validateDelete($proxyIds); $dbProxies = DBselect('SELECT h.hostid,h.host' . ' FROM hosts h' . ' WHERE ' . dbConditionInt('h.hostid', $proxyIds)); $dbProxies = DBfetchArrayAssoc($dbProxies, 'hostid'); $actionIds = array(); // get conditions $dbActions = DBselect('SELECT DISTINCT c.actionid' . ' FROM conditions c' . ' WHERE c.conditiontype=' . CONDITION_TYPE_PROXY . ' AND ' . dbConditionString('c.value', $proxyIds)); while ($dbAction = DBfetch($dbActions)) { $actionIds[$dbAction['actionid']] = $dbAction['actionid']; } if ($actionIds) { DB::update('actions', array('values' => array('status' => ACTION_STATUS_DISABLED), 'where' => array('actionid' => $actionIds))); } // delete action conditions DB::delete('conditions', array('conditiontype' => CONDITION_TYPE_PROXY, 'value' => $proxyIds)); // delete interface DB::delete('interface', array('hostid' => $proxyIds)); // delete host DB::delete('hosts', array('hostid' => $proxyIds)); // TODO: remove info from API foreach ($dbProxies as $proxy) { info(_s('Deleted: Proxy "%1$s".', $proxy['host'])); add_audit(AUDIT_ACTION_DELETE, AUDIT_RESOURCE_PROXY, '[' . $proxy['host'] . '] [' . $proxy['hostid'] . ']'); } return array('proxyids' => $proxyIds); }
/** * Validate web scenario parameters for update method. * - check permissions * - check if web scenario with same name already exists * - check that each web scenario object has httptestid defined * * @param array $httpTests */ protected function validateUpdate(array $httpTests) { $httpTestIds = zbx_objectValues($httpTests, 'httptestid'); if (!$this->isWritable($httpTestIds)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('You do not have permission to perform this operation.')); } $httpTestsNames = $this->checkNames($httpTests); $nameExists = DBfetch(DBselect('SELECT ht.name FROM httptest ht WHERE ' . dbConditionString('ht.name', $httpTestsNames) . ' AND ' . dbConditionInt('ht.httptestid', $httpTestIds, true), 1)); if ($nameExists) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Scenario "%s" already exists.', $nameExists['name'])); } foreach ($httpTests as $httpTest) { if (!check_db_fields(array('httptestid' => null), $httpTest)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function.')); } if (isset($httpTest['steps'])) { $this->checkSteps($httpTest['steps']); } } }
public function checkInput(&$applications, $method) { $create = $method == 'create'; $update = $method == 'update'; $delete = $method == 'delete'; // permissions if ($update || $delete) { $itemDbFields = array('applicationid' => null); $dbApplications = $this->get(array('output' => API_OUTPUT_EXTEND, 'applicationids' => zbx_objectValues($applications, 'applicationid'), 'editable' => 1, 'preservekeys' => 1)); } else { $itemDbFields = array('name' => null, 'hostid' => null); $dbHosts = API::Host()->get(array('output' => array('hostid', 'host', 'status'), 'hostids' => zbx_objectValues($applications, 'hostid'), 'templated_hosts' => 1, 'editable' => 1, 'preservekeys' => 1)); } if ($update) { $applications = $this->extendObjects($this->tableName(), $applications, array('name')); } foreach ($applications as &$application) { if (!check_db_fields($itemDbFields, $application)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function')); } // check permissions by hostid if ($create) { if (!isset($dbHosts[$application['hostid']])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('No permissions to referred object or it does not exist!')); } } // check permissions by applicationid if ($delete || $update) { if (!isset($dbApplications[$application['applicationid']])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('No permissions to referred object or it does not exist!')); } } // check for "templateid", because it is not allowed if (array_key_exists('templateid', $application)) { if ($update) { $error = _s('Cannot update "templateid" for application "%1$s".', $application['name']); } else { $error = _s('Cannot set "templateid" for application "%1$s".', $application['name']); } self::exception(ZBX_API_ERROR_PARAMETERS, $error); } // check on operating with templated applications if ($delete || $update) { if ($dbApplications[$application['applicationid']]['templateid'] != 0) { self::exception(ZBX_API_ERROR_PARAMETERS, 'Cannot interact templated applications'); } } if ($update) { if (!isset($application['hostid'])) { $application['hostid'] = $dbApplications[$application['applicationid']]['hostid']; } } // check existence if ($update || $create) { $applicationsExists = $this->get(array('output' => API_OUTPUT_EXTEND, 'filter' => array('hostid' => $application['hostid'], 'name' => $application['name']), 'nopermissions' => 1)); foreach ($applicationsExists as $applicationExists) { if (!$update || bccomp($applicationExists['applicationid'], $application['applicationid']) != 0) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Application "%1$s" already exists.', $application['name'])); } } } } unset($application); }
/** * Update screen items using the given 'x' and 'y' parameters. * If the given cell is free, a new screen item will be created. * * @param array $screenItems An array of screen items with the given X and Y coordinates * * @return array */ public function updateByPosition(array $screenItems) { $screenItemDBfields = array('screenid' => null, 'x' => null, 'y' => null); foreach ($screenItems as $screenItem) { if (!check_db_fields($screenItemDBfields, $screenItem)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Invalid method parameters.')); } } $dbScreenItems = $this->get(array('screenids' => zbx_objectValues($screenItems, 'screenid'), 'output' => array('screenitemid', 'screenid', 'x', 'y'), 'editable' => true, 'preservekeys' => true)); $create = $update = $affectedIds = array(); foreach ($screenItems as $screenItem) { foreach ($dbScreenItems as $dbScreenItem) { if ($screenItem['screenid'] == $dbScreenItem['screenid'] && $screenItem['x'] == $dbScreenItem['x'] && $screenItem['y'] == $dbScreenItem['y']) { $screenItem['screenitemid'] = $dbScreenItem['screenitemid']; $update[$dbScreenItem['screenitemid']] = $screenItem; continue 2; } } $create[] = $screenItem; } if ($update) { $screenItems = API::ScreenItem()->update($update); $affectedIds = $screenItems['screenitemids']; } if ($create) { $screenItems = API::ScreenItem()->create($create); $affectedIds = array_merge($affectedIds, $screenItems['screenitemids']); } return array('screenitemids' => $affectedIds); }
/** * Check graph data * * @param array $graphs * @param boolean $update * * @return void */ protected function checkInput($graphs, $update = false) { $itemids = array(); foreach ($graphs as $graph) { // no items if (!isset($graph['gitems']) || !is_array($graph['gitems']) || empty($graph['gitems'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Missing items for graph "%1$s".', $graph['name'])); } $fields = array('itemid' => null); foreach ($graph['gitems'] as $gitem) { if (!check_db_fields($fields, $gitem)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Missing "itemid" field for item.')); } // assigning with key preserves unique itemids $itemids[$gitem['itemid']] = $gitem['itemid']; } } $allowedItems = API::Item()->get(array('nodeids' => get_current_nodeid(true), 'itemids' => $itemids, 'webitems' => true, 'editable' => true, 'output' => array('flags'), 'selectItemDiscovery' => array('parent_itemid'), 'preservekeys' => true, 'filter' => array('flags' => array(ZBX_FLAG_DISCOVERY_NORMAL, ZBX_FLAG_DISCOVERY_CHILD, ZBX_FLAG_DISCOVERY_CREATED)))); foreach ($itemids as $itemid) { if (!isset($allowedItems[$itemid])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('No permissions to referred object or it does not exist!')); } } parent::checkInput($graphs, $update); $this->checkDiscoveryRuleCount($graphs, $allowedItems); }
/** * Create triggers. * * @param array $triggers * @param string $triggers['expression'] * @param string $triggers['description'] * @param int $triggers['type'] * @param int $triggers['priority'] * @param int $triggers['status'] * @param string $triggers['comments'] * @param string $triggers['url'] * @param string $triggers['flags'] * @param int $triggers['templateid'] * * @return boolean */ public function create(array $triggers) { $triggers = zbx_toArray($triggers); $triggerIds = array(); foreach ($triggers as $trigger) { $triggerDbFields = array('description' => null, 'expression' => null, 'error' => _('Trigger just added. No status update so far.')); if (!check_db_fields($triggerDbFields, $trigger)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Wrong fields for trigger.')); } // check for "templateid", because it is not allowed if (array_key_exists('templateid', $trigger)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Cannot set "templateid" for trigger prototype "%1$s".', $trigger['description'])); } $triggerExpression = new CTriggerExpression(); if (!$triggerExpression->parse($trigger['expression'])) { self::exception(ZBX_API_ERROR_PARAMETERS, $triggerExpression->error); } $this->checkIfExistsOnHost($trigger); // check item prototypes $items = getExpressionItems($triggerExpression); $hasPrototype = false; foreach ($items as $item) { if ($item['flags'] == ZBX_FLAG_DISCOVERY_PROTOTYPE) { $hasPrototype = true; break; } } if (!$hasPrototype) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Trigger prototype expression "%1$s" must contain at least one item prototype.', $trigger['expression'])); } } $this->createReal($triggers); foreach ($triggers as $trigger) { $this->inherit($trigger); } return array('triggerids' => zbx_objectValues($triggers, 'triggerid')); }
/** * Fetches the fields given in $fields from the database and extends the objects with the loaded data. * * @param string $tableName * @param array $objects * @param array $fields * * @return array */ protected function extendObjects($tableName, array $objects, array $fields) { if ($objects) { $dbObjects = API::getApiService()->select($tableName, ['output' => $fields, $this->pkOption($tableName) => zbx_objectValues($objects, $this->pk($tableName)), 'preservekeys' => true]); foreach ($objects as &$object) { $pk = $object[$this->pk($tableName)]; if (isset($dbObjects[$pk])) { check_db_fields($dbObjects[$pk], $object); } } unset($object); } return $objects; }
/** * Update IconMap. * @param array $iconMaps * @return array */ public function update(array $iconMaps) { if (USER_TYPE_SUPER_ADMIN != self::$userData['type']) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('Only Super Admins can update icon maps.')); } $iconMaps = zbx_toArray($iconMaps); $iconMapids = zbx_objectValues($iconMaps, 'iconmapid'); $updates = []; $duplicates = []; foreach ($iconMaps as $iconMap) { if (!check_db_fields(['iconmapid' => null], $iconMap)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect parameters for icon map update method "%s".', $iconMap['name'])); } if (isset($iconMap['name'])) { if (zbx_empty($iconMap['name'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Icon map name cannot be empty.')); } elseif (isset($duplicates[$iconMap['name']])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Cannot create icon maps with identical name "%s".', $iconMap['name'])); } else { $duplicates[$iconMap['name']] = $iconMap['name']; } } } $this->validateMappings($iconMaps, false); $iconMapsUpd = API::IconMap()->get(['iconmapids' => $iconMapids, 'output' => API_OUTPUT_EXTEND, 'preservekeys' => true, 'selectMappings' => API_OUTPUT_EXTEND]); $oldIconMappings = []; $newIconMappings = []; foreach ($iconMaps as $iconMap) { if (!isset($iconMapsUpd[$iconMap['iconmapid']])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Icon map with iconmapid "%s" does not exist.', $iconMap['iconmapid'])); } // Existence if (isset($iconMap['name'])) { $iconMapExists = $this->get(['filter' => ['name' => $iconMap['name']], 'output' => ['iconmapid'], 'editable' => true, 'nopermissions' => true, 'preservekeys' => true]); if (($iconMapExists = reset($iconMapExists)) && bccomp($iconMapExists['iconmapid'], $iconMap['iconmapid']) != 0) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Icon map "%s" already exists.', $iconMap['name'])); } } if (isset($iconMap['mappings'])) { $mappingsDb = $iconMapsUpd[$iconMap['iconmapid']]['mappings']; foreach ($mappingsDb as $mapping) { $oldIconMappings[] = $mapping; } foreach ($iconMap['mappings'] as $mapping) { $mapping['iconmapid'] = $iconMap['iconmapid']; $newIconMappings[] = $mapping; } } $iconMapid = $iconMap['iconmapid']; unset($iconMap['iconmapid']); if (!empty($iconMap)) { $updates[] = ['values' => $iconMap, 'where' => ['iconmapid' => $iconMapid]]; } } DB::save('icon_map', $iconMaps); DB::replace('icon_mapping', $oldIconMappings, $newIconMappings); return ['iconmapids' => $iconMapids]; }
/** * Add Host * * @param _array $hosts multidimensional array with Hosts data * @param string $hosts['host'] Host name. * @param array $hosts['groups'] array of HostGroup objects with IDs add Host to. * @param int $hosts['port'] Port. OPTIONAL * @param int $hosts['status'] Host Status. OPTIONAL * @param int $hosts['useip'] Use IP. OPTIONAL * @param string $hosts['dns'] DNS. OPTIONAL * @param string $hosts['ip'] IP. OPTIONAL * @param int $hosts['proxy_hostid'] Proxy Host ID. OPTIONAL * @param int $hosts['useipmi'] Use IPMI. OPTIONAL * @param string $hosts['ipmi_ip'] IPMAI IP. OPTIONAL * @param int $hosts['ipmi_port'] IPMI port. OPTIONAL * @param int $hosts['ipmi_authtype'] IPMI authentication type. OPTIONAL * @param int $hosts['ipmi_privilege'] IPMI privilege. OPTIONAL * @param string $hosts['ipmi_username'] IPMI username. OPTIONAL * @param string $hosts['ipmi_password'] IPMI password. OPTIONAL * @return boolean */ public static function create($hosts) { $hosts = zbx_toArray($hosts); $hostids = array(); $groupids = array(); try { self::BeginTransaction(__METHOD__); // BASIC VALIDATION {{{ foreach ($hosts as $hnum => $host) { // CHECK IF HOSTS HAVE AT LEAST 1 GROUP if (empty($host['groups'])) { self::exception(ZBX_API_ERROR_PARAMETERS, sprintf(S_NO_GROUPS_FOR_HOST, $host['host'])); } // Check if host name isn't longer then 64 chars if (zbx_strlen($host['host']) > 64) { self::exception(ZBX_API_ERROR_PARAMETERS, sprintf(S_HOST_NAME_MUST_BE_LONGER, 64, $host['host'], zbx_strlen($host['host']))); } $hosts[$hnum]['groups'] = zbx_toArray($hosts[$hnum]['groups']); foreach ($hosts[$hnum]['groups'] as $gnum => $group) { $groupids[$group['groupid']] = $group['groupid']; } } // }}} // PERMISSIONS {{{ $upd_groups = CHostGroup::get(array('groupids' => $groupids, 'editable' => 1, 'preservekeys' => 1)); foreach ($groupids as $gnum => $groupid) { if (!isset($upd_groups[$groupid])) { self::exception(ZBX_API_ERROR_PERMISSIONS, S_NO_PERMISSIONS); } } // }}} PERMISSIONS foreach ($hosts as $num => $host) { $host_db_fields = array('host' => null, 'port' => 0, 'status' => 0, 'useip' => 0, 'dns' => '', 'ip' => '0.0.0.0', 'proxy_hostid' => 0, 'useipmi' => 0, 'ipmi_ip' => '', 'ipmi_port' => 623, 'ipmi_authtype' => 0, 'ipmi_privilege' => 0, 'ipmi_username' => '', 'ipmi_password' => ''); if (!check_db_fields($host_db_fields, $host)) { self::exception(ZBX_API_ERROR_PARAMETERS, 'Wrong fields for host [ ' . $host['host'] . ' ]'); } if (!preg_match('/^' . ZBX_PREG_HOST_FORMAT . '$/i', $host['host'])) { self::exception(ZBX_API_ERROR_PARAMETERS, 'Incorrect characters used for Hostname [ ' . $host['host'] . ' ]'); } if (!empty($host['dns']) && !preg_match('/^' . ZBX_PREG_DNS_FORMAT . '$/i', $host['dns'])) { self::exception(ZBX_API_ERROR_PARAMETERS, 'Incorrect characters used for DNS [ ' . $host['dns'] . ' ]'); } if (self::exists(array('host' => $host['host']))) { self::exception(ZBX_API_ERROR_PARAMETERS, S_HOST . ' [ ' . $host['host'] . ' ] ' . S_ALREADY_EXISTS_SMALL); } if (CTemplate::exists(array('host' => $host['host']))) { self::exception(ZBX_API_ERROR_PARAMETERS, S_TEMPLATE . ' [ ' . $host['host'] . ' ] ' . S_ALREADY_EXISTS_SMALL); } $hostid = get_dbid('hosts', 'hostid'); $hostids[] = $hostid; $result = DBexecute('INSERT INTO hosts (hostid, proxy_hostid, host, port, status, useip, dns, ip, disable_until, available,' . 'useipmi,ipmi_port,ipmi_authtype,ipmi_privilege,ipmi_username,ipmi_password,ipmi_ip) VALUES (' . $hostid . ',' . $host['proxy_hostid'] . ',' . zbx_dbstr($host['host']) . ',' . $host['port'] . ',' . $host['status'] . ',' . $host['useip'] . ',' . zbx_dbstr($host['dns']) . ',' . zbx_dbstr($host['ip']) . ',0,' . HOST_AVAILABLE_UNKNOWN . ',' . $host['useipmi'] . ',' . $host['ipmi_port'] . ',' . $host['ipmi_authtype'] . ',' . $host['ipmi_privilege'] . ',' . zbx_dbstr($host['ipmi_username']) . ',' . zbx_dbstr($host['ipmi_password']) . ',' . zbx_dbstr($host['ipmi_ip']) . ')'); if (!$result) { self::exception(ZBX_API_ERROR_PARAMETERS, 'DBerror'); } foreach ($host['groups'] as $group) { $hostgroupid = get_dbid('hosts_groups', 'hostgroupid'); $result = DBexecute("INSERT INTO hosts_groups (hostgroupid, hostid, groupid) VALUES ({$hostgroupid}, {$hostid}, {$group['groupid']})"); if (!$result) { self::exception(ZBX_API_ERROR_PARAMETERS, 'DBerror'); } } $host['hostid'] = $hostid; $options = array(); $options['hosts'] = $host; if (isset($host['templates']) && !is_null($host['templates'])) { $options['templates'] = $host['templates']; } if (isset($host['macros']) && !is_null($host['macros'])) { $options['macros'] = $host['macros']; } $result = CHost::massAdd($options); if (!$result) { self::exception(); } if (isset($host['profile']) && !empty($host['extendedProfile'])) { $fields = array_keys($host['profile']); $fields = implode(', ', $fields); $values = array_map('zbx_dbstr', $host['profile']); $values = implode(', ', $values); DBexecute('INSERT INTO hosts_profiles (hostid, ' . $fields . ') VALUES (' . $hostid . ', ' . $values . ')'); } if (isset($host['extendedProfile']) && !empty($host['extendedProfile'])) { $fields = array_keys($host['extendedProfile']); $fields = implode(', ', $fields); $values = array_map('zbx_dbstr', $host['extendedProfile']); $values = implode(', ', $values); DBexecute('INSERT INTO hosts_profiles_ext (hostid, ' . $fields . ') VALUES (' . $hostid . ', ' . $values . ')'); } } self::EndTransaction(true, __METHOD__); return array('hostids' => $hostids); } catch (APIException $e) { self::EndTransaction(false, __METHOD__); $error = $e->getErrors(); $error = reset($error); self::setError(__METHOD__, $e->getCode(), $error); return false; } }
/** * Check input. * * @param array $triggers * @param string $method */ public function checkInput(array &$triggers, $method) { $update = $method == 'update'; // permissions if ($update) { $triggerDbFields = ['triggerid' => null]; $dbTriggers = $this->get(['output' => API_OUTPUT_EXTEND, 'triggerids' => zbx_objectValues($triggers, 'triggerid'), 'editable' => true, 'preservekeys' => true]); $dbTriggers = CMacrosResolverHelper::resolveTriggerExpressions($dbTriggers); $updateDiscoveredValidator = new CUpdateDiscoveredValidator(['allowed' => ['triggerid', 'status'], 'messageAllowedField' => _('Cannot update "%2$s" for a discovered trigger "%1$s".')]); foreach ($triggers as $trigger) { $triggerId = $trigger['triggerid']; // check permissions if (!isset($dbTriggers[$triggerId])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('No permissions to referred object or it does not exist!')); } $dbTrigger = $dbTriggers[$triggerId]; $triggerName = isset($trigger['description']) ? $trigger['description'] : $dbTrigger['description']; $updateDiscoveredValidator->setObjectName($triggerName); // discovered fields, except status, cannot be updated $this->checkPartialValidator($trigger, $updateDiscoveredValidator, $dbTrigger); } $triggers = $this->extendObjects($this->tableName(), $triggers, ['description']); } else { $triggerDbFields = ['description' => null, 'expression' => null, 'value' => TRIGGER_VALUE_FALSE]; } foreach ($triggers as $tnum => &$trigger) { $currentTrigger = $triggers[$tnum]; $this->checkNoParameters($trigger, ['templateid', 'state', 'value'], $update ? _('Cannot update "%1$s" for trigger "%2$s".') : _('Cannot set "%1$s" for trigger "%2$s".'), $trigger['description']); if (!check_db_fields($triggerDbFields, $trigger)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect fields for trigger.')); } $expressionChanged = true; if ($update) { $dbTrigger = $dbTriggers[$trigger['triggerid']]; if (array_key_exists('expression', $trigger) && $trigger['expression'] === $dbTrigger['expression']) { $expressionChanged = false; } if (array_key_exists('description', $trigger) && strcmp($trigger['description'], $dbTrigger['description']) == 0) { unset($trigger['description']); } } // if some of the properties are unchanged, no need to update them in DB // validating trigger expression if (isset($trigger['expression']) && $expressionChanged) { // expression permissions $expressionData = new CTriggerExpression(['lldmacros' => false]); if (!$expressionData->parse($trigger['expression'])) { self::exception(ZBX_API_ERROR_PARAMETERS, $expressionData->error); } if (!isset($expressionData->expressions[0])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Trigger expression must contain at least one host:key reference.')); } $expressionHosts = $expressionData->getHosts(); $hosts = API::Host()->get(['output' => ['hostid', 'host', 'status'], 'filter' => ['host' => $expressionHosts], 'editable' => true, 'templated_hosts' => true, 'preservekeys' => true]); $hosts = zbx_toHash($hosts, 'host'); $hostsStatusFlags = 0x0; foreach ($expressionHosts as $host) { if (!isset($hosts[$host])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect trigger expression. Host "%s" does not exist or you have no access to this host.', $host)); } // find out if both templates and hosts are referenced in expression $hostsStatusFlags |= $hosts[$host]['status'] == HOST_STATUS_TEMPLATE ? 0x1 : 0x2; if ($hostsStatusFlags == 0x3) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect trigger expression. Trigger expression elements should not belong to a template and a host simultaneously.')); } } foreach ($expressionData->expressions as $exprPart) { $sql = 'SELECT i.itemid,i.value_type' . ' FROM items i,hosts h' . ' WHERE i.key_=' . zbx_dbstr($exprPart['item']) . ' AND ' . dbConditionInt('i.flags', [ZBX_FLAG_DISCOVERY_NORMAL, ZBX_FLAG_DISCOVERY_CREATED]) . ' AND h.host=' . zbx_dbstr($exprPart['host']) . ' AND h.hostid=i.hostid'; if (!DBfetch(DBselect($sql))) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect item key "%1$s" provided for trigger expression on "%2$s".', $exprPart['item'], $exprPart['host'])); } } } // check existing $this->checkIfExistsOnHost($currentTrigger); } unset($trigger); }
public function checkInput(&$maps, $method) { $create = $method == 'create'; $update = $method == 'update'; $delete = $method == 'delete'; // permissions if ($update || $delete) { $mapDbFields = array('sysmapid' => null); $dbMaps = $this->get(array('sysmapids' => zbx_objectValues($maps, 'sysmapid'), 'output' => API_OUTPUT_EXTEND, 'editable' => true, 'preservekeys' => true, 'selectLinks' => API_OUTPUT_EXTEND, 'selectSelements' => API_OUTPUT_EXTEND, 'selectUrls' => API_OUTPUT_EXTEND)); } else { $mapDbFields = array('name' => null, 'width' => null, 'height' => null, 'urls' => array(), 'selements' => array(), 'links' => array()); } $mapNames = array(); foreach ($maps as &$map) { if (!check_db_fields($mapDbFields, $map)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect fields for sysmap.')); } if ($update || $delete) { if (!isset($dbMaps[$map['sysmapid']])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('No permissions to referred object or it does not exist!')); } $dbMap = array_merge($dbMaps[$map['sysmapid']], $map); } else { $dbMap = $map; } if (isset($map['name'])) { if (isset($mapNames[$map['name']])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Duplicate map name for map "%s".', $dbMap['name'])); } else { $mapNames[$map['name']] = $update ? $map['sysmapid'] : 1; } } if (isset($map['width']) && ($map['width'] > 65535 || $map['width'] < 1)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect map width value for map "%s".', $dbMap['name'])); } if (isset($map['height']) && ($map['height'] > 65535 || $map['height'] < 1)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect map height value for map "%s".', $dbMap['name'])); } // labels $mapLabels = array('label_type' => array('typeName' => _('icon'))); if ($dbMap['label_format'] == SYSMAP_LABEL_ADVANCED_ON) { $mapLabels['label_type_hostgroup'] = array('string' => 'label_string_hostgroup', 'typeName' => _('host group')); $mapLabels['label_type_host'] = array('string' => 'label_string_host', 'typeName' => _('host')); $mapLabels['label_type_trigger'] = array('string' => 'label_string_trigger', 'typeName' => _('trigger')); $mapLabels['label_type_map'] = array('string' => 'label_string_map', 'typeName' => _('map')); $mapLabels['label_type_image'] = array('string' => 'label_string_image', 'typeName' => _('image')); } foreach ($mapLabels as $labelName => $labelData) { if (!isset($map[$labelName])) { continue; } if (sysmapElementLabel($map[$labelName]) === false) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect %1$s label type value for map "%2$s".', $labelData['typeName'], $dbMap['name'])); } if ($map[$labelName] == MAP_LABEL_TYPE_CUSTOM) { if (!isset($labelData['string'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect %1$s label type value for map "%2$s".', $labelData['typeName'], $dbMap['name'])); } if (!isset($map[$labelData['string']]) || zbx_empty($map[$labelData['string']])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Custom label for map "%2$s" elements of type "%1$s" may not be empty.', $labelData['typeName'], $dbMap['name'])); } } if ($labelName == 'label_type_image' && $map[$labelName] == MAP_LABEL_TYPE_STATUS) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect %1$s label type value for map "%2$s".', $labelData['typeName'], $dbMap['name'])); } if ($labelName == 'label_type' || $labelName == 'label_type_host') { continue; } if ($map[$labelName] == MAP_LABEL_TYPE_IP) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect %1$s label type value for map "%2$s".', $labelData['typeName'], $dbMap['name'])); } } // validating grid options $possibleGridSizes = array(20, 40, 50, 75, 100); if ($update || $create) { // grid size if (isset($map['grid_size']) && !in_array($map['grid_size'], $possibleGridSizes)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Value "%1$s" is invalid for parameter "grid_show". Choices are: "%2$s".', $map['grid_size'], implode('", "', $possibleGridSizes))); } // grid auto align if (isset($map['grid_align']) && $map['grid_align'] != SYSMAP_GRID_ALIGN_ON && $map['grid_align'] != SYSMAP_GRID_ALIGN_OFF) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Value "%1$s" is invalid for parameter "grid_align". Choices are: "%2$s" and "%3$s"', $map['grid_align'], SYSMAP_GRID_ALIGN_ON, SYSMAP_GRID_ALIGN_OFF)); } // grid show if (isset($map['grid_show']) && $map['grid_show'] != SYSMAP_GRID_SHOW_ON && $map['grid_show'] != SYSMAP_GRID_SHOW_OFF) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Value "%1$s" is invalid for parameter "grid_show". Choices are: "%2$s" and "%3$s".', $map['grid_show'], SYSMAP_GRID_SHOW_ON, SYSMAP_GRID_SHOW_OFF)); } } // urls if (isset($map['urls']) && !empty($map['urls'])) { $urlNames = zbx_toHash($map['urls'], 'name'); foreach ($map['urls'] as $url) { if ($url['name'] === '' || $url['url'] === '') { self::exception(ZBX_API_ERROR_PARAMETERS, _s('URL should have both "name" and "url" fields for map "%s".', $dbMap['name'])); } if (!isset($urlNames[$url['name']])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('URL name should be unique for map "%s".', $dbMap['name'])); } unset($urlNames[$url['name']]); } } // map selement links if (!empty($map['links'])) { $selementIds = zbx_objectValues($dbMap['selements'], 'selementid'); foreach ($map['links'] as $link) { if (!in_array($link['selementid1'], $selementIds)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Link selementid1 field is pointing to a nonexistent map selement ID "%1$s" for map "%2$s".', $link['selementid1'], $dbMap['name'])); } if (!in_array($link['selementid2'], $selementIds)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Link selementid2 field is pointing to a nonexistent map selement ID "%1$s" for map "%2$s".', $link['selementid2'], $dbMap['name'])); } } } } unset($map); // exists if (($create || $update) && $mapNames) { $existDbMaps = $this->get(array('filter' => array('name' => array_keys($mapNames)), 'output' => array('sysmapid', 'name'), 'nopermissions' => true)); foreach ($existDbMaps as $dbMap) { if ($create || bccomp($mapNames[$dbMap['name']], $dbMap['sysmapid']) != 0) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Map with name "%s" already exists.', $dbMap['name'])); } } } return $update || $delete ? $dbMaps : true; }
/** * Update maintenances * * @param array $maintenances * @return boolean */ public function update(array $maintenances) { $maintenances = zbx_toArray($maintenances); $maintenanceids = zbx_objectValues($maintenances, 'maintenanceid'); // validate maintenance permissions if (self::$userData['type'] == USER_TYPE_ZABBIX_USER) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!')); } $hostids = array(); $groupids = array(); $updMaintenances = $this->get(array('maintenanceids' => zbx_objectValues($maintenances, 'maintenanceid'), 'editable' => true, 'output' => API_OUTPUT_EXTEND, 'selectGroups' => API_OUTPUT_REFER, 'selectHosts' => API_OUTPUT_REFER, 'selectTimeperiods' => API_OUTPUT_EXTEND, 'preservekeys' => true)); foreach ($maintenances as $maintenance) { if (!isset($updMaintenances[$maintenance['maintenanceid']])) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!')); } // Checking whether a maintenance with this name already exists. First, getting all maintenances with the same name as this $receivedMaintenances = API::Maintenance()->get(array('filter' => array('name' => $maintenance['name']))); // validate if maintenance name already exists foreach ($receivedMaintenances as $rMaintenance) { if (bccomp($rMaintenance['maintenanceid'], $maintenance['maintenanceid']) != 0) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Maintenance "%s" already exists.', $maintenance['name'])); } } // validate maintenance active since if (!validateUnixTime($maintenance['active_since'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('"%s" must be between 1970.01.01 and 2038.01.18.', _('Active since'))); } // validate maintenance active till if (!validateUnixTime($maintenance['active_till'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('"%s" must be between 1970.01.01 and 2038.01.18.', _('Active till'))); } // validate maintenance active interval if ($maintenance['active_since'] > $maintenance['active_till']) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Maintenance "Active since" value cannot be bigger than "Active till".')); } // validate timeperiods if (empty($maintenance['timeperiods'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('At least one maintenance period must be created.')); } $hostids = array_merge($hostids, $maintenance['hostids']); $groupids = array_merge($groupids, $maintenance['groupids']); } // validate hosts & groups if (empty($hostids) && empty($groupids)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('At least one host or group should be selected.')); } // validate hosts permissions $options = array('hostids' => $hostids, 'editable' => true, 'output' => array('hostid'), 'preservekeys' => true); $updHosts = API::Host()->get($options); foreach ($hostids as $hostid) { if (!isset($updHosts[$hostid])) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('You do not have permission to perform this operation.')); } } // validate groups permissions $options = array('groupids' => $groupids, 'editable' => true, 'output' => array('groupid'), 'preservekeys' => true); $updGroups = API::HostGroup()->get($options); foreach ($groupids as $groupid) { if (!isset($updGroups[$groupid])) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!')); } } $this->removeSecondsFromTimes($maintenances); $update = array(); foreach ($maintenances as $mnum => $maintenance) { $dbFields = array('maintenanceid' => null); // validate fields if (!check_db_fields($dbFields, $maintenance)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect parameters for maintenance.')); } $update[$mnum] = array('values' => $maintenance, 'where' => array('maintenanceid' => $maintenance['maintenanceid'])); // update time periods $this->replaceTimePeriods($updMaintenances[$maintenance['maintenanceid']], $maintenance); } DB::update('maintenances', $update); // some of the hosts and groups bound to maintenance must be deleted, other inserted and others left alone $insertHosts = array(); $insertGroups = array(); foreach ($maintenances as $maintenance) { // putting apart those host<->maintenance connections that should be inserted, deleted and not changed // $hostDiff['first'] - new hosts, that should be inserted // $hostDiff['second'] - hosts, that should be deleted // $hostDiff['both'] - hosts, that should not be touched $hostDiff = zbx_array_diff(zbx_toObject($maintenance['hostids'], 'hostid'), $updMaintenances[$maintenance['maintenanceid']]['hosts'], 'hostid'); foreach ($hostDiff['first'] as $host) { $insertHosts[] = array('hostid' => $host['hostid'], 'maintenanceid' => $maintenance['maintenanceid']); } foreach ($hostDiff['second'] as $host) { $deleteHosts = array('hostid' => $host['hostid'], 'maintenanceid' => $maintenance['maintenanceid']); DB::delete('maintenances_hosts', $deleteHosts); } // now the same with the groups $groupDiff = zbx_array_diff(zbx_toObject($maintenance['groupids'], 'groupid'), $updMaintenances[$maintenance['maintenanceid']]['groups'], 'groupid'); foreach ($groupDiff['first'] as $group) { $insertGroups[] = array('groupid' => $group['groupid'], 'maintenanceid' => $maintenance['maintenanceid']); } foreach ($groupDiff['second'] as $group) { $deleteGroups = array('groupid' => $group['groupid'], 'maintenanceid' => $maintenance['maintenanceid']); DB::delete('maintenances_groups', $deleteGroups); } } DB::insert('maintenances_hosts', $insertHosts); DB::insert('maintenances_groups', $insertGroups); return array('maintenanceids' => $maintenanceids); }