mirror of
https://github.com/netdata/netdata.git
synced 2025-05-13 13:12:05 +00:00

* 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
164 lines
5.3 KiB
C
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);
|
|
}
|