You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1156 lines
38 KiB
1156 lines
38 KiB
<?php
|
|
/*
|
|
** Zabbix
|
|
** Copyright (C) 2001-2023 Zabbix SIA
|
|
**
|
|
** This program is free software; you can redistribute it and/or modify
|
|
** it under the terms of the GNU General Public License as published by
|
|
** the Free Software Foundation; either version 2 of the License, or
|
|
** (at your option) any later version.
|
|
**
|
|
** This program is distributed in the hope that it will be useful,
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
** GNU General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program; if not, write to the Free Software
|
|
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
**/
|
|
|
|
|
|
/**
|
|
* Class containing methods for operations with user macro.
|
|
*/
|
|
class CUserMacro extends CApiService {
|
|
|
|
public const ACCESS_RULES = [
|
|
'get' => ['min_user_type' => USER_TYPE_ZABBIX_USER],
|
|
'create' => ['min_user_type' => USER_TYPE_ZABBIX_ADMIN],
|
|
'update' => ['min_user_type' => USER_TYPE_ZABBIX_ADMIN],
|
|
'delete' => ['min_user_type' => USER_TYPE_ZABBIX_ADMIN],
|
|
'createglobal' => ['min_user_type' => USER_TYPE_SUPER_ADMIN],
|
|
'updateglobal' => ['min_user_type' => USER_TYPE_SUPER_ADMIN],
|
|
'deleteglobal' => ['min_user_type' => USER_TYPE_SUPER_ADMIN]
|
|
];
|
|
|
|
protected $tableName = 'hostmacro';
|
|
protected $tableAlias = 'hm';
|
|
protected $sortColumns = ['macro'];
|
|
|
|
/**
|
|
* Get UserMacros data.
|
|
*
|
|
* @param array $options
|
|
* @param array $options['groupids'] usermacrosgroup ids
|
|
* @param array $options['hostids'] host ids
|
|
* @param array $options['hostmacroids'] host macros ids
|
|
* @param array $options['globalmacroids'] global macros ids
|
|
* @param array $options['templateids'] template ids
|
|
* @param boolean $options['globalmacro'] only global macros
|
|
* @param boolean $options['selectGroups'] select groups - deprecated!
|
|
* @param boolean $options['selectHostGroups'] select host groups
|
|
* @param boolean $options['selectTemplateGroups'] select template groups
|
|
* @param boolean $options['selectHosts'] select hosts
|
|
* @param boolean $options['selectTemplates'] select templates
|
|
*
|
|
* @return array|boolean UserMacros data as array or false if error
|
|
*/
|
|
public function get($options = []) {
|
|
$result = [];
|
|
$userid = self::$userData['userid'];
|
|
|
|
$sqlParts = [
|
|
'select' => ['macros' => 'hm.hostmacroid'],
|
|
'from' => ['hostmacro hm'],
|
|
'where' => [],
|
|
'order' => [],
|
|
'limit' => null
|
|
];
|
|
|
|
$sqlPartsGlobal = [
|
|
'select' => ['macros' => 'gm.globalmacroid'],
|
|
'from' => ['globalmacro gm'],
|
|
'where' => [],
|
|
'order' => [],
|
|
'limit' => null
|
|
];
|
|
|
|
$defOptions = [
|
|
'groupids' => null,
|
|
'hostids' => null,
|
|
'hostmacroids' => null,
|
|
'globalmacroids' => null,
|
|
'templateids' => null,
|
|
'globalmacro' => null,
|
|
'inherited' => null,
|
|
'editable' => false,
|
|
'nopermissions' => null,
|
|
// filter
|
|
'filter' => null,
|
|
'search' => null,
|
|
'searchByAny' => null,
|
|
'startSearch' => false,
|
|
'excludeSearch' => false,
|
|
'searchWildcardsEnabled' => null,
|
|
// output
|
|
'output' => API_OUTPUT_EXTEND,
|
|
'selectGroups' => null,
|
|
'selectHostGroups' => null,
|
|
'selectTemplateGroups' => null,
|
|
'selectHosts' => null,
|
|
'selectTemplates' => null,
|
|
'countOutput' => false,
|
|
'preservekeys' => false,
|
|
'sortfield' => '',
|
|
'sortorder' => '',
|
|
'limit' => null
|
|
];
|
|
$options = zbx_array_merge($defOptions, $options);
|
|
|
|
$this->checkDeprecatedParam($options, 'selectGroups');
|
|
|
|
// editable + PERMISSION CHECK
|
|
if (self::$userData['type'] != USER_TYPE_SUPER_ADMIN && !$options['nopermissions']) {
|
|
if ($options['editable'] && !is_null($options['globalmacro'])) {
|
|
return [];
|
|
}
|
|
else {
|
|
$permission = $options['editable'] ? PERM_READ_WRITE : PERM_READ;
|
|
|
|
$userGroups = getUserGroupsByUserId($userid);
|
|
|
|
$sqlParts['where'][] = 'EXISTS ('.
|
|
'SELECT NULL'.
|
|
' FROM hosts_groups hgg'.
|
|
' JOIN rights r'.
|
|
' ON r.id=hgg.groupid'.
|
|
' AND '.dbConditionInt('r.groupid', $userGroups).
|
|
' WHERE hm.hostid=hgg.hostid'.
|
|
' GROUP BY hgg.hostid'.
|
|
' HAVING MIN(r.permission)>'.PERM_DENY.
|
|
' AND MAX(r.permission)>='.zbx_dbstr($permission).
|
|
')';
|
|
}
|
|
}
|
|
|
|
// global macro
|
|
if (!is_null($options['globalmacro'])) {
|
|
$options['groupids'] = null;
|
|
$options['hostmacroids'] = null;
|
|
$options['triggerids'] = null;
|
|
$options['hostids'] = null;
|
|
$options['itemids'] = null;
|
|
$options['selectGroups'] = null;
|
|
$options['selectHostGroups'] = null;
|
|
$options['selectTemplateGroups'] = null;
|
|
$options['selectTemplates'] = null;
|
|
$options['selectHosts'] = null;
|
|
$options['inherited'] = null;
|
|
}
|
|
|
|
// globalmacroids
|
|
if (!is_null($options['globalmacroids'])) {
|
|
zbx_value2array($options['globalmacroids']);
|
|
$sqlPartsGlobal['where'][] = dbConditionInt('gm.globalmacroid', $options['globalmacroids']);
|
|
}
|
|
|
|
// hostmacroids
|
|
if (!is_null($options['hostmacroids'])) {
|
|
zbx_value2array($options['hostmacroids']);
|
|
$sqlParts['where'][] = dbConditionInt('hm.hostmacroid', $options['hostmacroids']);
|
|
}
|
|
|
|
// inherited
|
|
if (!is_null($options['inherited'])) {
|
|
$sqlParts['from']['hosts'] = 'hosts h';
|
|
$sqlParts['where'][] = $options['inherited'] ? 'h.templateid IS NOT NULL' : 'h.templateid IS NULL';
|
|
$sqlParts['where']['hmh'] = 'hm.hostid=h.hostid';
|
|
}
|
|
|
|
// groupids
|
|
if (!is_null($options['groupids'])) {
|
|
zbx_value2array($options['groupids']);
|
|
|
|
$sqlParts['from']['hosts_groups'] = 'hosts_groups hg';
|
|
$sqlParts['where'][] = dbConditionInt('hg.groupid', $options['groupids']);
|
|
$sqlParts['where']['hgh'] = 'hg.hostid=hm.hostid';
|
|
}
|
|
|
|
// hostids
|
|
if (!is_null($options['hostids'])) {
|
|
zbx_value2array($options['hostids']);
|
|
|
|
$sqlParts['where'][] = dbConditionInt('hm.hostid', $options['hostids']);
|
|
}
|
|
|
|
// templateids
|
|
if (!is_null($options['templateids'])) {
|
|
zbx_value2array($options['templateids']);
|
|
|
|
$sqlParts['from']['macros_templates'] = 'hosts_templates ht';
|
|
$sqlParts['where'][] = dbConditionInt('ht.templateid', $options['templateids']);
|
|
$sqlParts['where']['hht'] = 'hm.hostid=ht.hostid';
|
|
}
|
|
|
|
// sorting
|
|
$sqlParts = $this->applyQuerySortOptions('hostmacro', 'hm', $options, $sqlParts);
|
|
$sqlPartsGlobal = $this->applyQuerySortOptions('globalmacro', 'gm', $options, $sqlPartsGlobal);
|
|
|
|
// limit
|
|
if (zbx_ctype_digit($options['limit']) && $options['limit']) {
|
|
$sqlParts['limit'] = $options['limit'];
|
|
$sqlPartsGlobal['limit'] = $options['limit'];
|
|
}
|
|
|
|
// init GLOBALS
|
|
if (!is_null($options['globalmacro'])) {
|
|
$sqlPartsGlobal = $this->applyQueryFilterOptions('globalmacro', 'gm', $options, $sqlPartsGlobal);
|
|
$sqlPartsGlobal = $this->applyQueryOutputOptions('globalmacro', 'gm', $options, $sqlPartsGlobal);
|
|
$res = DBselect(self::createSelectQueryFromParts($sqlPartsGlobal), $sqlPartsGlobal['limit']);
|
|
while ($macro = DBfetch($res)) {
|
|
if ($options['countOutput']) {
|
|
$result = $macro['rowscount'];
|
|
}
|
|
else {
|
|
$result[$macro['globalmacroid']] = $macro;
|
|
}
|
|
}
|
|
}
|
|
// init HOSTS
|
|
else {
|
|
$sqlParts = $this->applyQueryFilterOptions('hostmacro', 'hm', $options, $sqlParts);
|
|
$sqlParts = $this->applyQueryOutputOptions('hostmacro', 'hm', $options, $sqlParts);
|
|
$res = DBselect(self::createSelectQueryFromParts($sqlParts), $sqlParts['limit']);
|
|
while ($macro = DBfetch($res)) {
|
|
if ($options['countOutput']) {
|
|
$result = $macro['rowscount'];
|
|
}
|
|
else {
|
|
$result[$macro['hostmacroid']] = $macro;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($options['countOutput']) {
|
|
return $result;
|
|
}
|
|
|
|
if ($result) {
|
|
$result = $this->addRelatedObjects($options, $result);
|
|
$result = $this->unsetExtraFields($result, ['hostid', 'type'], $options['output']);
|
|
}
|
|
|
|
// removing keys (hash -> array)
|
|
if (!$options['preservekeys']) {
|
|
$result = zbx_cleanHashes($result);
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* @param array $globalmacros
|
|
*
|
|
* @return array
|
|
*/
|
|
public function createGlobal(array $globalmacros) {
|
|
$this->validateCreateGlobal($globalmacros);
|
|
|
|
$globalmacroids = DB::insert('globalmacro', $globalmacros);
|
|
|
|
foreach ($globalmacros as $index => &$globalmacro) {
|
|
$globalmacro['globalmacroid'] = $globalmacroids[$index];
|
|
}
|
|
unset($globalmacro);
|
|
|
|
self::addAuditLog(CAudit::ACTION_ADD, CAudit::RESOURCE_MACRO, $globalmacros);
|
|
|
|
return ['globalmacroids' => $globalmacroids];
|
|
}
|
|
|
|
/**
|
|
* @param array $globalmacros
|
|
*
|
|
* @throws APIException if the input is invalid.
|
|
*/
|
|
private function validateCreateGlobal(array &$globalmacros) {
|
|
$api_input_rules = ['type' => API_OBJECTS, 'flags' => API_NOT_EMPTY | API_NORMALIZE, 'uniq' => [['macro']], 'fields' => [
|
|
'macro' => ['type' => API_USER_MACRO, 'flags' => API_REQUIRED, 'length' => DB::getFieldLength('globalmacro', 'macro')],
|
|
'type' => ['type' => API_INT32, 'in' => implode(',', [ZBX_MACRO_TYPE_TEXT, ZBX_MACRO_TYPE_SECRET, ZBX_MACRO_TYPE_VAULT]), 'default' => ZBX_MACRO_TYPE_TEXT],
|
|
'value' => ['type' => API_MULTIPLE, 'flags' => API_REQUIRED, 'rules' => [
|
|
['if' => ['field' => 'type', 'in' => implode(',', [ZBX_MACRO_TYPE_TEXT, ZBX_MACRO_TYPE_SECRET])], 'type' => API_STRING_UTF8, 'length' => DB::getFieldLength('globalmacro', 'value')],
|
|
['if' => ['field' => 'type', 'in' => ZBX_MACRO_TYPE_VAULT], 'type' => API_VAULT_SECRET, 'provider' => CSettingsHelper::get(CSettingsHelper::VAULT_PROVIDER), 'length' => DB::getFieldLength('globalmacro', 'value')]
|
|
]],
|
|
'description' => ['type' => API_STRING_UTF8, 'length' => DB::getFieldLength('globalmacro', 'description')]
|
|
]];
|
|
|
|
if (!CApiInputValidator::validate($api_input_rules, $globalmacros, '/', $error)) {
|
|
self::exception(ZBX_API_ERROR_PARAMETERS, $error);
|
|
}
|
|
|
|
$this->checkDuplicates($globalmacros);
|
|
}
|
|
|
|
/**
|
|
* @param array $globalmacros
|
|
*
|
|
* @return array
|
|
*/
|
|
public function updateGlobal(array $globalmacros) {
|
|
$this->validateUpdateGlobal($globalmacros, $db_globalmacros);
|
|
|
|
$upd_globalmacros = [];
|
|
|
|
foreach ($globalmacros as $globalmacro) {
|
|
$db_globalmacro = $db_globalmacros[$globalmacro['globalmacroid']];
|
|
|
|
$upd_globalmacro = DB::getUpdatedValues('globalmacro', $globalmacro, $db_globalmacro);
|
|
|
|
if ($upd_globalmacro) {
|
|
$upd_globalmacros[] = [
|
|
'values'=> $upd_globalmacro,
|
|
'where'=> ['globalmacroid' => $globalmacro['globalmacroid']]
|
|
];
|
|
}
|
|
}
|
|
|
|
if ($upd_globalmacros) {
|
|
DB::update('globalmacro', $upd_globalmacros);
|
|
}
|
|
|
|
self::addAuditLog(CAudit::ACTION_UPDATE, CAudit::RESOURCE_MACRO, $globalmacros, $db_globalmacros);
|
|
|
|
return ['globalmacroids' => array_column($globalmacros, 'globalmacroid')];
|
|
}
|
|
|
|
/**
|
|
* @param array $globalmacros
|
|
* @param array $db_globalmacros
|
|
*
|
|
* @throws APIException if the input is invalid
|
|
*/
|
|
private function validateUpdateGlobal(array &$globalmacros, array &$db_globalmacros = null) {
|
|
$api_input_rules = ['type' => API_OBJECTS, 'flags' => API_NOT_EMPTY | API_NORMALIZE, 'uniq' => [['globalmacroid'], ['macro']], 'fields' => [
|
|
'globalmacroid' => ['type' => API_ID, 'flags' => API_REQUIRED],
|
|
'macro' => ['type' => API_USER_MACRO, 'length' => DB::getFieldLength('globalmacro', 'macro')],
|
|
'type' => ['type' => API_INT32, 'in' => implode(',', [ZBX_MACRO_TYPE_TEXT, ZBX_MACRO_TYPE_SECRET, ZBX_MACRO_TYPE_VAULT])],
|
|
'value' => ['type' => API_STRING_UTF8, 'length' => DB::getFieldLength('globalmacro', 'value')],
|
|
'description' => ['type' => API_STRING_UTF8, 'length' => DB::getFieldLength('globalmacro', 'description')]
|
|
]];
|
|
|
|
if (!CApiInputValidator::validate($api_input_rules, $globalmacros, '/', $error)) {
|
|
self::exception(ZBX_API_ERROR_PARAMETERS, $error);
|
|
}
|
|
|
|
$db_globalmacros = DB::select('globalmacro', [
|
|
'output' => ['globalmacroid', 'macro', 'value', 'description', 'type'],
|
|
'globalmacroids' => array_column($globalmacros, 'globalmacroid'),
|
|
'preservekeys' => true
|
|
]);
|
|
|
|
if (count($globalmacros) != count($db_globalmacros)) {
|
|
self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!'));
|
|
}
|
|
|
|
$globalmacros = $this->extendObjectsByKey($globalmacros, $db_globalmacros, 'globalmacroid', ['type']);
|
|
|
|
foreach ($globalmacros as $index => &$globalmacro) {
|
|
$db_globalmacro = $db_globalmacros[$globalmacro['globalmacroid']];
|
|
|
|
if ($globalmacro['type'] != $db_globalmacro['type']) {
|
|
if ($db_globalmacro['type'] == ZBX_MACRO_TYPE_SECRET) {
|
|
$globalmacro += ['value' => ''];
|
|
}
|
|
|
|
if ($globalmacro['type'] == ZBX_MACRO_TYPE_VAULT) {
|
|
$globalmacro += ['value' => $db_globalmacro['value']];
|
|
}
|
|
}
|
|
|
|
if (array_key_exists('value', $globalmacro) && $globalmacro['type'] == ZBX_MACRO_TYPE_VAULT) {
|
|
if (!CApiInputValidator::validate([
|
|
'type' => API_VAULT_SECRET,
|
|
'provider' => CSettingsHelper::get(CSettingsHelper::VAULT_PROVIDER)
|
|
], $globalmacro['value'], '/'.($index + 1).'/value', $error)) {
|
|
self::exception(ZBX_API_ERROR_PARAMETERS, $error);
|
|
}
|
|
}
|
|
}
|
|
unset($globalmacro);
|
|
|
|
$this->checkDuplicates($globalmacros, $db_globalmacros);
|
|
}
|
|
|
|
/**
|
|
* Check for duplicated macros.
|
|
*
|
|
* @param array $globalmacros
|
|
* @param string $globalmacros[]['globalmacroid'] (optional if $db_globalmacros is null)
|
|
* @param string $globalmacros[]['macro'] (optional if $db_globalmacros is not null)
|
|
* @param array|null $db_globalmacros
|
|
*
|
|
* @throws APIException if macros already exists.
|
|
*/
|
|
private function checkDuplicates(array $globalmacros, array $db_globalmacros = null): void {
|
|
$macros = [];
|
|
|
|
foreach ($globalmacros as $globalmacro) {
|
|
if ($db_globalmacros === null || (array_key_exists('macro', $globalmacro)
|
|
&& CApiInputValidator::trimMacro($globalmacro['macro'])
|
|
!== CApiInputValidator::trimMacro($db_globalmacros[$globalmacro['globalmacroid']]['macro']))) {
|
|
$macros[] = $globalmacro['macro'];
|
|
}
|
|
}
|
|
|
|
if (!$macros) {
|
|
return;
|
|
}
|
|
|
|
$db_macros = [];
|
|
|
|
$options = ['output' => ['macro']];
|
|
$db_globalmacros = DBselect(DB::makeSql('globalmacro', $options));
|
|
|
|
while ($db_globalmacro = DBfetch($db_globalmacros)) {
|
|
$db_macros[CApiInputValidator::trimMacro($db_globalmacro['macro'])] = true;
|
|
}
|
|
|
|
foreach ($macros as $macro) {
|
|
if (array_key_exists(CApiInputValidator::trimMacro($macro), $db_macros)) {
|
|
self::exception(ZBX_API_ERROR_PARAMETERS, _s('Macro "%1$s" already exists.', $macro));
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param array $globalmacroids
|
|
*
|
|
* @return array
|
|
*/
|
|
public function deleteGlobal(array $globalmacroids) {
|
|
$this->validateDeleteGlobal($globalmacroids, $db_globalmacros);
|
|
|
|
DB::delete('globalmacro', ['globalmacroid' => $globalmacroids]);
|
|
|
|
self::addAuditLog(CAudit::ACTION_DELETE, CAudit::RESOURCE_MACRO, $db_globalmacros);
|
|
|
|
return ['globalmacroids' => $globalmacroids];
|
|
}
|
|
|
|
/**
|
|
* @param array $globalmacroids
|
|
*
|
|
* @throws APIException if the input is invalid.
|
|
*/
|
|
private function validateDeleteGlobal(array &$globalmacroids, array &$db_globalmacros = null) {
|
|
$api_input_rules = ['type' => API_IDS, 'flags' => API_NOT_EMPTY, 'uniq' => true];
|
|
|
|
if (!CApiInputValidator::validate($api_input_rules, $globalmacroids, '/', $error)) {
|
|
self::exception(ZBX_API_ERROR_PARAMETERS, $error);
|
|
}
|
|
|
|
$db_globalmacros = DB::select('globalmacro', [
|
|
'output' => ['globalmacroid', 'macro'],
|
|
'globalmacroids' => $globalmacroids,
|
|
'preservekeys' => true
|
|
]);
|
|
|
|
if (count($globalmacroids) != count($db_globalmacros)) {
|
|
self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!'));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param array $hostmacros
|
|
*
|
|
* @throws APIException if the input is invalid.
|
|
*/
|
|
protected function validateCreate(array &$hostmacros) {
|
|
$api_input_rules = ['type' => API_OBJECTS, 'flags' => API_NOT_EMPTY | API_NORMALIZE, 'uniq' => [['hostid', 'macro']], 'fields' => [
|
|
'hostid' => ['type' => API_ID, 'flags' => API_REQUIRED],
|
|
'macro' => ['type' => API_USER_MACRO, 'flags' => API_REQUIRED, 'length' => DB::getFieldLength('hostmacro', 'macro')],
|
|
'type' => ['type' => API_INT32, 'in' => implode(',', [ZBX_MACRO_TYPE_TEXT, ZBX_MACRO_TYPE_SECRET, ZBX_MACRO_TYPE_VAULT]), 'default' => ZBX_MACRO_TYPE_TEXT],
|
|
'value' => ['type' => API_MULTIPLE, 'flags' => API_REQUIRED, 'rules' => [
|
|
['if' => ['field' => 'type', 'in' => implode(',', [ZBX_MACRO_TYPE_TEXT, ZBX_MACRO_TYPE_SECRET])], 'type' => API_STRING_UTF8, 'length' => DB::getFieldLength('hostmacro', 'value')],
|
|
['if' => ['field' => 'type', 'in' => implode(',', [ZBX_MACRO_TYPE_VAULT])], 'type' => API_VAULT_SECRET, 'provider' => CSettingsHelper::get(CSettingsHelper::VAULT_PROVIDER), 'length' => DB::getFieldLength('hostmacro', 'value')]
|
|
]],
|
|
'description' => ['type' => API_STRING_UTF8, 'length' => DB::getFieldLength('hostmacro', 'description')]
|
|
]];
|
|
|
|
if (!CApiInputValidator::validate($api_input_rules, $hostmacros, '/', $error)) {
|
|
self::exception(ZBX_API_ERROR_PARAMETERS, $error);
|
|
}
|
|
|
|
$this->checkHostPermissions(array_unique(array_column($hostmacros, 'hostid')));
|
|
$this->checkHostDuplicates($hostmacros);
|
|
}
|
|
|
|
/**
|
|
* @param array $hostmacros
|
|
*
|
|
* @return array
|
|
*/
|
|
public function create(array $hostmacros) {
|
|
$this->validateCreate($hostmacros);
|
|
|
|
$this->createReal($hostmacros);
|
|
|
|
if ($tpl_hostmacros = $this->getMacrosToInherit($hostmacros)) {
|
|
$this->inherit($tpl_hostmacros);
|
|
}
|
|
|
|
return ['hostmacroids' => array_column($hostmacros, 'hostmacroid')];
|
|
}
|
|
|
|
/**
|
|
* Inserts hostmacros records into the database.
|
|
*
|
|
* @param array $hostmacros
|
|
*/
|
|
private function createReal(array &$hostmacros): void {
|
|
$hostmacroids = DB::insert('hostmacro', $hostmacros);
|
|
|
|
foreach ($hostmacros as $index => &$hostmacro) {
|
|
$hostmacro['hostmacroid'] = $hostmacroids[$index];
|
|
}
|
|
unset($hostmacro);
|
|
}
|
|
|
|
/**
|
|
* @param array $hostmacros
|
|
*
|
|
* @throws APIException if the input is invalid.
|
|
*/
|
|
protected function validateUpdate(array &$hostmacros, array &$db_hostmacros = null) {
|
|
$api_input_rules = ['type' => API_OBJECTS, 'flags' => API_NOT_EMPTY | API_NORMALIZE, 'uniq' => [['hostmacroid']], 'fields' => [
|
|
'hostmacroid' => ['type' => API_ID, 'flags' => API_REQUIRED],
|
|
'macro' => ['type' => API_USER_MACRO, 'length' => DB::getFieldLength('hostmacro', 'macro')],
|
|
'type' => ['type' => API_INT32, 'in' => implode(',', [ZBX_MACRO_TYPE_TEXT, ZBX_MACRO_TYPE_SECRET, ZBX_MACRO_TYPE_VAULT])],
|
|
'value' => ['type' => API_STRING_UTF8, 'length' => DB::getFieldLength('hostmacro', 'value')],
|
|
'description' => ['type' => API_STRING_UTF8, 'length' => DB::getFieldLength('hostmacro', 'description')],
|
|
'automatic' => ['type' => API_INT32, 'in' => implode(',', [ZBX_USERMACRO_MANUAL])]
|
|
]];
|
|
|
|
if (!CApiInputValidator::validate($api_input_rules, $hostmacros, '/', $error)) {
|
|
self::exception(ZBX_API_ERROR_PARAMETERS, $error);
|
|
}
|
|
|
|
$db_hostmacros = $this->get([
|
|
'output' => ['hostmacroid', 'hostid', 'macro', 'type', 'description', 'automatic'],
|
|
'hostmacroids' => array_column($hostmacros, 'hostmacroid'),
|
|
'editable' => true,
|
|
'inherited' => false,
|
|
'preservekeys' => true
|
|
]);
|
|
|
|
if (count($hostmacros) != count($db_hostmacros)) {
|
|
self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!'));
|
|
}
|
|
|
|
// CUserMacro::get does not return secret values. Loading directly from the database.
|
|
$options = [
|
|
'output' => ['hostmacroid', 'value'],
|
|
'hostmacroids' => array_keys($db_hostmacros)
|
|
];
|
|
$db_hostmacro_values = DBselect(DB::makeSql('hostmacro', $options));
|
|
|
|
while ($db_hostmacro_value = DBfetch($db_hostmacro_values)) {
|
|
$db_hostmacros[$db_hostmacro_value['hostmacroid']] += $db_hostmacro_value;
|
|
}
|
|
|
|
$hostmacros = $this->extendObjectsByKey($hostmacros, $db_hostmacros, 'hostmacroid', ['hostid', 'type']);
|
|
|
|
foreach ($hostmacros as $index => &$hostmacro) {
|
|
$db_hostmacro = $db_hostmacros[$hostmacro['hostmacroid']];
|
|
|
|
if ($db_hostmacro['automatic'] == ZBX_USERMACRO_AUTOMATIC && !array_key_exists('automatic', $hostmacro)) {
|
|
self::exception(ZBX_API_ERROR_PERMISSIONS,
|
|
_s('Not allowed to modify automatic user macro "%1$s".', $db_hostmacro['macro'])
|
|
);
|
|
}
|
|
|
|
if ($hostmacro['type'] != $db_hostmacro['type']) {
|
|
if ($db_hostmacro['type'] == ZBX_MACRO_TYPE_SECRET) {
|
|
$hostmacro += ['value' => ''];
|
|
}
|
|
|
|
if ($hostmacro['type'] == ZBX_MACRO_TYPE_VAULT) {
|
|
$hostmacro += ['value' => $db_hostmacro['value']];
|
|
}
|
|
}
|
|
|
|
if (array_key_exists('value', $hostmacro) && $hostmacro['type'] == ZBX_MACRO_TYPE_VAULT) {
|
|
if (!CApiInputValidator::validate([
|
|
'type' => API_VAULT_SECRET,
|
|
'provider' => CSettingsHelper::get(CSettingsHelper::VAULT_PROVIDER)
|
|
], $hostmacro['value'], '/'.($index + 1).'/value', $error)) {
|
|
self::exception(ZBX_API_ERROR_PARAMETERS, $error);
|
|
}
|
|
}
|
|
}
|
|
unset($hostmacro);
|
|
|
|
$api_input_rules = ['type' => API_OBJECTS, 'uniq' => [['hostid', 'macro']], 'fields' => [
|
|
'hostid' => ['type' => API_ID],
|
|
'macro' => ['type' => API_USER_MACRO]
|
|
]];
|
|
|
|
if (!CApiInputValidator::validateUniqueness($api_input_rules, $hostmacros, '/', $error)) {
|
|
self::exception(ZBX_API_ERROR_PARAMETERS, $error);
|
|
}
|
|
|
|
$this->checkHostDuplicates($hostmacros, $db_hostmacros);
|
|
}
|
|
|
|
/**
|
|
* Checks if any of the given host macros already exist on the corresponding hosts. If the macros are updated and
|
|
* the "hostmacroid" field is set, the method will only fail, if a macro with a different hostmacroid exists.
|
|
* Assumes the "macro", "hostid" and "hostmacroid" fields are valid.
|
|
*
|
|
* @param array $hostmacros
|
|
* @param string $hostmacros[]['hostmacroid'] (optional if $db_hostmacros is null)
|
|
* @param string $hostmacros[]['hostid']
|
|
* @param string $hostmacros[]['macro'] (optional if $db_hostmacros is not null)
|
|
* @param array|null $db_hostmacros
|
|
*
|
|
* @throws APIException if any of the given macros already exist.
|
|
*/
|
|
private function checkHostDuplicates(array $hostmacros, array $db_hostmacros = null) {
|
|
$macro_names = [];
|
|
$existing_macros = [];
|
|
|
|
// Parse each macro, get unique names and, if context exists, narrow down the search.
|
|
foreach ($hostmacros as $index => $hostmacro) {
|
|
if ($db_hostmacros !== null && (!array_key_exists('macro', $hostmacro)
|
|
|| CApiInputValidator::trimMacro($hostmacro['macro'])
|
|
=== CApiInputValidator::trimMacro($db_hostmacros[$hostmacro['hostmacroid']]['macro']))) {
|
|
unset($hostmacros[$index]);
|
|
|
|
continue;
|
|
}
|
|
|
|
$trimmed_macro = CApiInputValidator::trimMacro($hostmacro['macro']);
|
|
[$macro_name] = explode(':', $trimmed_macro, 2);
|
|
$macro_name = !isset($trimmed_macro[strlen($macro_name)]) ? '{$'.$macro_name : '{$'.$macro_name.':';
|
|
|
|
$macro_names[$macro_name] = true;
|
|
$existing_macros[$hostmacro['hostid']] = [];
|
|
}
|
|
|
|
if (!$existing_macros) {
|
|
return;
|
|
}
|
|
|
|
$options = [
|
|
'output' => ['hostmacroid', 'hostid', 'macro'],
|
|
'filter' => ['hostid' => array_keys($existing_macros)],
|
|
'search' => ['macro' => array_keys($macro_names)],
|
|
'searchByAny' => true,
|
|
'startSearch' => true
|
|
];
|
|
|
|
$db_hostmacros = DBselect(DB::makeSql('hostmacro', $options));
|
|
|
|
// Collect existing unique macro names and their contexts for each host.
|
|
while ($db_hostmacro = DBfetch($db_hostmacros)) {
|
|
$trimmed_macro = CApiInputValidator::trimMacro($db_hostmacro['macro']);
|
|
|
|
$existing_macros[$db_hostmacro['hostid']][$trimmed_macro] = $db_hostmacro['hostmacroid'];
|
|
}
|
|
|
|
// Compare each macro name and context to existing one.
|
|
foreach ($hostmacros as $hostmacro) {
|
|
$hostid = $hostmacro['hostid'];
|
|
$trimmed_macro = CApiInputValidator::trimMacro($hostmacro['macro']);
|
|
|
|
if (array_key_exists($trimmed_macro, $existing_macros[$hostid])) {
|
|
$hosts = DB::select('hosts', [
|
|
'output' => ['name'],
|
|
'hostids' => $hostid
|
|
]);
|
|
|
|
self::exception(ZBX_API_ERROR_PARAMETERS,
|
|
_s('Macro "%1$s" already exists on "%2$s".', $hostmacro['macro'], $hosts[0]['name'])
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update host macros.
|
|
*
|
|
* @param array $hostmacros an array of host macros
|
|
*
|
|
* @return array
|
|
*/
|
|
public function update($hostmacros) {
|
|
$this->validateUpdate($hostmacros, $db_hostmacros);
|
|
|
|
$this->updateReal($hostmacros, $db_hostmacros);
|
|
|
|
if ($tpl_hostmacros = $this->getMacrosToInherit($hostmacros, $db_hostmacros)) {
|
|
$this->inherit($tpl_hostmacros);
|
|
}
|
|
|
|
return ['hostmacroids' => array_column($hostmacros, 'hostmacroid')];
|
|
}
|
|
|
|
/**
|
|
* Updates hostmacros records in the database.
|
|
*
|
|
* @param array $hostmacros
|
|
* @param array $db_hostmacros
|
|
*/
|
|
private function updateReal(array $hostmacros, array $db_hostmacros) {
|
|
$upd_hostmacros = [];
|
|
|
|
foreach ($hostmacros as $hostmacro) {
|
|
$db_hostmacro = $db_hostmacros[$hostmacro['hostmacroid']];
|
|
|
|
$upd_hostmacro = DB::getUpdatedValues('hostmacro', $hostmacro, $db_hostmacro);
|
|
|
|
if ($upd_hostmacro) {
|
|
$upd_hostmacros[] = [
|
|
'values' => $upd_hostmacro,
|
|
'where' => ['hostmacroid' => $hostmacro['hostmacroid']]
|
|
];
|
|
}
|
|
}
|
|
|
|
if ($upd_hostmacros) {
|
|
DB::update('hostmacro', $upd_hostmacros);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param array $hostmacroids
|
|
* @param array $db_hostmacros
|
|
*
|
|
* @throws APIException if the input is invalid.
|
|
*/
|
|
protected function validateDelete(array &$hostmacroids, array &$db_hostmacros = null) {
|
|
$api_input_rules = ['type' => API_IDS, 'flags' => API_NOT_EMPTY, 'uniq' => true];
|
|
|
|
if (!CApiInputValidator::validate($api_input_rules, $hostmacroids, '/', $error)) {
|
|
self::exception(ZBX_API_ERROR_PARAMETERS, $error);
|
|
}
|
|
|
|
$db_hostmacros = $this->get([
|
|
'output' => ['hostmacroid', 'hostid', 'macro'],
|
|
'hostmacroids' => $hostmacroids,
|
|
'editable' => true,
|
|
'inherited' => false,
|
|
'preservekeys' => true
|
|
]);
|
|
|
|
if (count($hostmacroids) != count($db_hostmacros)) {
|
|
self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!'));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Remove macros from hosts.
|
|
*
|
|
* @param array $hostmacroids
|
|
*
|
|
* @return array
|
|
*/
|
|
public function delete(array $hostmacroids) {
|
|
$this->validateDelete($hostmacroids, $db_hostmacros);
|
|
|
|
DB::delete('hostmacro', ['hostmacroid' => $hostmacroids]);
|
|
|
|
if ($tpl_hostmacros = $this->getMacrosToInherit($db_hostmacros)) {
|
|
$this->inherit($tpl_hostmacros, true);
|
|
}
|
|
|
|
return ['hostmacroids' => $hostmacroids];
|
|
}
|
|
|
|
/**
|
|
* Checks if the current user has access to the given hosts and templates. Assumes the "hostid" field is valid.
|
|
*
|
|
* @param array $hostids An array of host or template IDs.
|
|
*
|
|
* @throws APIException if the user doesn't have write permissions for the given hosts.
|
|
*/
|
|
protected function checkHostPermissions(array $hostids) {
|
|
$count = API::Host()->get([
|
|
'countOutput' => true,
|
|
'hostids' => $hostids,
|
|
'filter' => [
|
|
'flags' => [ZBX_FLAG_DISCOVERY_NORMAL, ZBX_FLAG_DISCOVERY_CREATED]
|
|
],
|
|
'editable' => true
|
|
]);
|
|
|
|
if ($count == count($hostids)) {
|
|
return;
|
|
}
|
|
|
|
$count += API::Template()->get([
|
|
'countOutput' => true,
|
|
'templateids' => $hostids,
|
|
'editable' => true
|
|
]);
|
|
|
|
if ($count == count($hostids)) {
|
|
return;
|
|
}
|
|
|
|
$count += API::HostPrototype()->get([
|
|
'countOutput' => true,
|
|
'hostids' => $hostids,
|
|
'editable' => true,
|
|
'inherited' => false
|
|
]);
|
|
|
|
if ($count != count($hostids)) {
|
|
self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!'));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Forms the array of hostmacros, which are support the inheritance, from the passed hostmacros array.
|
|
*
|
|
* @param array $hostmacros
|
|
* @param string $hostmacros[]['hostmacroid']
|
|
* @param string $hostmacros[]['hostid']
|
|
* @param string $hostmacros[]['macro'] (optional)
|
|
* @param string $hostmacros[]['value'] (optional)
|
|
* @param string $hostmacros[]['description'] (optional)
|
|
* @param int $hostmacros[]['type'] (optional)
|
|
* @param array|null $db_hostmacros Used to set the old macro name in case when it was
|
|
* updated.
|
|
* @param string $db_hostmacros[<hostmacroid>]['macro']
|
|
*
|
|
* @return array
|
|
*/
|
|
private function getMacrosToInherit(array $hostmacros, array $db_hostmacros = null): array {
|
|
$templated_host_prototypeids = DBfetchColumn(DBselect(
|
|
'SELECT hd.hostid'.
|
|
' FROM host_discovery hd,items i,hosts h'.
|
|
' WHERE hd.parent_itemid=i.itemid'.
|
|
' AND i.hostid=h.hostid'.
|
|
' AND h.status='.HOST_STATUS_TEMPLATE.
|
|
' AND '.dbConditionId('hd.hostid', array_unique(array_column($hostmacros, 'hostid')))
|
|
), 'hostid');
|
|
|
|
if (!$templated_host_prototypeids) {
|
|
return [];
|
|
}
|
|
|
|
foreach ($hostmacros as $index => &$hostmacro) {
|
|
if (!in_array($hostmacro['hostid'], $templated_host_prototypeids)) {
|
|
unset($hostmacros[$index]);
|
|
|
|
continue;
|
|
}
|
|
|
|
if ($db_hostmacros) {
|
|
$db_hostmacro = $db_hostmacros[$hostmacro['hostmacroid']];
|
|
$hostmacro += array_intersect_key($db_hostmacro, array_flip(['macro']));
|
|
|
|
if ($hostmacro['macro'] !== $db_hostmacro['macro']) {
|
|
$hostmacro['macro_old'] = $db_hostmacro['macro'];
|
|
}
|
|
}
|
|
}
|
|
unset($hostmacro);
|
|
|
|
return $hostmacros;
|
|
}
|
|
|
|
/**
|
|
* Prepares and returns an array of child hostmacros, inherited from hostmacros $tpl_hostmacros on the all hosts.
|
|
*
|
|
* @param array $tpl_hostmacros
|
|
* @param string $tpl_hostmacros[]['hostmacroid']
|
|
* @param string $tpl_hostmacros[]['hostid']
|
|
* @param string $tpl_hostmacros[]['macro']
|
|
* @param string $tpl_hostmacros[]['value'] (optional)
|
|
* @param string $tpl_hostmacros[]['description'] (optional)
|
|
* @param int $tpl_hostmacros[]['type'] (optional)
|
|
* @param string $tpl_hostmacros[]['macro_old'] (optional)
|
|
* @param array $ins_hostmacros
|
|
* @param array $upd_hostmacros
|
|
* @param array $db_hostmacros
|
|
*/
|
|
private function prepareInheritedObjects(array $tpl_hostmacros, array &$ins_hostmacros = null,
|
|
array &$upd_hostmacros = null, array &$db_hostmacros = null): void {
|
|
$ins_hostmacros = [];
|
|
$upd_hostmacros = [];
|
|
$db_hostmacros = [];
|
|
|
|
$templateids_hostids = [];
|
|
$hostids = [];
|
|
|
|
$options = [
|
|
'output' => ['hostid', 'templateid'],
|
|
'filter' => ['templateid' => array_unique(array_column($tpl_hostmacros, 'hostid'))]
|
|
];
|
|
$chd_hosts = DBselect(DB::makeSql('hosts', $options));
|
|
|
|
while ($chd_host = DBfetch($chd_hosts)) {
|
|
$templateids_hostids[$chd_host['templateid']][] = $chd_host['hostid'];
|
|
$hostids[] = $chd_host['hostid'];
|
|
}
|
|
|
|
if (!$templateids_hostids) {
|
|
return;
|
|
}
|
|
|
|
$macros = [];
|
|
foreach ($tpl_hostmacros as $tpl_hostmacro) {
|
|
if (array_key_exists('macro_old', $tpl_hostmacro)) {
|
|
$macros[$tpl_hostmacro['macro_old']] = true;
|
|
}
|
|
else {
|
|
$macros[$tpl_hostmacro['macro']] = true;
|
|
}
|
|
}
|
|
|
|
$chd_hostmacros = DB::select('hostmacro', [
|
|
'output' => ['hostmacroid', 'hostid', 'macro', 'type', 'value', 'description'],
|
|
'filter' => ['hostid' => $hostids, 'macro' => array_keys($macros)],
|
|
'preservekeys' => true
|
|
]);
|
|
|
|
$host_macros = array_fill_keys($hostids, []);
|
|
|
|
foreach ($chd_hostmacros as $hostmacroid => $hostmacro) {
|
|
$host_macros[$hostmacro['hostid']][$hostmacro['macro']] = $hostmacroid;
|
|
}
|
|
|
|
foreach ($tpl_hostmacros as $tpl_hostmacro) {
|
|
$templateid = $tpl_hostmacro['hostid'];
|
|
|
|
if (!array_key_exists($templateid, $templateids_hostids)) {
|
|
continue;
|
|
}
|
|
|
|
foreach ($templateids_hostids[$templateid] as $hostid) {
|
|
if (array_key_exists('macro_old', $tpl_hostmacro)) {
|
|
$hostmacroid = $host_macros[$hostid][$tpl_hostmacro['macro_old']];
|
|
|
|
$upd_hostmacros[] = ['hostmacroid' => $hostmacroid, 'hostid' => $hostid] + $tpl_hostmacro;
|
|
$db_hostmacros[$hostmacroid] = $chd_hostmacros[$hostmacroid];
|
|
|
|
unset($chd_hostmacros[$hostmacroid], $host_macros[$hostid][$tpl_hostmacro['macro_old']]);
|
|
}
|
|
elseif (array_key_exists($tpl_hostmacro['macro'], $host_macros[$hostid])) {
|
|
$hostmacroid = $host_macros[$hostid][$tpl_hostmacro['macro']];
|
|
|
|
$upd_hostmacros[] = ['hostmacroid' => $hostmacroid, 'hostid' => $hostid] + $tpl_hostmacro;
|
|
$db_hostmacros[$hostmacroid] = $chd_hostmacros[$hostmacroid];
|
|
|
|
unset($chd_hostmacros[$hostmacroid], $host_macros[$hostid][$tpl_hostmacro['macro']]);
|
|
}
|
|
else {
|
|
$ins_hostmacros[] = ['hostid' => $hostid] + $tpl_hostmacro;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Updates the macros for the children of host prototypes and propagates the inheritance to the child host
|
|
* prototypes.
|
|
*
|
|
* @param array $tpl_hostmacros
|
|
* @param string $tpl_hostmacros[]['hostmacroid']
|
|
* @param string $tpl_hostmacros[]['hostid']
|
|
* @param string $tpl_hostmacros[]['macro']
|
|
* @param string $tpl_hostmacros[]['value'] (optional)
|
|
* @param string $tpl_hostmacros[]['description'] (optional)
|
|
* @param int $tpl_hostmacros[]['type'] (optional)
|
|
* @param string $tpl_hostmacros[]['macro_old'] (optional)
|
|
* @param bool $is_delete Whether the passed hostmacros are intended to delete.
|
|
*/
|
|
private function inherit(array $tpl_hostmacros, bool $is_delete = false): void {
|
|
$this->prepareInheritedObjects($tpl_hostmacros, $ins_hostmacros, $upd_hostmacros, $db_hostmacros);
|
|
|
|
if ($ins_hostmacros) {
|
|
$this->createReal($ins_hostmacros);
|
|
}
|
|
|
|
if ($upd_hostmacros) {
|
|
if ($is_delete) {
|
|
DB::delete('hostmacro', ['hostmacroid' => array_column($upd_hostmacros, 'hostmacroid')]);
|
|
}
|
|
else {
|
|
$this->updateReal($upd_hostmacros, $db_hostmacros);
|
|
}
|
|
}
|
|
|
|
if ($ins_hostmacros || $upd_hostmacros) {
|
|
$this->inherit(array_merge($ins_hostmacros, $upd_hostmacros), $is_delete);
|
|
}
|
|
}
|
|
|
|
protected function applyQueryOutputOptions($tableName, $tableAlias, array $options, array $sqlParts) {
|
|
// Added type to query because it required to check macro is secret or not.
|
|
if (!$this->outputIsRequested('type', $options['output'])) {
|
|
$options['output'][] = 'type';
|
|
}
|
|
|
|
$sqlParts = parent::applyQueryOutputOptions($tableName, $tableAlias, $options, $sqlParts);
|
|
|
|
if ($options['output'] != API_OUTPUT_COUNT && $options['globalmacro'] === null) {
|
|
if ($options['selectGroups'] !== null || $options['selectHostGroups'] !== null
|
|
|| $options['selectTemplateGroups'] !== null || $options['selectHosts'] !== null
|
|
|| $options['selectTemplates'] !== null) {
|
|
$sqlParts = $this->addQuerySelect($this->fieldId('hostid'), $sqlParts);
|
|
}
|
|
}
|
|
|
|
return $sqlParts;
|
|
}
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
protected function applyQueryFilterOptions($table, $alias, array $options, $sql_parts) {
|
|
if (is_array($options['search'])) {
|
|
// Do not allow to search by value for macro of type ZBX_MACRO_TYPE_SECRET.
|
|
if (array_key_exists('value', $options['search'])) {
|
|
$sql_parts['where']['search'] = $alias.'.type!='.ZBX_MACRO_TYPE_SECRET;
|
|
zbx_db_search($table.' '.$alias, [
|
|
'searchByAny' => false,
|
|
'search' => ['value' => $options['search']['value']]
|
|
] + $options, $sql_parts
|
|
);
|
|
unset($options['search']['value']);
|
|
}
|
|
|
|
if ($options['search']) {
|
|
zbx_db_search($table.' '.$alias, $options, $sql_parts);
|
|
}
|
|
}
|
|
|
|
if (is_array($options['filter'])) {
|
|
// Do not allow to filter by value for macro of type ZBX_MACRO_TYPE_SECRET.
|
|
if (array_key_exists('value', $options['filter'])) {
|
|
$sql_parts['where']['filter'] = $alias.'.type!='.ZBX_MACRO_TYPE_SECRET;
|
|
$this->dbFilter($table.' '.$alias, [
|
|
'searchByAny' => false,
|
|
'filter' => ['value' => $options['filter']['value']]
|
|
] + $options, $sql_parts
|
|
);
|
|
unset($options['filter']['value']);
|
|
}
|
|
|
|
if ($options['filter']) {
|
|
$this->dbFilter($table.' '.$alias, $options, $sql_parts);
|
|
}
|
|
}
|
|
|
|
return $sql_parts;
|
|
}
|
|
|
|
protected function addRelatedObjects(array $options, array $result) {
|
|
$result = parent::addRelatedObjects($options, $result);
|
|
|
|
if ($options['globalmacro'] === null) {
|
|
/*
|
|
* Adding objects
|
|
*/
|
|
// adding groups
|
|
$this->addRelatedGroups($options, $result, 'selectGroups');
|
|
$this->addRelatedGroups($options, $result, 'selectHostGroups');
|
|
$this->addRelatedGroups($options, $result, 'selectTemplateGroups');
|
|
|
|
// adding templates
|
|
if ($options['selectTemplates'] !== null && $options['selectTemplates'] != API_OUTPUT_COUNT) {
|
|
$relationMap = $this->createRelationMap($result, 'hostmacroid', 'hostid');
|
|
$templates = API::Template()->get([
|
|
'output' => $options['selectTemplates'],
|
|
'templateids' => $relationMap->getRelatedIds(),
|
|
'preservekeys' => true
|
|
]);
|
|
$result = $relationMap->mapMany($result, $templates, 'templates');
|
|
}
|
|
|
|
// adding templates
|
|
if ($options['selectHosts'] !== null && $options['selectHosts'] != API_OUTPUT_COUNT) {
|
|
$relationMap = $this->createRelationMap($result, 'hostmacroid', 'hostid');
|
|
$templates = API::Host()->get([
|
|
'output' => $options['selectHosts'],
|
|
'hostids' => $relationMap->getRelatedIds(),
|
|
'preservekeys' => true
|
|
]);
|
|
$result = $relationMap->mapMany($result, $templates, 'hosts');
|
|
}
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Adds related host or template groups requested by "select*" options to the resulting object set.
|
|
*
|
|
* @param array $options [IN] Original input options.
|
|
* @param array $result [IN/OUT] Result output.
|
|
* @param string $option [IN] Possible values:
|
|
* - "selectGroups" (deprecated);
|
|
* - "selectHostGroups";
|
|
* - "selectTemplateGroups".
|
|
*/
|
|
private function addRelatedGroups(array $options, array &$result, string $option): void {
|
|
if ($options[$option] === null || $options[$option] === API_OUTPUT_COUNT) {
|
|
return;
|
|
}
|
|
|
|
$res = DBselect(
|
|
'SELECT hm.hostmacroid,hg.groupid'.
|
|
' FROM hostmacro hm,hosts_groups hg'.
|
|
' WHERE '.dbConditionInt('hm.hostmacroid', array_keys($result)).
|
|
' AND hm.hostid=hg.hostid'
|
|
);
|
|
$relationMap = new CRelationMap();
|
|
while ($relation = DBfetch($res)) {
|
|
$relationMap->addRelation($relation['hostmacroid'], $relation['groupid']);
|
|
}
|
|
|
|
switch ($option) {
|
|
case 'selectGroups':
|
|
$output_tag = 'groups';
|
|
$entities = [API::HostGroup(), API::TemplateGroup()];
|
|
break;
|
|
|
|
case 'selectHostGroups':
|
|
$entities = [API::HostGroup()];
|
|
$output_tag = 'hostgroups';
|
|
break;
|
|
|
|
case 'selectTemplateGroups':
|
|
$entities = [API::TemplateGroup()];
|
|
$output_tag = 'templategroups';
|
|
break;
|
|
}
|
|
|
|
$groups = [];
|
|
foreach ($entities as $entity) {
|
|
$groups += $entity->get([
|
|
'output' => $options[$option],
|
|
'groupids' => $relationMap->getRelatedIds(),
|
|
'preservekeys' => true
|
|
]);
|
|
}
|
|
|
|
$result = $relationMap->mapMany($result, $groups, $output_tag);
|
|
}
|
|
|
|
protected function unsetExtraFields(array $objects, array $fields, $output = []) {
|
|
foreach ($objects as &$object) {
|
|
if ($object['type'] == ZBX_MACRO_TYPE_SECRET) {
|
|
unset($object['value']);
|
|
}
|
|
}
|
|
unset($object);
|
|
|
|
return parent::unsetExtraFields($objects, $fields, $output);
|
|
}
|
|
}
|