0
0
Fork 0
mirror of https://github.com/netdata/netdata.git synced 2025-05-13 13:12:05 +00:00
netdata_netdata/database/rrdfunctions-exporters.c
Costa Tsaousis f2b250a1f5
dyncfg v2 ()
* split rrdfunctions streaming and progress

* simplified internal inline functions API

* split rrdfunctions inflight management

* split rrd functions exporters

* renames

* base dyncfg structure

* config pluginsd

* intercept dyncfg function calls

* loading and saving of dyncfg metadata and data

* save metadata and payload to a single file; added code to update the plugins with jobs and saved configs

* basic working unit test

* added payload to functions execution

* removed old dyncfg code that is not needed any more

* more cleanup

* cleanup sender for functions with payload

* dyncfg functions are not exposed as functions

* remaining work to avoid indexing the \0 terminating character in dictionary keys

* added back old dyncfg plugins.d commands as noop, to allow plugins continue working

* working api; working streaming;

* updated plugins.d documentation

* aclk and http api requests share the same header parsing logic

* added source type internal

* fixed crashes

* added god mode for tests

* fixes

* fixed messages

* save host machine guids to configs

* cleaner manipulation of supported commands

* the functions event loop for external plugins can now process dyncfg requests

* unified internal and external plugins dyncfg API

* Netdata serves schema requests from /etc/netdata/schema.d and /var/lib/netdata/conf.d/schema.d

* cleanup and various fixes; fixed bug in previous dyncfg implementation on streaming that was sending the paylod in a way that allowed other streaming commands to be multiplexed

* internals go to a separate header file

* fix duplicate ACLK requests sent by aclk queue mechanism

* use fstat instead of stat

* working api

* plugin actions renamed to create and delete; dyncfg files are removed only from user actions

* prevent deadlock by using the react callback

* fix for string_strndupz()

* better dyncfg unittests

* more tests at the unittests

* properly detect dyncfg functions

* hide config functions from the UI

* tree response improvements

* send the initial update with payload

* determine tty using stdout, not stderr

* changes to statuses, cleanup and the code to bring all business logic into interception

* do not crash when the status is empty

* functions now propagate the source of the requests to plugins

* avoid warning about unused functions

* in the count at items for attention, do not count the orphan entries

* save source into dyncfg

* make the list null terminated

* fixed invalid comparison

* prevent memory leak on duplicated headers; log x-forwarded-for

* more unit tests

* added dyncfg unittests into the default unittests

* more unit tests and fixes

* more unit tests and fixes

* fix dictionary unittests

* config functions require admin access
2024-01-11 16:56:45 +02:00

164 lines
5.3 KiB
C

// SPDX-License-Identifier: GPL-3.0-or-later
#define NETDATA_RRD_INTERNALS
#include "rrdfunctions-internals.h"
#include "rrdfunctions-exporters.h"
void rrd_chart_functions_expose_rrdpush(RRDSET *st, BUFFER *wb) {
if(!st->functions_view)
return;
struct rrd_host_function *t;
dfe_start_read(st->functions_view, t) {
if(t->options & RRD_FUNCTION_DYNCFG) continue;
buffer_sprintf(wb
, PLUGINSD_KEYWORD_FUNCTION " \"%s\" %d \"%s\" \"%s\" \"%s\" %d\n"
, t_dfe.name
, t->timeout
, string2str(t->help)
, string2str(t->tags)
, http_id2access(t->access)
,
t->priority
);
}
dfe_done(t);
}
void rrd_global_functions_expose_rrdpush(RRDHOST *host, BUFFER *wb, bool dyncfg) {
rrdhost_flag_clear(host, RRDHOST_FLAG_GLOBAL_FUNCTIONS_UPDATED);
size_t configs = 0;
struct rrd_host_function *tmp;
dfe_start_read(host->functions, tmp) {
if(tmp->options & RRD_FUNCTION_LOCAL) continue;
if(tmp->options & RRD_FUNCTION_DYNCFG) {
// we should not send dyncfg to this parent
configs++;
continue;
}
buffer_sprintf(wb
, PLUGINSD_KEYWORD_FUNCTION " GLOBAL \"%s\" %d \"%s\" \"%s\" \"%s\" %d\n"
, tmp_dfe.name
, tmp->timeout
, string2str(tmp->help)
, string2str(tmp->tags)
, http_id2access(tmp->access)
, tmp->priority
);
}
dfe_done(tmp);
if(dyncfg && configs)
dyncfg_add_streaming(wb);
}
static void functions2json(DICTIONARY *functions, BUFFER *wb) {
struct rrd_host_function *t;
dfe_start_read(functions, t) {
if (!rrd_collector_running(t->collector)) continue;
if(t->options & RRD_FUNCTION_DYNCFG) continue;
buffer_json_member_add_object(wb, t_dfe.name);
{
buffer_json_member_add_string_or_empty(wb, "help", string2str(t->help));
buffer_json_member_add_int64(wb, "timeout", (int64_t) t->timeout);
char options[65];
snprintfz(
options, 64
, "%s%s"
, (t->options & RRD_FUNCTION_LOCAL) ? "LOCAL " : ""
, (t->options & RRD_FUNCTION_GLOBAL) ? "GLOBAL" : ""
);
buffer_json_member_add_string_or_empty(wb, "options", options);
buffer_json_member_add_string_or_empty(wb, "tags", string2str(t->tags));
buffer_json_member_add_string(wb, "access", http_id2access(t->access));
buffer_json_member_add_uint64(wb, "priority", t->priority);
}
buffer_json_object_close(wb);
}
dfe_done(t);
}
void chart_functions2json(RRDSET *st, BUFFER *wb) {
if(!st || !st->functions_view) return;
functions2json(st->functions_view, wb);
}
void host_functions2json(RRDHOST *host, BUFFER *wb) {
if(!host || !host->functions) return;
buffer_json_member_add_object(wb, "functions");
struct rrd_host_function *t;
dfe_start_read(host->functions, t) {
if(!rrd_collector_running(t->collector)) continue;
if(t->options & RRD_FUNCTION_DYNCFG) continue;
buffer_json_member_add_object(wb, t_dfe.name);
{
buffer_json_member_add_string(wb, "help", string2str(t->help));
buffer_json_member_add_int64(wb, "timeout", t->timeout);
buffer_json_member_add_array(wb, "options");
{
if (t->options & RRD_FUNCTION_GLOBAL)
buffer_json_add_array_item_string(wb, "GLOBAL");
if (t->options & RRD_FUNCTION_LOCAL)
buffer_json_add_array_item_string(wb, "LOCAL");
}
buffer_json_array_close(wb);
buffer_json_member_add_string(wb, "tags", string2str(t->tags));
buffer_json_member_add_string(wb, "access", http_id2access(t->access));
buffer_json_member_add_uint64(wb, "priority", t->priority);
}
buffer_json_object_close(wb);
}
dfe_done(t);
buffer_json_object_close(wb);
}
void chart_functions_to_dict(DICTIONARY *rrdset_functions_view, DICTIONARY *dst, void *value, size_t value_size) {
if(!rrdset_functions_view || !dst) return;
struct rrd_host_function *t;
dfe_start_read(rrdset_functions_view, t) {
if(!rrd_collector_running(t->collector)) continue;
if(t->options & RRD_FUNCTION_DYNCFG) continue;
dictionary_set(dst, t_dfe.name, value, value_size);
}
dfe_done(t);
}
void host_functions_to_dict(RRDHOST *host, DICTIONARY *dst, void *value, size_t value_size, STRING **help, STRING **tags, HTTP_ACCESS *access, int *priority) {
if(!host || !host->functions || !dictionary_entries(host->functions) || !dst) return;
struct rrd_host_function *t;
dfe_start_read(host->functions, t) {
if(!rrd_collector_running(t->collector)) continue;
if(t->options & RRD_FUNCTION_DYNCFG) continue;
if(help)
*help = t->help;
if(tags)
*tags = t->tags;
if(access)
*access = t->access;
if(priority)
*priority = t->priority;
dictionary_set(dst, t_dfe.name, value, value_size);
}
dfe_done(t);
}