@cryptotaxi247 / netdata-1 / commits / fd1edfb69

Allow to create alert hashes with --disable-cloud (#15519)

* check for alarm ids with zero hashes * use zeroblob(16)

Emmanuel Vasilakis committed Jul 25, 2023 at 19:53 UTC fd1edfb699ea2572046a8f7189b6f389a3e22840
3 files changed +139 -5
database/rrdcalc.c
+7 -3
@@ -82,10 +82,14 @@ uint32_t rrdcalc_get_unique_id(RRDHOST *host, STRING *chart, STRING *name, uint3
82 alarm_id = sql_get_alarm_id(host, chart, name, next_event_id, config_hash_id);
83
84 if (!alarm_id) {
85 - if (unlikely(!host->health_log.next_alarm_id))
86 - host->health_log.next_alarm_id = (uint32_t)now_realtime_sec();
85 + //check possible stored config hash as zeroes or null
86 + alarm_id = sql_get_alarm_id_check_zero_hash(host, chart, name, next_event_id, config_hash_id);
87 + if (!alarm_id) {
88 + if (unlikely(!host->health_log.next_alarm_id))
89 + host->health_log.next_alarm_id = (uint32_t)now_realtime_sec();
90
88 - alarm_id = host->health_log.next_alarm_id++;
91 + alarm_id = host->health_log.next_alarm_id++;
92 + }
93 }
94 }
95
database/sqlite/sqlite_health.c
+131 -2
@@ -1215,7 +1215,7 @@ bind_fail:
1215 if cloud is disabled or openssl is not available (which will prevent cloud connectivity)
1216 skip hash calculations
1217 */
1218 -#if !defined DISABLE_CLOUD && defined ENABLE_HTTPS
1218 +#if defined ENABLE_HTTPS
1219 #define DIGEST_ALERT_CONFIG_VAL(v) ((v) ? EVP_DigestUpdate(evpctx, (string2str(v)), string_strlen((v))) : EVP_DigestUpdate(evpctx, "", 1))
1220 #endif
1221 int alert_hash_and_store_config(
@@ -1223,7 +1223,7 @@ int alert_hash_and_store_config(
1223 struct alert_config *cfg,
1224 int store_hash)
1225 {
1226 -#if !defined DISABLE_CLOUD && defined ENABLE_HTTPS
1226 +#if defined ENABLE_HTTPS
1227 EVP_MD_CTX *evpctx;
1228 unsigned char hash_value[EVP_MAX_MD_SIZE];
1229 unsigned int hash_len;
@@ -1729,6 +1729,135 @@ uint32_t sql_get_alarm_id(RRDHOST *host, STRING *chart, STRING *name, uint32_t *
1729 return alarm_id;
1730 }
1731
1732 +#define SQL_UPDATE_ALARM_ID_WITH_CONFIG_HASH "update health_log set config_hash_id = @config_hash_id where host_id = @host_id and alarm_id = @alarm_id and health_log_id = @health_log_id"
1733 +void sql_update_alarm_with_config_hash(RRDHOST *host, uint32_t alarm_id, uint64_t health_log_id, uuid_t *config_hash_id)
1734 +{
1735 + int rc = 0;
1736 + sqlite3_stmt *res = NULL;
1737 +
1738 + rc = sqlite3_prepare_v2(db_meta, SQL_UPDATE_ALARM_ID_WITH_CONFIG_HASH, -1, &res, 0);
1739 + if (rc != SQLITE_OK) {
1740 + error_report("Failed to prepare statement when trying to update an alarm id with a config hash.");
1741 + return;
1742 + }
1743 +
1744 + rc = sqlite3_bind_blob(res, 1, config_hash_id, sizeof(*config_hash_id), SQLITE_STATIC);
1745 + if (unlikely(rc != SQLITE_OK)) {
1746 + error_report("Failed to bind config_hash_id parameter for SQL_UPDATE_ALARM_ID_WITH_CONFIG_HASH.");
1747 + sqlite3_finalize(res);
1748 + return;
1749 + }
1750 +
1751 + rc = sqlite3_bind_blob(res, 2, &host->host_uuid, sizeof(host->host_uuid), SQLITE_STATIC);
1752 + if (unlikely(rc != SQLITE_OK)) {
1753 + error_report("Failed to bind host_id parameter for SQL_UPDATE_ALARM_ID_WITH_CONFIG_HASH.");
1754 + sqlite3_finalize(res);
1755 + return;
1756 + }
1757 +
1758 + rc = sqlite3_bind_int64(res, 3, (sqlite3_int64) alarm_id);
1759 + if (unlikely(rc != SQLITE_OK)) {
1760 + error_report("Failed to bind alarm_id parameter for SQL_GET_ALARM_ID.");
1761 + sqlite3_finalize(res);
1762 + return;
1763 + }
1764 +
1765 + rc = sqlite3_bind_int64(res, 4, (sqlite3_int64) health_log_id);
1766 + if (unlikely(rc != SQLITE_OK)) {
1767 + error_report("Failed to bind alarm_id parameter for SQL_GET_ALARM_ID.");
1768 + sqlite3_finalize(res);
1769 + return;
1770 + }
1771 +
1772 + rc = execute_insert(res);
1773 + if (unlikely(rc != SQLITE_DONE)) {
1774 + error_report("Failed to execute SQL_UPDATE_ALARM_ID_WITH_CONFIG_HASH, rc = %d", rc);
1775 + rc = sqlite3_finalize(res);
1776 + if (unlikely(rc != SQLITE_OK))
1777 + error_report("Failed to reset statement to update health log detail table with config hash ids, rc = %d", rc);
1778 + return;
1779 + }
1780 +}
1781 +
1782 +#define SQL_GET_ALARM_ID_CHECK_ZERO_HASH "select alarm_id, health_log_id from health_log where host_id = @host_id and chart = @chart and name = @name and (config_hash_id is null or config_hash_id = zeroblob(16))"
1783 +uint32_t sql_get_alarm_id_check_zero_hash(RRDHOST *host, STRING *chart, STRING *name, uint32_t *next_event_id, uuid_t *config_hash_id)
1784 +{
1785 + int rc = 0;
1786 + sqlite3_stmt *res = NULL;
1787 + uint32_t alarm_id = 0;
1788 + uint64_t health_log_id = 0;
1789 +
1790 + rc = sqlite3_prepare_v2(db_meta, SQL_GET_ALARM_ID_CHECK_ZERO_HASH, -1, &res, 0);
1791 + if (rc != SQLITE_OK) {
1792 + error_report("Failed to prepare statement when trying to get an alarm id with zero hash");
1793 + return alarm_id;
1794 + }
1795 +
1796 + rc = sqlite3_bind_blob(res, 1, &host->host_uuid, sizeof(host->host_uuid), SQLITE_STATIC);
1797 + if (unlikely(rc != SQLITE_OK)) {
1798 + error_report("Failed to bind host_id parameter for SQL_GET_ALARM_ID_CHECK_ZERO_HASH.");
1799 + sqlite3_finalize(res);
1800 + return alarm_id;
1801 + }
1802 +
1803 + rc = sqlite3_bind_string_or_null(res, chart, 2);
1804 + if (unlikely(rc != SQLITE_OK)) {
1805 + error_report("Failed to bind char parameter for SQL_GET_ALARM_ID_CHECK_ZERO_HASH.");
1806 + sqlite3_finalize(res);
1807 + return alarm_id;
1808 + }
1809 +
1810 + rc = sqlite3_bind_string_or_null(res, name, 3);
1811 + if (unlikely(rc != SQLITE_OK)) {
1812 + error_report("Failed to bind name parameter for SQL_GET_ALARM_ID_CHECK_ZERO_HASH.");
1813 + sqlite3_finalize(res);
1814 + return alarm_id;
1815 + }
1816 +
1817 + while (sqlite3_step_monitored(res) == SQLITE_ROW) {
1818 + alarm_id = (uint32_t) sqlite3_column_int64(res, 0);
1819 + health_log_id = (uint64_t) sqlite3_column_int64(res, 1);
1820 + }
1821 +
1822 + rc = sqlite3_finalize(res);
1823 + if (unlikely(rc != SQLITE_OK))
1824 + error_report("Failed to finalize the statement while getting an alarm id.");
1825 +
1826 + if (alarm_id) {
1827 + sql_update_alarm_with_config_hash(host, alarm_id, health_log_id, config_hash_id);
1828 +
1829 + rc = sqlite3_prepare_v2(db_meta, SQL_GET_EVENT_ID, -1, &res, 0);
1830 + if (rc != SQLITE_OK) {
1831 + error_report("Failed to prepare statement when trying to get an event id");
1832 + return alarm_id;
1833 + }
1834 +
1835 + rc = sqlite3_bind_int64(res, 1, (sqlite3_int64) health_log_id);
1836 + if (unlikely(rc != SQLITE_OK)) {
1837 + error_report("Failed to bind host_id parameter for SQL_GET_EVENT_ID.");
1838 + sqlite3_finalize(res);
1839 + return alarm_id;
1840 + }
1841 +
1842 + rc = sqlite3_bind_int64(res, 2, (sqlite3_int64) alarm_id);
1843 + if (unlikely(rc != SQLITE_OK)) {
1844 + error_report("Failed to bind char parameter for SQL_GET_EVENT_ID.");
1845 + sqlite3_finalize(res);
1846 + return alarm_id;
1847 + }
1848 +
1849 + while (sqlite3_step_monitored(res) == SQLITE_ROW) {
1850 + *next_event_id = (uint32_t) sqlite3_column_int64(res, 0);
1851 + }
1852 +
1853 + rc = sqlite3_finalize(res);
1854 + if (unlikely(rc != SQLITE_OK))
1855 + error_report("Failed to finalize the statement while getting an alarm id.");
1856 + }
1857 +
1858 + return alarm_id;
1859 +}
1860 +
1861 #define SQL_GET_ALARM_ID_FROM_TRANSITION_ID "SELECT hld.alarm_id, hl.host_id, hl.chart_context FROM " \
1862 "health_log_detail hld, health_log hl WHERE hld.transition_id = @transition_id " \
1863 "and hld.health_log_id = hl.health_log_id"
database/sqlite/sqlite_health.h
+1
@@ -19,6 +19,7 @@ int sql_health_get_last_executed_event(RRDHOST *host, ALARM_ENTRY *ae, RRDCALC_S
19 void sql_health_alarm_log2json(RRDHOST *host, BUFFER *wb, uint32_t after, char *chart);
20 int health_migrate_old_health_log_table(char *table);
21 uint32_t sql_get_alarm_id(RRDHOST *host, STRING *chart, STRING *name, uint32_t *next_event_id, uuid_t *config_hash_id);
22 +uint32_t sql_get_alarm_id_check_zero_hash(RRDHOST *host, STRING *chart, STRING *name, uint32_t *next_event_id, uuid_t *config_hash_id);
23 void sql_alert_transitions(
24 DICTIONARY *nodes,
25 time_t after,