Skip to content

Commit

Permalink
Merge pull request #1064 from openziti/move-file-update-to-zet
Browse files Browse the repository at this point in the history
move config file update from tunneler lib to ZET
  • Loading branch information
ekoby authored Dec 11, 2024
2 parents b447e17 + 448a171 commit 7718bd5
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 105 deletions.
3 changes: 2 additions & 1 deletion lib/ziti-tunnel-cbs/include/ziti/ziti_tunnel_cbs.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,8 @@ XX(recovery_codes, model_string, array, recovery_codes, __VA_ARGS__) \
XX(code, model_number, none, code, __VA_ARGS__)

#define ZTX_API_EVENT_MODEL(XX, ...) \
BASE_EVENT_MODEL(XX, __VA_ARGS__) \
BASE_EVENT_MODEL(XX, __VA_ARGS__) \
XX(config_json, json, none, config, __VA_ARGS__) \
XX(new_ctrl_address, model_string, none, new_ctrl_address, __VA_ARGS__) \
XX(new_ca_bundle, model_string, none, new_ca_bundle, __VA_ARGS__)

Expand Down
107 changes: 3 additions & 104 deletions lib/ziti-tunnel-cbs/ziti_tunnel_ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,6 @@ struct tunnel_cb_s {
void *cmd_ctx;
};

typedef struct api_update_req_s {
uv_work_t wr;
struct ziti_instance_s *inst;
char *config_json;
int err;
const char *errmsg;
} api_update_req;

static uv_signal_t sigusr1;

const ziti_tunnel_ctrl* ziti_tunnel_init_cmd(uv_loop_t *loop, tunneler_context tunnel_ctx, event_cb on_event) {
Expand Down Expand Up @@ -1102,20 +1094,15 @@ static void on_ziti_event(ziti_context ztx, const ziti_event_t *event) {

case ZitiConfigEvent: {
if (event->cfg.config) {
if (instance->identifier) {
api_update_req *req = calloc(1, sizeof(api_update_req));
req->wr.data = req;
req->inst = instance;
req->config_json = ziti_config_to_json(event->cfg.config, 0, NULL);
uv_queue_work(CMD_CTX.loop, &req->wr, update_config, update_config_done);
}

char *cfg_json = ziti_config_to_json(event->cfg.config, 0, NULL);
api_event ev = {0};
ev.event_type = TunnelEvents.APIEvent;
ev.identifier = instance->identifier;
ev.new_ctrl_address = event->cfg.config->controller_url;
ev.new_ca_bundle = event->cfg.config->id.ca;
ev.config_json = cfg_json;
CMD_CTX.on_event((const base_event *) &ev);
free(cfg_json);
} else {
ZITI_LOG(WARN, "unexpected config event: config is missing");
}
Expand Down Expand Up @@ -1467,95 +1454,7 @@ static void on_sigdump(uv_signal_t *sig, int signum) {
}


static int update_file(const char *path, char *content, size_t content_len) {
#define CHECK_UV(desc, op) do{ \
uv_fs_req_cleanup(&fs_req); \
rc = op; \
if (rc < 0) { \
ZITI_LOG(ERROR, "op[" desc "] failed: %d(%s)", rc, uv_strerror(rc)); \
goto DONE; \
}} while(0)

int rc = 0;
uv_fs_t fs_req = {0};
CHECK_UV("check exiting config", uv_fs_stat(NULL, &fs_req, path, NULL));
uint64_t mode = fs_req.statbuf.st_mode;

char backup[FILENAME_MAX];
snprintf(backup, sizeof(backup), "%s.bak", path);
CHECK_UV("create backup", uv_fs_rename(NULL, &fs_req, path, backup, NULL));

uv_os_fd_t f;
CHECK_UV("open new config", f = uv_fs_open(NULL, &fs_req, path, UV_FS_O_WRONLY | UV_FS_O_CREAT, (int) mode, NULL));
uv_buf_t buf = uv_buf_init(content, content_len);
CHECK_UV("write new config", uv_fs_write(NULL, &fs_req, f, &buf, 1, 0, NULL));
CHECK_UV("close new config", uv_fs_close(NULL, &fs_req, f, NULL));

DONE:
return rc;
#undef CHECK_UV
}

#define CHECK_UV(desc, op) do{ \
int rc = op; \
if (rc < 0) { \
req->err = rc; \
req->errmsg = uv_strerror(rc); \
ZITI_LOG(ERROR, "op[" desc "] failed: %d(%s)", req->err, req->errmsg); \
goto DONE; \
}} while(0)

static void update_config(uv_work_t *wr) {
api_update_req *req = wr->data;
const char *config_file = req->inst->identifier;
size_t cfg_len;
char *cfg_buf = NULL;
uv_file f;

ziti_config cfg = {0};
if (ziti_load_config(&cfg, config_file) != ZITI_OK) {
ZITI_LOG(ERROR, "failed to parse config file[%s]", config_file);
req->err = -1;
req->errmsg = "failed to parse existing config";
goto DONE;
}

ziti_config new_cfg = {0};
parse_ziti_config(&new_cfg, req->config_json, strlen(req->config_json));

// attempt to update CA bundle external to config file
if (strncmp(cfg.id.ca, "file://", strlen("file://")) == 0) {
struct tlsuv_url_s path_uri;
CHECK_UV("parse CA bundle path", tlsuv_parse_url(&path_uri, cfg.id.ca));
const char *path = path_uri.path;
CHECK_UV("update CA bundle file", update_file(path, (char*)new_cfg.id.ca, strlen(new_cfg.id.ca)));
FREE(new_cfg.id.ca);
new_cfg.id.ca = cfg.id.ca;
cfg.id.ca = NULL;
}

bool write_new_cfg = true;

if (write_new_cfg) {
cfg_buf = ziti_config_to_json(&new_cfg, 0, &cfg_len);
CHECK_UV("update config", update_file(config_file, cfg_buf, cfg_len));
}
DONE:
free_ziti_config(&cfg);
free_ziti_config(&new_cfg);
FREE(cfg_buf);
}

static void update_config_done(uv_work_t *wr, int err) {
api_update_req *req = wr->data;
if (req->err != 0) {
ZITI_LOG(ERROR, "failed to update config file[%s]: %d(%s)", req->inst->identifier, req->err, req->errmsg);
} else {
ZITI_LOG(INFO, "updated config file ztx[%s]", req->inst->identifier);
}
free(req->config_json);
free(req);
}

IMPL_ENUM(TunnelCommand, TUNNEL_COMMANDS)

Expand Down
116 changes: 116 additions & 0 deletions programs/ziti-edge-tunnel/config-utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <uv.h>
#include <ziti/ziti_model.h>
#include <ziti/ziti.h>
#include <ziti/ziti_log.h>
#include "tlsuv/http.h"

#if __linux__
#include <pwd.h>
#include <unistd.h>
Expand Down Expand Up @@ -66,3 +72,113 @@ char* get_backup_config_file_name(char* config_path) {
}
}

typedef struct api_update_req_s {
uv_work_t wr;
char *identifier;
char *config_json;
int err;
const char *errmsg;
} api_update_req;


static int update_file(const char *path, char *content, size_t content_len) {
#define CHECK_UV(desc, op) do{ \
uv_fs_req_cleanup(&fs_req); \
rc = op; \
if (rc < 0) { \
ZITI_LOG(ERROR, "op[" desc "] failed: %d(%s)", rc, uv_strerror(rc)); \
goto DONE; \
}} while(0)

int rc = 0;
uv_fs_t fs_req = {0};
CHECK_UV("check exiting config", uv_fs_stat(NULL, &fs_req, path, NULL));
uint64_t mode = fs_req.statbuf.st_mode;

char backup[FILENAME_MAX];
snprintf(backup, sizeof(backup), "%s.bak", path);
CHECK_UV("create backup", uv_fs_rename(NULL, &fs_req, path, backup, NULL));

uv_os_fd_t f;
CHECK_UV("open new config", f = uv_fs_open(NULL, &fs_req, path, UV_FS_O_WRONLY | UV_FS_O_CREAT, (int) mode, NULL));
uv_buf_t buf = uv_buf_init(content, content_len);
CHECK_UV("write new config", uv_fs_write(NULL, &fs_req, f, &buf, 1, 0, NULL));
CHECK_UV("close new config", uv_fs_close(NULL, &fs_req, f, NULL));

DONE:
return rc;
#undef CHECK_UV
}

#define CHECK_UV(desc, op) do{ \
int rc = op; \
if (rc < 0) { \
req->err = rc; \
req->errmsg = uv_strerror(rc); \
ZITI_LOG(ERROR, "op[" desc "] failed: %d(%s)", req->err, req->errmsg); \
goto DONE; \
}} while(0)

static void update_config(uv_work_t *wr) {
api_update_req *req = wr->data;
const char *config_file = req->identifier;
size_t cfg_len;
char *cfg_buf = NULL;
uv_file f;

ziti_config cfg = {0};
ziti_config new_cfg = {0};
if (ziti_load_config(&cfg, config_file) != ZITI_OK) {
ZITI_LOG(ERROR, "failed to parse config file[%s]", config_file);
req->err = -1;
req->errmsg = "failed to parse existing config";
goto DONE;
}

parse_ziti_config(&new_cfg, req->config_json, strlen(req->config_json));

// attempt to update CA bundle external to config file
if (strncmp(cfg.id.ca, "file://", strlen("file://")) == 0) {
struct tlsuv_url_s path_uri;
CHECK_UV("parse CA bundle path", tlsuv_parse_url(&path_uri, cfg.id.ca));
const char *path = path_uri.path;
CHECK_UV("update CA bundle file", update_file(path, (char*)new_cfg.id.ca, strlen(new_cfg.id.ca)));
free((void*)new_cfg.id.ca);
new_cfg.id.ca = cfg.id.ca;
cfg.id.ca = NULL;
}

bool write_new_cfg = true;

if (write_new_cfg) {
cfg_buf = ziti_config_to_json(&new_cfg, 0, &cfg_len);
CHECK_UV("update config", update_file(config_file, cfg_buf, cfg_len));
}
DONE:
free_ziti_config(&cfg);
free_ziti_config(&new_cfg);
free(cfg_buf);
}

static void update_config_done(uv_work_t *wr, int err) {
api_update_req *req = wr->data;
if (req->err != 0) {
ZITI_LOG(ERROR, "failed to update config file[%s]: %d(%s)", req->identifier, req->err, req->errmsg);
} else {
ZITI_LOG(INFO, "updated config file ztx[%s]", req->identifier);
}
free(req->config_json);
free(req->identifier);
free(req);
}

void update_identity_config(uv_loop_t *l, const char *identifier, const char *cfg_json) {
if (identifier) {
api_update_req *req = calloc(1, sizeof(api_update_req));
req->wr.data = req;
req->identifier = strdup(identifier);
req->config_json = strdup(cfg_json);
uv_queue_work(l, &req->wr, update_config, update_config_done);
}
}

3 changes: 3 additions & 0 deletions programs/ziti-edge-tunnel/include/config-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@

#ifndef ZITI_TUNNEL_SDK_C_CONFIG_UTILS_H
#define ZITI_TUNNEL_SDK_C_CONFIG_UTILS_H
#include <uv.h>

char* get_system_config_path();
void set_identifier_path(char* id_dir);
char* get_identifier_path();
char* get_config_file_name(char* config_path);
char* get_backup_config_file_name(char* config_path);

void update_identity_config(uv_loop_t *l, const char *identifier, const char *cfg_json);

#endif //ZITI_TUNNEL_SDK_C_CONFIG_UTILS_H
1 change: 1 addition & 0 deletions programs/ziti-edge-tunnel/ziti-edge-tunnel.c
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,7 @@ static void on_event(const base_event *ev) {
break;
}

update_identity_config(global_loop_ref, api_ev->identifier, api_ev->config_json);
identity_event id_event = {0};
id_event.Op = strdup("identity");
id_event.Action = strdup(event_name(event_updated));
Expand Down

0 comments on commit 7718bd5

Please sign in to comment.