From: Vsevolod Stakhov Date: Thu, 5 Jan 2017 17:20:13 +0000 (+0000) Subject: [Feature] Add neighbours option to support Rspamd cluster in WebUI X-Git-Tag: 1.5.0~419 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=348e129aac10e5668aa16d19bffdb95473d52883;p=rspamd.git [Feature] Add neighbours option to support Rspamd cluster in WebUI --- diff --git a/src/controller.c b/src/controller.c index b780e3c4c..78c397c80 100644 --- a/src/controller.c +++ b/src/controller.c @@ -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, diff --git a/src/libserver/cfg_file.h b/src/libserver/cfg_file.h index 3be0c7c4d..a6399010b 100644 --- a/src/libserver/cfg_file.h +++ b/src/libserver/cfg_file.h @@ -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 */ }; diff --git a/src/libserver/cfg_rcl.c b/src/libserver/cfg_rcl.c index 20dc7ea60..f2d8bcd08 100644 --- a/src/libserver/cfg_rcl.c +++ b/src/libserver/cfg_rcl.c @@ -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, diff --git a/src/libserver/cfg_utils.c b/src/libserver/cfg_utils.c index 306965df8..8ee284212 100644 --- a/src/libserver/cfg_utils.c +++ b/src/libserver/cfg_utils.c @@ -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);