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
{