18
bool from_dyncfg_echo;
19
};
20
21
-DYNCFG_STATUS dyncfg_status_from_successful_response(int code) {
22
- DYNCFG_STATUS status = DYNCFG_STATUS_ACCEPTED;
23
-
24
- switch(code) {
25
- default:
26
- case DYNCFG_RESP_ACCEPTED:
27
- case DYNCFG_RESP_ACCEPTED_RESTART_REQUIRED:
28
- status = DYNCFG_STATUS_ACCEPTED;
29
- break;
21
+static void dyncfg_function_intercept_job_successfully_added(DYNCFG *df_template, int code, struct dyncfg_call *dc) {
22
+ char id[strlen(dc->id) + 1 + strlen(dc->add_name) + 1];
23
+ snprintfz(id, sizeof(id), "%s:%s", dc->id, dc->add_name);
24
+
25
+ RRDHOST *host = dyncfg_rrdhost(df_template);
26
+ if(!host) {
27
+ nd_log(NDLS_DAEMON, NDLP_ERR,
28
+ "DYNCFG: cannot add job '%s' because host is missing", id);
29
+ }
30
+ else {
31
+ const DICTIONARY_ITEM *item = dyncfg_add_internal(
32
+ host,
33
+ id,
34
+ string2str(df_template->path),
35
+ dyncfg_status_from_successful_response(code),
36
+ DYNCFG_TYPE_JOB,
37
+ DYNCFG_SOURCE_TYPE_DYNCFG,
38
+ dc->source,
39
+ (df_template->cmds & ~DYNCFG_CMD_ADD) | DYNCFG_CMD_GET | DYNCFG_CMD_UPDATE | DYNCFG_CMD_TEST | DYNCFG_CMD_ENABLE |
40
+ DYNCFG_CMD_DISABLE | DYNCFG_CMD_REMOVE,
41
+ 0,
42
+ 0,
43
+ df_template->sync,
44
+ df_template->view_access,
45
+ df_template->edit_access,
46
+ df_template->execute_cb,
47
+ df_template->execute_cb_data,
48
+ false);
49
+
50
+ // adding does not create df->dyncfg
51
+ // we have to do it here
52
31
- case DYNCFG_RESP_ACCEPTED_DISABLED:
32
- status = DYNCFG_STATUS_DISABLED;
33
- break;
53
+ DYNCFG *df = dictionary_acquired_item_value(item);
54
+ SWAP(df->dyncfg.payload, dc->payload);
55
+ dyncfg_set_dyncfg_source_from_txt(df, dc->source);
56
+ df->dyncfg.user_disabled = false;
57
+ df->dyncfg.source_type = DYNCFG_SOURCE_TYPE_DYNCFG;
58
+ df->dyncfg.status = dyncfg_status_from_successful_response(code);
59
35
- case DYNCFG_RESP_RUNNING:
36
- status = DYNCFG_STATUS_RUNNING;
37
- break;
60
+ dyncfg_file_save(id, df); // updates also the df->dyncfg timestamps
61
+ dyncfg_update_status_on_successful_add_or_update(df, code);
62
63
+ dictionary_acquired_item_release(dyncfg_globals.nodes, item);
64
}
40
-
41
- return status;
65
}
66
44
-static void dyncfg_function_intercept_keep_source(DYNCFG *df, const char *source) {
45
- STRING *old = df->source;
46
- df->source = string_strdupz(source);
47
- string_freez(old);
67
+static void dyncfg_function_intercept_job_successfully_updated(DYNCFG *df, int code, struct dyncfg_call *dc) {
68
+ df->dyncfg.status = dyncfg_status_from_successful_response(code);
69
+ df->dyncfg.source_type = DYNCFG_SOURCE_TYPE_DYNCFG;
70
+ SWAP(df->dyncfg.payload, dc->payload);
71
+ dyncfg_set_dyncfg_source_from_txt(df, dc->source);
72
+
73
+ dyncfg_update_status_on_successful_add_or_update(df, code);
74
}
75
76
void dyncfg_function_intercept_result_cb(BUFFER *wb, int code, void *result_cb_data) {
81
const DICTIONARY_ITEM *item = dictionary_get_and_acquire_item_advanced(dyncfg_globals.nodes, dc->id, -1);
82
if(item) {
83
DYNCFG *df = dictionary_acquired_item_value(item);
58
- bool old_user_disabled = df->user_disabled;
84
+ bool old_user_disabled = df->dyncfg.user_disabled;
85
bool save_required = false;
86
87
if (!called_from_dyncfg_echo) {
89
90
if (DYNCFG_RESP_SUCCESS(code)) {
91
if (dc->cmd == DYNCFG_CMD_ADD) {
66
- char id[strlen(dc->id) + 1 + strlen(dc->add_name) + 1];
67
- snprintfz(id, sizeof(id), "%s:%s", dc->id, dc->add_name);
68
-
69
- RRDHOST *host = dyncfg_rrdhost(df);
70
- if(!host) {
71
- nd_log(NDLS_DAEMON, NDLP_ERR,
72
- "DYNCFG: cannot add job '%s' because host is missing", id);
73
- }
74
- else {
75
- const DICTIONARY_ITEM *new_item = dyncfg_add_internal(
76
- host,
77
- id,
78
- string2str(df->path),
79
- dyncfg_status_from_successful_response(code),
80
- DYNCFG_TYPE_JOB,
81
- DYNCFG_SOURCE_TYPE_DYNCFG,
82
- dc->source,
83
- (df->cmds & ~DYNCFG_CMD_ADD) | DYNCFG_CMD_GET | DYNCFG_CMD_UPDATE | DYNCFG_CMD_TEST |
84
- DYNCFG_CMD_ENABLE | DYNCFG_CMD_DISABLE | DYNCFG_CMD_REMOVE,
85
- 0,
86
- 0,
87
- df->sync,
88
- df->execute_cb,
89
- df->execute_cb_data,
90
- false);
91
-
92
- DYNCFG *new_df = dictionary_acquired_item_value(new_item);
93
- SWAP(new_df->payload, dc->payload);
94
- if (code == DYNCFG_RESP_ACCEPTED_RESTART_REQUIRED)
95
- new_df->restart_required = true;
96
-
97
- dyncfg_file_save(id, new_df);
98
- dictionary_acquired_item_release(dyncfg_globals.nodes, new_item);
99
- }
92
+ dyncfg_function_intercept_job_successfully_added(df, code, dc);
93
} else if (dc->cmd == DYNCFG_CMD_UPDATE) {
101
- df->source_type = DYNCFG_SOURCE_TYPE_DYNCFG;
102
- dyncfg_function_intercept_keep_source(df, dc->source);
103
-
104
- df->status = dyncfg_status_from_successful_response(code);
105
- SWAP(df->payload, dc->payload);
106
-
94
+ dyncfg_function_intercept_job_successfully_updated(df, code, dc);
95
save_required = true;
108
- } else if (dc->cmd == DYNCFG_CMD_ENABLE) {
109
- df->user_disabled = false;
110
- dyncfg_function_intercept_keep_source(df, dc->source);
111
- } else if (dc->cmd == DYNCFG_CMD_DISABLE) {
112
- df->user_disabled = true;
113
- dyncfg_function_intercept_keep_source(df, dc->source);
114
- } else if (dc->cmd == DYNCFG_CMD_REMOVE) {
96
+ }
97
+ else if (dc->cmd == DYNCFG_CMD_ENABLE) {
98
+ df->dyncfg.user_disabled = false;
99
+ }
100
+ else if (dc->cmd == DYNCFG_CMD_DISABLE) {
101
+ df->dyncfg.user_disabled = true;
102
+ }
103
+ else if (dc->cmd == DYNCFG_CMD_REMOVE) {
104
dyncfg_file_delete(dc->id);
105
dictionary_del(dyncfg_globals.nodes, dc->id);
106
}
107
119
- if(dc->cmd != DYNCFG_CMD_ADD && code == DYNCFG_RESP_ACCEPTED_RESTART_REQUIRED)
120
- df->restart_required = true;
108
+ if (save_required || old_user_disabled != df->dyncfg.user_disabled)
109
+ dyncfg_file_save(dc->id, df);
110
}
111
else
112
nd_log(NDLS_DAEMON, NDLP_ERR,
114
}
115
else {
116
// the command was sent by dyncfg
128
-
129
- if(DYNCFG_RESP_SUCCESS(code)) {
130
- if(dc->cmd == DYNCFG_CMD_ADD) {
131
- char id[strlen(dc->id) + 1 + strlen(dc->add_name) + 1];
132
- snprintfz(id, sizeof(id), "%s:%s", dc->id, dc->add_name);
133
-
134
- const DICTIONARY_ITEM *new_item = dictionary_get_and_acquire_item(dyncfg_globals.nodes, id);
135
- if(new_item) {
136
- DYNCFG *new_df = dictionary_acquired_item_value(new_item);
137
- new_df->status = dyncfg_status_from_successful_response(code);
138
-
139
- if(code == DYNCFG_RESP_ACCEPTED_RESTART_REQUIRED)
140
- new_df->restart_required = true;
141
-
142
- dictionary_acquired_item_release(dyncfg_globals.nodes, new_item);
143
- }
144
- }
145
- else if(dc->cmd == DYNCFG_CMD_UPDATE) {
146
- df->status = dyncfg_status_from_successful_response(code);
147
- df->plugin_rejected = false;
148
- }
149
- else if(dc->cmd == DYNCFG_CMD_DISABLE)
150
- df->status = DYNCFG_STATUS_DISABLED;
151
- else if(dc->cmd == DYNCFG_CMD_ENABLE)
152
- df->status = dyncfg_status_from_successful_response(code);
153
-
154
- if(dc->cmd != DYNCFG_CMD_ADD && code == DYNCFG_RESP_ACCEPTED_RESTART_REQUIRED)
155
- df->restart_required = true;
156
- }
157
- else {
158
- nd_log(NDLS_DAEMON, NDLP_ERR,
159
- "DYNCFG: plugin returned code %d to dyncfg initiated call: %s", code, dc->function);
160
-
161
- if(dc->cmd & (DYNCFG_CMD_UPDATE | DYNCFG_CMD_ADD))
162
- df->plugin_rejected = true;
163
- }
117
+ // these are handled by the echo callback, we don't need to do anything here
118
+ ;
119
}
120
166
- if (save_required || old_user_disabled != df->user_disabled)
167
- dyncfg_file_save(dc->id, df);
168
-
121
dictionary_acquired_item_release(dyncfg_globals.nodes, item);
122
}
123
153
DYNCFG_CMDS cmd_to_send_to_plugin = c;
154
155
if(c == DYNCFG_CMD_ENABLE)
204
- cmd_to_send_to_plugin = df->user_disabled ? DYNCFG_CMD_DISABLE : DYNCFG_CMD_ENABLE;
156
+ cmd_to_send_to_plugin = df->dyncfg.user_disabled ? DYNCFG_CMD_DISABLE : DYNCFG_CMD_ENABLE;
157
else if(c == DYNCFG_CMD_DISABLE)
158
cmd_to_send_to_plugin = DYNCFG_CMD_DISABLE;
159
171
// ----------------------------------------------------------------------------
172
// the callback for all config functions
173
174
+static int dyncfg_intercept_early_error(struct rrd_function_execute *rfe, int rc, const char *msg) {
175
+ rc = dyncfg_default_response(rfe->result.wb, rc, msg);
176
+
177
+ if(rfe->result.cb)
178
+ rfe->result.cb(rfe->result.wb, rc, rfe->result.data);
179
+
180
+ return rc;
181
+}
182
+
183
int dyncfg_function_intercept_cb(struct rrd_function_execute *rfe, void *data __maybe_unused) {
184
185
// IMPORTANT: this function MUST call the result_cb even on failures
186
187
bool called_from_dyncfg_echo = rrd_function_has_this_original_result_callback(rfe->transaction, dyncfg_echo_cb);
188
+ bool has_payload = rfe->payload && buffer_strlen(rfe->payload) ? true : false;
189
+ bool make_the_call_to_plugin = true;
190
228
- DYNCFG_CMDS c = DYNCFG_CMD_NONE;
191
+ int rc = HTTP_RESP_INTERNAL_SERVER_ERROR;
192
+ DYNCFG_CMDS cmd;
193
const DICTIONARY_ITEM *item = NULL;
194
const char *add_name = NULL;
231
- size_t add_name_len = 0;
232
- if(strncmp(rfe->function, PLUGINSD_FUNCTION_CONFIG " ", sizeof(PLUGINSD_FUNCTION_CONFIG)) == 0) {
233
- const char *id = &rfe->function[sizeof(PLUGINSD_FUNCTION_CONFIG)];
234
- while(isspace(*id)) id++;
235
- const char *space = id;
236
- while(*space && !isspace(*space)) space++;
237
- size_t id_len = space - id;
238
-
239
- const char *cmd = space;
240
- while(isspace(*cmd)) cmd++;
241
- space = cmd;
242
- while(*space && !isspace(*space)) space++;
243
- size_t cmd_len = space - cmd;
244
-
245
- char cmd_copy[cmd_len + 1];
246
- strncpyz(cmd_copy, cmd, cmd_len);
247
- c = dyncfg_cmds2id(cmd_copy);
248
-
249
- if(c == DYNCFG_CMD_ADD) {
250
- add_name = space;
251
- while(isspace(*add_name)) add_name++;
252
- space = add_name;
253
- while(*space && !isspace(*space)) space++;
254
- add_name_len = space - add_name;
255
- }
195
257
- item = dictionary_get_and_acquire_item_advanced(dyncfg_globals.nodes, id, (ssize_t)id_len);
258
- }
196
+ char buf[strlen(rfe->function) + 1];
197
+ memcpy(buf, rfe->function, sizeof(buf));
198
260
- int rc = HTTP_RESP_INTERNAL_SERVER_ERROR;
199
+ char *words[20];
200
+ size_t num_words = quoted_strings_splitter_pluginsd(buf, words, 20);
201
262
- if(!item) {
263
- rc = HTTP_RESP_NOT_FOUND;
264
- dyncfg_default_response(rfe->result.wb, rc, "dyncfg functions intercept: id is not found");
202
+ size_t i = 0;
203
+ char *config = get_word(words, num_words, i++);
204
+ char *id = get_word(words, num_words, i++);
205
+ char *cmd_str = get_word(words, num_words, i++);
206
266
- if(rfe->result.cb)
267
- rfe->result.cb(rfe->result.wb, rc, rfe->result.data);
207
+ if(!config || !*config || strcmp(config, PLUGINSD_FUNCTION_CONFIG) != 0)
208
+ return dyncfg_intercept_early_error(rfe, HTTP_RESP_BAD_REQUEST,
209
+ "dyncfg functions intercept: this is not a dyncfg request");
210
269
- return HTTP_RESP_NOT_FOUND;
270
- }
211
+ cmd = dyncfg_cmds2id(cmd_str);
212
+ if(cmd == DYNCFG_CMD_NONE)
213
+ return dyncfg_intercept_early_error(rfe, HTTP_RESP_BAD_REQUEST,
214
+ "dyncfg functions intercept: invalid command received");
215
272
- DYNCFG *df = dictionary_acquired_item_value(item);
273
- const char *id = dictionary_acquired_item_name(item);
274
- bool has_payload = rfe->payload && buffer_strlen(rfe->payload) ? true : false;
275
- bool make_the_call_to_plugin = true;
216
+ if(cmd == DYNCFG_CMD_ADD) {
217
+ add_name = get_word(words, num_words, i++);
218
277
- if((c & (DYNCFG_CMD_GET | DYNCFG_CMD_ENABLE | DYNCFG_CMD_DISABLE | DYNCFG_CMD_REMOVE | DYNCFG_CMD_RESTART)) && has_payload)
278
- nd_log(NDLS_DAEMON, NDLP_ERR, "DYNCFG: command has a payload, but it is not going to be used: %s", rfe->function);
219
+ if(!add_name || !*add_name)
220
+ return dyncfg_intercept_early_error(rfe, HTTP_RESP_BAD_REQUEST,
221
+ "dyncfg functions intercept: this action requires a name");
222
280
- if(c == DYNCFG_CMD_NONE) {
281
- nd_log(NDLS_DAEMON, NDLP_ERR, "DYNCFG: this command is unknown: %s", rfe->function);
223
+ if(!called_from_dyncfg_echo) {
224
+ char nid[strlen(id) + strlen(add_name) + 2];
225
+ snprintfz(nid, sizeof(nid), "%s:%s", id, add_name);
226
283
- rc = HTTP_RESP_BAD_REQUEST;
284
- dyncfg_default_response(rfe->result.wb, rc,
285
- "dyncfg functions intercept: unknown command");
286
- make_the_call_to_plugin = false;
227
+ if (dictionary_get(dyncfg_globals.nodes, nid))
228
+ return dyncfg_intercept_early_error(rfe, HTTP_RESP_BAD_REQUEST,
229
+ "dyncfg functions intercept: a configuration with this name already exists");
230
+ }
231
}
288
- else if(!(df->cmds & c)) {
289
- nd_log(NDLS_DAEMON, NDLP_ERR, "DYNCFG: this command is not supported by the configuration node: %s", rfe->function);
232
291
- rc = HTTP_RESP_BAD_REQUEST;
292
- dyncfg_default_response(rfe->result.wb, rc,
293
- "dyncfg functions intercept: this command is not supported by this configuration node");
294
- make_the_call_to_plugin = false;
295
- }
296
- else if((c & (DYNCFG_CMD_ADD | DYNCFG_CMD_UPDATE | DYNCFG_CMD_TEST)) && !has_payload) {
297
- nd_log(NDLS_DAEMON, NDLP_ERR, "DYNCFG: command requires a payload, but no payload given: %s", rfe->function);
233
+ if((cmd == DYNCFG_CMD_ADD || cmd == DYNCFG_CMD_UPDATE || cmd == DYNCFG_CMD_TEST) && !has_payload)
234
+ return dyncfg_intercept_early_error(rfe, HTTP_RESP_BAD_REQUEST,
235
+ "dyncfg functions intercept: this action requires a payload");
236
299
- rc = HTTP_RESP_BAD_REQUEST;
300
- dyncfg_default_response(rfe->result.wb, rc,
301
- "dyncfg functions intercept: payload is required");
302
- make_the_call_to_plugin = false;
303
- }
304
- else if(c == DYNCFG_CMD_SCHEMA) {
305
- bool loaded = false;
306
- if(df->type == DYNCFG_TYPE_JOB) {
307
- if(df->template)
308
- loaded = dyncfg_get_schema(string2str(df->template), rfe->result.wb);
309
- }
310
- else
311
- loaded = dyncfg_get_schema(id, rfe->result.wb);
237
+ if((cmd != DYNCFG_CMD_ADD && cmd != DYNCFG_CMD_UPDATE && cmd != DYNCFG_CMD_TEST) && has_payload)
238
+ return dyncfg_intercept_early_error(rfe, HTTP_RESP_BAD_REQUEST,
239
+ "dyncfg functions intercept: this action does not require a payload");
240
313
- if(loaded) {
314
- rfe->result.wb->content_type = CT_APPLICATION_JSON;
315
- rfe->result.wb->expires = now_realtime_sec();
316
- rc = HTTP_RESP_OK;
241
+ item = dictionary_get_and_acquire_item(dyncfg_globals.nodes, id);
242
+ if(!item)
243
+ return dyncfg_intercept_early_error(rfe, HTTP_RESP_NOT_FOUND,
244
+ "dyncfg functions intercept: id is not found");
245
+
246
+ DYNCFG *df = dictionary_acquired_item_value(item);
247
+
248
+ // 1. check the permissions of the request
249
+
250
+ switch(cmd) {
251
+ case DYNCFG_CMD_GET:
252
+ case DYNCFG_CMD_SCHEMA:
253
+ if(!http_access_user_has_enough_access_level_for_endpoint(rfe->user_access, df->view_access)) {
254
+ make_the_call_to_plugin = false;
255
+ rc = dyncfg_default_response(rfe->result.wb, HTTP_RESP_FORBIDDEN,
256
+ "dyncfg: you don't have enough view permissions to execute this command");
257
+ }
258
+ break;
259
+
260
+ case DYNCFG_CMD_ENABLE:
261
+ case DYNCFG_CMD_DISABLE:
262
+ case DYNCFG_CMD_ADD:
263
+ case DYNCFG_CMD_TEST:
264
+ case DYNCFG_CMD_UPDATE:
265
+ case DYNCFG_CMD_REMOVE:
266
+ case DYNCFG_CMD_RESTART:
267
+ if(!http_access_user_has_enough_access_level_for_endpoint(rfe->user_access, df->edit_access)) {
268
+ make_the_call_to_plugin = false;
269
+ rc = dyncfg_default_response(rfe->result.wb, HTTP_RESP_FORBIDDEN,
270
+ "dyncfg: you don't have enough edit permissions to execute this command");
271
+ }
272
+ break;
273
+
274
+ default: {
275
make_the_call_to_plugin = false;
276
+ rc = dyncfg_default_response(rfe->result.wb, HTTP_RESP_INTERNAL_SERVER_ERROR,
277
+ "dyncfg: permissions for this command are not set");
278
}
279
+ break;
280
}
320
- else if(c & (DYNCFG_CMD_ENABLE | DYNCFG_CMD_DISABLE | DYNCFG_CMD_RESTART) && df->type == DYNCFG_TYPE_TEMPLATE) {
321
- if(!called_from_dyncfg_echo) {
322
- bool old_user_disabled = df->user_disabled;
323
- if (c == DYNCFG_CMD_ENABLE)
324
- df->user_disabled = false;
325
- else if (c == DYNCFG_CMD_DISABLE)
326
- df->user_disabled = true;
327
-
328
- if (df->user_disabled != old_user_disabled)
329
- dyncfg_file_save(id, df);
330
- }
281
332
- dyncfg_apply_action_on_all_template_jobs(rfe, id, c);
282
+ // 2. validate the request parameters
283
+
284
+ if(make_the_call_to_plugin) {
285
+ if (!(df->cmds & cmd)) {
286
+ nd_log(NDLS_DAEMON, NDLP_ERR,
287
+ "DYNCFG: this command is not supported by the configuration node: %s", rfe->function);
288
334
- rc = HTTP_RESP_OK;
335
- dyncfg_default_response(rfe->result.wb, rc, "applied");
336
- make_the_call_to_plugin = false;
337
- }
338
- else if(c == DYNCFG_CMD_ADD) {
339
- if (df->type != DYNCFG_TYPE_TEMPLATE) {
340
- nd_log(NDLS_DAEMON, NDLP_ERR, "DYNCFG: add command can only be applied on templates, not %s: %s",
341
- dyncfg_id2type(df->type), rfe->function);
342
-
343
- rc = HTTP_RESP_BAD_REQUEST;
344
- dyncfg_default_response(rfe->result.wb, rc,
345
- "dyncfg functions intercept: add command is only allowed in templates");
289
make_the_call_to_plugin = false;
290
+ rc = dyncfg_default_response(
291
+ rfe->result.wb, HTTP_RESP_BAD_REQUEST,
292
+ "dyncfg functions intercept: this command is not supported by this configuration node");
293
}
348
- else if (!add_name || !*add_name || !add_name_len) {
349
- nd_log(NDLS_DAEMON, NDLP_ERR, "DYNCFG: add command does not specify a name: %s", rfe->function);
294
+ else if (cmd == DYNCFG_CMD_ADD) {
295
+ if (df->type != DYNCFG_TYPE_TEMPLATE) {
296
+ make_the_call_to_plugin = false;
297
+ rc = dyncfg_default_response(rfe->result.wb, HTTP_RESP_BAD_REQUEST,
298
+ "dyncfg functions intercept: add command is only allowed in templates");
299
351
- rc = HTTP_RESP_BAD_REQUEST;
352
- dyncfg_default_response(rfe->result.wb, rc,
353
- "dyncfg functions intercept: command add requires a name, which is missing");
300
+ nd_log(NDLS_DAEMON, NDLP_ERR,
301
+ "DYNCFG: add command can only be applied on templates, not %s: %s",
302
+ dyncfg_id2type(df->type), rfe->function);
303
+ }
304
+ }
305
+ else if (
306
+ cmd == DYNCFG_CMD_ENABLE && df->type == DYNCFG_TYPE_JOB &&
307
+ dyncfg_is_user_disabled(string2str(df->template))) {
308
+ nd_log(NDLS_DAEMON, NDLP_ERR, "DYNCFG: cannot enable a job of a disabled template: %s", rfe->function);
309
310
make_the_call_to_plugin = false;
311
+ rc = dyncfg_default_response(rfe->result.wb, HTTP_RESP_BAD_REQUEST,
312
+ "dyncfg functions intercept: this job belongs to disabled template");
313
}
314
}
358
- else if(c == DYNCFG_CMD_ENABLE && df->type == DYNCFG_TYPE_JOB && dyncfg_is_user_disabled(string2str(df->template))) {
359
- nd_log(NDLS_DAEMON, NDLP_ERR, "DYNCFG: cannot enable a job of a disabled template: %s", rfe->function);
315
361
- rc = HTTP_RESP_BAD_REQUEST;
362
- dyncfg_default_response(rfe->result.wb, rc,
363
- "dyncfg functions intercept: this job belongs to disabled template");
316
+ // 3. check if it is one of the commands we should execute
317
365
- make_the_call_to_plugin = false;
318
+ if(make_the_call_to_plugin) {
319
+ if (cmd & (DYNCFG_CMD_ENABLE | DYNCFG_CMD_DISABLE | DYNCFG_CMD_RESTART) && df->type == DYNCFG_TYPE_TEMPLATE) {
320
+ if (!called_from_dyncfg_echo) {
321
+ bool old_user_disabled = df->dyncfg.user_disabled;
322
+ if (cmd == DYNCFG_CMD_ENABLE)
323
+ df->dyncfg.user_disabled = false;
324
+ else if (cmd == DYNCFG_CMD_DISABLE)
325
+ df->dyncfg.user_disabled = true;
326
+
327
+ if (df->dyncfg.user_disabled != old_user_disabled)
328
+ dyncfg_file_save(id, df);
329
+ }
330
+
331
+ dyncfg_apply_action_on_all_template_jobs(rfe, id, cmd);
332
+
333
+ rc = dyncfg_default_response(rfe->result.wb, HTTP_RESP_OK, "applied");
334
+ make_the_call_to_plugin = false;
335
+ }
336
+ else if (cmd == DYNCFG_CMD_SCHEMA) {
337
+ bool loaded = false;
338
+ if (df->type == DYNCFG_TYPE_JOB) {
339
+ if (df->template)
340
+ loaded = dyncfg_get_schema(string2str(df->template), rfe->result.wb);
341
+ } else
342
+ loaded = dyncfg_get_schema(id, rfe->result.wb);
343
+
344
+ if (loaded) {
345
+ rfe->result.wb->content_type = CT_APPLICATION_JSON;
346
+ rfe->result.wb->expires = now_realtime_sec();
347
+ rc = HTTP_RESP_OK;
348
+ make_the_call_to_plugin = false;
349
+ }
350
+ }
351
}
352
353
+ // 4. execute the command
354
+
355
if(make_the_call_to_plugin) {
356
struct dyncfg_call *dc = callocz(1, sizeof(*dc));
357
dc->function = strdupz(rfe->function);
358
dc->id = strdupz(id);
359
dc->source = rfe->source ? strdupz(rfe->source) : NULL;
373
- dc->add_name = (c == DYNCFG_CMD_ADD) ? strndupz(add_name, add_name_len) : NULL;
374
- dc->cmd = c;
360
+ dc->add_name = (add_name) ? strdupz(add_name) : NULL;
361
+ dc->cmd = cmd;
362
dc->result_cb = rfe->result.cb;
363
dc->result_cb_data = rfe->result.data;
364
dc->payload = buffer_dup(rfe->payload);