diff options
author | Jose M. Guisado <jguisado@soleta.eu> | 2023-08-22 16:09:58 +0200 |
---|---|---|
committer | Jose M. Guisado <jguisado@soleta.eu> | 2023-08-23 13:17:03 +0200 |
commit | 44745a3f22875af77da8f6e25ebc48b9840964ac (patch) | |
tree | 8ec61abf7cf1d5393845820d75a330e636612d55 | |
parent | a67c1088efac08840458c6b66660e06e5119f0cc (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.c | 105 |
1 files changed, 105 insertions, 0 deletions
@@ -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, ¶ms->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, ¶ms, 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, ¶ms, 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) { |