diff --git a/src/commands/module-list.json b/src/commands/module-list.json index 92a022bc73..a48d3f9aab 100644 --- a/src/commands/module-list.json +++ b/src/commands/module-list.json @@ -39,6 +39,13 @@ "items": { "type": "string" } + }, + "configs": { + "type": "array", + "description": "Module configs.", + "items": { + "type": "string" + } } } } diff --git a/src/config.c b/src/config.c index 7bee87946d..efef58ddf6 100644 --- a/src/config.c +++ b/src/config.c @@ -2218,6 +2218,21 @@ static void numericConfigRewrite(standardConfig *config, const char *name, struc } } +sds getConfigValue(sds config_name) { + standardConfig *config = lookupConfig(config_name); + switch (config->type) { + case BOOL_CONFIG: + return boolConfigGet(config); + case SDS_CONFIG: + return sdsConfigGet(config); + case NUMERIC_CONFIG: + return numericConfigGet(config); + case ENUM_CONFIG: + return enumConfigGet(config); + default: serverPanic("Config type of module config is not allowed."); + } +} + #define embedCommonNumericalConfig(name, alias, _flags, lower, upper, config_addr, default, num_conf_flags, is_valid, \ apply) \ { \ diff --git a/src/module.c b/src/module.c index 2884239200..5598d9d025 100644 --- a/src/module.c +++ b/src/module.c @@ -12356,7 +12356,7 @@ void addReplyLoadedModules(client *c) { sds name = dictGetKey(de); struct ValkeyModule *module = dictGetVal(de); sds path = module->loadmod->path; - addReplyMapLen(c, 4); + addReplyMapLen(c, 5); addReplyBulkCString(c, "name"); addReplyBulkCBuffer(c, name, sdslen(name)); addReplyBulkCString(c, "ver"); @@ -12368,6 +12368,20 @@ void addReplyLoadedModules(client *c) { for (int i = 0; i < module->loadmod->argc; i++) { addReplyBulk(c, module->loadmod->argv[i]); } + addReplyBulkCString(c, "configs"); + addReplyArrayLen(c, listLength(module->module_configs) * 2); + listIter li; + listNode *ln; + listRewind(module->module_configs, &li); + while ((ln = listNext(&li))) { + ModuleConfig *module_config = listNodeValue(ln); + sds config_name = sdscatfmt(sdsempty(), "%s.%s", module->name, module_config->name); + addReplyBulkCBuffer(c, config_name, sdslen(config_name)); + sds config_value = getConfigValue(config_name); + addReplyBulkCBuffer(c, config_value, sdslen(config_value)); + sdsfree(config_name); + sdsfree(config_value); + } } dictReleaseIterator(di); } diff --git a/src/server.h b/src/server.h index 280c439323..1ef6e33dbb 100644 --- a/src/server.h +++ b/src/server.h @@ -3473,6 +3473,7 @@ void freeServerClientMemUsageBuckets(void); /* Module Configuration */ typedef struct ModuleConfig ModuleConfig; +sds getConfigValue(sds config_name); int performModuleConfigSetFromName(sds name, sds value, const char **err); int performModuleConfigSetDefaultFromName(sds name, const char **err); void addModuleBoolConfig(const char *module_name, const char *name, int flags, void *privdata, int default_val); diff --git a/tests/unit/moduleapi/moduleconfigs.tcl b/tests/unit/moduleapi/moduleconfigs.tcl index 44f994d2d0..3f62dc6d1d 100644 --- a/tests/unit/moduleapi/moduleconfigs.tcl +++ b/tests/unit/moduleapi/moduleconfigs.tcl @@ -15,6 +15,16 @@ start_server {tags {"modules"}} { assert_equal [r config get moduleconfigs.numeric] "moduleconfigs.numeric -1" } + test {check config value output correctly from module list} { + set config_value [lindex [lmap x [r module list] {dict get $x configs}] 0] + assert_equal [lindex $config_value 0] "moduleconfigs.mutable_bool" + assert_equal [lindex $config_value 1] "yes" + assert_equal [lindex $config_value 2] "moduleconfigs.immutable_bool" + assert_equal [lindex $config_value 3] "no" + assert_equal [lindex $config_value 4] "moduleconfigs.string" + assert_equal [lindex $config_value 5] "secret password" + } + test {Config set commands work} { # Make sure that config sets work during runtime r config set moduleconfigs.mutable_bool no