/* ** Copyright (C) 2001-2025 Zabbix SIA ** ** This program is free software: you can redistribute it and/or modify it under the terms of ** the GNU Affero General Public License as published by the Free Software Foundation, version 3. ** ** 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 Affero General Public License for more details. ** ** You should have received a copy of the GNU Affero General Public License along with this program. ** If not, see . **/ #include "zbxdbhigh.h" #include "zbxalgo.h" #include "zbxdb.h" #include "zbxnum.h" #include "zbxstr.h" #include "zbx_trigger_constants.h" #include "zbx_host_constants.h" #include "zbxregexp.h" ZBX_PTR_VECTOR_IMPL(lld_override_ptr, zbx_lld_override_t *) ZBX_PTR_VECTOR_IMPL(lld_condition_ptr, zbx_lld_condition_t *) ZBX_PTR_VECTOR_IMPL(lld_override_operation, zbx_lld_override_operation_t*) void zbx_lld_override_operation_free(zbx_lld_override_operation_t *override_operation) { zbx_vector_db_tag_ptr_clear_ext(&override_operation->tags, zbx_db_tag_free); zbx_vector_db_tag_ptr_destroy(&override_operation->tags); zbx_vector_uint64_destroy(&override_operation->templateids); zbx_free(override_operation->value); zbx_free(override_operation->delay); zbx_free(override_operation->history); zbx_free(override_operation->trends); zbx_free(override_operation); } /****************************************************************************** * * * Purpose: load tag override operations from database * * * * Parameters: overrideids - [IN] lld overrideids, sorted * * sql - [IN/OUT] sql query buffer * * sql_alloc - [IN/OUT] sql query buffer size * * ops - [IN/OUT] lld override operations, sorted by * * override_operationid * * * ******************************************************************************/ static void lld_override_operations_load_tags(const zbx_vector_uint64_t *overrideids, char **sql, size_t *sql_alloc, zbx_vector_lld_override_operation_t *ops) { size_t sql_offset = 0; zbx_db_result_t result; zbx_db_row_t row; zbx_lld_override_operation_t *op = NULL; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__); zbx_strcpy_alloc(sql, sql_alloc, &sql_offset, "select o.lld_override_operationid,ot.tag,ot.value" " from lld_override_operation o,lld_override_optag ot" " where o.lld_override_operationid=ot.lld_override_operationid" " and"); zbx_db_add_condition_alloc(sql, sql_alloc, &sql_offset, "o.lld_overrideid", overrideids->values, overrideids->values_num); zbx_snprintf_alloc(sql, sql_alloc, &sql_offset, " and o.operationobject in (%d,%d,%d)", ZBX_LLD_OVERRIDE_OP_OBJECT_TRIGGER, ZBX_LLD_OVERRIDE_OP_OBJECT_HOST, ZBX_LLD_OVERRIDE_OP_OBJECT_ITEM); zbx_strcpy_alloc(sql, sql_alloc, &sql_offset, " order by o.lld_override_operationid"); result = zbx_db_select("%s", *sql); while (NULL != (row = zbx_db_fetch(result))) { zbx_uint64_t override_operationid; zbx_db_tag_t *tag; ZBX_STR2UINT64(override_operationid, row[0]); if (NULL == op || op->override_operationid != override_operationid) { int index; if (FAIL == (index = zbx_vector_ptr_bsearch((const zbx_vector_ptr_t *)ops, (const void *)&override_operationid, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC))) { THIS_SHOULD_NEVER_HAPPEN; continue; } op = ops->values[index]; } tag = zbx_db_tag_create(row[1], row[2]); zbx_vector_db_tag_ptr_append(&op->tags, tag); } zbx_db_free_result(result); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__); } /****************************************************************************** * * * Purpose: load template lld override operations from database * * * * Parameters: overrideids - [IN] lld overrideids, sorted * * sql - [IN/OUT] sql query buffer * * sql_alloc - [IN/OUT] sql query buffer size * * ops - [IN/OUT] lld override operations, sorted by * * override_operationid * * * ******************************************************************************/ static void lld_override_operations_load_templates(const zbx_vector_uint64_t *overrideids, char **sql, size_t *sql_alloc, zbx_vector_lld_override_operation_t *ops) { size_t sql_offset = 0; zbx_db_result_t result; zbx_db_row_t row; zbx_lld_override_operation_t *op = NULL; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__); zbx_strcpy_alloc(sql, sql_alloc, &sql_offset, "select o.lld_override_operationid,ot.templateid" " from lld_override_operation o,lld_override_optemplate ot" " where o.lld_override_operationid=ot.lld_override_operationid" " and"); zbx_db_add_condition_alloc(sql, sql_alloc, &sql_offset, "o.lld_overrideid", overrideids->values, overrideids->values_num); zbx_snprintf_alloc(sql, sql_alloc, &sql_offset, " and o.operationobject=%d", ZBX_LLD_OVERRIDE_OP_OBJECT_HOST); zbx_strcpy_alloc(sql, sql_alloc, &sql_offset, " order by o.lld_override_operationid"); result = zbx_db_select("%s", *sql); while (NULL != (row = zbx_db_fetch(result))) { zbx_uint64_t templateid, override_operationid; ZBX_STR2UINT64(override_operationid, row[0]); if (NULL == op || op->override_operationid != override_operationid) { int index; if (FAIL == (index = zbx_vector_ptr_bsearch((const zbx_vector_ptr_t *)ops, (const void *)&override_operationid, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC))) { THIS_SHOULD_NEVER_HAPPEN; continue; } op = ops->values[index]; } ZBX_STR2UINT64(templateid, row[1]); zbx_vector_uint64_append(&op->templateids, templateid); } zbx_db_free_result(result); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__); } /****************************************************************************** * * * Purpose: load lld override operations from database * * * * Parameters: overrideids - [IN] lld overrideids, sorted * * sql - [IN/OUT] sql query buffer * * sql_alloc - [IN/OUT] sql query buffer size * * ops - [OUT] lld override operations, sorted by * * override_operationid * * * ******************************************************************************/ void zbx_load_lld_override_operations(const zbx_vector_uint64_t *overrideids, char **sql, size_t *sql_alloc, zbx_vector_lld_override_operation_t *ops) { size_t sql_offset = 0; zbx_db_result_t result; zbx_db_row_t row; zbx_lld_override_operation_t *override_operation = NULL; zbx_uint64_t object_mask = 0; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__); zbx_strcpy_alloc(sql, sql_alloc, &sql_offset, "select o.lld_overrideid,o.lld_override_operationid,o.operationobject,o.operator,o.value," "s.status," "d.discover," "p.delay," "h.history," "t.trends," "os.severity," "i.inventory_mode" " from lld_override_operation o" " left join lld_override_opstatus s" " on o.lld_override_operationid=s.lld_override_operationid" " left join lld_override_opdiscover d" " on o.lld_override_operationid=d.lld_override_operationid" " left join lld_override_opperiod p" " on o.lld_override_operationid=p.lld_override_operationid" " left join lld_override_ophistory h" " on o.lld_override_operationid=h.lld_override_operationid" " left join lld_override_optrends t" " on o.lld_override_operationid=t.lld_override_operationid" " left join lld_override_opseverity os" " on o.lld_override_operationid=os.lld_override_operationid" " left join lld_override_opinventory i" " on o.lld_override_operationid=i.lld_override_operationid" " where"); zbx_db_add_condition_alloc(sql, sql_alloc, &sql_offset, "o.lld_overrideid", overrideids->values, overrideids->values_num); zbx_strcpy_alloc(sql, sql_alloc, &sql_offset, " order by o.lld_override_operationid"); result = zbx_db_select("%s", *sql); while (NULL != (row = zbx_db_fetch(result))) { override_operation = (zbx_lld_override_operation_t *)zbx_malloc(NULL, sizeof(zbx_lld_override_operation_t)); ZBX_STR2UINT64(override_operation->overrideid, row[0]); zbx_vector_db_tag_ptr_create(&override_operation->tags); zbx_vector_uint64_create(&override_operation->templateids); ZBX_STR2UINT64(override_operation->override_operationid, row[1]); override_operation->operationtype = (unsigned char)atoi(row[2]); override_operation->operator = (unsigned char)atoi(row[3]); override_operation->value = zbx_strdup(NULL, row[4]); override_operation->status = FAIL == zbx_db_is_null(row[5]) ? (unsigned char)atoi(row[5]) : ZBX_PROTOTYPE_STATUS_COUNT; override_operation->discover = FAIL == zbx_db_is_null(row[6]) ? (unsigned char)atoi(row[6]) : ZBX_PROTOTYPE_DISCOVER_COUNT; override_operation->delay = FAIL == zbx_db_is_null(row[7]) ? zbx_strdup(NULL, row[7]) : NULL; override_operation->history = FAIL == zbx_db_is_null(row[8]) ? zbx_strdup(NULL, row[8]) : NULL; override_operation->trends = FAIL == zbx_db_is_null(row[9]) ? zbx_strdup(NULL, row[9]) : NULL; override_operation->severity = FAIL == zbx_db_is_null(row[10]) ? (unsigned char)atoi(row[10]) : TRIGGER_SEVERITY_COUNT; override_operation->inventory_mode = FAIL == zbx_db_is_null(row[11]) ? (signed char)atoi(row[11]) : HOST_INVENTORY_COUNT; zbx_vector_lld_override_operation_append(ops, override_operation); object_mask |= (__UINT64_C(1) << override_operation->operationtype); } zbx_db_free_result(result); if (0 != (object_mask & ((1 << ZBX_LLD_OVERRIDE_OP_OBJECT_HOST) | (1 << ZBX_LLD_OVERRIDE_OP_OBJECT_TRIGGER) | (1 << ZBX_LLD_OVERRIDE_OP_OBJECT_ITEM)))) { lld_override_operations_load_tags(overrideids, sql, sql_alloc, ops); } if (0 != (object_mask & (1 << ZBX_LLD_OVERRIDE_OP_OBJECT_HOST))) lld_override_operations_load_templates(overrideids, sql, sql_alloc, ops); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__); } /****************************************************************************** * * * Purpose: releases resources allocated by filter condition * * * * Parameters: condition - [IN] filter condition * * * ******************************************************************************/ static void lld_condition_free(zbx_lld_condition_t *condition) { zbx_regexp_clean_expressions(&condition->regexps); zbx_vector_expression_destroy(&condition->regexps); zbx_free(condition->macro); zbx_free(condition->regexp); zbx_free(condition); } /****************************************************************************** * * * Purpose: releases resources allocated by filter conditions * * * * Parameters: conditions - [IN] filter conditions * * * ******************************************************************************/ static void lld_conditions_free(zbx_vector_lld_condition_ptr_t *conditions) { zbx_vector_lld_condition_ptr_clear_ext(conditions, lld_condition_free); zbx_vector_lld_condition_ptr_destroy(conditions); } void zbx_lld_filter_init(zbx_lld_filter_t *filter) { zbx_vector_lld_condition_ptr_create(&filter->conditions); filter->expression = NULL; filter->evaltype = ZBX_CONDITION_EVAL_TYPE_AND_OR; } /****************************************************************************** * * * Purpose: releases resources allocated by LLD filter * * * ******************************************************************************/ void zbx_lld_filter_clean(zbx_lld_filter_t *filter) { zbx_free(filter->expression); lld_conditions_free(&filter->conditions); } zbx_lld_override_t *zbx_lld_override_create(const char *lld_overrideid, const char *itemid, const char *name, const char *step, const char *evaltype, const char *formula, const char *stop) { zbx_lld_override_t *override = (zbx_lld_override_t *)zbx_malloc(NULL, sizeof(zbx_lld_override_t)); ZBX_DBROW2UINT64(override->overrideid, lld_overrideid); ZBX_DBROW2UINT64(override->itemid, itemid); override->name = (NULL != name ? zbx_strdup(NULL, name) : NULL); ZBX_STR2UCHAR(override->step, step); ZBX_STR2UCHAR(override->stop, stop); zbx_lld_filter_init(&override->filter); override->filter.evaltype = atoi(evaltype); override->filter.expression = zbx_strdup(NULL, formula); zbx_vector_lld_override_operation_create(&override->override_operations); return override; } void zbx_lld_override_free(zbx_lld_override_t *override) { zbx_free(override->name); zbx_lld_filter_clean(&override->filter); zbx_vector_lld_override_operation_clear_ext(&override->override_operations, zbx_lld_override_operation_free); zbx_vector_lld_override_operation_destroy(&override->override_operations); zbx_free(override); } int zbx_lld_override_compare_func(const void *d1, const void *d2) { const zbx_lld_override_t *override_1 = *(const zbx_lld_override_t * const *)d1; const zbx_lld_override_t *override_2 = *(const zbx_lld_override_t * const *)d2; ZBX_RETURN_IF_NOT_EQUAL(override_1->overrideid, override_2->overrideid); return 0; } zbx_lld_condition_t *zbx_lld_filter_condition_create(const char *id, const char *operator, const char *macro, const char *value) { zbx_lld_condition_t *condition = (zbx_lld_condition_t *)zbx_malloc(NULL, sizeof(zbx_lld_condition_t)); ZBX_STR2UINT64(condition->id, id); condition->macro = zbx_strdup(NULL, macro); condition->regexp = zbx_strdup(NULL, value); ZBX_STR2UCHAR(condition->op, operator); zbx_vector_expression_create(&condition->regexps); return condition; }