#971 split into smaller file

Split ogAdmServer into several files:

* sources/rest.c that implements the server REST API.
* sources/client.c that implements the client REST API.
* sources/json.c that provides a few JSON helpers.
master
OpenGnSys Support Team 2020-06-18 18:15:25 +02:00
parent 0b9465f783
commit 04ca20e9f1
11 changed files with 4118 additions and 3997 deletions

View File

@ -6,4 +6,7 @@ ogAdmServer_SOURCES= sources/ogAdmServer.c \
sources/dbi.c \
sources/schedule.c \
sources/utils.c \
sources/rest.c \
sources/client.c \
sources/json.c \
sources/ogAdmLib.c

689
sources/client.c 100644
View File

@ -0,0 +1,689 @@
/*
* Copyright (C) 2020 Soleta Networks <info@soleta.eu>
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the
* Free Software Foundation, version 3.
*/
#include "ogAdmServer.h"
#include "dbi.h"
#include "utils.h"
#include "list.h"
#include "rest.h"
#include "json.h"
#include "schedule.h"
#include <syslog.h>
#include <sys/ioctl.h>
#include <ifaddrs.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <jansson.h>
#include <time.h>
#define OG_COMPUTER_NAME_MAXLEN 100
struct og_computer {
unsigned int id;
unsigned int center;
unsigned int room;
char name[OG_COMPUTER_NAME_MAXLEN + 1];
unsigned int procedure_id;
};
static int og_dbi_get_computer_info(struct og_computer *computer,
struct in_addr addr)
{
const char *msglog;
struct og_dbi *dbi;
dbi_result result;
dbi = og_dbi_open(&dbi_config);
if (!dbi) {
syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
__func__, __LINE__);
return -1;
}
result = dbi_conn_queryf(dbi->conn,
"SELECT ordenadores.idordenador,"
" ordenadores.nombreordenador,"
" ordenadores.idaula,"
" ordenadores.idproautoexec,"
" centros.idcentro FROM ordenadores "
"INNER JOIN aulas ON aulas.idaula=ordenadores.idaula "
"INNER JOIN centros ON centros.idcentro=aulas.idcentro "
"WHERE ordenadores.ip='%s'", inet_ntoa(addr));
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;
}
if (!dbi_result_next_row(result)) {
syslog(LOG_ERR, "client does not exist in database (%s:%d)\n",
__func__, __LINE__);
dbi_result_free(result);
og_dbi_close(dbi);
return -1;
}
computer->id = dbi_result_get_uint(result, "idordenador");
computer->center = dbi_result_get_uint(result, "idcentro");
computer->room = dbi_result_get_uint(result, "idaula");
computer->procedure_id = dbi_result_get_uint(result, "idproautoexec");
strncpy(computer->name,
dbi_result_get_string(result, "nombreordenador"),
OG_COMPUTER_NAME_MAXLEN);
dbi_result_free(result);
og_dbi_close(dbi);
return 0;
}
static int og_resp_probe(struct og_client *cli, json_t *data)
{
const char *status = NULL;
const char *key;
json_t *value;
int err = 0;
if (json_typeof(data) != JSON_OBJECT)
return -1;
json_object_foreach(data, key, value) {
if (!strcmp(key, "status")) {
err = og_json_parse_string(value, &status);
if (err < 0)
return err;
} else {
return -1;
}
}
if (!strcmp(status, "BSY"))
cli->status = OG_CLIENT_STATUS_BUSY;
else if (!strcmp(status, "OPG"))
cli->status = OG_CLIENT_STATUS_OGLIVE;
return status ? 0 : -1;
}
static int og_resp_shell_run(struct og_client *cli, json_t *data)
{
const char *output = NULL;
char filename[4096];
const char *key;
json_t *value;
int err = -1;
FILE *file;
if (json_typeof(data) != JSON_OBJECT)
return -1;
json_object_foreach(data, key, value) {
if (!strcmp(key, "out")) {
err = og_json_parse_string(value, &output);
if (err < 0)
return err;
} else {
return -1;
}
}
if (!output) {
syslog(LOG_ERR, "%s:%d: malformed json response\n",
__FILE__, __LINE__);
return -1;
}
sprintf(filename, "/tmp/_Seconsola_%s", inet_ntoa(cli->addr.sin_addr));
file = fopen(filename, "wt");
if (!file) {
syslog(LOG_ERR, "cannot open file %s: %s\n",
filename, strerror(errno));
return -1;
}
fprintf(file, "%s", output);
fclose(file);
return 0;
}
struct og_computer_legacy {
char center[OG_DB_INT_MAXLEN + 1];
char id[OG_DB_INT_MAXLEN + 1];
char hardware[8192];
};
static int og_resp_hardware(json_t *data, struct og_client *cli)
{
struct og_computer_legacy legacy = {};
const char *hardware = NULL;
struct og_computer computer;
struct og_dbi *dbi;
const char *key;
json_t *value;
int err = 0;
bool res;
if (json_typeof(data) != JSON_OBJECT)
return -1;
json_object_foreach(data, key, value) {
if (!strcmp(key, "hardware")) {
err = og_json_parse_string(value, &hardware);
if (err < 0)
return -1;
} else {
return -1;
}
}
if (!hardware) {
syslog(LOG_ERR, "malformed response json\n");
return -1;
}
err = og_dbi_get_computer_info(&computer, cli->addr.sin_addr);
if (err < 0)
return -1;
snprintf(legacy.center, sizeof(legacy.center), "%d", computer.center);
snprintf(legacy.id, sizeof(legacy.id), "%d", computer.id);
snprintf(legacy.hardware, sizeof(legacy.hardware), "%s", hardware);
dbi = og_dbi_open(&dbi_config);
if (!dbi) {
syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
__func__, __LINE__);
return -1;
}
res = actualizaHardware(dbi, legacy.hardware, legacy.id, computer.name,
legacy.center);
og_dbi_close(dbi);
if (!res) {
syslog(LOG_ERR, "Problem updating client configuration\n");
return -1;
}
return 0;
}
struct og_software_legacy {
char software[8192];
char center[OG_DB_INT_MAXLEN + 1];
char part[OG_DB_SMALLINT_MAXLEN + 1];
char id[OG_DB_INT_MAXLEN + 1];
};
static int og_resp_software(json_t *data, struct og_client *cli)
{
struct og_software_legacy legacy = {};
const char *partition = NULL;
const char *software = NULL;
struct og_computer computer;
struct og_dbi *dbi;
const char *key;
json_t *value;
int err = 0;
bool res;
if (json_typeof(data) != JSON_OBJECT)
return -1;
json_object_foreach(data, key, value) {
if (!strcmp(key, "software"))
err = og_json_parse_string(value, &software);
else if (!strcmp(key, "partition"))
err = og_json_parse_string(value, &partition);
else
return -1;
if (err < 0)
return -1;
}
if (!software || !partition) {
syslog(LOG_ERR, "malformed response json\n");
return -1;
}
err = og_dbi_get_computer_info(&computer, cli->addr.sin_addr);
if (err < 0)
return -1;
snprintf(legacy.software, sizeof(legacy.software), "%s", software);
snprintf(legacy.part, sizeof(legacy.part), "%s", partition);
snprintf(legacy.id, sizeof(legacy.id), "%d", computer.id);
snprintf(legacy.center, sizeof(legacy.center), "%d", computer.center);
dbi = og_dbi_open(&dbi_config);
if (!dbi) {
syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
__func__, __LINE__);
return -1;
}
res = actualizaSoftware(dbi, legacy.software, legacy.part, legacy.id,
computer.name, legacy.center);
og_dbi_close(dbi);
if (!res) {
syslog(LOG_ERR, "Problem updating client configuration\n");
return -1;
}
return 0;
}
#define OG_PARAMS_RESP_REFRESH (OG_PARAM_PART_DISK | \
OG_PARAM_PART_NUMBER | \
OG_PARAM_PART_CODE | \
OG_PARAM_PART_FILESYSTEM | \
OG_PARAM_PART_OS | \
OG_PARAM_PART_SIZE | \
OG_PARAM_PART_USED_SIZE)
static int og_json_parse_partition_array(json_t *value,
struct og_partition *partitions)
{
json_t *element;
int i, err;
if (json_typeof(value) != JSON_ARRAY)
return -1;
for (i = 0; i < json_array_size(value) && i < OG_PARTITION_MAX; i++) {
element = json_array_get(value, i);
err = og_json_parse_partition(element, &partitions[i],
OG_PARAMS_RESP_REFRESH);
if (err < 0)
return err;
}
return 0;
}
static int og_dbi_queue_autorun(uint32_t computer_id, uint32_t proc_id)
{
struct og_task dummy_task = {
.scope = computer_id,
.type_scope = AMBITO_ORDENADORES,
.procedure_id = proc_id,
};
struct og_dbi *dbi;
dbi = og_dbi_open(&dbi_config);
if (!dbi) {
syslog(LOG_ERR, "cannot open connection database "
"(%s:%d)\n", __func__, __LINE__);
return -1;
}
if (og_dbi_queue_procedure(dbi, &dummy_task)) {
og_dbi_close(dbi);
return -1;
}
og_dbi_close(dbi);
return 0;
}
static int og_resp_refresh(json_t *data, struct og_client *cli)
{
struct og_partition partitions[OG_PARTITION_MAX] = {};
const char *serial_number = NULL;
struct og_computer computer = {};
struct og_partition disk_setup;
char cfg[1024] = {};
struct og_dbi *dbi;
const char *key;
unsigned int i;
json_t *value;
int err = 0;
bool res;
if (json_typeof(data) != JSON_OBJECT)
return -1;
json_object_foreach(data, key, value) {
if (!strcmp(key, "disk_setup")) {
err = og_json_parse_partition(value,
&disk_setup,
OG_PARAMS_RESP_REFRESH);
} else if (!strcmp(key, "partition_setup")) {
err = og_json_parse_partition_array(value, partitions);
} else if (!strcmp(key, "serial_number")) {
err = og_json_parse_string(value, &serial_number);
} else {
return -1;
}
if (err < 0)
return err;
}
err = og_dbi_get_computer_info(&computer, cli->addr.sin_addr);
if (err < 0)
return -1;
if (strlen(serial_number) > 0)
snprintf(cfg, sizeof(cfg), "ser=%s\n", serial_number);
if (!disk_setup.disk || !disk_setup.number || !disk_setup.code ||
!disk_setup.filesystem || !disk_setup.os || !disk_setup.size ||
!disk_setup.used_size)
return -1;
snprintf(cfg + strlen(cfg), sizeof(cfg) - strlen(cfg),
"disk=%s\tpar=%s\tcpt=%s\tfsi=%s\tsoi=%s\ttam=%s\tuso=%s\n",
disk_setup.disk, disk_setup.number, disk_setup.code,
disk_setup.filesystem, disk_setup.os, disk_setup.size,
disk_setup.used_size);
for (i = 0; i < OG_PARTITION_MAX; i++) {
if (!partitions[i].disk || !partitions[i].number ||
!partitions[i].code || !partitions[i].filesystem ||
!partitions[i].os || !partitions[i].size ||
!partitions[i].used_size)
continue;
snprintf(cfg + strlen(cfg), sizeof(cfg) - strlen(cfg),
"disk=%s\tpar=%s\tcpt=%s\tfsi=%s\tsoi=%s\ttam=%s\tuso=%s\n",
partitions[i].disk, partitions[i].number,
partitions[i].code, partitions[i].filesystem,
partitions[i].os, partitions[i].size,
partitions[i].used_size);
}
dbi = og_dbi_open(&dbi_config);
if (!dbi) {
syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
__func__, __LINE__);
return -1;
}
res = actualizaConfiguracion(dbi, cfg, computer.id);
og_dbi_close(dbi);
if (!res) {
syslog(LOG_ERR, "Problem updating client configuration\n");
return -1;
}
if (!cli->autorun && computer.procedure_id) {
cli->autorun = true;
if (og_dbi_queue_autorun(computer.id, computer.procedure_id))
return -1;
}
return 0;
}
static int og_resp_image_create(json_t *data, struct og_client *cli)
{
struct og_software_legacy soft_legacy;
struct og_image_legacy img_legacy;
const char *partition = NULL;
const char *software = NULL;
const char *image_id = NULL;
struct og_computer computer;
const char *disk = NULL;
const char *code = NULL;
const char *name = NULL;
const char *repo = NULL;
struct og_dbi *dbi;
const char *key;
json_t *value;
int err = 0;
bool res;
if (json_typeof(data) != JSON_OBJECT)
return -1;
json_object_foreach(data, key, value) {
if (!strcmp(key, "software"))
err = og_json_parse_string(value, &software);
else if (!strcmp(key, "partition"))
err = og_json_parse_string(value, &partition);
else if (!strcmp(key, "disk"))
err = og_json_parse_string(value, &disk);
else if (!strcmp(key, "code"))
err = og_json_parse_string(value, &code);
else if (!strcmp(key, "id"))
err = og_json_parse_string(value, &image_id);
else if (!strcmp(key, "name"))
err = og_json_parse_string(value, &name);
else if (!strcmp(key, "repository"))
err = og_json_parse_string(value, &repo);
else
return -1;
if (err < 0)
return err;
}
if (!software || !partition || !disk || !code || !image_id || !name ||
!repo) {
syslog(LOG_ERR, "malformed response json\n");
return -1;
}
err = og_dbi_get_computer_info(&computer, cli->addr.sin_addr);
if (err < 0)
return -1;
snprintf(soft_legacy.center, sizeof(soft_legacy.center), "%d",
computer.center);
snprintf(soft_legacy.software, sizeof(soft_legacy.software), "%s",
software);
snprintf(img_legacy.image_id, sizeof(img_legacy.image_id), "%s",
image_id);
snprintf(soft_legacy.id, sizeof(soft_legacy.id), "%d", computer.id);
snprintf(img_legacy.part, sizeof(img_legacy.part), "%s", partition);
snprintf(img_legacy.disk, sizeof(img_legacy.disk), "%s", disk);
snprintf(img_legacy.code, sizeof(img_legacy.code), "%s", code);
snprintf(img_legacy.name, sizeof(img_legacy.name), "%s", name);
snprintf(img_legacy.repo, sizeof(img_legacy.repo), "%s", repo);
dbi = og_dbi_open(&dbi_config);
if (!dbi) {
syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
__func__, __LINE__);
return -1;
}
res = actualizaSoftware(dbi,
soft_legacy.software,
img_legacy.part,
soft_legacy.id,
computer.name,
soft_legacy.center);
if (!res) {
og_dbi_close(dbi);
syslog(LOG_ERR, "Problem updating client configuration\n");
return -1;
}
res = actualizaCreacionImagen(dbi,
img_legacy.image_id,
img_legacy.disk,
img_legacy.part,
img_legacy.code,
img_legacy.repo,
soft_legacy.id);
og_dbi_close(dbi);
if (!res) {
syslog(LOG_ERR, "Problem updating client configuration\n");
return -1;
}
return 0;
}
static int og_resp_image_restore(json_t *data, struct og_client *cli)
{
struct og_software_legacy soft_legacy;
struct og_image_legacy img_legacy;
const char *partition = NULL;
const char *image_id = NULL;
struct og_computer computer;
const char *disk = NULL;
dbi_result query_result;
struct og_dbi *dbi;
const char *key;
json_t *value;
int err = 0;
bool res;
if (json_typeof(data) != JSON_OBJECT)
return -1;
json_object_foreach(data, key, value) {
if (!strcmp(key, "partition"))
err = og_json_parse_string(value, &partition);
else if (!strcmp(key, "disk"))
err = og_json_parse_string(value, &disk);
else if (!strcmp(key, "image_id"))
err = og_json_parse_string(value, &image_id);
else
return -1;
if (err < 0)
return err;
}
if (!partition || !disk || !image_id) {
syslog(LOG_ERR, "malformed response json\n");
return -1;
}
err = og_dbi_get_computer_info(&computer, cli->addr.sin_addr);
if (err < 0)
return -1;
snprintf(img_legacy.image_id, sizeof(img_legacy.image_id), "%s",
image_id);
snprintf(img_legacy.part, sizeof(img_legacy.part), "%s", partition);
snprintf(img_legacy.disk, sizeof(img_legacy.disk), "%s", disk);
snprintf(soft_legacy.id, sizeof(soft_legacy.id), "%d", computer.id);
dbi = og_dbi_open(&dbi_config);
if (!dbi) {
syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
__func__, __LINE__);
return -1;
}
query_result = dbi_conn_queryf(dbi->conn,
"SELECT idperfilsoft FROM imagenes "
" WHERE idimagen='%s'",
image_id);
if (!query_result) {
og_dbi_close(dbi);
syslog(LOG_ERR, "failed to query database\n");
return -1;
}
if (!dbi_result_next_row(query_result)) {
dbi_result_free(query_result);
og_dbi_close(dbi);
syslog(LOG_ERR, "software profile does not exist in database\n");
return -1;
}
snprintf(img_legacy.software_id, sizeof(img_legacy.software_id),
"%d", dbi_result_get_uint(query_result, "idperfilsoft"));
dbi_result_free(query_result);
res = actualizaRestauracionImagen(dbi,
img_legacy.image_id,
img_legacy.disk,
img_legacy.part,
soft_legacy.id,
img_legacy.software_id);
og_dbi_close(dbi);
if (!res) {
syslog(LOG_ERR, "Problem updating client configuration\n");
return -1;
}
return 0;
}
int og_agent_state_process_response(struct og_client *cli)
{
json_error_t json_err;
json_t *root;
int err = -1;
char *body;
if (!strncmp(cli->buf, "HTTP/1.0 202 Accepted",
strlen("HTTP/1.0 202 Accepted"))) {
og_dbi_update_action(cli->last_cmd_id, true);
cli->last_cmd_id = 0;
return 1;
}
if (strncmp(cli->buf, "HTTP/1.0 200 OK", strlen("HTTP/1.0 200 OK"))) {
og_dbi_update_action(cli->last_cmd_id, false);
cli->last_cmd_id = 0;
return -1;
}
og_dbi_update_action(cli->last_cmd_id, true);
cli->last_cmd_id = 0;
if (!cli->content_length) {
cli->last_cmd = OG_CMD_UNSPEC;
return 0;
}
body = strstr(cli->buf, "\r\n\r\n") + 4;
root = json_loads(body, 0, &json_err);
if (!root) {
syslog(LOG_ERR, "%s:%d: malformed json line %d: %s\n",
__FILE__, __LINE__, json_err.line, json_err.text);
return -1;
}
switch (cli->last_cmd) {
case OG_CMD_PROBE:
err = og_resp_probe(cli, root);
break;
case OG_CMD_SHELL_RUN:
err = og_resp_shell_run(cli, root);
break;
case OG_CMD_HARDWARE:
err = og_resp_hardware(root, cli);
break;
case OG_CMD_SOFTWARE:
err = og_resp_software(root, cli);
break;
case OG_CMD_REFRESH:
err = og_resp_refresh(root, cli);
break;
case OG_CMD_SETUP:
err = og_resp_refresh(root, cli);
break;
case OG_CMD_IMAGE_CREATE:
err = og_resp_image_create(root, cli);
break;
case OG_CMD_IMAGE_RESTORE:
err = og_resp_image_restore(root, cli);
break;
default:
err = -1;
break;
}
cli->last_cmd = OG_CMD_UNSPEC;
return err;
}

6
sources/client.h 100644
View File

@ -0,0 +1,6 @@
#ifndef OG_CLIENT_H_
#define OG_CLIENT_H_
int og_agent_state_process_response(struct og_client *cli);
#endif

View File

@ -18,4 +18,31 @@ struct og_dbi {
struct og_dbi *og_dbi_open(struct og_dbi_config *config);
void og_dbi_close(struct og_dbi *db);
#define OG_DB_IMAGE_NAME_MAXLEN 50
#define OG_DB_FILESYSTEM_MAXLEN 16
#define OG_DB_INT8_MAXLEN 8
#define OG_DB_INT_MAXLEN 11
#define OG_DB_IP_MAXLEN 15
#define OG_DB_SMALLINT_MAXLEN 6
struct og_image_legacy {
char software_id[OG_DB_INT_MAXLEN + 1];
char image_id[OG_DB_INT_MAXLEN + 1];
char name[OG_DB_IMAGE_NAME_MAXLEN + 1];
char repo[OG_DB_IP_MAXLEN + 1];
char part[OG_DB_SMALLINT_MAXLEN + 1];
char disk[OG_DB_SMALLINT_MAXLEN + 1];
char code[OG_DB_INT8_MAXLEN + 1];
};
struct og_legacy_partition {
char partition[OG_DB_SMALLINT_MAXLEN + 1];
char code[OG_DB_INT8_MAXLEN + 1];
char size[OG_DB_INT_MAXLEN + 1];
char filesystem[OG_DB_FILESYSTEM_MAXLEN + 1];
char format[2]; /* Format is a boolean 0 or 1 => length is 2 */
};
extern struct og_dbi_config dbi_config;
#endif

85
sources/json.c 100644
View File

@ -0,0 +1,85 @@
/*
* Copyright (C) 2020 Soleta Networks <info@soleta.eu>
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the
* Free Software Foundation, version 3.
*/
#include "json.h"
#include <stdint.h>
int og_json_parse_string(json_t *element, const char **str)
{
if (json_typeof(element) != JSON_STRING)
return -1;
*str = json_string_value(element);
return 0;
}
int og_json_parse_uint(json_t *element, uint32_t *integer)
{
if (json_typeof(element) != JSON_INTEGER)
return -1;
*integer = json_integer_value(element);
return 0;
}
int og_json_parse_bool(json_t *element, bool *value)
{
if (json_typeof(element) == JSON_TRUE)
*value = true;
else if (json_typeof(element) == JSON_FALSE)
*value = false;
else
return -1;
return 0;
}
int og_json_parse_partition(json_t *element, struct og_partition *part,
uint64_t required_flags)
{
uint64_t flags = 0UL;
const char *key;
json_t *value;
int err = 0;
json_object_foreach(element, key, value) {
if (!strcmp(key, "partition")) {
err = og_json_parse_string(value, &part->number);
flags |= OG_PARAM_PART_NUMBER;
} else if (!strcmp(key, "code")) {
err = og_json_parse_string(value, &part->code);
flags |= OG_PARAM_PART_CODE;
} else if (!strcmp(key, "filesystem")) {
err = og_json_parse_string(value, &part->filesystem);
flags |= OG_PARAM_PART_FILESYSTEM;
} else if (!strcmp(key, "size")) {
err = og_json_parse_string(value, &part->size);
flags |= OG_PARAM_PART_SIZE;
} else if (!strcmp(key, "format")) {
err = og_json_parse_string(value, &part->format);
flags |= OG_PARAM_PART_FORMAT;
} else if (!strcmp(key, "disk")) {
err = og_json_parse_string(value, &part->disk);
flags |= OG_PARAM_PART_DISK;
} else if (!strcmp(key, "os")) {
err = og_json_parse_string(value, &part->os);
flags |= OG_PARAM_PART_OS;
} else if (!strcmp(key, "used_size")) {
err = og_json_parse_string(value, &part->used_size);
flags |= OG_PARAM_PART_USED_SIZE;
}
if (err < 0)
return err;
}
if (flags != required_flags)
return -1;
return err;
}

77
sources/json.h 100644
View File

@ -0,0 +1,77 @@
#ifndef _OG_JSON_H
#define _OG_JSON_H
#include <jansson.h>
#include "schedule.h"
int og_json_parse_string(json_t *element, const char **str);
int og_json_parse_uint(json_t *element, uint32_t *integer);
int og_json_parse_bool(json_t *element, bool *value);
#define OG_PARAM_PART_NUMBER (1UL << 0)
#define OG_PARAM_PART_CODE (1UL << 1)
#define OG_PARAM_PART_FILESYSTEM (1UL << 2)
#define OG_PARAM_PART_SIZE (1UL << 3)
#define OG_PARAM_PART_FORMAT (1UL << 4)
#define OG_PARAM_PART_DISK (1UL << 5)
#define OG_PARAM_PART_OS (1UL << 6)
#define OG_PARAM_PART_USED_SIZE (1UL << 7)
struct og_partition {
const char *disk;
const char *number;
const char *code;
const char *size;
const char *filesystem;
const char *format;
const char *os;
const char *used_size;
};
#define OG_PARTITION_MAX 4
int og_json_parse_partition(json_t *element, struct og_partition *part,
uint64_t required_flags);
#define OG_CLIENTS_MAX 4096
struct og_sync_params {
const char *sync;
const char *diff;
const char *remove;
const char *compress;
const char *cleanup;
const char *cache;
const char *cleanup_cache;
const char *remove_dst;
const char *diff_id;
const char *diff_name;
const char *path;
const char *method;
};
struct og_msg_params {
const char *ips_array[OG_CLIENTS_MAX];
const char *mac_array[OG_CLIENTS_MAX];
unsigned int ips_array_len;
const char *wol_type;
char run_cmd[4096];
const char *disk;
const char *partition;
const char *repository;
const char *name;
const char *id;
const char *code;
const char *type;
const char *profile;
const char *cache;
const char *cache_size;
bool echo;
struct og_partition partition_setup[OG_PARTITION_MAX];
struct og_sync_params sync_setup;
struct og_schedule_time time;
const char *task_id;
uint64_t flags;
};
#endif

File diff suppressed because it is too large Load Diff

3100
sources/rest.c 100644

File diff suppressed because it is too large Load Diff

98
sources/rest.h 100644
View File

@ -0,0 +1,98 @@
#ifndef OG_REST_H
#define OG_REST_H
#include <ev.h>
extern struct ev_loop *og_loop;
enum og_client_state {
OG_CLIENT_RECEIVING_HEADER = 0,
OG_CLIENT_RECEIVING_PAYLOAD,
OG_CLIENT_PROCESSING_REQUEST,
};
enum og_client_status {
OG_CLIENT_STATUS_OGLIVE,
OG_CLIENT_STATUS_BUSY,
};
enum og_cmd_type {
OG_CMD_UNSPEC,
OG_CMD_WOL,
OG_CMD_PROBE,
OG_CMD_SHELL_RUN,
OG_CMD_SESSION,
OG_CMD_POWEROFF,
OG_CMD_REFRESH,
OG_CMD_REBOOT,
OG_CMD_STOP,
OG_CMD_HARDWARE,
OG_CMD_SOFTWARE,
OG_CMD_IMAGE_CREATE,
OG_CMD_IMAGE_RESTORE,
OG_CMD_SETUP,
OG_CMD_RUN_SCHEDULE,
OG_CMD_MAX
};
#define OG_MSG_REQUEST_MAXLEN 65536
struct og_client {
struct list_head list;
struct ev_io io;
struct ev_timer timer;
struct sockaddr_in addr;
enum og_client_state state;
char buf[OG_MSG_REQUEST_MAXLEN];
unsigned int buf_len;
unsigned int msg_len;
int keepalive_idx;
bool rest;
bool agent;
int content_length;
char auth_token[64];
enum og_client_status status;
enum og_cmd_type last_cmd;
unsigned int last_cmd_id;
bool autorun;
};
void og_client_add(struct og_client *cli);
static inline int og_client_socket(const struct og_client *cli)
{
return cli->io.fd;
}
#include "json.h"
int og_client_state_process_payload_rest(struct og_client *cli);
enum og_rest_method {
OG_METHOD_GET = 0,
OG_METHOD_POST,
OG_METHOD_NO_HTTP
};
int og_send_request(enum og_rest_method method, enum og_cmd_type type,
const struct og_msg_params *params,
const json_t *data);
struct og_cmd {
uint32_t id;
struct list_head list;
uint32_t client_id;
const char *ip;
const char *mac;
enum og_cmd_type type;
enum og_rest_method method;
struct og_msg_params params;
json_t *json;
};
const struct og_cmd *og_cmd_find(const char *client_ip);
void og_cmd_free(const struct og_cmd *cmd);
extern char auth_token[LONPRM];
#endif

View File

@ -1,3 +1,11 @@
/*
* Copyright (C) 2020 Soleta Networks <info@soleta.eu>
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the
* Free Software Foundation, version 3.
*/
#include "schedule.h"
#include "list.h"
#include <sys/types.h>

View File

@ -45,4 +45,21 @@ void og_schedule_refresh(struct ev_loop *loop);
void og_schedule_run(unsigned int task_id, unsigned int schedule_id,
enum og_schedule_type type);
int og_dbi_schedule_get(void);
int og_dbi_update_action(uint32_t id, bool success);
struct og_task {
uint32_t task_id;
uint32_t procedure_id;
uint32_t command_id;
uint32_t center_id;
uint32_t schedule_id;
uint32_t type_scope;
uint32_t scope;
const char *filtered_scope;
const char *params;
};
int og_dbi_queue_procedure(struct og_dbi *dbi, struct og_task *task);
#endif