| 1 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 2 | |
| 3 | #include "web/api/v2/api_v2_calls.h" |
| 4 | |
| 5 | int api_v1_config(RRDHOST *host, struct web_client *w, char *url __maybe_unused) { |
| 6 | char *action = "tree"; |
| 7 | char *path = "/"; |
| 8 | char *id = NULL; |
| 9 | char *add_name = NULL; |
| 10 | int timeout = 120; |
| 11 | |
| 12 | while(url) { |
| 13 | char *value = strsep_skip_consecutive_separators(&url, "&"); |
| 14 | if(!value || !*value) continue; |
| 15 | |
| 16 | char *name = strsep_skip_consecutive_separators(&value, "="); |
| 17 | if(!name || !*name) continue; |
| 18 | if(!value || !*value) continue; |
| 19 | |
| 20 | // name and value are now the parameters |
| 21 | // they are not null and not empty |
| 22 | |
| 23 | if(!strcmp(name, "action")) |
| 24 | action = value; |
| 25 | else if(!strcmp(name, "path")) |
| 26 | path = value; |
| 27 | else if(!strcmp(name, "id")) |
| 28 | id = value; |
| 29 | else if(!strcmp(name, "name")) |
| 30 | add_name = value; |
| 31 | else if(!strcmp(name, "timeout")) { |
| 32 | timeout = (int)strtol(value, NULL, 10); |
| 33 | if(timeout < 10) |
| 34 | timeout = 10; |
| 35 | } |
| 36 | } |
| 37 | |
| 38 | char transaction[UUID_COMPACT_STR_LEN]; |
| 39 | uuid_unparse_lower_compact(w->transaction, transaction); |
| 40 | |
| 41 | size_t len = strlen(action) + (id ? strlen(id) : 0) + strlen(path) + (add_name ? strlen(add_name) : 0) + 100; |
| 42 | |
| 43 | char *cmd = mallocz(len); |
| 44 | if(strcmp(action, "tree") == 0) |
| 45 | snprintfz(cmd, len, PLUGINSD_FUNCTION_CONFIG " tree '%s' '%s'", path, id?id:""); |
| 46 | else { |
| 47 | DYNCFG_CMDS c = dyncfg_cmds2id(action); |
| 48 | if(!id || !*id || !dyncfg_is_valid_id(id)) { |
| 49 | rrd_call_function_error(w->response.data, "Invalid id", HTTP_RESP_BAD_REQUEST); |
| 50 | freez(cmd); |
| 51 | return HTTP_RESP_BAD_REQUEST; |
| 52 | } |
| 53 | |
| 54 | if(c == DYNCFG_CMD_NONE) { |
| 55 | rrd_call_function_error(w->response.data, "Invalid action", HTTP_RESP_BAD_REQUEST); |
| 56 | freez(cmd); |
| 57 | return HTTP_RESP_BAD_REQUEST; |
| 58 | } |
| 59 | |
| 60 | if(c == DYNCFG_CMD_ADD || c == DYNCFG_CMD_USERCONFIG || c == DYNCFG_CMD_TEST) { |
| 61 | if(c == DYNCFG_CMD_TEST && (!add_name || !*add_name)) { |
| 62 | // backwards compatibility for TEST without a name |
| 63 | char *colon = strrchr(id, ':'); |
| 64 | if(colon) { |
| 65 | *colon = '\0'; |
| 66 | add_name = ++colon; |
| 67 | } |
| 68 | else |
| 69 | add_name = "test"; |
| 70 | } |
| 71 | |
| 72 | if(!add_name || !*add_name || !dyncfg_is_valid_id(add_name)) { |
| 73 | rrd_call_function_error(w->response.data, "Invalid name", HTTP_RESP_BAD_REQUEST); |
| 74 | freez(cmd); |
| 75 | return HTTP_RESP_BAD_REQUEST; |
| 76 | } |
| 77 | snprintfz(cmd, len, PLUGINSD_FUNCTION_CONFIG " %s %s %s", id, dyncfg_id2cmd_one(c), add_name); |
| 78 | } |
| 79 | else |
| 80 | snprintfz(cmd, len, PLUGINSD_FUNCTION_CONFIG " %s %s", id, dyncfg_id2cmd_one(c)); |
| 81 | } |
| 82 | |
| 83 | CLEAN_BUFFER *source = buffer_create(100, NULL); |
| 84 | user_auth_to_source_buffer(&w->user_auth, source); |
| 85 | |
| 86 | buffer_flush(w->response.data); |
| 87 | int code = rrd_function_run(host, w->response.data, timeout, w->user_auth.access, cmd, |
| 88 | true, transaction, |
| 89 | NULL, NULL, |
| 90 | web_client_progress_functions_update, NULL, |
| 91 | web_client_interrupt_callback, w, |
| 92 | w->payload, buffer_tostring(source), false); |
| 93 | |
| 94 | freez(cmd); |
| 95 | return code; |
| 96 | } |