function getDeletableHostGroups($groupids = null) { zbx_value2array($groupids); $dlt_groupids = array(); $hostids = getUnlinkableHosts($groupids); $sql_where = ''; if (!is_null($groupids)) { $sql_where .= ' AND ' . DBcondition('g.groupid', $groupids); } $sql = 'SELECT DISTINCT g.groupid ' . ' FROM groups g ' . ' WHERE g.internal=' . ZBX_NOT_INTERNAL_GROUP . $sql_where . ' AND NOT EXISTS (' . 'SELECT hg.groupid ' . ' FROM hosts_groups hg ' . ' WHERE g.groupid=hg.groupid ' . ' AND ' . DBcondition('hg.hostid', $hostids, true) . ')'; $res = DBselect($sql); while ($group = DBfetch($res)) { $dlt_groupids[$group['groupid']] = $group['groupid']; } return $dlt_groupids; }
function getDeletableHostGroups($groupids = null) { $deletable_groupids = array(); zbx_value2array($groupids); $hostids = getUnlinkableHosts($groupids); $sql_where = ''; if (!is_null($groupids)) { $sql_where .= ' AND ' . dbConditionInt('g.groupid', $groupids); } $db_groups = DBselect('SELECT DISTINCT g.groupid' . ' FROM groups g' . ' WHERE g.internal=' . ZBX_NOT_INTERNAL_GROUP . $sql_where . ' AND NOT EXISTS (' . 'SELECT NULL' . ' FROM hosts_groups hg' . ' WHERE g.groupid=hg.groupid' . (!empty($hostids) ? ' AND ' . dbConditionInt('hg.hostid', $hostids, true) : '') . ')'); while ($group = DBfetch($db_groups)) { $deletable_groupids[$group['groupid']] = $group['groupid']; } return $deletable_groupids; }
/** * Update host groups with new hosts (rewrite). * * @param array $data * @param array $data['groups'] * @param array $data['hosts'] * @param array $data['templates'] * * @return array */ public function massUpdate(array $data) { $groupIds = array_unique(zbx_objectValues(zbx_toArray($data['groups']), 'groupid')); $hostIds = array_unique(zbx_objectValues(isset($data['hosts']) ? zbx_toArray($data['hosts']) : null, 'hostid')); $templateIds = array_unique(zbx_objectValues(isset($data['templates']) ? zbx_toArray($data['templates']) : null, 'templateid')); $workHostIds = array(); // validate permission $allowedGroups = $this->get(array('groupids' => $groupIds, 'editable' => true, 'preservekeys' => true)); foreach ($groupIds as $groupId) { if (!isset($allowedGroups[$groupId])) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('You do not have permission to perform this operation.')); } } // validate allowed hosts if (!empty($hostIds)) { $allowedHosts = API::Host()->get(array('hostids' => $hostIds, 'editable' => true, 'preservekeys' => true)); foreach ($hostIds as $hostId) { if (!isset($allowedHosts[$hostId])) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('You do not have permission to perform this operation.')); } $workHostIds[$hostId] = $hostId; } } // validate allowed templates if (!empty($templateIds)) { $allowedTemplates = API::Template()->get(array('templateids' => $templateIds, 'editable' => true, 'preservekeys' => true)); foreach ($templateIds as $templateId) { if (!isset($allowedTemplates[$templateId])) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('You do not have permission to perform this operation.')); } $workHostIds[$templateId] = $templateId; } } // get old records $oldRecords = DBfetchArray(DBselect('SELECT *' . ' FROM hosts_groups hg' . ' WHERE ' . dbConditionInt('hg.groupid', $groupIds))); // calculate new records $replaceRecords = array(); $newRecords = array(); $hostIdsToValidate = array(); foreach ($groupIds as $groupId) { $groupRecords = array(); foreach ($oldRecords as $oldRecord) { if ($oldRecord['groupid'] == $groupId) { $groupRecords[] = $oldRecord; } } // find records for replace foreach ($groupRecords as $groupRecord) { if (isset($workHostIds[$groupRecord['hostid']])) { $replaceRecords[] = $groupRecord; } } // find records for create $groupHostIds = zbx_toHash(zbx_objectValues($groupRecords, 'hostid')); $newHostIds = array_diff($workHostIds, $groupHostIds); if ($newHostIds) { foreach ($newHostIds as $newHostId) { $newRecords[] = array('groupid' => $groupId, 'hostid' => $newHostId); } } // find records for delete $deleteHostIds = array_diff($groupHostIds, $workHostIds); if ($deleteHostIds) { foreach ($deleteHostIds as $deleteHostId) { $hostIdsToValidate[$deleteHostId] = $deleteHostId; } } } // validate hosts without groups if ($hostIdsToValidate) { $unlinkable = getUnlinkableHosts($groupIds, $hostIdsToValidate); if (count($unlinkable) != count($hostIdsToValidate)) { self::exception(ZBX_API_ERROR_PARAMETERS, 'One of the objects is left without host group.'); } } // save DB::replace('hosts_groups', $oldRecords, array_merge($replaceRecords, $newRecords)); return array('groupids' => $groupIds); }
/** * Validate write permissions to host groups that are removed from given hosts and templates. Also check * if host and template has at least one host group left. * * @param array $data * @param array $data['groupids'] * @param array $data['hostids'] * @param array $data['templateids'] * * @throws APIException if user has no write permissions to any of the given host groups or one of the hosts and * templates is left without a host group */ protected function validateMassRemove(array $data) { $groupIdsToRemove = array(); $hostIds = isset($data['hostids']) ? $data['hostids'] : array(); $templateIds = isset($data['templateids']) ? $data['templateids'] : array(); $objectIds = array(); if ($hostIds) { $dbHosts = API::Host()->get(array('output' => array('hostid'), 'selectGroups' => array('groupid'), 'hostids' => $hostIds, 'editable' => true, 'preservekeys' => true)); $this->validateHostsPermissions($hostIds, $dbHosts); $this->checkValidator($hostIds, new CHostNormalValidator(array('message' => _('Cannot update groups for discovered host "%1$s".')))); foreach ($dbHosts as $dbHost) { $oldGroupIds = zbx_objectValues($dbHost['groups'], 'groupid'); // check if host belongs to the removable host group $hostGroupIdsToRemove = array_intersect($data['groupids'], $oldGroupIds); if ($hostGroupIdsToRemove) { $objectIds[] = $dbHost['hostid']; foreach ($hostGroupIdsToRemove as $groupId) { $groupIdsToRemove[$groupId] = $groupId; } } } } if ($templateIds) { $dbTemplates = API::Template()->get(array('output' => array('templateid'), 'selectGroups' => array('groupid'), 'templateids' => $templateIds, 'editable' => true, 'preservekeys' => true)); $this->validateHostsPermissions($templateIds, $dbTemplates); foreach ($dbTemplates as $dbTemplate) { $oldGroupIds = zbx_objectValues($dbTemplate['groups'], 'groupid'); // check if template belongs to the removable host group $templateGroupIdsToRemove = array_intersect($data['groupids'], $oldGroupIds); if ($templateGroupIdsToRemove) { $objectIds[] = $dbTemplate['templateid']; foreach ($templateGroupIdsToRemove as $groupId) { $groupIdsToRemove[$groupId] = $groupId; } } } } if ($groupIdsToRemove) { if (!$this->isWritable($groupIdsToRemove)) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!')); } // check if host group can be removed from given hosts and templates leaving them with at least one more host group $unlinkableObjectIds = getUnlinkableHosts($groupIdsToRemove, $objectIds); if (count($objectIds) != count($unlinkableObjectIds)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('One of the objects is left without a host group.')); } } }
/** * Update HostGroups with new Hosts (rewrite) * * @param array $data * @param array $data['groups'] * @param array $data['hosts'] * @param array $data['templates'] * @return boolean */ public static function massUpdate($data) { $groups = zbx_toArray($data['groups']); $hosts = isset($data['hosts']) ? zbx_toArray($data['hosts']) : null; $templates = isset($data['templates']) ? zbx_toArray($data['templates']) : null; $groupids = zbx_objectValues($groups, 'groupid'); $hostids = zbx_objectValues($hosts, 'hostid'); $templateids = zbx_objectValues($templates, 'templateid'); try { self::BeginTransaction(__METHOD__); $hosts_to_unlink = $hosts_to_link = array(); $options = array('groupids' => $groupids, 'preservekeys' => 1); if (!is_null($hosts)) { $groups_hosts = CHost::get($options); $hosts_to_unlink = array_diff(array_keys($groups_hosts), $hostids); $hosts_to_link = array_diff($hostids, array_keys($groups_hosts)); } $templates_to_unlink = $templates_to_link = array(); if (!is_null($templates)) { $groups_templates = CTemplate::get($options); $templates_to_unlink = array_diff(array_keys($groups_templates), $templateids); $templates_to_link = array_diff($templateids, array_keys($groups_templates)); } $objectids_to_link = array_merge($hosts_to_link, $templates_to_link); $objectids_to_unlink = array_merge($hosts_to_unlink, $templates_to_unlink); // PERMISSION {{{ $options = array('groupids' => $groupids, 'editable' => 1, 'preservekeys' => 1); $allowed_groups = self::get($options); foreach ($groups as $num => $group) { if (!isset($allowed_groups[$group['groupid']])) { self::exception(ZBX_API_ERROR_PERMISSIONS, S_NO_PERMISSION); } } if (!is_null($hosts)) { $hosts_to_check = array_merge($hosts_to_link, $hosts_to_unlink); $options = array('hostids' => $hosts_to_check, 'editable' => 1, 'preservekeys' => 1); $allowed_hosts = CHost::get($options); foreach ($hosts_to_check as $num => $hostid) { if (!isset($allowed_hosts[$hostid])) { self::exception(ZBX_API_ERROR_PERMISSIONS, S_NO_PERMISSION); } } } if (!is_null($templates)) { $templates_to_check = array_merge($templates_to_link, $templates_to_unlink); $options = array('templateids' => $templates_to_check, 'editable' => 1, 'preservekeys' => 1); $allowed_templates = CTemplate::get($options); foreach ($templates_to_check as $num => $templateid) { if (!isset($allowed_templates[$templateid])) { self::exception(ZBX_API_ERROR_PERMISSIONS, S_NO_PERMISSION); } } } // }}} PERMISSION $unlinkable = getUnlinkableHosts($groupids, $objectids_to_unlink); if (count($objectids_to_unlink) != count($unlinkable)) { self::exception(ZBX_API_ERROR_PARAMETERS, 'One of the Objects is left without Hostgroup'); } $sql = 'DELETE FROM hosts_groups WHERE ' . DBcondition('groupid', $groupids) . ' AND ' . DBcondition('hostid', $objectids_to_unlink); if (!DBexecute($sql)) { self::exception(ZBX_API_ERROR_PARAMETERS, 'DBerror'); } foreach ($groupids as $gnum => $groupid) { foreach ($objectids_to_link as $objectid) { $hostgroupid = get_dbid('hosts_groups', 'hostgroupid'); $result = DBexecute("INSERT INTO hosts_groups (hostgroupid, hostid, groupid) VALUES ({$hostgroupid}, {$objectid}, {$groupid})"); if (!$result) { self::exception(ZBX_API_ERROR_PARAMETERS, 'DBerror'); } } } self::EndTransaction(true, __METHOD__); return array('groupids' => $groupids); } catch (APIException $e) { self::EndTransaction(false, __METHOD__); $error = $e->getErrors(); $error = reset($error); self::setError(__METHOD__, $e->getCode(), $error); return false; } }
/** * Update host groups with new hosts (rewrite). * * @param array $data * @param array $data['groups'] * @param array $data['hosts'] * @param array $data['templates'] * * @return array */ public function massUpdate(array $data) { $groupIds = array_unique(zbx_objectValues(zbx_toArray($data['groups']), 'groupid')); $hostIds = array_unique(zbx_objectValues(isset($data['hosts']) ? zbx_toArray($data['hosts']) : null, 'hostid')); $templateIds = array_unique(zbx_objectValues(isset($data['templates']) ? zbx_toArray($data['templates']) : null, 'templateid')); $workHostIds = array(); // validate permission $allowedGroups = $this->get(array('groupids' => $groupIds, 'editable' => true, 'preservekeys' => true)); foreach ($groupIds as $groupId) { if (!isset($allowedGroups[$groupId])) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!')); } } // validate allowed hosts if (!empty($hostIds)) { if (!API::Host()->isWritable($hostIds)) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!')); } // check if any of the hosts are discovered $this->checkValidator($hostIds, new CHostNormalValidator(array('message' => _('Cannot update groups for discovered host "%1$s".')))); $workHostIds = zbx_toHash($hostIds); } // validate allowed templates if (!empty($templateIds)) { $allowedTemplates = API::Template()->get(array('templateids' => $templateIds, 'editable' => true, 'preservekeys' => true)); foreach ($templateIds as $templateId) { if (!isset($allowedTemplates[$templateId])) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!')); } $workHostIds[$templateId] = $templateId; } } // get old records // skip discovered hosts $oldRecords = DBfetchArray(DBselect('SELECT *' . ' FROM hosts_groups hg,hosts h' . ' WHERE ' . dbConditionInt('hg.groupid', $groupIds) . ' AND hg.hostid=h.hostid' . ' AND h.flags=' . ZBX_FLAG_DISCOVERY_NORMAL)); // calculate new records $replaceRecords = array(); $newRecords = array(); $hostIdsToValidate = array(); foreach ($groupIds as $groupId) { $groupRecords = array(); foreach ($oldRecords as $oldRecord) { if ($oldRecord['groupid'] == $groupId) { $groupRecords[] = $oldRecord; } } // find records for replace foreach ($groupRecords as $groupRecord) { if (isset($workHostIds[$groupRecord['hostid']])) { $replaceRecords[] = $groupRecord; } } // find records for create $groupHostIds = zbx_toHash(zbx_objectValues($groupRecords, 'hostid')); $newHostIds = array_diff($workHostIds, $groupHostIds); if ($newHostIds) { foreach ($newHostIds as $newHostId) { $newRecords[] = array('groupid' => $groupId, 'hostid' => $newHostId); } } // find records for delete $deleteHostIds = array_diff($groupHostIds, $workHostIds); if ($deleteHostIds) { foreach ($deleteHostIds as $deleteHostId) { $hostIdsToValidate[$deleteHostId] = $deleteHostId; } } } // validate hosts without groups if ($hostIdsToValidate) { $unlinkable = getUnlinkableHosts($groupIds, $hostIdsToValidate); if (count($unlinkable) != count($hostIdsToValidate)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('One of the objects is left without a host group.')); } } // save DB::replace('hosts_groups', $oldRecords, array_merge($replaceRecords, $newRecords)); return array('groupids' => $groupIds); }