mirror of https://git.48k.eu/ogserver
#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
parent
0b9465f783
commit
04ca20e9f1
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef OG_CLIENT_H_
|
||||
#define OG_CLIENT_H_
|
||||
|
||||
int og_agent_state_process_response(struct og_client *cli);
|
||||
|
||||
#endif
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
File diff suppressed because it is too large
Load Diff
|
@ -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
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue