summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--claim/claim.c1
-rw-r--r--database/rrd.h1
-rw-r--r--database/rrdhost.c2
-rw-r--r--database/sqlite/sqlite_functions.c248
-rw-r--r--database/sqlite/sqlite_functions.h16
5 files changed, 268 insertions, 0 deletions
diff --git a/claim/claim.c b/claim/claim.c
index b29afe6df2..ce3f0803de 100644
--- a/claim/claim.c
+++ b/claim/claim.c
@@ -165,6 +165,7 @@ void load_claiming_state(void)
}
localhost->aclk_state.claimed_id = claimed_id;
+ invalidate_node_instances(&localhost->host_uuid, claimed_id ? &uuid : NULL);
store_claim_id(&localhost->host_uuid, claimed_id ? &uuid : NULL);
rrdhost_aclk_state_unlock(localhost);
diff --git a/database/rrd.h b/database/rrd.h
index d4a3d62179..d91913864f 100644
--- a/database/rrd.h
+++ b/database/rrd.h
@@ -879,6 +879,7 @@ struct rrdhost {
struct rrdengine_instance *rrdeng_ctx; // DB engine instance for this host
#endif
uuid_t host_uuid; // Global GUID for this host
+ uuid_t *node_id; // Cloud node_id
#ifdef ENABLE_HTTPS
struct netdata_ssl ssl; //Structure used to encrypt the connection
diff --git a/database/rrdhost.c b/database/rrdhost.c
index ae49036a8b..5ce5366d23 100644
--- a/database/rrdhost.c
+++ b/database/rrdhost.c
@@ -302,6 +302,7 @@ RRDHOST *rrdhost_create(const char *hostname,
int rc = sql_store_host(&host->host_uuid, hostname, registry_hostname, update_every, os, timezone, tags);
if (unlikely(rc))
error_report("Failed to store machine GUID to the database");
+ sql_load_node_id(host);
}
else
error_report("Host machine GUID %s is not valid", host->machine_guid);
@@ -899,6 +900,7 @@ void rrdhost_free(RRDHOST *host) {
netdata_rwlock_destroy(&host->labels.labels_rwlock);
netdata_rwlock_destroy(&host->health_log.alarm_log_rwlock);
netdata_rwlock_destroy(&host->rrdhost_rwlock);
+ freez(host->node_id);
freez(host);
diff --git a/database/sqlite/sqlite_functions.c b/database/sqlite/sqlite_functions.c
index a41ad44339..382ed8b025 100644
--- a/database/sqlite/sqlite_functions.c
+++ b/database/sqlite/sqlite_functions.c
@@ -1385,3 +1385,251 @@ failed:
return;
}
+
+static inline void set_host_node_id(RRDHOST *host, uuid_t *node_id)
+{
+ if (unlikely(!host))
+ return;
+
+ if (unlikely(!node_id)) {
+ freez(host->node_id);
+ host->node_id = NULL;
+ return;
+ }
+
+ if (unlikely(!host->node_id))
+ host->node_id = mallocz(sizeof(*host->node_id));
+ uuid_copy(*(host->node_id), *node_id);
+ return;
+}
+
+#define SQL_UPDATE_NODE_ID "update node_instance set node_id = @node_id where host_id = @host_id;"
+
+int update_node_id(uuid_t *host_id, uuid_t *node_id)
+{
+ sqlite3_stmt *res = NULL;
+ RRDHOST *host = NULL;
+ int rc = 2;
+
+ if (unlikely(!db_meta)) {
+ if (default_rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE)
+ error_report("Database has not been initialized");
+ return 1;
+ }
+
+ rc = sqlite3_prepare_v2(db_meta, SQL_UPDATE_NODE_ID, -1, &res, 0);
+ if (unlikely(rc != SQLITE_OK)) {
+ error_report("Failed to prepare statement to store node instance information");
+ return 1;
+ }
+
+ rc = sqlite3_bind_blob(res, 1, node_id, sizeof(*node_id), SQLITE_STATIC);
+ if (unlikely(rc != SQLITE_OK)) {
+ error_report("Failed to bind host_id parameter to store node instance information");
+ goto failed;
+ }
+
+ rc = sqlite3_bind_blob(res, 2, host_id, sizeof(*host_id), SQLITE_STATIC);
+ if (unlikely(rc != SQLITE_OK)) {
+ error_report("Failed to bind host_id parameter to store node instance information");
+ goto failed;
+ }
+
+ rc = execute_insert(res);
+ if (unlikely(rc != SQLITE_DONE))
+ error_report("Failed to store node instance information, rc = %d", rc);
+ rc = sqlite3_changes(db_meta);
+
+ char host_guid[GUID_LEN + 1];
+ uuid_unparse_lower(*host_id, host_guid);
+ rrd_wrlock();
+ host = rrdhost_find_by_guid(host_guid, 0);
+ if (likely(host))
+ set_host_node_id(host, node_id);
+ rrd_unlock();
+
+failed:
+ if (unlikely(sqlite3_finalize(res) != SQLITE_OK))
+ error_report("Failed to finalize the prepared statement when storing node instance information");
+
+ return rc - 1;
+}
+
+#define SQL_SELECT_NODE_ID "select node_id from node_instance where host_id = @host_id and node_id not null;"
+
+int get_node_id(uuid_t *host_id, uuid_t *node_id)
+{
+ sqlite3_stmt *res = NULL;
+ int rc;
+
+ if (unlikely(!db_meta)) {
+ if (default_rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE)
+ error_report("Database has not been initialized");
+ return 1;
+ }
+
+ rc = sqlite3_prepare_v2(db_meta, SQL_SELECT_NODE_ID, -1, &res, 0);
+ if (unlikely(rc != SQLITE_OK)) {
+ error_report("Failed to prepare statement to select node instance information for a host");
+ return 1;
+ }
+
+ rc = sqlite3_bind_blob(res, 1, host_id, sizeof(*host_id), SQLITE_STATIC);
+ if (unlikely(rc != SQLITE_OK)) {
+ error_report("Failed to bind host_id parameter to select node instance information");
+ goto failed;
+ }
+
+ rc = sqlite3_step(res);
+ if (likely(rc == SQLITE_ROW && node_id))
+ uuid_copy(*node_id, *((uuid_t *) sqlite3_column_blob(res, 0)));
+
+failed:
+ if (unlikely(sqlite3_finalize(res) != SQLITE_OK))
+ error_report("Failed to finalize the prepared statement when selecting node instance information");
+
+ return (rc == SQLITE_ROW) ? 0 : -1;
+}
+
+#define SQL_INVALIDATE_NODE_INSTANCES "update node_instance set node_id = NULL where exists " \
+ "(select host_id from node_instance where host_id = @host_id and (@claim_id is null or claim_id <> @claim_id));"
+
+void invalidate_node_instances(uuid_t *host_id, uuid_t *claim_id)
+{
+ sqlite3_stmt *res = NULL;
+ int rc;
+
+ if (unlikely(!db_meta)) {
+ if (default_rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE)
+ error_report("Database has not been initialized");
+ return;
+ }
+
+ rc = sqlite3_prepare_v2(db_meta, SQL_INVALIDATE_NODE_INSTANCES, -1, &res, 0);
+ if (unlikely(rc != SQLITE_OK)) {
+ error_report("Failed to prepare statement to invalidate node instance ids");
+ return;
+ }
+
+ rc = sqlite3_bind_blob(res, 1, host_id, sizeof(*host_id), SQLITE_STATIC);
+ if (unlikely(rc != SQLITE_OK)) {
+ error_report("Failed to bind host_id parameter to invalidate node instance information");
+ goto failed;
+ }
+
+ if (claim_id)
+ rc = sqlite3_bind_blob(res, 2, claim_id, sizeof(*claim_id), SQLITE_STATIC);
+ else
+ rc = sqlite3_bind_null(res, 2);
+
+ if (unlikely(rc != SQLITE_OK)) {
+ error_report("Failed to bind claim_id parameter to invalidate node instance information");
+ goto failed;
+ }
+
+ rc = execute_insert(res);
+ if (unlikely(rc != SQLITE_DONE))
+ error_report("Failed to invalidate node instance information, rc = %d", rc);
+
+failed:
+ if (unlikely(sqlite3_finalize(res) != SQLITE_OK))
+ error_report("Failed to finalize the prepared statement when invalidating node instance information");
+}
+
+#define SQL_GET_NODE_INSTANCE_LIST "select ni.node_id, ni.host_id, h.hostname " \
+ "from node_instance ni, host h where ni.host_id = h.host_id;"
+
+struct node_instance_list *get_node_list(void)
+{
+ struct node_instance_list *node_list = NULL;
+ sqlite3_stmt *res = NULL;
+ int rc;
+
+ if (unlikely(!db_meta)) {
+ if (default_rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE)
+ error_report("Database has not been initialized");
+ return NULL;
+ }
+
+ rc = sqlite3_prepare_v2(db_meta, SQL_GET_NODE_INSTANCE_LIST, -1, &res, 0);
+ if (unlikely(rc != SQLITE_OK)) {
+ error_report("Failed to prepare statement store chart labels");
+ return NULL;
+ };
+
+ int row = 0;
+ char host_guid[37];
+ while (sqlite3_step(res) == SQLITE_ROW)
+ row++;
+
+ if (sqlite3_reset(res) != SQLITE_OK) {
+ error_report("Failed to reset the prepared statement fetching storing node instance information");
+ goto failed;
+ }
+ node_list = callocz(row + 1, sizeof(*node_list));
+ int max_rows = row;
+ row = 0;
+ while (sqlite3_step(res) == SQLITE_ROW) {
+ if (sqlite3_column_bytes(res, 0) == sizeof(uuid_t))
+ uuid_copy(node_list[row].node_id, *((uuid_t *)sqlite3_column_blob(res, 0)));
+ if (sqlite3_column_bytes(res, 1) == sizeof(uuid_t)) {
+ uuid_t *host_id = (uuid_t *)sqlite3_column_blob(res, 1);
+ uuid_copy(node_list[row].host_id, *host_id);
+ node_list[row].querable = 1;
+ uuid_unparse_lower(*host_id, host_guid);
+ node_list[row].live = rrdhost_find_by_guid(host_guid, 0) ? 1 : 0;
+ node_list[row].hops = uuid_compare(*host_id, localhost->host_uuid) ? 1 : 0;
+ node_list[row].hostname =
+ sqlite3_column_bytes(res, 2) ? strdupz((char *)sqlite3_column_text(res, 2)) : NULL;
+ }
+ row++;
+ if (row == max_rows)
+ break;
+ }
+
+failed:
+ if (unlikely(sqlite3_finalize(res) != SQLITE_OK))
+ error_report("Failed to finalize the prepared statement when storing node instance information");
+
+ return node_list;
+};
+
+#define SQL_GET_HOST_NODE_ID "select node_id from node_instance where host_id = @host_id;"
+
+void sql_load_node_id(RRDHOST *host)
+{
+ sqlite3_stmt *res = NULL;
+ int rc;
+
+ if (unlikely(!db_meta)) {
+ if (default_rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE)
+ error_report("Database has not been initialized");
+ return;
+ }
+
+ rc = sqlite3_prepare_v2(db_meta, SQL_GET_HOST_NODE_ID, -1, &res, 0);
+ if (unlikely(rc != SQLITE_OK)) {
+ error_report("Failed to prepare statement store chart labels");
+ return;
+ };
+
+ rc = sqlite3_bind_blob(res, 1, &host->host_uuid, sizeof(host->host_uuid), SQLITE_STATIC);
+ if (unlikely(rc != SQLITE_OK)) {
+ error_report("Failed to bind host_id parameter to store node instance information");
+ goto failed;
+ }
+
+ rc = sqlite3_step(res);
+ if (likely(rc == SQLITE_ROW)) {
+ if (likely(sqlite3_column_bytes(res, 0) == sizeof(uuid_t)))
+ set_host_node_id(host, (uuid_t *)sqlite3_column_blob(res, 0));
+ else
+ set_host_node_id(host, NULL);
+ }
+
+failed:
+ if (unlikely(sqlite3_finalize(res) != SQLITE_OK))
+ error_report("Failed to finalize the prepared statement when storing node instance information");
+
+ return;
+};
diff --git a/database/sqlite/sqlite_functions.h b/database/sqlite/sqlite_functions.h
index efbc15ad35..30a52bf734 100644
--- a/database/sqlite/sqlite_functions.h
+++ b/database/sqlite/sqlite_functions.h
@@ -6,6 +6,17 @@
#include "../../daemon/common.h"
#include "sqlite3.h"
+// return a node list
+struct node_instance_list {
+ uuid_t node_id;
+ uuid_t host_id;
+ char *hostname;
+ int live;
+ int querable;
+ int hops;
+};
+
+
#define SQLITE_INSERT_DELAY (50) // Insert delay in case of lock
#define SQL_STORE_HOST "insert or replace into host (host_id,hostname,registry_hostname,update_every,os,timezone,tags) values (?1,?2,?3,?4,?5,?6,?7);"
@@ -61,4 +72,9 @@ extern void delete_dimension_uuid(uuid_t *dimension_uuid);
extern void sql_store_chart_label(uuid_t *chart_uuid, int source_type, char *label, char *value);
extern void sql_build_context_param_list(struct context_param **param_list, RRDHOST *host, char *context, char *chart);
extern void store_claim_id(uuid_t *host_id, uuid_t *claim_id);
+extern int update_node_id(uuid_t *host_id, uuid_t *node_id);
+extern int get_node_id(uuid_t *host_id, uuid_t *node_id);
+extern void invalidate_node_instances(uuid_t *host_id, uuid_t *claim_id);
+extern struct node_instance_list *get_node_list(void);
+extern void sql_load_node_id(RRDHOST *host);
#endif //NETDATA_SQLITE_FUNCTIONS_H