aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Ghigonis <laurent@p1sec.com>2013-09-20 07:03:26 +0200
committerLaurent Ghigonis <laurent@p1sec.com>2013-09-20 07:03:26 +0200
commitabd38736e4a82cf828868a0075c840d23f5556d6 (patch)
treef2502ef142ed1fe500c94b77e0e97012583e402b
parentglougloud viz module notification (diff)
downloadglouglou-abd38736e4a82cf828868a0075c840d23f5556d6.tar.xz
glouglou-abd38736e4a82cf828868a0075c840d23f5556d6.zip
glougloud viz module notification
-rw-r--r--v3/glougloud/Makefile9
-rw-r--r--v3/glougloud/glougloud.h1
-rw-r--r--v3/glougloud/glougloud_internal.h13
-rw-r--r--v3/glougloud/glougloud_mod_0_internal/glougloud_mod_0_internal.c9
-rw-r--r--v3/glougloud/glougloud_mod_1_net/Makefile4
-rw-r--r--v3/glougloud/glougloud_mod_1_net/glougloud_mod_1_net.c30
-rw-r--r--v3/glougloud/redis.c5
-rw-r--r--v3/glougloud/viz.c35
8 files changed, 79 insertions, 27 deletions
diff --git a/v3/glougloud/Makefile b/v3/glougloud/Makefile
index b0e5233..1e3e71d 100644
--- a/v3/glougloud/Makefile
+++ b/v3/glougloud/Makefile
@@ -16,7 +16,8 @@ BINDIR=$(PREFIX)/sbin
all:
make $(OBJECTS)
$(CC) $(OBJECTS) -o $(PROG) $(LDFLAGS)
- make -C glougloud_mod_net/
+ make -C glougloud_mod_0_internal/
+ make -C glougloud_mod_1_net/
install: $(PROG)
@echo "creating 2 users: $(USER_PROBES), $(USER_VIZ)"
@@ -40,8 +41,10 @@ install: $(PROG)
mkdir -p $(INCLUDEDIR)
install -m 0755 $(PROG) $(BINDIR)
install -m 0644 $(HEADERS) $(INCLUDEDIR)
- make -C glougloud_mod_net/ install
+ make -C glougloud_mod_0_internal/ install
+ make -C glougloud_mod_1_net/ install
clean:
rm -f $(PROG) $(OBJECTS) *~
-
+ make -C glougloud_mod_0_internal/ clean
+ make -C glougloud_mod_1_net/ clean
diff --git a/v3/glougloud/glougloud.h b/v3/glougloud/glougloud.h
index 618db9e..334fe17 100644
--- a/v3/glougloud/glougloud.h
+++ b/v3/glougloud/glougloud.h
@@ -54,5 +54,6 @@ struct ggdprobe_cli {
struct ggdmodviz_conf {
int id;
+ int api_version;
};
diff --git a/v3/glougloud/glougloud_internal.h b/v3/glougloud/glougloud_internal.h
index 8d65e1c..7d791e9 100644
--- a/v3/glougloud/glougloud_internal.h
+++ b/v3/glougloud/glougloud_internal.h
@@ -5,15 +5,16 @@
#include <hiredis/hiredis.h>
#include <hiredis/async.h>
+#include "glougloud.h"
+
#define GLOUGLOUD_VERSION 3
+#define GLOUGLOUD_MOD_API_VERSION 1
#define GLOUGLOUD_USER_PROBES "_ggdprobe"
#define GLOUGLOUD_USER_VIZ "_ggdviz"
#define GLOUGLOUD_LOGFILE "/var/log/glougloud.log"
#define GLOUGLOUD_MOD_PATH "/modules/"
-#include "glougloud.h"
-
/* redis.c */
int redis_init(struct glougloud *);
@@ -24,9 +25,11 @@ redisAsyncContext *redis_connect(struct event_base *,
void (*cb_disconnect)(const redisAsyncContext *, int));
void redis_disconnect(redisAsyncContext *);
-int redis_parse_keyspace_notification(redisReply *reply,
- char **ntf_type, char **ntf_pattern, char **ntf_event_type,
- int *ntf_db, char **ntf_op, char **ntf_target);
+int
+redis_parse_keyspace_notification(redisReply *reply,
+ char **ntf_type, char **ntf_pattern, char **ntf_event_type,
+ int *ntf_db, char **ntf_op, int *ntf_op_len,
+ char **ntf_target, int *ntf_target_len);
/* probes.c */
diff --git a/v3/glougloud/glougloud_mod_0_internal/glougloud_mod_0_internal.c b/v3/glougloud/glougloud_mod_0_internal/glougloud_mod_0_internal.c
index 38d7119..01931b6 100644
--- a/v3/glougloud/glougloud_mod_0_internal/glougloud_mod_0_internal.c
+++ b/v3/glougloud/glougloud_mod_0_internal/glougloud_mod_0_internal.c
@@ -16,11 +16,12 @@ ggdmodviz_init(struct glougloud *ggd)
return mod;
}
-char *
-ggdmodviz_text_get(struct ggdviz_cli *cli, char *op, char *target)
+int
+ggdmodviz_text_get(struct ggdviz_cli *cli, char *op, int op_len,
+ char *target, int target_len, char **resp)
{
- log_debug("glougloud_mod_internal:\nop: %s\ntarget: %s");
- return NULL;
+ log_debug("glougloud_mod_internal:\nop: %s\ntarget: %s", op, target);
+ return -1;
}
void *
diff --git a/v3/glougloud/glougloud_mod_1_net/Makefile b/v3/glougloud/glougloud_mod_1_net/Makefile
index 8bdcf2f..0dbfabd 100644
--- a/v3/glougloud/glougloud_mod_1_net/Makefile
+++ b/v3/glougloud/glougloud_mod_1_net/Makefile
@@ -2,10 +2,10 @@
CFLAGS += -Wall -O0 -fPIC -shared -g
LIBDIR=/var/lib/glougloud/chroot/modules/
-LIBNAME=glougloud_mod_net
+LIBNAME=glougloud_mod_1_net
TARGET = ${LIBNAME}.so
-SOURCES = glougloud_mod_net.c
+SOURCES = glougloud_mod_1_net.c
OBJECTS = $(SOURCES:.c=.o)
all: $(TARGET)
diff --git a/v3/glougloud/glougloud_mod_1_net/glougloud_mod_1_net.c b/v3/glougloud/glougloud_mod_1_net/glougloud_mod_1_net.c
index 758767b..55ead25 100644
--- a/v3/glougloud/glougloud_mod_1_net/glougloud_mod_1_net.c
+++ b/v3/glougloud/glougloud_mod_1_net/glougloud_mod_1_net.c
@@ -13,15 +13,37 @@ ggdmodviz_init(struct glougloud *ggd)
mod = xcalloc(1, sizeof(struct ggdmodviz_conf));
mod->id = GLOUGLOUD_MOD_NET_ID;
+ mod->api_version = 1;
return mod;
}
-char *
-ggdmodviz_text_get(struct ggdviz_cli *cli, char *op, char *target)
+int
+ggdmodviz_text_get(struct ggdviz_cli *cli, char *op, int op_len,
+ char *target, int target_len, char **resp)
{
- log_debug("glougloud_mod_net:\nop: %s\ntarget: %s");
- return NULL;
+ static char text[4096];
+ int len;
+
+ log_debug("glougloud_mod_net:\nop: %s\ntarget: %s", op, target);
+ text[0] = '\0';
+ *resp = text;
+ if (target_len < 4)
+ return -1;
+
+ switch(target[1]) {
+ case 'n':
+ len = snprintf(text, sizeof(text), "New node %s\n", target+3);
+ break;
+ case 'N':
+ len = snprintf(text, sizeof(text), "Delete node %s\n", target+3);
+ break;
+ default:
+ log_debug("ggdmodviz_text_get: unsupported target %s", target);
+ len = -1;
+ }
+
+ return len;
}
void *
diff --git a/v3/glougloud/redis.c b/v3/glougloud/redis.c
index 22f4fd1..8576f30 100644
--- a/v3/glougloud/redis.c
+++ b/v3/glougloud/redis.c
@@ -113,7 +113,8 @@ redis_disconnect(redisAsyncContext *rc)
int
redis_parse_keyspace_notification(redisReply *reply,
char **ntf_type, char **ntf_pattern, char **ntf_event_type,
- int *ntf_db, char **ntf_op, char **ntf_target)
+ int *ntf_db, char **ntf_op, int *ntf_op_len,
+ char **ntf_target, int *ntf_target_len)
{
redisReply *r;
int i;
@@ -160,9 +161,11 @@ redis_parse_keyspace_notification(redisReply *reply,
if (!tmp) return -6;
memcpy(l_ntf_op, tmp, strlen(tmp) + 1);
*ntf_op = l_ntf_op;
+ *ntf_op_len = strlen(l_ntf_op);
break;
case 3: /* /n/192.168.1.3 */
*ntf_target = r->str;
+ *ntf_target_len = r->len;
break;
}
case REDIS_REPLY_INTEGER:
diff --git a/v3/glougloud/viz.c b/v3/glougloud/viz.c
index 0411e97..01ee751 100644
--- a/v3/glougloud/viz.c
+++ b/v3/glougloud/viz.c
@@ -20,7 +20,7 @@ struct ggdmodviz {
char *name;
struct ggdmodviz_conf *conf;
struct ggdmodviz_conf *(*ggdmodviz_init)(struct glougloud *);
- char *(*ggdmodviz_text_get)(struct ggdviz_cli *, char *, char *);
+ int (*ggdmodviz_text_get)(struct ggdviz_cli *, char *, int, char *, int, char **);
};
struct glougloud_viz {
@@ -53,7 +53,7 @@ _modules_load(void)
char *dir;
struct ggdmodviz_conf *modconf;
struct ggdmodviz_conf *(*fn_ggdmodviz_init)(struct glougloud *);
- char *(*fn_ggdmodviz_text_get)(struct ggdviz_cli *, char *, char *);
+ int (*fn_ggdmodviz_text_get)(struct ggdviz_cli *, char *, int, char *, int, char **);
dir = GLOUGLOUD_MOD_PATH;
d = opendir(dir);
@@ -87,6 +87,12 @@ _modules_load(void)
modconf = fn_ggdmodviz_init(_ggd);
if (!modconf)
continue;
+ if (modconf->api_version < GLOUGLOUD_MOD_API_VERSION) {
+ log_warn("not loading mod %s: old api version %d, should be %d",
+ ent->d_name,
+ modconf->api_version, GLOUGLOUD_MOD_API_VERSION);
+ continue;
+ }
log_tmp("m 5");
mod = xcalloc(1, sizeof(struct ggdmodviz));
@@ -129,14 +135,15 @@ _redis_cb_notification(redisAsyncContext *c, void *r, void *privdata)
struct ggdviz_cli *cli;
struct ggdmodviz *m;
char *ntf_type, *ntf_pattern, *ntf_event_type, *ntf_op, *ntf_target;
- int ntf_db, res;
+ int ntf_db, ntf_op_len, ntf_target_len, res, len;
+ char *s;
reply = r;
if (!reply)
return;
res = redis_parse_keyspace_notification(reply,
- &ntf_type, &ntf_pattern, &ntf_event_type, &ntf_db, &ntf_op, &ntf_target);
+ &ntf_type, &ntf_pattern, &ntf_event_type, &ntf_db, &ntf_op, &ntf_op_len, &ntf_target, &ntf_target_len);
if (res < 0) {
log_info("viz: could not parse redis keyspace notification (%d) !\n"
"Notification was: %s", res, reply->str);
@@ -145,14 +152,26 @@ _redis_cb_notification(redisAsyncContext *c, void *r, void *privdata)
log_info("viz: redis notification not about db changes, ignoring.");
return;
}
- log_debug("viz: db change %d %s %s", ntf_db, ntf_op, ntf_target);
+ log_debug("viz: db change: %d %s %s", ntf_db, ntf_op, ntf_target);
LIST_FOREACH(m, &_viz->mods, entry) {
if (m->conf->id != ntf_db)
continue;
LIST_FOREACH(cli, &_viz->clients, entry) {
- if (cli->type == GGDVIZ_CLI_TCP)
- m->ggdmodviz_text_get(cli, ntf_op, ntf_target);
+ switch (cli->type) {
+ case GGDVIZ_CLI_TCP:
+ len = m->ggdmodviz_text_get(cli, ntf_op, ntf_op_len, ntf_target, ntf_target_len, &s);
+ if (len <= 0) {
+ log_warn("module %s failed on ggdmodviz_text_get %s %s",
+ m->name, ntf_op, ntf_target);
+ break;
+ }
+ bufferevent_write(cli->tcp.bev, s, len);
+ break;
+ case GGDVIZ_CLI_WS:
+ log_tmp("_redis_cb_notification: GGDVIZ_CLI_WS not implemented !");
+ break;
+ }
}
}
}
@@ -185,7 +204,7 @@ _redis_connect(void)
if (_viz->rc->err)
return -1;
redisAsyncCommand(_viz->rc, _redis_cb_notification, "event",
- "PSUBSCRIBE __key*@*__:*");
+ "PSUBSCRIBE __keyevent@*__:*");
return 0;
}