Example #1
0
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;
}
Example #2
0
 /**
  * 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);
     }
 }
Example #3
0
 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;
}