@cryptotaxi247 / netdata-1 / commits / f10a34775

unify claiming response json (#18777)

* unify claiming response json * emulate old api error responses * fix last commit

Costa Tsaousis committed Oct 16, 2024 at 15:54 UTC f10a34775339ed01ad5357f0da4060b0297d0a2a
3 files changed +107 -79
src/web/api/v2/api_v2_calls.h
+1
@@ -25,6 +25,7 @@ int api_v2_node_instances(RRDHOST *host, struct web_client *w, char *url);
25 int api_v2_ilove(RRDHOST *host, struct web_client *w, char *url);
26
27 int api_v2_claim(RRDHOST *host, struct web_client *w, char *url);
28 +int api_v3_claim(RRDHOST *host, struct web_client *w, char *url);
29
30 int api_v2_webrtc(RRDHOST *host, struct web_client *w, char *url);
31
src/web/api/v2/api_v2_claim.c
+105 -78
@@ -85,7 +85,92 @@ static bool check_claim_param(const char *s) {
85 return true;
86 }
87
88 -int api_v2_claim(RRDHOST *host __maybe_unused, struct web_client *w, char *url) {
88 +static bool agent_can_be_claimed(void) {
89 + CLOUD_STATUS status = cloud_status();
90 + switch(status) {
91 + case CLOUD_STATUS_AVAILABLE:
92 + case CLOUD_STATUS_OFFLINE:
93 + case CLOUD_STATUS_INDIRECT:
94 + return true;
95 +
96 + case CLOUD_STATUS_BANNED:
97 + case CLOUD_STATUS_ONLINE:
98 + return false;
99 + }
100 +}
101 +
102 +typedef enum {
103 + CLAIM_RESP_INFO,
104 + CLAIM_RESP_ERROR,
105 + CLAIM_RESP_ACTION_OK,
106 + CLAIM_RESP_ACTION_FAILED,
107 +} CLAIM_RESPONSE;
108 +
109 +static void claim_add_user_info_command(BUFFER *wb) {
110 + const char *filename = netdata_random_session_id_get_filename();
111 + CLEAN_BUFFER *os_cmd = buffer_create(0, NULL);
112 +
113 + const char *os_filename;
114 + const char *os_prefix;
115 + const char *os_quote;
116 + const char *os_message;
117 +
118 +#if defined(OS_WINDOWS)
119 + char win_path[MAX_PATH];
120 + cygwin_conv_path(CCP_POSIX_TO_WIN_A, filename, win_path, sizeof(win_path));
121 + os_filename = win_path;
122 + os_prefix = "more";
123 + os_message = "We need to verify this Windows server is yours. So, open a Command Prompt on this server to run the command. It will give you a UUID. Copy and paste this UUID to this box:";
124 +#else
125 + os_filename = filename;
126 + os_prefix = "sudo cat";
127 + os_message = "We need to verify this server is yours. SSH to this server and run this command. It will give you a UUID. Copy and paste this UUID to this box:";
128 +#endif
129 +
130 + // add quotes only when the filename has a space
131 + if(strchr(os_filename, ' '))
132 + os_quote = "\"";
133 + else
134 + os_quote = "";
135 +
136 + buffer_sprintf(os_cmd, "%s %s%s%s", os_prefix, os_quote, os_filename, os_quote);
137 +
138 + buffer_json_member_add_string(wb, "key_filename", os_filename);
139 + buffer_json_member_add_string(wb, "cmd", buffer_tostring(os_cmd));
140 + buffer_json_member_add_string(wb, "help", os_message);
141 +}
142 +
143 +static int claim_json_response(BUFFER *wb, CLAIM_RESPONSE response, const char *msg) {
144 + time_t now_s = now_realtime_sec();
145 + buffer_reset(wb);
146 + buffer_json_initialize(wb, "\"", "\"", 0, true, BUFFER_JSON_OPTIONS_DEFAULT);
147 +
148 + if(response != CLAIM_RESP_INFO) {
149 + // this is not an info, so it needs a status report
150 + buffer_json_member_add_boolean(wb, "success", response == CLAIM_RESP_ACTION_OK ? true : false);
151 + buffer_json_member_add_string_or_empty(wb, "message", msg ? msg : "");
152 + }
153 +
154 + buffer_json_cloud_status(wb, now_s);
155 +
156 + if(response != CLAIM_RESP_ACTION_OK) {
157 + buffer_json_member_add_boolean(wb, "can_be_claimed", agent_can_be_claimed());
158 + claim_add_user_info_command(wb);
159 + }
160 +
161 + buffer_json_agents_v2(wb, NULL, now_s, false, false);
162 + buffer_json_finalize(wb);
163 +
164 + return (response == CLAIM_RESP_ERROR) ? HTTP_RESP_BAD_REQUEST : HTTP_RESP_OK;
165 +}
166 +
167 +static int claim_txt_response(BUFFER *wb, const char *msg) {
168 + buffer_reset(wb);
169 + buffer_strcat(wb, msg);
170 + return HTTP_RESP_BAD_REQUEST;
171 +}
172 +
173 +static int api_claim(uint8_t version, struct web_client *w, char *url) {
174 char *key = NULL;
175 char *token = NULL;
176 char *rooms = NULL;
@@ -110,103 +195,45 @@ int api_v2_claim(RRDHOST *host __maybe_unused, struct web_client *w, char *url)
195 }
196
197 BUFFER *wb = w->response.data;
113 - buffer_flush(wb);
114 - buffer_json_initialize(wb, "\"", "\"", 0, true, BUFFER_JSON_OPTIONS_DEFAULT);
198
116 - time_t now_s = now_realtime_sec();
117 - CLOUD_STATUS status = buffer_json_cloud_status(wb, now_s);
118 -
119 - bool can_be_claimed = false;
120 - switch(status) {
121 - case CLOUD_STATUS_AVAILABLE:
122 - case CLOUD_STATUS_OFFLINE:
123 - case CLOUD_STATUS_INDIRECT:
124 - can_be_claimed = true;
125 - break;
126 -
127 - case CLOUD_STATUS_BANNED:
128 - case CLOUD_STATUS_ONLINE:
129 - can_be_claimed = false;
130 - break;
131 - }
132 -
133 - buffer_json_member_add_boolean(wb, "can_be_claimed", can_be_claimed);
199 + CLAIM_RESPONSE response = CLAIM_RESP_INFO;
200 + const char *msg = NULL;
201 + bool can_be_claimed = agent_can_be_claimed();
202
203 if(can_be_claimed && key) {
204 if(!netdata_random_session_id_matches(key)) {
137 - buffer_reset(wb);
138 - buffer_strcat(wb, "invalid key");
205 netdata_random_session_id_generate(); // generate a new key, to avoid an attack to find it
140 - return HTTP_RESP_FORBIDDEN;
206 + if(version < 3) return claim_txt_response(wb, "invalid key");
207 + return claim_json_response(wb, CLAIM_RESP_ERROR, "invalid key");
208 }
209
210 if(!token || !base_url || !check_claim_param(token) || !check_claim_param(base_url) || (rooms && !check_claim_param(rooms))) {
144 - buffer_reset(wb);
145 - buffer_strcat(wb, "invalid parameters");
211 netdata_random_session_id_generate(); // generate a new key, to avoid an attack to find it
147 - return HTTP_RESP_BAD_REQUEST;
212 + if(version < 3) return claim_txt_response(wb, "invalid parameters");
213 + return claim_json_response(wb, CLAIM_RESP_ERROR, "invalid parameters");
214 }
215
216 netdata_random_session_id_generate(); // generate a new key, to avoid an attack to find it
217
152 - bool success = false;
153 - const char *msg;
218 if(claim_agent(base_url, token, rooms, cloud_config_proxy_get(), cloud_config_insecure_get())) {
219 msg = "ok";
156 - success = true;
220 can_be_claimed = false;
158 - status = claim_reload_and_wait_online();
221 + claim_reload_and_wait_online();
222 + response = CLAIM_RESP_ACTION_OK;
223 }
160 - else
224 + else {
225 msg = claim_agent_failure_reason_get();
162 -
163 - // our status may have changed
164 - // refresh the status in our output
165 - buffer_flush(wb);
166 - buffer_json_initialize(wb, "\"", "\"", 0, true, BUFFER_JSON_OPTIONS_DEFAULT);
167 - now_s = now_realtime_sec();
168 - buffer_json_cloud_status(wb, now_s);
169 -
170 - // and this is the status of the claiming command we run
171 - buffer_json_member_add_boolean(wb, "success", success);
172 - buffer_json_member_add_string_or_empty(wb, "message", msg);
226 + response = CLAIM_RESP_ACTION_FAILED;
227 + }
228 }
229
175 - if(can_be_claimed) {
176 - const char *filename = netdata_random_session_id_get_filename();
177 - CLEAN_BUFFER *buffer = buffer_create(0, NULL);
178 -
179 - const char *os_filename;
180 - const char *os_prefix;
181 - const char *os_quote;
182 - const char *os_message;
183 -
184 -#if defined(OS_WINDOWS)
185 - char win_path[MAX_PATH];
186 - cygwin_conv_path(CCP_POSIX_TO_WIN_A, filename, win_path, sizeof(win_path));
187 - os_filename = win_path;
188 - os_prefix = "more";
189 - os_message = "We need to verify this Windows server is yours. So, open a Command Prompt on this server to run the command. It will give you a UUID. Copy and paste this UUID to this box:";
190 -#else
191 - os_filename = filename;
192 - os_prefix = "sudo cat";
193 - os_message = "We need to verify this server is yours. SSH to this server and run this command. It will give you a UUID. Copy and paste this UUID to this box:";
194 -#endif
195 -
196 - // add quotes only when the filename has a space
197 - if(strchr(os_filename, ' '))
198 - os_quote = "\"";
199 - else
200 - os_quote = "";
201 -
202 - buffer_sprintf(buffer, "%s %s%s%s", os_prefix, os_quote, os_filename, os_quote);
203 - buffer_json_member_add_string(wb, "key_filename", os_filename);
204 - buffer_json_member_add_string(wb, "cmd", buffer_tostring(buffer));
205 - buffer_json_member_add_string(wb, "help", os_message);
206 - }
230 + return claim_json_response(wb, response, msg);
231 +}
232
208 - buffer_json_agents_v2(wb, NULL, now_s, false, false);
209 - buffer_json_finalize(wb);
233 +int api_v2_claim(RRDHOST *host __maybe_unused, struct web_client *w, char *url) {
234 + return api_claim(2, w, url);
235 +}
236
211 - return HTTP_RESP_OK;
237 +int api_v3_claim(RRDHOST *host __maybe_unused, struct web_client *w, char *url) {
238 + return api_claim(3, w, url);
239 }
src/web/api/web_api_v3.c
+1 -1
@@ -201,7 +201,7 @@ static struct web_api_command api_commands_v3[] = {
201 .hash = 0,
202 .acl = HTTP_ACL_NOCHECK,
203 .access = HTTP_ACCESS_NONE,
204 - .callback = api_v2_claim,
204 + .callback = api_v3_claim,
205 .allow_subpaths = 0
206 },
207 {