@cryptotaxi247 / netdata-1 / commits / 9726ca103

Add agent CLI command to remove a stale node (#17691)

* Mark the node as ephemeral in the database Remove node command * Do not unregister the localhost Do not unregister a live node Make sure we rewrite the ephemeral value when a child reconnects

Stelios Fragkakis committed May 20, 2024 at 12:13 UTC 9726ca103cca75236fb090eff97843403b3ed430
5 files changed +94 -4
src/collectors/plugins.d/pluginsd_parser.c
+5 -3
@@ -649,10 +649,12 @@ static inline PARSER_RC pluginsd_label(char **words, size_t num_words, PARSER *p
649
650 if (strcmp(name,HOST_LABEL_IS_EPHEMERAL) == 0) {
651 int is_ephemeral = appconfig_test_boolean_value((char *) value);
652 - if (is_ephemeral) {
653 - RRDHOST *host = pluginsd_require_scope_host(parser, PLUGINSD_KEYWORD_LABEL);
654 - if (likely(host))
652 + RRDHOST *host = pluginsd_require_scope_host(parser, PLUGINSD_KEYWORD_LABEL);
653 + if (host) {
654 + if (is_ephemeral)
655 rrdhost_option_set(host, RRDHOST_OPTION_EPHEMERAL_HOST);
656 + else
657 + rrdhost_option_clear(host, RRDHOST_OPTION_EPHEMERAL_HOST);
658 }
659 }
660
src/daemon/commands.c
+53 -1
@@ -47,6 +47,7 @@ static cmd_status_t cmd_ping_execute(char *args, char **message);
47 static cmd_status_t cmd_aclk_state(char *args, char **message);
48 static cmd_status_t cmd_version(char *args, char **message);
49 static cmd_status_t cmd_dumpconfig(char *args, char **message);
50 +static cmd_status_t cmd_remove_node(char *args, char **message);
51
52 static command_info_t command_info_array[] = {
53 {"help", cmd_help_execute, CMD_TYPE_HIGH_PRIORITY}, // show help menu
@@ -61,7 +62,8 @@ static command_info_t command_info_array[] = {
62 {"ping", cmd_ping_execute, CMD_TYPE_ORTHOGONAL},
63 {"aclk-state", cmd_aclk_state, CMD_TYPE_ORTHOGONAL},
64 {"version", cmd_version, CMD_TYPE_ORTHOGONAL},
64 - {"dumpconfig", cmd_dumpconfig, CMD_TYPE_ORTHOGONAL}
65 + {"dumpconfig", cmd_dumpconfig, CMD_TYPE_ORTHOGONAL},
66 + {"remove-stale-node", cmd_remove_node, CMD_TYPE_ORTHOGONAL}
67 };
68
69 /* Mutexes for commands of type CMD_TYPE_ORTHOGONAL */
@@ -129,6 +131,8 @@ static cmd_status_t cmd_help_execute(char *args, char **message)
131 " Returns current state of ACLK and Cloud connection. (optionally in json).\n"
132 "dumpconfig\n"
133 " Returns the current netdata.conf on stdout.\n"
134 + "remove-stale-node node_id|machine_guid\n"
135 + " Unregisters and removes a node from the cloud.\n"
136 "version\n"
137 " Returns the netdata version.\n",
138 MAX_COMMAND_LENGTH - 1);
@@ -326,6 +330,54 @@ static cmd_status_t cmd_dumpconfig(char *args, char **message)
330 return CMD_STATUS_SUCCESS;
331 }
332
333 +static cmd_status_t cmd_remove_node(char *args, char **message)
334 +{
335 + (void)args;
336 +
337 + BUFFER *wb = buffer_create(1024, NULL);
338 + if (strlen(args) == 0) {
339 + buffer_sprintf(wb, "Please specify a machine or node UUID");
340 + goto done;
341 + }
342 +
343 + RRDHOST *host = NULL;
344 + host = rrdhost_find_by_guid(args);
345 + if (!host)
346 + host = find_host_by_node_id(args);
347 +
348 + if (!host)
349 + buffer_sprintf(wb, "Node with machine or node UUID \"%s\" not found", args);
350 + else {
351 +
352 + if (host == localhost) {
353 + buffer_sprintf(wb, "You cannot unregister the parent node");
354 + goto done;
355 + }
356 +
357 + if (rrdhost_is_online(host)) {
358 + buffer_sprintf(wb, "Cannot unregister a live node");
359 + goto done;
360 + }
361 +
362 + if (!rrdhost_option_check(host, RRDHOST_OPTION_EPHEMERAL_HOST)) {
363 + rrdhost_option_set(host, RRDHOST_OPTION_EPHEMERAL_HOST);
364 + sql_set_host_label(&host->host_uuid, "_is_ephemeral", "true");
365 + aclk_host_state_update(host, 0, 0);
366 + unregister_node(host->machine_guid);
367 + freez(host->node_id);
368 + host->node_id = NULL;
369 + buffer_sprintf(wb, "Unregistering node with machine guid %s, hostname = %s", host->machine_guid, rrdhost_hostname(host));
370 + }
371 + else
372 + buffer_sprintf(wb, "Node with machine guid %s, hostname = %s is already unregistered", host->machine_guid, rrdhost_hostname(host));
373 + }
374 +
375 +done:
376 + *message = strdupz(buffer_tostring(wb));
377 + buffer_free(wb);
378 + return CMD_STATUS_SUCCESS;
379 +}
380 +
381 static void cmd_lock_exclusive(unsigned index)
382 {
383 (void)index;
src/daemon/commands.h
+1
@@ -20,6 +20,7 @@ typedef enum cmd {
20 CMD_ACLK_STATE,
21 CMD_VERSION,
22 CMD_DUMPCONFIG,
23 + CMD_REMOVE_NODE,
24 CMD_TOTAL_COMMANDS
25 } cmd_t;
26
src/database/sqlite/sqlite_metadata.c
+34
@@ -256,6 +256,40 @@ static inline void set_host_node_id(RRDHOST *host, nd_uuid_t *node_id)
256 uuid_unparse_lower(*node_id, wc->node_id);
257 }
258
259 +#define SQL_SET_HOST_LABEL \
260 + "INSERT INTO host_label (host_id, source_type, label_key, label_value, date_created) " \
261 + "VALUES (@host_id, @source_type, @label_key, @label_value, UNIXEPOCH()) ON CONFLICT (host_id, label_key) " \
262 + " DO UPDATE SET source_type = excluded.source_type, label_value=excluded.label_value, date_created=UNIXEPOCH()"
263 +
264 +bool sql_set_host_label(nd_uuid_t *host_id, const char *label_key, const char *label_value)
265 +{
266 + sqlite3_stmt *res = NULL;
267 + bool status = false;
268 +
269 + if (!label_key || !label_value || !host_id)
270 + return false;
271 +
272 + if (!PREPARE_STATEMENT(db_meta, SQL_SET_HOST_LABEL, &res))
273 + return 1;
274 +
275 + int param = 0;
276 + SQLITE_BIND_FAIL(done, sqlite3_bind_blob(res, ++param, host_id, sizeof(*host_id), SQLITE_STATIC));
277 + SQLITE_BIND_FAIL(done, sqlite3_bind_int(res, ++param, RRDLABEL_SRC_AUTO));
278 + SQLITE_BIND_FAIL(done, sqlite3_bind_text(res, ++param, label_key, -1, SQLITE_STATIC));
279 + SQLITE_BIND_FAIL(done, sqlite3_bind_text(res, ++param, label_value, -1, SQLITE_STATIC));
280 +
281 + param = 0;
282 + int rc = execute_insert(res);
283 + status = (rc == SQLITE_DONE);
284 + if (false == status)
285 + error_report("Failed to store node instance information, rc = %d", rc);
286 +done:
287 + REPORT_BIND_FAIL(res, param);
288 + SQLITE_FINALIZE(res);
289 + return status;
290 +}
291 +
292 +
293 #define SQL_UPDATE_NODE_ID "UPDATE node_instance SET node_id = @node_id WHERE host_id = @host_id"
294
295 int update_node_id(nd_uuid_t *host_id, nd_uuid_t *node_id)
src/database/sqlite/sqlite_metadata.h
+1
@@ -49,6 +49,7 @@ void sql_load_node_id(RRDHOST *host);
49 void sql_build_host_system_info(nd_uuid_t *host_id, struct rrdhost_system_info *system_info);
50 void invalidate_node_instances(nd_uuid_t *host_id, nd_uuid_t *claim_id);
51 RRDLABELS *sql_load_host_labels(nd_uuid_t *host_id);
52 +bool sql_set_host_label(nd_uuid_t *host_id, const char *label_key, const char *label_value);
53
54 uint64_t sqlite_get_meta_space(void);
55 int sql_init_meta_database(db_check_action_type_t rebuild, int memory);