MXS-1220: Expose module information via the REST API
The modules, their types and default values are exposed via the /maxscale/modules resource. Currently, only a list of resources can be exposed as the externally exposed module object (MXS_MODULE) does not have the name and type information in it.
This commit is contained in:
parent
73cf7999f2
commit
afff5e98b3
@ -20,6 +20,8 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <maxscale/debug.h>
|
||||
|
||||
MXS_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
@ -217,4 +219,76 @@ typedef struct mxs_module
|
||||
/** Name of the symbol that MaxScale will load */
|
||||
#define MXS_MODULE_SYMBOL_NAME "mxs_get_module_object"
|
||||
|
||||
static inline const char* mxs_module_param_type_to_string(enum mxs_module_param_type type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case MXS_MODULE_PARAM_COUNT:
|
||||
return "count";
|
||||
case MXS_MODULE_PARAM_INT:
|
||||
return "int";
|
||||
case MXS_MODULE_PARAM_SIZE:
|
||||
return "size";
|
||||
case MXS_MODULE_PARAM_BOOL:
|
||||
return "bool";
|
||||
case MXS_MODULE_PARAM_STRING:
|
||||
return "string";
|
||||
case MXS_MODULE_PARAM_ENUM:
|
||||
return "enum";
|
||||
case MXS_MODULE_PARAM_PATH:
|
||||
return "path";
|
||||
case MXS_MODULE_PARAM_SERVICE:
|
||||
return "service";
|
||||
case MXS_MODULE_PARAM_SERVER:
|
||||
return "server";
|
||||
case MXS_MODULE_PARAM_SERVERLIST:
|
||||
return "serverlist";
|
||||
default:
|
||||
ss_dassert(!true);
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static inline const char* mxs_module_api_to_string(MXS_MODULE_API type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case MXS_MODULE_API_PROTOCOL:
|
||||
return "protocol";
|
||||
case MXS_MODULE_API_ROUTER:
|
||||
return "router";
|
||||
case MXS_MODULE_API_MONITOR:
|
||||
return "monitor";
|
||||
case MXS_MODULE_API_FILTER:
|
||||
return "filter";
|
||||
case MXS_MODULE_API_AUTHENTICATOR:
|
||||
return "authenticator";
|
||||
case MXS_MODULE_API_QUERY_CLASSIFIER:
|
||||
return "query_classifier";
|
||||
default:
|
||||
ss_dassert(!true);
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static inline const char* mxs_module_status_to_string(MXS_MODULE_STATUS type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case MXS_MODULE_IN_DEVELOPMENT:
|
||||
return "In development";
|
||||
case MXS_MODULE_ALPHA_RELEASE:
|
||||
return "Alpha";
|
||||
case MXS_MODULE_BETA_RELEASE:
|
||||
return "Beta";
|
||||
case MXS_MODULE_GA:
|
||||
return "GA";
|
||||
case MXS_MODULE_EXPERIMENTAL:
|
||||
return "Experimental";
|
||||
default:
|
||||
ss_dassert(!true);
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
MXS_END_DECLS
|
||||
|
@ -28,12 +28,16 @@
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
#include "maxscale/modules.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include <maxscale/modinfo.h>
|
||||
#include <maxscale/log_manager.h>
|
||||
#include <maxscale/version.h>
|
||||
@ -45,6 +49,7 @@
|
||||
#include <maxscale/alloc.h>
|
||||
|
||||
#include "maxscale/modules.h"
|
||||
#include "maxscale/config.h"
|
||||
|
||||
typedef struct loaded_module
|
||||
{
|
||||
@ -401,6 +406,64 @@ void dprintAllModules(DCB *dcb)
|
||||
dcb_printf(dcb, "----------------+-----------------+---------+-------+-------------------------\n\n");
|
||||
}
|
||||
|
||||
static json_t* module_to_json(const LOADED_MODULE *mod, const char* host)
|
||||
{
|
||||
json_t* obj = json_object();
|
||||
|
||||
json_object_set_new(obj, "name", json_string(mod->module));
|
||||
json_object_set_new(obj, "type", json_string(mod->type));
|
||||
json_object_set_new(obj, "version", json_string(mod->info->version));
|
||||
json_object_set_new(obj, "description", json_string(mod->info->description));
|
||||
json_object_set_new(obj, "api", json_string(mxs_module_api_to_string(mod->info->modapi)));
|
||||
json_object_set_new(obj, "status", json_string(mxs_module_status_to_string(mod->info->status)));
|
||||
|
||||
json_t* params = json_array();
|
||||
|
||||
for (int i = 0; mod->info->parameters[i].name; i++)
|
||||
{
|
||||
json_t* p = json_object();
|
||||
|
||||
json_object_set_new(p, CN_NAME, json_string(mod->info->parameters[i].name));
|
||||
json_object_set_new(p, CN_TYPE, json_string(mxs_module_param_type_to_string(mod->info->parameters[i].type)));
|
||||
|
||||
if (mod->info->parameters[i].default_value)
|
||||
{
|
||||
json_object_set(p, "default_value", json_string(mod->info->parameters[i].default_value));
|
||||
}
|
||||
|
||||
if (mod->info->parameters[i].type == MXS_MODULE_PARAM_ENUM &&
|
||||
mod->info->parameters[i].accepted_values)
|
||||
{
|
||||
json_t* arr = json_array();
|
||||
|
||||
for (int x = 0; mod->info->parameters[i].accepted_values[x].name; x++)
|
||||
{
|
||||
json_array_append_new(arr, json_string(mod->info->parameters[i].accepted_values[x].name));
|
||||
}
|
||||
|
||||
json_object_set_new(p, "enum_values", arr);
|
||||
}
|
||||
|
||||
json_array_append_new(params, p);
|
||||
}
|
||||
|
||||
json_object_set_new(obj, CN_PARAMETERS, params);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
json_t* module_list_to_json(const char* host)
|
||||
{
|
||||
json_t* arr = json_array();
|
||||
|
||||
for (LOADED_MODULE *ptr = registered; ptr; ptr = ptr->next)
|
||||
{
|
||||
json_array_append_new(arr, module_to_json(ptr, host));
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
void moduleShowFeedbackReport(DCB *dcb)
|
||||
{
|
||||
GWBUF *buffer;
|
||||
@ -843,7 +906,7 @@ const MXS_MODULE *get_module(const char *name, const char *type)
|
||||
{
|
||||
LOADED_MODULE *mod = find_module(name);
|
||||
|
||||
if (mod == NULL && load_module(name, type))
|
||||
if (mod == NULL && type && load_module(name, type))
|
||||
{
|
||||
mod = find_module(name);
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ void *load_module(const char *module, const char *type);
|
||||
* @brief Get a module
|
||||
*
|
||||
* @param name Name of the module
|
||||
* @param type The module type
|
||||
* @param type The module type or NULL for any type
|
||||
* @return The loaded module or NULL if the module is not loaded
|
||||
*/
|
||||
const MXS_MODULE *get_module(const char *name, const char *type);
|
||||
@ -161,4 +161,12 @@ bool mxs_module_iterator_has_next(const MXS_MODULE_ITERATOR* iterator);
|
||||
*/
|
||||
MXS_MODULE* mxs_module_iterator_get_next(MXS_MODULE_ITERATOR* iterator);
|
||||
|
||||
/**
|
||||
* @brief Convert all modules to JSON
|
||||
*
|
||||
* @param host The hostname of this server
|
||||
* @return Array of modules in JSON format
|
||||
*/
|
||||
json_t* module_list_to_json(const char* host);
|
||||
|
||||
MXS_END_DECLS
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "maxscale/monitor.h"
|
||||
#include "maxscale/service.h"
|
||||
#include "maxscale/config_runtime.h"
|
||||
#include "maxscale/modules.h"
|
||||
|
||||
using std::list;
|
||||
using std::string;
|
||||
@ -340,10 +341,9 @@ HttpResponse cb_tasks(const HttpRequest& request)
|
||||
return HttpResponse(MHD_HTTP_OK);
|
||||
}
|
||||
|
||||
HttpResponse cb_modules(const HttpRequest& request)
|
||||
HttpResponse cb_all_modules(const HttpRequest& request)
|
||||
{
|
||||
// TODO: Show modules
|
||||
return HttpResponse(MHD_HTTP_OK);
|
||||
return HttpResponse(MHD_HTTP_OK, module_list_to_json(request.host()));
|
||||
}
|
||||
|
||||
HttpResponse cb_send_ok(const HttpRequest& request)
|
||||
@ -384,7 +384,7 @@ public:
|
||||
m_get.push_back(SResource(new Resource(cb_threads, 2, "maxscale", "threads")));
|
||||
m_get.push_back(SResource(new Resource(cb_logs, 2, "maxscale", "logs")));
|
||||
m_get.push_back(SResource(new Resource(cb_tasks, 2, "maxscale", "tasks")));
|
||||
m_get.push_back(SResource(new Resource(cb_modules, 2, "maxscale", "modules")));
|
||||
m_get.push_back(SResource(new Resource(cb_all_modules, 2, "maxscale", "modules")));
|
||||
|
||||
/** Create new resources */
|
||||
m_post.push_back(SResource(new Resource(cb_flush, 3, "maxscale", "logs", "flush")));
|
||||
|
Loading…
x
Reference in New Issue
Block a user