master
c 163 lines 6.36 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "api_v2_calls.h"
4
5 int web_client_api_request_weights(RRDHOST *host, struct web_client *w, char *url, WEIGHTS_METHOD method, WEIGHTS_FORMAT format, size_t api_version) {
6 if (!netdata_ready_load())
7 return HTTP_RESP_SERVICE_UNAVAILABLE;
8
9 time_t baseline_after = 0, baseline_before = 0, after = 0, before = 0;
10 size_t points = 0;
11 RRDR_OPTIONS options = 0;
12 RRDR_TIME_GROUPING time_group_method = RRDR_GROUPING_AVERAGE;
13 time_t timeout_ms = 0;
14 size_t tier = 0;
15 size_t cardinality_limit = 0;
16 const char *time_group_options = NULL, *scope_contexts = NULL, *scope_nodes = NULL, *scope_instances = NULL, *scope_labels = NULL, *scope_dimensions = NULL,
17 *contexts = NULL, *nodes = NULL, *instances = NULL, *dimensions = NULL, *labels = NULL, *alerts = NULL;
18
19 struct group_by_pass group_by = {
20 .group_by = RRDR_GROUP_BY_NONE,
21 .group_by_label = NULL,
22 .aggregation = RRDR_GROUP_BY_FUNCTION_AVERAGE,
23 };
24
25 while (url) {
26 char *value = strsep_skip_consecutive_separators(&url, "&");
27 if (!value || !*value)
28 continue;
29
30 char *name = strsep_skip_consecutive_separators(&value, "=");
31 if (!name || !*name)
32 continue;
33 if (!value || !*value)
34 continue;
35
36 if (!strcmp(name, "baseline_after"))
37 baseline_after = str2l(value);
38
39 else if (!strcmp(name, "baseline_before"))
40 baseline_before = str2l(value);
41
42 else if (!strcmp(name, "after") || !strcmp(name, "highlight_after"))
43 after = str2l(value);
44
45 else if (!strcmp(name, "before") || !strcmp(name, "highlight_before"))
46 before = str2l(value);
47
48 else if (!strcmp(name, "points") || !strcmp(name, "max_points"))
49 points = str2ul(value);
50
51 else if (!strcmp(name, "timeout"))
52 timeout_ms = str2l(value);
53
54 else if (!strcmp(name, "cardinality_limit"))
55 cardinality_limit = str2ul(value);
56
57 else if((api_version == 1 && !strcmp(name, "group")) || (api_version >= 2 && !strcmp(name, "time_group")))
58 time_group_method = time_grouping_parse(value, RRDR_GROUPING_AVERAGE);
59
60 else if((api_version == 1 && !strcmp(name, "group_options")) || (api_version >= 2 && !strcmp(name, "time_group_options")))
61 time_group_options = value;
62
63 else if(!strcmp(name, "options"))
64 options |= rrdr_options_parse(value);
65
66 else if(!strcmp(name, "method"))
67 method = weights_string_to_method(value);
68
69 else if(api_version == 1 && (!strcmp(name, "context") || !strcmp(name, "contexts")))
70 scope_contexts = value;
71
72 else if(api_version >= 2 && !strcmp(name, "scope_nodes")) scope_nodes = value;
73 else if(api_version >= 2 && !strcmp(name, "scope_contexts")) scope_contexts = value;
74 else if(api_version >= 2 && !strcmp(name, "scope_instances")) scope_instances = value;
75 else if(api_version >= 2 && !strcmp(name, "scope_labels")) scope_labels = value;
76 else if(api_version >= 2 && !strcmp(name, "scope_dimensions")) scope_dimensions = value;
77 else if(api_version >= 2 && !strcmp(name, "nodes")) nodes = value;
78 else if(api_version >= 2 && !strcmp(name, "contexts")) contexts = value;
79 else if(api_version >= 2 && !strcmp(name, "instances")) instances = value;
80 else if(api_version >= 2 && !strcmp(name, "dimensions")) dimensions = value;
81 else if(api_version >= 2 && !strcmp(name, "labels")) labels = value;
82 else if(api_version >= 2 && !strcmp(name, "alerts")) alerts = value;
83 else if(api_version >= 2 && (!strcmp(name, "group_by") || !strcmp(name, "group_by[0]"))) {
84 group_by.group_by = group_by_parse(value);
85 }
86 else if(api_version >= 2 && (!strcmp(name, "group_by_label") || !strcmp(name, "group_by_label[0]"))) {
87 group_by.group_by_label = value;
88 }
89 else if(api_version >= 2 && (!strcmp(name, "aggregation") || !strcmp(name, "aggregation[0]"))) {
90 group_by.aggregation = group_by_aggregate_function_parse(value);
91 }
92
93 else if(!strcmp(name, "tier")) {
94 tier = str2ul(value);
95 if(tier < nd_profile.storage_tiers)
96 options |= RRDR_OPTION_SELECTED_TIER;
97 else
98 tier = 0;
99 }
100 }
101
102 if(options == 0)
103 // the user did not set any options
104 options = RRDR_OPTION_NOT_ALIGNED | RRDR_OPTION_NULL2ZERO | RRDR_OPTION_NONZERO;
105 else
106 // the user set some options, add also these
107 options |= RRDR_OPTION_NOT_ALIGNED | RRDR_OPTION_NULL2ZERO;
108
109 if(options & RRDR_OPTION_PERCENTAGE)
110 options |= RRDR_OPTION_ABSOLUTE;
111
112 if(options & RRDR_OPTION_DEBUG)
113 options &= ~RRDR_OPTION_MINIFY;
114
115 BUFFER *wb = w->response.data;
116 buffer_flush(wb);
117 wb->content_type = CT_APPLICATION_JSON;
118
119 QUERY_WEIGHTS_REQUEST qwr = {
120 .version = api_version,
121 .host = (api_version == 1) ? NULL : host,
122 .scope_nodes = scope_nodes,
123 .scope_contexts = scope_contexts,
124 .scope_instances = scope_instances,
125 .scope_labels = scope_labels,
126 .scope_dimensions = scope_dimensions,
127 .nodes = nodes,
128 .contexts = contexts,
129 .instances = instances,
130 .dimensions = dimensions,
131 .labels = labels,
132 .alerts = alerts,
133 .group_by = {
134 .group_by = group_by.group_by,
135 .group_by_label = group_by.group_by_label,
136 .aggregation = group_by.aggregation,
137 },
138 .method = method,
139 .format = format,
140 .time_group_method = time_group_method,
141 .time_group_options = time_group_options,
142 .baseline_after = baseline_after,
143 .baseline_before = baseline_before,
144 .after = after,
145 .before = before,
146 .points = points,
147 .options = options,
148 .tier = tier,
149 .timeout_ms = timeout_ms,
150 .cardinality_limit = cardinality_limit,
151
152 .interrupt_callback = web_client_interrupt_callback,
153 .interrupt_callback_data = w,
154
155 .transaction = &w->transaction,
156 };
157
158 return web_api_v12_weights(wb, &qwr);
159 }
160
161 int api_v2_weights(RRDHOST *host __maybe_unused, struct web_client *w, char *url) {
162 return web_client_api_request_weights(host, w, url, WEIGHTS_METHOD_VALUE, WEIGHTS_FORMAT_MULTINODE, 2);
163 }