/** * Mass update hosts. * * @param array $hosts multidimensional array with Hosts data * @param array $hosts['hosts'] Array of Host objects to update * @param string $hosts['fields']['host'] Host name. * @param array $hosts['fields']['groupids'] HostGroup IDs add Host to. * @param int $hosts['fields']['port'] Port. OPTIONAL * @param int $hosts['fields']['status'] Host Status. OPTIONAL * @param int $hosts['fields']['useip'] Use IP. OPTIONAL * @param string $hosts['fields']['dns'] DNS. OPTIONAL * @param string $hosts['fields']['ip'] IP. OPTIONAL * @param int $hosts['fields']['bulk'] bulk. OPTIONAL * @param int $hosts['fields']['proxy_hostid'] Proxy Host ID. OPTIONAL * @param int $hosts['fields']['ipmi_authtype'] IPMI authentication type. OPTIONAL * @param int $hosts['fields']['ipmi_privilege'] IPMI privilege. OPTIONAL * @param string $hosts['fields']['ipmi_username'] IPMI username. OPTIONAL * @param string $hosts['fields']['ipmi_password'] IPMI password. OPTIONAL * * @return boolean */ public function massUpdate($data) { $hosts = zbx_toArray($data['hosts']); $inputHostIds = zbx_objectValues($hosts, 'hostid'); $hostids = array_unique($inputHostIds); sort($hostids); $db_hosts = $this->get(['output' => ['hostid', 'tls_connect', 'tls_accept', 'tls_issuer', 'tls_subject', 'tls_psk_identity', 'tls_psk'], 'hostids' => $hostids, 'editable' => true, 'preservekeys' => true]); foreach ($hosts as $host) { if (!array_key_exists($host['hostid'], $db_hosts)) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('You do not have permission to perform this operation.')); } } // Check connection fields only for massupdate action. if ((array_key_exists('tls_connect', $data) || array_key_exists('tls_accept', $data) || array_key_exists('tls_psk_identity', $data) || array_key_exists('tls_psk', $data) || array_key_exists('tls_issuer', $data) || array_key_exists('tls_subject', $data)) && (!array_key_exists('tls_connect', $data) || !array_key_exists('tls_accept', $data))) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('Cannot update host encryption settings. Connection settings for both directions should be specified.')); } $this->validateEncryption([$data]); // Clean PSK fields. if (array_key_exists('tls_connect', $data) && $data['tls_connect'] != HOST_ENCRYPTION_PSK && (array_key_exists('tls_accept', $data) && ($data['tls_accept'] & HOST_ENCRYPTION_PSK) != HOST_ENCRYPTION_PSK)) { $data['tls_psk_identity'] = ''; $data['tls_psk'] = ''; } // Clean certificate fields. if (array_key_exists('tls_connect', $data) && $data['tls_connect'] != HOST_ENCRYPTION_CERTIFICATE && (array_key_exists('tls_accept', $data) && ($data['tls_accept'] & HOST_ENCRYPTION_CERTIFICATE) != HOST_ENCRYPTION_CERTIFICATE)) { $data['tls_issuer'] = ''; $data['tls_subject'] = ''; } // check if hosts have at least 1 group if (isset($data['groups']) && empty($data['groups'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('No groups for hosts.')); } /* * Update hosts properties */ if (isset($data['name'])) { if (count($hosts) > 1) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Cannot mass update visible host name.')); } } if (isset($data['host'])) { if (!preg_match('/^' . ZBX_PREG_HOST_FORMAT . '$/', $data['host'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect characters used for host name "%s".', $data['host'])); } if (count($hosts) > 1) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Cannot mass update host name.')); } $curHost = reset($hosts); $sameHostnameHost = $this->get(['output' => ['hostid'], 'filter' => ['host' => $data['host']], 'nopermissions' => true, 'limit' => 1]); $sameHostnameHost = reset($sameHostnameHost); if ($sameHostnameHost && bccomp($sameHostnameHost['hostid'], $curHost['hostid']) != 0) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Host "%1$s" already exists.', $data['host'])); } // can't add host with the same name as existing template $sameHostnameTemplate = API::Template()->get(['output' => ['templateid'], 'filter' => ['host' => $data['host']], 'nopermissions' => true, 'limit' => 1]); if ($sameHostnameTemplate) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Template "%1$s" already exists.', $data['host'])); } } if (isset($data['groups'])) { $updateGroups = $data['groups']; } if (isset($data['interfaces'])) { $updateInterfaces = $data['interfaces']; } if (array_key_exists('templates_clear', $data)) { $updateTemplatesClear = zbx_toArray($data['templates_clear']); } if (isset($data['templates'])) { $updateTemplates = $data['templates']; } if (isset($data['macros'])) { $updateMacros = $data['macros']; } // second check is necessary, because import incorrectly inputs unset 'inventory' as empty string rather than null if (isset($data['inventory']) && $data['inventory']) { if (isset($data['inventory_mode']) && $data['inventory_mode'] == HOST_INVENTORY_DISABLED) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Cannot set inventory fields for disabled inventory.')); } $updateInventory = $data['inventory']; $updateInventory['inventory_mode'] = null; } if (isset($data['inventory_mode'])) { if (!isset($updateInventory)) { $updateInventory = []; } $updateInventory['inventory_mode'] = $data['inventory_mode']; } if (isset($data['status'])) { $updateStatus = $data['status']; } unset($data['hosts'], $data['groups'], $data['interfaces'], $data['templates_clear'], $data['templates'], $data['macros'], $data['inventory'], $data['inventory_mode'], $data['status']); if (!zbx_empty($data)) { DB::update('hosts', ['values' => $data, 'where' => ['hostid' => $hostids]]); } if (isset($updateStatus)) { updateHostStatus($hostids, $updateStatus); } /* * Update template linkage */ if (isset($updateTemplatesClear)) { $templateIdsClear = zbx_objectValues($updateTemplatesClear, 'templateid'); if ($updateTemplatesClear) { $this->massRemove(['hostids' => $hostids, 'templateids_clear' => $templateIdsClear]); } } else { $templateIdsClear = []; } // unlink templates if (isset($updateTemplates)) { $hostTemplates = API::Template()->get(['hostids' => $hostids, 'output' => ['templateid'], 'preservekeys' => true]); $hostTemplateids = array_keys($hostTemplates); $newTemplateids = zbx_objectValues($updateTemplates, 'templateid'); $templatesToDel = array_diff($hostTemplateids, $newTemplateids); $templatesToDel = array_diff($templatesToDel, $templateIdsClear); if ($templatesToDel) { $result = $this->massRemove(['hostids' => $hostids, 'templateids' => $templatesToDel]); if (!$result) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Cannot unlink template')); } } } /* * update interfaces */ if (isset($updateInterfaces)) { foreach ($hostids as $hostid) { API::HostInterface()->replaceHostInterfaces(['hostid' => $hostid, 'interfaces' => $updateInterfaces]); } } // link new templates if (isset($updateTemplates)) { $result = $this->massAdd(['hosts' => $hosts, 'templates' => $updateTemplates]); if (!$result) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Cannot link template')); } } // macros if (isset($updateMacros)) { DB::delete('hostmacro', ['hostid' => $hostids]); $this->massAdd(['hosts' => $hosts, 'macros' => $updateMacros]); } /* * Inventory */ if (isset($updateInventory)) { // disabling inventory if ($updateInventory['inventory_mode'] == HOST_INVENTORY_DISABLED) { $sql = 'DELETE FROM host_inventory WHERE ' . dbConditionInt('hostid', $hostids); if (!DBexecute($sql)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Cannot delete inventory.')); } } else { $existingInventoriesDb = DBfetchArrayAssoc(DBselect('SELECT hostid,inventory_mode' . ' FROM host_inventory' . ' WHERE ' . dbConditionInt('hostid', $hostids)), 'hostid'); // check existing host inventory data $automaticHostIds = []; if ($updateInventory['inventory_mode'] === null) { foreach ($hostids as $hostid) { // if inventory is disabled for one of the updated hosts, throw an exception if (!isset($existingInventoriesDb[$hostid])) { $host = get_host_by_hostid($hostid); self::exception(ZBX_API_ERROR_PARAMETERS, _s('Inventory disabled for host "%1$s".', $host['host'])); } elseif ($existingInventoriesDb[$hostid]['inventory_mode'] == HOST_INVENTORY_AUTOMATIC) { $automaticHostIds[] = $hostid; } } } $inventoriesToSave = []; foreach ($hostids as $hostid) { $hostInventory = $updateInventory; $hostInventory['hostid'] = $hostid; // if no 'inventory_mode' has been passed, set inventory 'inventory_mode' from DB if ($updateInventory['inventory_mode'] === null) { $hostInventory['inventory_mode'] = $existingInventoriesDb[$hostid]['inventory_mode']; } $inventoriesToSave[$hostid] = $hostInventory; } // when updating automatic inventory, ignore fields that have items linked to them if ($updateInventory['inventory_mode'] == HOST_INVENTORY_AUTOMATIC || $updateInventory['inventory_mode'] === null && $automaticHostIds) { $itemsToInventories = API::item()->get(['output' => ['inventory_link', 'hostid'], 'hostids' => $automaticHostIds ? $automaticHostIds : $hostids, 'nopermissions' => true]); $inventoryFields = getHostInventories(); foreach ($itemsToInventories as $hinv) { // 0 means 'no link' if ($hinv['inventory_link'] != 0) { $inventoryName = $inventoryFields[$hinv['inventory_link']]['db_field']; unset($inventoriesToSave[$hinv['hostid']][$inventoryName]); } } } // save inventory data foreach ($inventoriesToSave as $inventory) { $hostid = $inventory['hostid']; if (isset($existingInventoriesDb[$hostid])) { DB::update('host_inventory', ['values' => $inventory, 'where' => ['hostid' => $hostid]]); } else { DB::insert('host_inventory', [$inventory], false); } } } } /* * Update host and host group linkage. This procedure should be done the last because user can unlink * him self from a group with write permissions leaving only read premissions. Thus other procedures, like * host-template linkage, inventory update, macros update, must be done before this. */ if (isset($updateGroups)) { $updateGroups = zbx_toArray($updateGroups); $hostGroups = API::HostGroup()->get(['output' => ['groupid'], 'hostids' => $hostids]); $hostGroupIds = zbx_objectValues($hostGroups, 'groupid'); $newGroupIds = zbx_objectValues($updateGroups, 'groupid'); $groupsToAdd = array_diff($newGroupIds, $hostGroupIds); if ($groupsToAdd) { $this->massAdd(['hosts' => $hosts, 'groups' => zbx_toObject($groupsToAdd, 'groupid')]); } $groupIdsToDelete = array_diff($hostGroupIds, $newGroupIds); if ($groupIdsToDelete) { $this->massRemove(['hostids' => $hostids, 'groupids' => $groupIdsToDelete]); } } return ['hostids' => $inputHostIds]; }
$goResult = DBend($goResult); show_messages($goResult, _('Host deleted'), _('Cannot delete host')); clearCookies($goResult); } elseif (str_in_array(getRequest('go'), array('activate', 'disable'))) { $enable = getRequest('go') == 'activate'; $status = $enable ? TRIGGER_STATUS_ENABLED : TRIGGER_STATUS_DISABLED; $hosts = getRequest('hosts', array()); $actHosts = API::Host()->get(array('hostids' => $hosts, 'editable' => true, 'templated_hosts' => true, 'output' => array('hostid', 'name'))); ########################################## # get host name $hostNames = zbx_objectValues($actHosts, 'name'); ########################################## $actHosts = zbx_objectValues($actHosts, 'hostid'); if ($actHosts) { DBstart(); $result = updateHostStatus($actHosts, $status); $result = DBend($result); $updated = count($actHosts); $messageSuccess = $enable ? _n('Host enabled', 'Hosts enabled', $updated) : _n('Host disabled', 'Hosts disabled', $updated); $messageFailed = $enable ? _n('Cannot enable host', 'Cannot enable hosts', $updated) : _n('Cannot disable host', 'Cannot disable hosts', $updated); ################################################################ # update racktables object require_once 'racktablesapi.php'; $response = updateObjectStatus($hostNames, $status); if (isset($response['error'])) { show_messages(false, '', "Updating racktables object is failed. Error messageļ¼" . $response['error']); } ################################################################ show_messages($result, $messageSuccess, $messageFailed); clearCookies($result); }
/** * Mass update hosts * * @param array $hosts multidimensional array with Hosts data * @param array $hosts ['hosts'] Array of Host objects to update * @param string $hosts ['fields']['host'] Host name. * @param array $hosts ['fields']['groupids'] HostGroup IDs add Host to. * @param int $hosts ['fields']['port'] Port. OPTIONAL * @param int $hosts ['fields']['status'] Host Status. OPTIONAL * @param int $hosts ['fields']['useip'] Use IP. OPTIONAL * @param string $hosts ['fields']['dns'] DNS. OPTIONAL * @param string $hosts ['fields']['ip'] IP. OPTIONAL * @param int $hosts ['fields']['proxy_hostid'] Proxy Host ID. OPTIONAL * @param int $hosts ['fields']['ipmi_authtype'] IPMI authentication type. OPTIONAL * @param int $hosts ['fields']['ipmi_privilege'] IPMI privilege. OPTIONAL * @param string $hosts ['fields']['ipmi_username'] IPMI username. OPTIONAL * @param string $hosts ['fields']['ipmi_password'] IPMI password. OPTIONAL * * @return boolean */ public function massUpdate($data) { $hosts = zbx_toArray($data['hosts']); $hostids = zbx_objectValues($hosts, 'hostid'); $updHosts = $this->get(array('hostids' => $hostids, 'editable' => true, 'output' => API_OUTPUT_EXTEND, 'preservekeys' => true)); foreach ($hosts as $host) { if (!isset($updHosts[$host['hostid']])) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('You do not have permission to perform this operation.')); } } // check if hosts have at least 1 group if (isset($data['groups']) && empty($data['groups'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('No groups for hosts.')); } /* * Update hosts properties */ if (isset($data['name'])) { if (count($hosts) > 1) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Cannot mass update visible host name.')); } } if (isset($data['host'])) { if (!preg_match('/^' . ZBX_PREG_HOST_FORMAT . '$/', $data['host'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect characters used for host name "%s".', $data['host'])); } if (count($hosts) > 1) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Cannot mass update host name.')); } $curHost = reset($hosts); $hostExists = $this->get(array('filter' => array('host' => $curHost['host']), 'output' => API_OUTPUT_SHORTEN, 'editable' => true, 'nopermissions' => true)); $hostExist = reset($hostExists); if ($hostExist && bccomp($hostExist['hostid'], $curHost['hostid']) != 0) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Host "%1$s" already exists.', $data['host'])); } // can't add host with the same name as existing template if (API::Template()->exists(array('host' => $curHost['host']))) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Template "%1$s" already exists.', $curHost['host'])); } } if (isset($data['groups'])) { $updateGroups = $data['groups']; unset($data['groups']); } if (isset($data['interfaces'])) { $updateInterfaces = $data['interfaces']; unset($data['interfaces']); } if (isset($data['templates_clear'])) { $updateTemplatesClear = zbx_toArray($data['templates_clear']); unset($data['templates_clear']); } if (isset($data['templates'])) { $updateTemplates = $data['templates']; unset($data['templates']); } if (isset($data['macros'])) { $updateMacros = $data['macros']; unset($data['macros']); } if (isset($data['inventory'])) { $updateInventory = $data['inventory']; unset($data['inventory']); } if (isset($data['inventory_mode'])) { if (!isset($updateInventory)) { $updateInventory = array(); } $updateInventory['inventory_mode'] = $data['inventory_mode']; unset($data['inventory_mode']); } if (isset($data['status'])) { $updateStatus = $data['status']; unset($data['status']); } unset($data['hosts']); if (!zbx_empty($data)) { $update = array('values' => $data, 'where' => array('hostid' => $hostids)); DB::update('hosts', $update); } if (isset($updateStatus)) { updateHostStatus($hostids, $updateStatus); } /* * Update hostgroups linkage */ if (isset($updateGroups)) { $updateGroups = zbx_toArray($updateGroups); $hostGroups = API::HostGroup()->get(array('hostids' => $hostids)); $hostGroupids = zbx_objectValues($hostGroups, 'groupid'); $newGroupids = zbx_objectValues($updateGroups, 'groupid'); $result = $this->massAdd(array('hosts' => $hosts, 'groups' => $updateGroups)); if (!$result) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Cannot create host group.')); } $groupidsToDel = array_diff($hostGroupids, $newGroupids); if (!empty($groupidsToDel)) { $result = $this->massRemove(array('hostids' => $hostids, 'groupids' => $groupidsToDel)); if (!$result) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Cannot delete host group.')); } } } /* * Update interfaces */ if (isset($updateInterfaces)) { $hostInterfaces = API::HostInterface()->get(array('hostids' => $hostids, 'output' => API_OUTPUT_EXTEND, 'preservekeys' => true, 'nopermissions' => true)); $this->massRemove(array('hostids' => $hostids, 'interfaces' => $hostInterfaces)); $this->massAdd(array('hosts' => $hosts, 'interfaces' => $updateInterfaces)); } if (isset($updateTemplatesClear)) { $templateidsClear = zbx_objectValues($updateTemplatesClear, 'templateid'); if (!empty($updateTemplatesClear)) { $this->massRemove(array('hostids' => $hostids, 'templateids_clear' => $templateidsClear)); } } else { $templateidsClear = array(); } /* * Update template linkage */ if (isset($updateTemplates)) { $hostTemplates = API::Template()->get(array('hostids' => $hostids, 'output' => API_OUTPUT_SHORTEN, 'preservekeys' => true)); $hostTemplateids = array_keys($hostTemplates); $newTemplateids = zbx_objectValues($updateTemplates, 'templateid'); $templatesToDel = array_diff($hostTemplateids, $newTemplateids); $templatesToDel = array_diff($templatesToDel, $templateidsClear); if (!empty($templatesToDel)) { $result = $this->massRemove(array('hostids' => $hostids, 'templateids' => $templatesToDel)); if (!$result) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Cannot unlink template')); } } $result = $this->massAdd(array('hosts' => $hosts, 'templates' => $updateTemplates)); if (!$result) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Cannot link template')); } } // macros if (isset($updateMacros)) { DB::delete('hostmacro', array('hostid' => $hostids)); $this->massAdd(array('hosts' => $hosts, 'macros' => $updateMacros)); } /* * Inventory */ if (isset($updateInventory)) { if ($updateInventory['inventory_mode'] == HOST_INVENTORY_DISABLED) { $sql = 'DELETE FROM host_inventory WHERE ' . dbConditionInt('hostid', $hostids); if (!DBexecute($sql)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Cannot delete inventory.')); } } else { $hostsWithInventories = array(); $existingInventoriesDb = DBselect('SELECT hostid FROM host_inventory WHERE ' . dbConditionInt('hostid', $hostids)); while ($existingInventory = DBfetch($existingInventoriesDb)) { $hostsWithInventories[] = $existingInventory['hostid']; } // when hosts are being updated to use automatic mode for host inventories, // we must check if some items are set to populate inventory fields of every host. // if they do, mass update for those fields should be ignored if ($updateInventory['inventory_mode'] == HOST_INVENTORY_AUTOMATIC) { // getting all items on all affected hosts $itemsToInventories = API::item()->get(array('output' => array('inventory_link', 'hostid'), 'filter' => array('hostid' => $hostids), 'nopermissions' => true)); // gathering links to array: 'hostid'=>array('inventory_name_1'=>true, 'inventory_name_2'=>true) $inventoryLinksOnHosts = array(); $inventoryFields = getHostInventories(); foreach ($itemsToInventories as $hinv) { if ($hinv['inventory_link'] != 0) { // 0 means 'no link' if (isset($inventoryLinksOnHosts[$hinv['hostid']])) { $inventoryLinksOnHosts[$hinv['hostid']][$inventoryFields[$hinv['inventory_link']]['db_field']] = true; } else { $inventoryLinksOnHosts[$hinv['hostid']] = array($inventoryFields[$hinv['inventory_link']]['db_field'] => true); } } } // now we have all info we need to determine, which inventory fields should be saved $inventoriesToSave = array(); foreach ($hostids as $hostid) { $inventoriesToSave[$hostid] = $updateInventory; $inventoriesToSave[$hostid]['hostid'] = $hostid; foreach ($updateInventory as $inventoryName => $hinv) { if (isset($inventoryLinksOnHosts[$hostid][$inventoryName])) { unset($inventoriesToSave[$hostid][$inventoryName]); } } } } else { // if mode is not automatic, all fields can be saved $inventoriesToSave = array(); foreach ($hostids as $hostid) { $inventoriesToSave[$hostid] = $updateInventory; $inventoriesToSave[$hostid]['hostid'] = $hostid; } } $hostsWithoutInventory = array_diff($hostids, $hostsWithInventories); // hosts that have no inventory yet, need it to be inserted foreach ($hostsWithoutInventory as $hostid) { DB::insert('host_inventory', array($inventoriesToSave[$hostid]), false); } // those hosts that already have an inventory, need it to be updated foreach ($hostsWithInventories as $hostid) { DB::update('host_inventory', array('values' => $inventoriesToSave[$hostid], 'where' => array('hostid' => $hostid))); } } } return array('hostids' => $hostids); }
} elseif (isset($_REQUEST['clone']) && isset($_REQUEST['proxyid'])) { unset($_REQUEST['proxyid'], $_REQUEST['hosts']); $_REQUEST['form'] = 'clone'; } elseif (str_in_array($_REQUEST['go'], array('activate', 'disable')) && isset($_REQUEST['hosts'])) { $goResult = true; $status = $_REQUEST['go'] == 'activate' ? HOST_STATUS_MONITORED : HOST_STATUS_NOT_MONITORED; $hosts = get_request('hosts', array()); DBstart(); foreach ($hosts as $hostId) { $dbHosts = DBselect('SELECT h.hostid,h.status' . ' FROM hosts h' . ' WHERE h.proxy_hostid=' . zbx_dbstr($hostId) . andDbNode('h.hostid')); while ($dbHost = DBfetch($dbHosts)) { $oldStatus = $dbHost['status']; if ($oldStatus == $status) { continue; } $goResult &= updateHostStatus($dbHost['hostid'], $status); if (!$goResult) { continue; } } } $goResult = DBend($goResult && $hosts); show_messages($goResult, _('Host status updated'), null); clearCookies($goResult); } elseif ($_REQUEST['go'] == 'delete' && isset($_REQUEST['hosts'])) { DBstart(); $goResult = API::Proxy()->delete(get_request('hosts')); $goResult = DBend($goResult); show_messages($goResult, _('Proxy deleted'), _('Cannot delete proxy')); clearCookies($goResult); }
$result = updateHostStatus($_REQUEST['hostid'], $_REQUEST['chstatus']); $result = DBend($result); show_messages($result, _('Host status updated'), _('Cannot update host status')); unset($_REQUEST['chstatus'], $_REQUEST['hostid']); } elseif ($_REQUEST['go'] == 'delete') { $hostids = get_request('hosts', array()); DBstart(); $go_result = API::Host()->delete(zbx_toObject($hostids, 'hostid')); $go_result = DBend($go_result); show_messages($go_result, _('Host deleted'), _('Cannot delete host')); } elseif (str_in_array($_REQUEST['go'], array('activate', 'disable'))) { $status = $_REQUEST['go'] == 'activate' ? HOST_STATUS_MONITORED : HOST_STATUS_NOT_MONITORED; $hosts = get_request('hosts', array()); $act_hosts = available_hosts($hosts, 1); DBstart(); $go_result = updateHostStatus($act_hosts, $status); $go_result = DBend($go_result); show_messages($go_result, _('Host status updated'), _('Cannot update host status')); } if ($_REQUEST['go'] != 'none' && isset($go_result) && $go_result) { $url = new CUrl(); $path = $url->getPath(); insert_js('cookie.eraseArray("' . $path . '")'); } /* * Display */ $hosts_wdgt = new CWidget(); $pageFilter = new CPageFilter(array('groups' => array('real_hosts' => 1, 'editable' => true), 'groupid' => get_request('groupid', null))); $_REQUEST['groupid'] = $pageFilter->groupid; $_REQUEST['hostid'] = get_request('hostid', 0);
/** * Mass update hosts. * * @param array $hosts multidimensional array with Hosts data * @param array $hosts['hosts'] Array of Host objects to update * @param string $hosts['fields']['host'] Host name. * @param array $hosts['fields']['groupids'] HostGroup IDs add Host to. * @param int $hosts['fields']['port'] Port. OPTIONAL * @param int $hosts['fields']['status'] Host Status. OPTIONAL * @param int $hosts['fields']['useip'] Use IP. OPTIONAL * @param string $hosts['fields']['dns'] DNS. OPTIONAL * @param string $hosts['fields']['ip'] IP. OPTIONAL * @param int $hosts['fields']['bulk'] bulk. OPTIONAL * @param int $hosts['fields']['proxy_hostid'] Proxy Host ID. OPTIONAL * @param int $hosts['fields']['ipmi_authtype'] IPMI authentication type. OPTIONAL * @param int $hosts['fields']['ipmi_privilege'] IPMI privilege. OPTIONAL * @param string $hosts['fields']['ipmi_username'] IPMI username. OPTIONAL * @param string $hosts['fields']['ipmi_password'] IPMI password. OPTIONAL * * @return boolean */ public function massUpdate($data) { $hosts = zbx_toArray($data['hosts']); $inputHostIds = zbx_objectValues($hosts, 'hostid'); $hostIds = array_unique($inputHostIds); sort($hostIds); $dbHosts = $this->get(array('hostids' => $hostIds, 'editable' => true, 'output' => array('hostid'), 'preservekeys' => true)); foreach ($hosts as $host) { if (!isset($dbHosts[$host['hostid']])) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('You do not have permission to perform this operation.')); } } // check if hosts have at least 1 group if (isset($data['groups']) && empty($data['groups'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('No groups for hosts.')); } /* * Update hosts properties */ if (isset($data['name'])) { if (count($hosts) > 1) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Cannot mass update visible host name.')); } } if (isset($data['host'])) { if (!preg_match('/^' . ZBX_PREG_HOST_FORMAT . '$/', $data['host'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect characters used for host name "%s".', $data['host'])); } if (count($hosts) > 1) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Cannot mass update host name.')); } $curHost = reset($hosts); $sameHostnameHost = $this->get(array('output' => array('hostid'), 'filter' => array('host' => $data['host']), 'nopermissions' => true, 'limit' => 1)); $sameHostnameHost = reset($sameHostnameHost); if ($sameHostnameHost && bccomp($sameHostnameHost['hostid'], $curHost['hostid']) != 0) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Host "%1$s" already exists.', $data['host'])); } // can't add host with the same name as existing template $sameHostnameTemplate = API::Template()->get(array('output' => array('templateid'), 'filter' => array('host' => $data['host']), 'nopermissions' => true, 'limit' => 1)); if ($sameHostnameTemplate) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Template "%1$s" already exists.', $data['host'])); } } if (isset($data['groups'])) { $updateGroups = $data['groups']; } if (isset($data['interfaces'])) { $updateInterfaces = $data['interfaces']; } $b = isset($data['templates_clear']); $c = array_key_exists('templates_clear', $data); $d = array_keys($data); if ($b) { $updateTemplatesClear = zbx_toArray($data['templates_clear']); } if (isset($data['templates'])) { $updateTemplates = $data['templates']; } if (isset($data['macros'])) { $updateMacros = $data['macros']; } // second check is necessary, because import incorrectly inputs unset 'inventory' as empty string rather than null if (isset($data['inventory']) && $data['inventory']) { if (isset($data['inventory_mode']) && $data['inventory_mode'] == HOST_INVENTORY_DISABLED) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Cannot set inventory fields for disabled inventory.')); } $updateInventory = $data['inventory']; $updateInventory['inventory_mode'] = null; } if (isset($data['inventory_mode'])) { if (!isset($updateInventory)) { $updateInventory = array(); } $updateInventory['inventory_mode'] = $data['inventory_mode']; } if (isset($data['status'])) { $updateStatus = $data['status']; } unset($data['hosts'], $data['groups'], $data['interfaces'], $data['templates_clear'], $data['templates'], $data['macros'], $data['inventory'], $data['inventory_mode'], $data['status']); if (!zbx_empty($data)) { DB::update('hosts', array('values' => $data, 'where' => array('hostid' => $hostIds))); } if (isset($updateStatus)) { updateHostStatus($hostIds, $updateStatus); } /* * Update hostgroups linkage */ if (isset($updateGroups)) { $updateGroups = zbx_toArray($updateGroups); $hostGroups = API::HostGroup()->get(array('output' => array('groupid'), 'hostids' => $hostIds)); $hostGroupIds = zbx_objectValues($hostGroups, 'groupid'); $newGroupIds = zbx_objectValues($updateGroups, 'groupid'); $result = $this->massAdd(array('hosts' => $hosts, 'groups' => $updateGroups)); if (!$result) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Cannot create host group.')); } $groupIdsToDel = array_diff($hostGroupIds, $newGroupIds); if ($groupIdsToDel) { $result = $this->massRemove(array('hostids' => $hostIds, 'groupids' => $groupIdsToDel)); if (!$result) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Cannot delete host group.')); } } } /* * Update template linkage */ if (isset($updateTemplatesClear)) { $templateIdsClear = zbx_objectValues($updateTemplatesClear, 'templateid'); if ($updateTemplatesClear) { $this->massRemove(array('hostids' => $hostIds, 'templateids_clear' => $templateIdsClear)); } } else { $templateIdsClear = array(); } // unlink templates if (isset($updateTemplates)) { $hostTemplates = API::Template()->get(array('hostids' => $hostIds, 'output' => array('templateid'), 'preservekeys' => true)); $hostTemplateids = array_keys($hostTemplates); $newTemplateids = zbx_objectValues($updateTemplates, 'templateid'); $templatesToDel = array_diff($hostTemplateids, $newTemplateids); $templatesToDel = array_diff($templatesToDel, $templateIdsClear); if ($templatesToDel) { $result = $this->massRemove(array('hostids' => $hostIds, 'templateids' => $templatesToDel)); if (!$result) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Cannot unlink template')); } } } /* * update interfaces */ if (isset($updateInterfaces)) { foreach ($hostIds as $hostId) { API::HostInterface()->replaceHostInterfaces(array('hostid' => $hostId, 'interfaces' => $updateInterfaces)); } } // link new templates if (isset($updateTemplates)) { $result = $this->massAdd(array('hosts' => $hosts, 'templates' => $updateTemplates)); if (!$result) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Cannot link template')); } } // macros if (isset($updateMacros)) { DB::delete('hostmacro', array('hostid' => $hostIds)); $this->massAdd(array('hosts' => $hosts, 'macros' => $updateMacros)); } /* * Inventory */ if (isset($updateInventory)) { // disabling inventory if ($updateInventory['inventory_mode'] == HOST_INVENTORY_DISABLED) { $sql = 'DELETE FROM host_inventory WHERE ' . dbConditionInt('hostid', $hostIds); if (!DBexecute($sql)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Cannot delete inventory.')); } } else { $existingInventoriesDb = DBfetchArrayAssoc(DBselect('SELECT hostid,inventory_mode' . ' FROM host_inventory' . ' WHERE ' . dbConditionInt('hostid', $hostIds)), 'hostid'); // check existing host inventory data $automaticHostIds = array(); if ($updateInventory['inventory_mode'] === null) { foreach ($hostIds as $hostId) { // if inventory is disabled for one of the updated hosts, throw an exception if (!isset($existingInventoriesDb[$hostId])) { $host = get_host_by_hostid($hostId); self::exception(ZBX_API_ERROR_PARAMETERS, _s('Inventory disabled for host "%1$s".', $host['host'])); } elseif ($existingInventoriesDb[$hostId]['inventory_mode'] == HOST_INVENTORY_AUTOMATIC) { $automaticHostIds[] = $hostId; } } } $inventoriesToSave = array(); foreach ($hostIds as $hostId) { $hostInventory = $updateInventory; $hostInventory['hostid'] = $hostId; // if no 'inventory_mode' has been passed, set inventory 'inventory_mode' from DB if ($updateInventory['inventory_mode'] === null) { $hostInventory['inventory_mode'] = $existingInventoriesDb[$hostId]['inventory_mode']; } $inventoriesToSave[$hostId] = $hostInventory; } // when updating automatic inventory, ignore fields that have items linked to them if ($updateInventory['inventory_mode'] == HOST_INVENTORY_AUTOMATIC || $updateInventory['inventory_mode'] === null && $automaticHostIds) { $itemsToInventories = API::item()->get(array('output' => array('inventory_link', 'hostid'), 'hostids' => $automaticHostIds ? $automaticHostIds : $hostIds, 'nopermissions' => true)); $inventoryFields = getHostInventories(); foreach ($itemsToInventories as $hinv) { // 0 means 'no link' if ($hinv['inventory_link'] != 0) { $inventoryName = $inventoryFields[$hinv['inventory_link']]['db_field']; unset($inventoriesToSave[$hinv['hostid']][$inventoryName]); } } } // save inventory data foreach ($inventoriesToSave as $inventory) { $hostId = $inventory['hostid']; if (isset($existingInventoriesDb[$hostId])) { DB::update('host_inventory', array('values' => $inventory, 'where' => array('hostid' => $hostId))); } else { DB::insert('host_inventory', array($inventory), false); } } } } return array('hostids' => $inputHostIds); }