summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJose M. Guisado <jguisado@soleta.eu>2023-08-22 16:09:58 +0200
committerJose M. Guisado <jguisado@soleta.eu>2023-08-23 13:17:03 +0200
commit44745a3f22875af77da8f6e25ebc48b9840964ac (patch)
tree8ec61abf7cf1d5393845820d75a330e636612d55
parenta67c1088efac08840458c6b66660e06e5119f0cc (diff)
rest: add POST client/server method
Enable modification of the associated ogserver of a given client. This API is exposed via the POST /client/server endpoint and expects a JSON payload with an array of clients ("client":[]) and the "id" of the ogserver ("identorno" column value inside the "entornos" table) For example: >>> POST /client/server { "client": [ "10.141.10.100", "10.141.10.101", "10.141.10.104", "10.141.10.102" ], "id": "6" } <<< HTTP/1.1 200 OK If the ogserver id does not exist the foreign key constraint (ON UPDATE RESTRICT) inside the "ordenadores" table will cancel the operation and the server will reply with 400 Bad Request. >>> POST /client/server { "client": [ "10.141.10.100", "10.141.10.101", "10.141.10.104", "10.141.10.102" ], "id": "666" } <<< HTTP/1.1 400 Bad Request The OpenGnsys database stores different ip addresses for the ogServer inside the "entornos" table. This table is related to the "ordenadores" table using a foreign key on the "identorno" column. i.e: Clients in the "ordenadores" table associate to an specific server in the database using the "identorno" column (from "entornos" table).
-rw-r--r--src/rest.c105
1 files changed, 105 insertions, 0 deletions
diff --git a/src/rest.c b/src/rest.c
index c1161eb..2897572 100644
--- a/src/rest.c
+++ b/src/rest.c
@@ -1390,6 +1390,97 @@ static int og_cmd_get_client_setup(json_t *element,
return 0;
}
+static int og_dbi_update_client_entorno(struct og_dbi *dbi,
+ const char *mac,
+ const char *server_id)
+{
+ const char *msglog;
+ dbi_result result;
+
+ result = dbi_conn_queryf(dbi->conn,
+ "UPDATE ordenadores SET identorno=%s "
+ "WHERE mac='%s'",
+ server_id, mac);
+
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to update client's server (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return -1;
+ }
+
+ dbi_result_free(result);
+ return 0;
+}
+
+static int og_cmd_post_client_server(json_t *element,
+ struct og_msg_params *params,
+ char *buffer_reply)
+{
+ char ips_str[(OG_DB_IP_MAXLEN + 1) * OG_CLIENTS_MAX + 1] = {};
+ const char *key, *msglog, *mac;
+ int ips_str_len = 0;
+ struct og_dbi *dbi;
+ dbi_result result;
+ int err = 0, i;
+ json_t *value;
+
+ json_object_foreach(element, key, value) {
+ if (!strcmp(key, "clients")) {
+ err = og_json_parse_clients(value, params);
+ } else if (!strcmp(key, "id")) {
+ err = og_json_parse_string(value, &params->id);
+ params->flags |= OG_REST_PARAM_ID;
+ }
+
+ if (err < 0)
+ return err;
+ }
+
+ if (!og_msg_params_validate(params, OG_REST_PARAM_ADDR |
+ OG_REST_PARAM_ID))
+ return -1;
+
+ dbi = og_dbi_open(&ogconfig.db);
+ if (!dbi) {
+ syslog(LOG_ERR, "cannot open conection database (%s:%d)\n",
+ __func__, __LINE__);
+ return -1;
+ }
+
+ for (i = 0; i < params->ips_array_len; ++i) {
+ ips_str_len += snprintf(ips_str + ips_str_len,
+ sizeof(ips_str) - ips_str_len,
+ "'%s',", params->ips_array[i]);
+ }
+ ips_str[ips_str_len - 1] = '\0';
+
+ result = dbi_conn_queryf(dbi->conn,
+ "SELECT mac FROM ordenadores "
+ "WHERE ip IN (%s)", ips_str);
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ og_dbi_close(dbi);
+ return -1;
+ }
+
+ while (dbi_result_next_row(result)) {
+ mac = dbi_result_get_string(result, "mac");
+ err = og_dbi_update_client_entorno(dbi, mac, params->id);
+ if (err != 0) {
+ dbi_result_free(result);
+ og_dbi_close(dbi);
+ return -1;
+ }
+ }
+
+ dbi_result_free(result);
+ og_dbi_close(dbi);
+ return 0;
+}
+
static int og_cmd_get_client_info(json_t *element,
struct og_msg_params *params,
char *buffer_reply)
@@ -6044,6 +6135,20 @@ int og_client_state_process_payload_rest(struct og_client *cli)
}
err = og_cmd_get_client_setup(root, &params, buf_reply);
+ } else if (!strncmp(cmd, "client/server", strlen("client/server"))) {
+ switch (method) {
+ case OG_METHOD_POST:
+ if (!root) {
+ syslog(LOG_ERR, "client post server command with no payload\n");
+ err = og_client_bad_request(cli);
+ goto err_process_rest_payload;
+ }
+ err = og_cmd_post_client_server(root, &params, buf_reply);
+ break;
+ default:
+ err = og_client_method_not_found(cli);
+ goto err_process_rest_payload;
+ }
} else if (!strncmp(cmd, "client/info",
strlen("client/info"))) {
if (method != OG_METHOD_GET) {