Add flag for ability of a module context to execute debug commands (#13774)

This PR adds a flag to the `RM_GetContextFlags` module-API function that
depicts whether the context may execute debug commands, according to
redis's standards.
This commit is contained in:
Raz Monsonego
2025-02-03 09:52:41 +02:00
committed by GitHub
parent e3b9397dfe
commit c688537d49
4 changed files with 58 additions and 2 deletions
+11
View File
@@ -3901,6 +3901,9 @@ int RM_GetSelectedDb(RedisModuleCtx *ctx) {
* context is using RESP3.
*
* * REDISMODULE_CTX_FLAGS_SERVER_STARTUP: The Redis instance is starting
*
* * REDISMODULE_CTX_FLAGS_DEBUG_ENABLED: Debug commands are enabled for this
* context.
*/
int RM_GetContextFlags(RedisModuleCtx *ctx) {
int flags = 0;
@@ -3923,6 +3926,9 @@ int RM_GetContextFlags(RedisModuleCtx *ctx) {
if (c && (c->flags & (CLIENT_DIRTY_CAS|CLIENT_DIRTY_EXEC))) {
flags |= REDISMODULE_CTX_FLAGS_MULTI_DIRTY;
}
if (c && allowProtectedAction(server.enable_debug_cmd, c)) {
flags |= REDISMODULE_CTX_FLAGS_DEBUG_ENABLED;
}
}
if (scriptIsRunning())
@@ -3990,6 +3996,11 @@ int RM_GetContextFlags(RedisModuleCtx *ctx) {
if (listLength(server.loadmodule_queue) > 0)
flags |= REDISMODULE_CTX_FLAGS_SERVER_STARTUP;
/* If debug commands are completely enabled */
if (server.enable_debug_cmd == PROTECTED_ACTION_ALLOWED_YES) {
flags |= REDISMODULE_CTX_FLAGS_DEBUG_ENABLED;
}
return flags;
}
+3 -1
View File
@@ -208,11 +208,13 @@ typedef struct RedisModuleStreamID {
#define REDISMODULE_CTX_FLAGS_ASYNC_LOADING (1<<23)
/* Redis is starting. */
#define REDISMODULE_CTX_FLAGS_SERVER_STARTUP (1<<24)
/* This context can call execute debug commands. */
#define REDISMODULE_CTX_FLAGS_DEBUG_ENABLED (1<<25)
/* Next context flag, must be updated when adding new flags above!
This flag should not be used directly by the module.
* Use RedisModule_GetContextFlagsAll instead. */
#define _REDISMODULE_CTX_FLAGS_NEXT (1<<25)
#define _REDISMODULE_CTX_FLAGS_NEXT (1<<26)
/* Keyspace changes notification classes. Every class is associated with a
* character for configuration purposes.
+20 -1
View File
@@ -794,6 +794,21 @@ int TestAssertIntegerReply(RedisModuleCtx *ctx, RedisModuleCallReply *reply, lon
return 1;
}
/* Replies "yes", "no" otherwise if the context may execute debug commands */
int TestCanDebug(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
REDISMODULE_NOT_USED(argv);
REDISMODULE_NOT_USED(argc);
int flags = RedisModule_GetContextFlags(ctx);
int allFlags = RedisModule_GetContextFlagsAll();
if ((allFlags & REDISMODULE_CTX_FLAGS_DEBUG_ENABLED) &&
(flags & REDISMODULE_CTX_FLAGS_DEBUG_ENABLED)) {
RedisModule_ReplyWithSimpleString(ctx, "yes");
} else {
RedisModule_ReplyWithSimpleString(ctx, "no");
}
return REDISMODULE_OK;
}
#define T(name,...) \
do { \
RedisModule_Log(ctx,"warning","Testing %s", name); \
@@ -802,7 +817,7 @@ int TestAssertIntegerReply(RedisModuleCtx *ctx, RedisModuleCallReply *reply, lon
/* TEST.BASICS -- Run all the tests.
* Note: it is useful to run these tests from the module rather than TCL
* since it's easier to check the reply types like that (make a distinction
* since it's easier to check the reply types like that make a distinction
* between 0 and "0", etc. */
int TestBasics(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
REDISMODULE_NOT_USED(argv);
@@ -1017,6 +1032,10 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
TestGetResp,"readonly",1,1,1) == REDISMODULE_ERR)
return REDISMODULE_ERR;
if (RedisModule_CreateCommand(ctx,"test.candebug",
TestCanDebug,"readonly",1,1,1) == REDISMODULE_ERR)
return REDISMODULE_ERR;
RedisModule_SubscribeToKeyspaceEvents(ctx,
REDISMODULE_NOTIFY_HASH |
REDISMODULE_NOTIFY_SET |
+24
View File
@@ -44,3 +44,27 @@ start_server {tags {"modules external:skip"} overrides {enable-module-command no
assert_error "ERR *MODULE command not allowed*" {r module load $testmodule}
}
}
start_server {tags {"modules external:skip"} overrides {enable-debug-command no}} {
r module load $testmodule
test {debug command disabled} {
assert_equal {no} [r test.candebug]
}
}
start_server {tags {"modules external:skip"} overrides {enable-debug-command yes}} {
r module load $testmodule
test {debug command enabled} {
assert_equal {yes} [r test.candebug]
}
}
start_server {tags {"modules external:skip"} overrides {enable-debug-command local}} {
r module load $testmodule
test {debug commands are enabled for local connection} {
assert_equal {yes} [r test.candebug]
}
}