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,