function update_trigger($triggerid, $expression = NULL, $description = NULL, $type = NULL, $priority = NULL, $status = NULL, $comments = NULL, $url = NULL, $deps = array(), $templateid = 0) { $trigger = get_trigger_by_triggerid($triggerid); $trig_hosts = get_hosts_by_triggerid($triggerid); $trig_host = DBfetch($trig_hosts); $event_to_unknown = false; if (is_null($expression)) { /* Restore expression */ $expression = explode_exp($trigger["expression"], 0); } else { if ($expression != explode_exp($trigger["expression"], 0)) { $event_to_unknown = true; } } if (!validate_expression($expression)) { return false; } $exp_hosts = get_hosts_by_expression($expression); if ($exp_hosts) { $chd_hosts = get_hosts_by_templateid($trig_host["hostid"]); if (DBfetch($chd_hosts)) { $exp_host = DBfetch($exp_hosts); $db_chd_triggers = get_triggers_by_templateid($triggerid); while ($db_chd_trigger = DBfetch($db_chd_triggers)) { $chd_trig_hosts = get_hosts_by_triggerid($db_chd_trigger["triggerid"]); $chd_trig_host = DBfetch($chd_trig_hosts); $newexpression = str_replace("{" . $exp_host["host"] . ":", "{" . $chd_trig_host["host"] . ":", $expression); // recursion update_trigger($db_chd_trigger["triggerid"], $newexpression, $description, $type, $priority, NULL, $comments, $url, replace_template_dependencies($deps, $chd_trig_host['hostid']), $triggerid); } } } $result = delete_function_by_triggerid($triggerid); if (!$result) { return $result; } $expression = implode_exp($expression, $triggerid); /* errors can be ignored cose function must return NULL */ if ($event_to_unknown) { add_event($triggerid, TRIGGER_VALUE_UNKNOWN); } reset_items_nextcheck($triggerid); $sql = "UPDATE triggers SET"; if (!is_null($expression)) { $sql .= ' expression=' . zbx_dbstr($expression) . ','; } if (!is_null($description)) { $sql .= ' description=' . zbx_dbstr($description) . ','; } if (!is_null($type)) { $sql .= ' type=' . $type . ','; } if (!is_null($priority)) { $sql .= ' priority=' . $priority . ','; } if (!is_null($status)) { $sql .= ' status=' . $status . ','; } if (!is_null($comments)) { $sql .= ' comments=' . zbx_dbstr($comments) . ','; } if (!is_null($url)) { $sql .= ' url=' . zbx_dbstr($url) . ','; } if (!is_null($templateid)) { $sql .= ' templateid=' . $templateid . ','; } $sql .= ' value=2 WHERE triggerid=' . $triggerid; $result = DBexecute($sql); delete_dependencies_by_triggerid($triggerid); foreach ($deps as $id => $triggerid_up) { if (!($result2 = add_trigger_dependency($triggerid, $triggerid_up))) { error(S_INCORRECT_DEPENDENCY . ' [' . expand_trigger_description($triggerid_up) . ']'); } $result &= $result2; } if ($result) { $trig_hosts = get_hosts_by_triggerid($triggerid); $msg = "Trigger '" . $trigger["description"] . "' updated"; $trig_host = DBfetch($trig_hosts); if ($trig_host) { $msg .= " for host '" . $trig_host["host"] . "'"; } info($msg); } if ($result) { $trigger_new = get_trigger_by_triggerid($triggerid); add_audit_ext(AUDIT_ACTION_UPDATE, AUDIT_RESOURCE_TRIGGER, $triggerid, $trigger["description"], 'triggers', $trigger, $trigger_new); } return $result; }
/** * Updates trigger records in database. * * @param array $triggers */ protected function updateReal(array $triggers) { $triggers = zbx_toArray($triggers); $infos = []; $triggerIds = zbx_objectValues($triggers, 'triggerid'); $dbTriggers = $this->get(['output' => API_OUTPUT_EXTEND, 'triggerids' => $triggerIds, 'selectHosts' => ['name'], 'selectDependencies' => ['triggerid'], 'preservekeys' => true, 'nopermissions' => true]); $dbTriggers = CMacrosResolverHelper::resolveTriggerExpressions($dbTriggers); $changedPriorityTriggerIds = []; foreach ($triggers as &$trigger) { $descriptionChanged = false; $expressionChanged = false; $dbTrigger = $dbTriggers[$trigger['triggerid']]; $hosts = zbx_objectValues($dbTrigger['hosts'], 'name'); if (isset($trigger['description']) && strcmp($dbTrigger['description'], $trigger['description']) != 0) { $descriptionChanged = true; } else { $trigger['description'] = $dbTrigger['description']; } if (isset($trigger['expression']) && $dbTrigger['expression'] !== $trigger['expression']) { $this->validateItems($trigger); $expressionChanged = true; $expressionFull = $trigger['expression']; } if ($expressionChanged) { // check the expression $expressionData = new CTriggerExpression(); if (!$expressionData->parse($expressionFull)) { self::exception(ZBX_API_ERROR_PARAMETERS, $expressionData->error); } // remove triggers if expression is changed in a way that trigger will not appear in current host $oldExpressionData = new CTriggerExpression(); $oldExpressionData->parse($dbTrigger['expression']); // check if at least one template has stayed in expression, this means that child trigger will stay in host $oldTemplates = $oldExpressionData->getHosts(); $newTemplates = zbx_toHash($expressionData->getHosts()); $proceed = true; foreach ($oldTemplates as $oldTemplate) { if (isset($newTemplates[$oldTemplate])) { $proceed = false; break; } } // proceed if there is possibility that child triggers should be deleted if ($proceed) { $sql = 'SELECT t.triggerid' . ' FROM triggers t' . ' WHERE t.templateid=' . zbx_dbstr($trigger['triggerid']); $cTrigCursor = DBselect($sql); $cTrigIds = []; while ($cTrig = DBfetch($cTrigCursor)) { // get templates linked to templated trigger host $templateNames = DBfetchArrayAssoc(DBselect('SELECT h.name' . ' FROM hosts h, hosts_templates ht, items i, functions f' . ' WHERE h.hostid = ht.templateid AND ht.hostid = i.hostid AND i.itemid = f.itemid AND' . ' f.triggerid=' . zbx_dbstr($cTrig['triggerid'])), 'name'); // if we have at least one template linked to trigger host inside trigger expression, // then we don't delete this trigger $expressionHosts = $expressionData->getHosts(); foreach ($expressionHosts as $templateName) { if (isset($templateNames[$templateName])) { continue 2; } } $cTrigIds[] = $cTrig['triggerid']; } $this->deleteByIds($cTrigIds); } DB::delete('functions', ['triggerid' => $trigger['triggerid']]); try { $trigger['expression'] = implode_exp($expressionFull, $trigger['triggerid'], $hosts); } catch (Exception $e) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Cannot implode expression "%s".', $expressionFull) . ' ' . $e->getMessage()); } // if the expression has changed, we must revalidate the existing dependencies if (!isset($trigger['dependencies'])) { $trigger['dependencies'] = zbx_objectValues($dbTrigger['dependencies'], 'triggerid'); } } $triggerUpdate = $trigger; if (!$descriptionChanged) { unset($triggerUpdate['description']); } if (!$expressionChanged) { unset($triggerUpdate['expression']); } // skip updating read only values unset($triggerUpdate['state'], $triggerUpdate['value'], $triggerUpdate['lastchange'], $triggerUpdate['error']); DB::update('triggers', ['values' => $triggerUpdate, 'where' => ['triggerid' => $trigger['triggerid']]]); // update service status if (isset($trigger['priority']) && $trigger['priority'] != $dbTrigger['priority']) { $changedPriorityTriggerIds[] = $trigger['triggerid']; } // restore the full expression to properly validate dependencies $trigger['expression'] = $expressionChanged ? $expressionFull : $dbTrigger['expression']; $infos[] = _s('Updated: Trigger "%1$s" on "%2$s".', $trigger['description'], implode(', ', $hosts)); add_audit_ext(AUDIT_ACTION_UPDATE, AUDIT_RESOURCE_TRIGGER, $dbTrigger['triggerid'], $dbTrigger['description'], null, $dbTrigger, $triggerUpdate); } unset($trigger); if ($changedPriorityTriggerIds && $this->usedInItServices($changedPriorityTriggerIds)) { updateItServices(); } foreach ($infos as $info) { info($info); } }
protected function updateReal(array $triggers) { $triggers = zbx_toArray($triggers); $dbTriggers = $this->get(array('triggerids' => zbx_objectValues($triggers, 'triggerid'), 'output' => API_OUTPUT_EXTEND, 'selectHosts' => array('name'), 'preservekeys' => true, 'nopermissions' => true)); $descriptionChanged = $expressionChanged = false; foreach ($triggers as &$trigger) { $dbTrigger = $dbTriggers[$trigger['triggerid']]; $hosts = zbx_objectValues($dbTrigger['hosts'], 'name'); if (isset($trigger['description']) && strcmp($dbTrigger['description'], $trigger['description']) != 0) { $descriptionChanged = true; } $expressionFull = explode_exp($dbTrigger['expression']); if (isset($trigger['expression']) && strcmp($expressionFull, $trigger['expression']) != 0) { $expressionChanged = true; $expressionFull = $trigger['expression']; } if ($descriptionChanged || $expressionChanged) { $expressionData = new CTriggerExpression(); if (!$expressionData->parse($expressionFull)) { 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.')); } } if ($expressionChanged) { DB::delete('functions', array('triggerid' => $trigger['triggerid'])); try { $trigger['expression'] = implode_exp($expressionFull, $trigger['triggerid'], $hosts); } catch (Exception $e) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Cannot implode expression "%s".', $expressionFull) . ' ' . $e->getMessage()); } } $triggerUpdate = $trigger; if (!$descriptionChanged) { unset($triggerUpdate['description']); } if (!$expressionChanged) { unset($triggerUpdate['expression']); } // skip updating read only values unset($triggerUpdate['state'], $triggerUpdate['value'], $triggerUpdate['lastchange'], $triggerUpdate['error']); DB::update('triggers', array('values' => $triggerUpdate, 'where' => array('triggerid' => $trigger['triggerid']))); $description = isset($trigger['description']) ? $trigger['description'] : $dbTrigger['description']; info(_s('Updated: Trigger prototype "%1$s" on "%2$s".', $description, implode(', ', $hosts))); } unset($trigger); }
/** * Updates trigger prototype records in database. * * @param array $triggerPrototypes * * @throws APIException * * @return array */ protected function updateReal(array $triggerPrototypes) { $triggerPrototypes = zbx_toArray($triggerPrototypes); $dbTriggerPrototypes = $this->get(['triggerids' => zbx_objectValues($triggerPrototypes, 'triggerid'), 'output' => API_OUTPUT_EXTEND, 'selectHosts' => ['name'], 'selectDependencies' => ['triggerid'], 'preservekeys' => true, 'nopermissions' => true]); $dbTriggerPrototypes = CMacrosResolverHelper::resolveTriggerExpressions($dbTriggerPrototypes); foreach ($triggerPrototypes as &$triggerPrototype) { $descriptionChanged = false; $expressionChanged = false; $dbTriggerPrototype = $dbTriggerPrototypes[$triggerPrototype['triggerid']]; $hosts = zbx_objectValues($dbTriggerPrototype['hosts'], 'name'); if (isset($triggerPrototype['description']) && strcmp($dbTriggerPrototype['description'], $triggerPrototype['description']) != 0) { $descriptionChanged = true; } if (isset($triggerPrototype['expression']) && $dbTriggerPrototype['expression'] !== $triggerPrototype['expression']) { $expressionChanged = true; $expressionFull = $triggerPrototype['expression']; } if ($expressionChanged) { $expressionData = new CTriggerExpression(); if (!$expressionData->parse($expressionFull)) { 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.')); } DB::delete('functions', ['triggerid' => $triggerPrototype['triggerid']]); try { // Don't change the original expression for inheritance. $expression = implode_exp($expressionFull, $triggerPrototype['triggerid'], $hosts); } catch (Exception $e) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Cannot implode expression "%s".', $expressionFull) . ' ' . $e->getMessage()); } // if the expression has changed, revalidate the existing dependencies if (!isset($triggerPrototype['dependencies'])) { $triggerPrototype['dependencies'] = $dbTriggerPrototype['dependencies']; } } $triggerPrototypeUpdate = $triggerPrototype; if (!$descriptionChanged) { unset($triggerPrototypeUpdate['description']); } if ($expressionChanged) { $triggerPrototypeUpdate['expression'] = $expression; } else { unset($triggerPrototypeUpdate['expression']); } // skip updating read only values unset($triggerPrototypeUpdate['state'], $triggerPrototypeUpdate['value'], $triggerPrototypeUpdate['lastchange'], $triggerPrototypeUpdate['error']); DB::update('triggers', ['values' => $triggerPrototypeUpdate, 'where' => ['triggerid' => $triggerPrototype['triggerid']]]); $description = isset($triggerPrototype['description']) ? $triggerPrototype['description'] : $dbTriggerPrototype['description']; info(_s('Updated: Trigger prototype "%1$s" on "%2$s".', $description, implode(', ', $hosts))); } unset($triggerPrototype); return $triggerPrototypes; }
/** * @param $triggers */ protected function updateReal(array $triggers) { $triggers = zbx_toArray($triggers); $infos = array(); $dbTriggers = $this->get(array('triggerids' => zbx_objectValues($triggers, 'triggerid'), 'output' => API_OUTPUT_EXTEND, 'selectHosts' => array('name'), 'selectDependencies' => API_OUTPUT_REFER, 'preservekeys' => true, 'nopermissions' => true)); $descriptionChanged = $expressionChanged = false; foreach ($triggers as &$trigger) { $dbTrigger = $dbTriggers[$trigger['triggerid']]; $hosts = zbx_objectValues($dbTrigger['hosts'], 'name'); if (isset($trigger['description']) && strcmp($dbTrigger['description'], $trigger['description']) != 0) { $descriptionChanged = true; } else { $trigger['description'] = $dbTrigger['description']; } $expressionFull = explode_exp($dbTrigger['expression']); if (isset($trigger['expression']) && strcmp($expressionFull, $trigger['expression']) != 0) { $this->validateItems($trigger); $expressionChanged = true; $expressionFull = $trigger['expression']; $trigger['error'] = 'Trigger expression updated. No status update so far.'; } if ($expressionChanged) { // check the expression $expressionData = new CTriggerExpression(); if (!$expressionData->parse($expressionFull)) { self::exception(ZBX_API_ERROR_PARAMETERS, $expressionData->error); } // if the trigger contains templates, delete any events that may exist if ($this->expressionHasTemplates($expressionData)) { DB::delete('events', array('object' => EVENT_OBJECT_TRIGGER, 'objectid' => $trigger['triggerid'])); } DB::delete('functions', array('triggerid' => $trigger['triggerid'])); try { $trigger['expression'] = implode_exp($expressionFull, $trigger['triggerid'], $hosts); } catch (Exception $e) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Cannot implode expression "%s".', $expressionFull) . ' ' . $e->getMessage()); } if (isset($trigger['status']) && $trigger['status'] != TRIGGER_STATUS_ENABLED) { if ($trigger['value_flags'] == TRIGGER_VALUE_FLAG_NORMAL) { addUnknownEvent($trigger['triggerid']); $trigger['value_flags'] = TRIGGER_VALUE_FLAG_UNKNOWN; } } // if the expression has changed, we must revalidate the existing dependencies if (!isset($trigger['dependencies'])) { $trigger['dependencies'] = zbx_objectValues($dbTrigger['dependencies'], 'triggerid'); } } $triggerUpdate = $trigger; if (!$descriptionChanged) { unset($triggerUpdate['description']); } if (!$expressionChanged) { unset($triggerUpdate['expression']); } DB::update('triggers', array('values' => $triggerUpdate, 'where' => array('triggerid' => $trigger['triggerid']))); // update service status if (isset($trigger['priority']) && $trigger['priority'] != $dbTrigger['priority']) { $serviceStatus = $dbTrigger['value'] == TRIGGER_VALUE_TRUE ? $trigger['priority'] : 0; updateServices($trigger['triggerid'], $serviceStatus); } // restore the full expression to properly validate dependencies $trigger['expression'] = $expressionChanged ? explode_exp($trigger['expression']) : $expressionFull; $infos[] = _s('Updated: Trigger "%1$s" on "%2$s".', $trigger['description'], implode(', ', $hosts)); add_audit_ext(AUDIT_ACTION_UPDATE, AUDIT_RESOURCE_TRIGGER, $dbTrigger['triggerid'], $dbTrigger['description'], null, $dbTrigger, $triggerUpdate); } unset($trigger); foreach ($infos as $info) { info($info); } }
function update_trigger($triggerid, $expression = NULL, $description = NULL, $type = NULL, $priority = NULL, $status = NULL, $comments = NULL, $url = NULL, $deps = array(), $templateid = 0) { $trigger = get_trigger_by_triggerid($triggerid); $trig_hosts = get_hosts_by_triggerid($triggerid); $trig_host = DBfetch($trig_hosts); $event_to_unknown = false; // Restore expression if (is_null($expression)) { $expression = explode_exp($trigger['expression'], 0); $expr = new CTriggerExpression(array('expression' => $expression)); } else { $expr = new CTriggerExpression(array('expression' => $expression)); $event_to_unknown = empty($expr->errors) && $expression != explode_exp($trigger['expression'], 0); } if (!empty($expr->errors)) { foreach ($expr->errors as $error) { error($error); } return false; } if (!is_null($deps) && !validate_trigger_dependency($expression, $deps)) { error(S_WRONG_DEPENDENCY_ERROR); return false; } if (is_null($description)) { $description = $trigger['description']; } if (CTrigger::exists(array('description' => $description, 'expression' => $expression))) { $host = reset($expr->data['hosts']); $options = array('filter' => array('description' => $description, 'host' => $host), 'output' => API_OUTPUT_EXTEND, 'editable' => 1); $triggers_exist = CTrigger::get($options); $trigger_exist = false; foreach ($triggers_exist as $tnum => $tr) { $tmp_exp = explode_exp($tr['expression'], false); if (strcmp($tmp_exp, $expression) == 0) { $trigger_exist = $tr; break; } } if ($trigger_exist && $trigger_exist['triggerid'] != $trigger['triggerid']) { error('Trigger with name "' . $trigger['description'] . '" and expression "' . $expression . '" already exists.'); return false; } else { if (!$trigger_exist) { error('No Permissions'); return false; } } } $exp_hosts = $expr->data['hosts']; if (!empty($exp_hosts)) { $chd_hosts = get_hosts_by_templateid($trig_host['hostid']); if (DBfetch($chd_hosts)) { $expHostName = reset($exp_hosts); $db_chd_triggers = get_triggers_by_templateid($triggerid); while ($db_chd_trigger = DBfetch($db_chd_triggers)) { $chd_trig_hosts = get_hosts_by_triggerid($db_chd_trigger['triggerid']); $chd_trig_host = DBfetch($chd_trig_hosts); $newexpression = str_replace('{' . $expHostName . ':', '{' . $chd_trig_host['host'] . ':', $expression); // recursion update_trigger($db_chd_trigger['triggerid'], $newexpression, $description, $type, $priority, $status, $comments, $url, is_null($deps) ? null : replace_template_dependencies($deps, $chd_trig_host['hostid']), $triggerid); } } } $result = delete_function_by_triggerid($triggerid); if (!$result) { return $result; } $expression = implode_exp($expression, $triggerid); if (is_null($expression)) { return false; } $update_values = array(); if (!is_null($expression)) { $update_values['expression'] = $expression; } if (!is_null($description)) { $update_values['description'] = $description; } if (!is_null($type)) { $update_values['type'] = $type; } if (!is_null($priority)) { $update_values['priority'] = $priority; } if (!is_null($status)) { $update_values['status'] = $status; } if (!is_null($comments)) { $update_values['comments'] = $comments; } if (!is_null($url)) { $update_values['url'] = $url; } if (!is_null($templateid)) { $update_values['templateid'] = $templateid; } if ($event_to_unknown || !is_null($status) && $status != TRIGGER_STATUS_ENABLED) { if ($trigger['value'] != TRIGGER_VALUE_UNKNOWN) { addEvent($triggerid, TRIGGER_VALUE_UNKNOWN); $update_values['value'] = TRIGGER_VALUE_UNKNOWN; $update_values['lastchange'] = time(); } } DB::update('triggers', array('values' => $update_values, 'where' => array('triggerid=' . $triggerid))); if (!is_null($deps)) { delete_dependencies_by_triggerid($triggerid); foreach ($deps as $id => $triggerid_up) { if (!($result2 = add_trigger_dependency($triggerid, $triggerid_up))) { error(S_INCORRECT_DEPENDENCY . ' [' . expand_trigger_description($triggerid_up) . ']'); } $result &= $result2; } } if ($result) { $trig_hosts = get_hosts_by_triggerid($triggerid); $msg = S_TRIGGER . SPACE . '"' . $trigger['description'] . '"' . SPACE . S_UPDATED_SMALL; $trig_host = DBfetch($trig_hosts); if ($trig_host) { $msg .= SPACE . S_FOR_HOST_SMALL . SPACE . '"' . $trig_host['host'] . '"'; } info($msg); } if ($result) { $trigger_new = get_trigger_by_triggerid($triggerid); add_audit_ext(AUDIT_ACTION_UPDATE, AUDIT_RESOURCE_TRIGGER, $triggerid, $trig_host['host'] . ':' . $trigger['description'], 'triggers', $trigger, $trigger_new); } $result = $result ? $triggerid : $result; return $result; }