Browse Source

[Feature] Add neighbours option to support Rspamd cluster in WebUI

tags/1.5.0
Vsevolod Stakhov 7 years ago
parent
commit
348e129aac
4 changed files with 131 additions and 2 deletions
  1. 29
    0
      src/controller.c
  2. 1
    0
      src/libserver/cfg_file.h
  3. 99
    2
      src/libserver/cfg_rcl.c
  4. 2
    0
      src/libserver/cfg_utils.c

+ 29
- 0
src/controller.c View File

@@ -57,6 +57,7 @@
#define PATH_STAT_RESET "/statreset"
#define PATH_COUNTERS "/counters"
#define PATH_ERRORS "/errors"
#define PATH_NEIGHBOURS "/neighbours"

#define msg_err_session(...) rspamd_default_log_function(G_LOG_LEVEL_CRITICAL, \
session->pool->tag.tagname, session->pool->tag.uid, \
@@ -1403,6 +1404,31 @@ rspamd_controller_handle_errors (struct rspamd_http_connection_entry *conn_ent,
return 0;
}

/*
* Neighbours command handler:
* request: /neighbours
* headers: Password
* reply: json {name: {url: "http://...", host: "host"}}
*/
static int
rspamd_controller_handle_neighbours (struct rspamd_http_connection_entry *conn_ent,
struct rspamd_http_message *msg)
{
struct rspamd_controller_session *session = conn_ent->ud;
struct rspamd_controller_worker_ctx *ctx;

ctx = session->ctx;

if (!rspamd_controller_check_password (conn_ent, session, msg, FALSE)) {
return 0;
}

rspamd_controller_send_ucl (conn_ent, ctx->cfg->neighbours);

return 0;
}


static int
rspamd_controller_handle_history_reset (struct rspamd_http_connection_entry *conn_ent,
struct rspamd_http_message *msg)
@@ -3140,6 +3166,9 @@ start_controller_worker (struct rspamd_worker *worker)
rspamd_http_router_add_path (ctx->http,
PATH_ERRORS,
rspamd_controller_handle_errors);
rspamd_http_router_add_path (ctx->http,
PATH_NEIGHBOURS,
rspamd_controller_handle_neighbours);

rspamd_regexp_t *lua_re = rspamd_regexp_new ("^/.*/.*\\.lua$", NULL, NULL);
rspamd_http_router_add_regexp (ctx->http, lua_re,

+ 1
- 0
src/libserver/cfg_file.h View File

@@ -425,6 +425,7 @@ struct rspamd_config {
gchar *ssl_ciphers; /**< set of preferred ciphers */
gchar *zstd_input_dictionary; /**< path to zstd input dictionary */
gchar *zstd_output_dictionary; /**< path to zstd output dictionary */
ucl_object_t *neighbours; /**< other servers in the cluster */

ref_entry_t ref; /**< reference counter */
};

+ 99
- 2
src/libserver/cfg_rcl.c View File

@@ -236,9 +236,9 @@ rspamd_rcl_options_handler (rspamd_mempool_t *pool, const ucl_object_t *obj,
const gchar *key, gpointer ud,
struct rspamd_rcl_section *section, GError **err)
{
const ucl_object_t *dns, *upstream;
const ucl_object_t *dns, *upstream, *neighbours;
struct rspamd_config *cfg = ud;
struct rspamd_rcl_section *dns_section, *upstream_section;
struct rspamd_rcl_section *dns_section, *upstream_section, *neighbours_section;

HASH_FIND_STR (section->subsections, "dns", dns_section);

@@ -262,6 +262,20 @@ rspamd_rcl_options_handler (rspamd_mempool_t *pool, const ucl_object_t *obj,
}
}

HASH_FIND_STR (section->subsections, "neighbours", neighbours_section);

neighbours = ucl_object_lookup (obj, "neighbours");
if (neighbours_section != NULL && neighbours != NULL) {
const ucl_object_t *cur;

LL_FOREACH (neighbours, cur) {
if (!rspamd_rcl_process_section (cfg, neighbours_section, cfg, cur,
pool, err)) {
return FALSE;
}
}
}

if (rspamd_rcl_section_parse_defaults (cfg,
section, cfg->cfg_pool, obj,
cfg, err)) {
@@ -1489,6 +1503,82 @@ rspamd_rcl_composites_handler (rspamd_mempool_t *pool,
return success;
}

static gboolean
rspamd_rcl_neighbours_handler (rspamd_mempool_t *pool,
const ucl_object_t *obj,
const gchar *key,
gpointer ud,
struct rspamd_rcl_section *section,
GError **err)
{
struct rspamd_config *cfg = ud;
const ucl_object_t *hostval, *pathval;
ucl_object_t *neigh;
gboolean has_port = FALSE, has_proto = FALSE;
GString *urlstr;
const gchar *p;

if (key == NULL) {
g_set_error (err,
CFG_RCL_ERROR,
EINVAL,
"missing name for neighbour");
return FALSE;
}

hostval = ucl_object_lookup (obj, "host");

if (hostval == NULL || ucl_object_type (hostval) != UCL_STRING) {
g_set_error (err,
CFG_RCL_ERROR,
EINVAL,
"missing host for neighbour: %s", ucl_object_key (obj));
return FALSE;
}

neigh = ucl_object_typed_new (UCL_OBJECT);
ucl_object_insert_key (neigh, ucl_object_ref (hostval), "host", 0, false);

if ((p = strrchr (ucl_object_tostring (hostval), ':')) != NULL) {
if (g_ascii_isdigit (p[1])) {
has_port = TRUE;
}
}

if (strstr (ucl_object_tostring (hostval), "://") != NULL) {
has_proto = TRUE;
}

/* Now make url */
urlstr = g_string_sized_new (63);
pathval = ucl_object_lookup (obj, "path");

if (!has_proto) {
g_string_append_len (urlstr, "http://", sizeof ("http://") - 1);
}

g_string_append (urlstr, ucl_object_tostring (hostval));

if (!has_port) {
g_string_append (urlstr, ":11334");
}

if (pathval == NULL) {
g_string_append (urlstr, "/rspamd/");
}
else {
g_string_append (urlstr, ucl_object_tostring (pathval));
}

ucl_object_insert_key (neigh,
ucl_object_fromlstring (urlstr->str, urlstr->len),
"url", 0, false);
g_string_free (urlstr, TRUE);
ucl_object_insert_key (cfg->neighbours, neigh, key, 0, true);

return TRUE;
}


struct rspamd_rcl_section *
rspamd_rcl_add_section (struct rspamd_rcl_section **top,
@@ -2032,6 +2122,13 @@ rspamd_rcl_config_init (struct rspamd_config *cfg)
0,
"Use pre 1.4 style of messages in the protocol");

/* Neighbours configuration */
rspamd_rcl_add_section_doc (&sub->subsections, "neighbours", "name",
rspamd_rcl_neighbours_handler,
UCL_OBJECT, FALSE, TRUE,
cfg->doc_strings,
"List of members of Rspamd cluster");

/* New DNS configuration */
ssub = rspamd_rcl_add_section_doc (&sub->subsections, "dns", NULL, NULL,
UCL_OBJECT, FALSE, TRUE,

+ 2
- 0
src/libserver/cfg_utils.c View File

@@ -175,6 +175,7 @@ rspamd_config_new (void)
cfg->max_pic_size = DEFAULT_MAX_PIC;
cfg->images_cache_size = 256;
cfg->monitored_ctx = rspamd_monitored_ctx_init ();
cfg->neighbours = ucl_object_typed_new (UCL_OBJECT);
#ifdef WITH_HIREDIS
cfg->redis_pool = rspamd_redis_pool_init ();
#endif
@@ -193,6 +194,7 @@ rspamd_config_free (struct rspamd_config *cfg)
ucl_object_unref (cfg->rcl_obj);
ucl_object_unref (cfg->config_comments);
ucl_object_unref (cfg->doc_strings);
ucl_object_unref (cfg->neighbours);
g_hash_table_remove_all (cfg->metrics);
g_hash_table_unref (cfg->metrics);
g_hash_table_unref (cfg->c_modules);

Loading…
Cancel
Save