deployd/client/commands.c
Arija A. 8fbb8e8c18
Implement command client
Signed-off-by: Arija A. <ari@ari.lt>
2025-07-24 19:48:39 +03:00

107 lines
3.3 KiB
C

#include "include/conf.h"
#include <stdio.h>
#include <string.h>
#include "include/proto.h"
#include "include/commands.h"
#include "server/include/def.h"
#include "server/include/auth.h"
#include "server/include/proto.h"
#define DC_CMD_COMMAND_USAGE() \
dp_logf(logger, DP_LOG_ERROR, DC_COMMANDS_LOG "/command", \
"Usage: %s " \
"<trigger|teardown|deploy|rollback|cleanup|restart|sysadmin|logs>" \
" <is_unsafe = 1|0> <id> <domain> <key> <secret> <timestamp>", \
argv[0])
typedef struct {
const char *name;
dp_DeployCommand command;
} dc_DeployCommandMap;
int dc_cmd_command(SSL *ssl, int argc, const char *argv[], dp_Logger *logger) {
if (!ssl || argc < 1 || !logger) {
return -1;
}
if (argc < 8) {
DC_CMD_COMMAND_USAGE();
return 0;
}
static const dc_DeployCommandMap commands[] = {
{"trigger", dp_DeployCommand_trigger},
{"teardown", dp_DeployCommand_teardown},
{"deploy", dp_DeployCommand_deploy},
{"rollback", dp_DeployCommand_rollback},
{"cleanup", dp_DeployCommand_cleanup},
{"restart", dp_DeployCommand_restart},
{"sysadmin", dp_DeployCommand_sysadmin},
{"logs", dp_DeployCommand_logs},
};
dp_DeployCommand command = 0;
bool found = false;
for (size_t idx = 0; idx < sizeof(commands) / sizeof(commands[0]); ++idx) {
if (strcmp(commands[idx].name, argv[1]) == 0) {
command = commands[idx].command;
found = true;
break;
}
}
if (!found) {
dp_logf(logger, DP_LOG_ERROR, DC_COMMANDS_LOG "/command",
"Unknown command type: %s", argv[0]);
DC_CMD_COMMAND_USAGE();
return -1;
}
const bool is_unsafe = (argv[2][0] == '1' ? true : false);
if (!dp_isnumber(argv[3])) {
dp_logf(logger, DP_LOG_ERROR, DC_COMMANDS_LOG "/command",
"Invalid ID: %s", argv[2]);
return -1;
}
const uint64_t tid = dp_str2u64(argv[3]);
const char *domain = argv[4];
const size_t domain_len = strlen(domain);
if (domain_len > 255) {
dp_logf(logger, DP_LOG_ERROR, DC_COMMANDS_LOG "/command",
"Domain '%s' too long", argv[4]);
return -1;
}
const char *key = argv[5];
const char *secret = argv[6];
if (!dp_isnumber(argv[7])) {
dp_logf(logger, DP_LOG_ERROR, DC_COMMANDS_LOG "/command",
"Invalid timestamp: %s", argv[7]);
return -1;
}
const uint64_t timestamp = dp_str2u64(argv[7]);
/* Generate token */
uint8_t token[DP_AUTH_TOKEN_SIZE] = {0};
if (!dp_auth_gen_token(token, timestamp, (const uint8_t *)secret)) {
dp_log(logger, DP_LOG_ERROR, DC_COMMANDS_LOG "/command",
"Failed to generate an authentication token");
return -1;
}
dp_logf(logger, DP_LOG_INFO, DC_COMMANDS_LOG "/command",
"Running command '%s' on '%s'", argv[1], domain);
if (!dc_proto_command(ssl, logger, command, is_unsafe, tid,
(uint8_t)domain_len, domain, (const uint8_t *)key,
token, true)) {
return -1;
}
return 8;
}