MXS-1220: Add execution of module commands to REST API
The module command self links now point to an endpoint that executes the module command. Depending on the type of the module command, either a GET or a POST request must be made.
This commit is contained in:
parent
08a0883ec8
commit
ba546fcd21
@ -304,89 +304,69 @@ GET /v1/maxscale/modules
|
||||
"self": "http://localhost:8989/v1/maxscale/modules/"
|
||||
},
|
||||
"data": {
|
||||
"id": "readwritesplit",
|
||||
"id": "dbfwfilter",
|
||||
"type": "module",
|
||||
"attributes": {
|
||||
"module_type": "Router",
|
||||
"version": "V1.1.0",
|
||||
"description": "A Read/Write splitting router for enhancement read scalability",
|
||||
"api": "router",
|
||||
"module_type": "Filter",
|
||||
"version": "V1.2.0",
|
||||
"description": "Firewall Filter",
|
||||
"api": "filter",
|
||||
"status": "GA",
|
||||
"commands": [
|
||||
{
|
||||
"id": "rules/reload",
|
||||
"type": "module_command",
|
||||
"links": {
|
||||
"self": "http://localhost:8989/v1/modules/dbfwfilter/rules/reload"
|
||||
},
|
||||
"attributes": {
|
||||
"method": "POST",
|
||||
"arg_min": 1,
|
||||
"arg_max": 2,
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Filter to reload",
|
||||
"type": "FILTER",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"description": "Path to rule file",
|
||||
"type": "[STRING]",
|
||||
"required": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "use_sql_variables_in",
|
||||
"type": "enum",
|
||||
"default_value": "all",
|
||||
"enum_values": [
|
||||
"all",
|
||||
"master"
|
||||
]
|
||||
"name": "rules",
|
||||
"type": "path"
|
||||
},
|
||||
{
|
||||
"name": "slave_selection_criteria",
|
||||
"type": "enum",
|
||||
"default_value": "LEAST_CURRENT_OPERATIONS",
|
||||
"enum_values": [
|
||||
"LEAST_GLOBAL_CONNECTIONS",
|
||||
"LEAST_ROUTER_CONNECTIONS",
|
||||
"LEAST_BEHIND_MASTER",
|
||||
"LEAST_CURRENT_OPERATIONS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "master_failure_mode",
|
||||
"type": "enum",
|
||||
"default_value": "fail_instantly",
|
||||
"enum_values": [
|
||||
"fail_instantly",
|
||||
"fail_on_write",
|
||||
"error_on_write"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "max_slave_replication_lag",
|
||||
"type": "int",
|
||||
"default_value": "-1"
|
||||
},
|
||||
{
|
||||
"name": "max_slave_connections",
|
||||
"type": "string",
|
||||
"default_value": "255"
|
||||
},
|
||||
{
|
||||
"name": "retry_failed_reads",
|
||||
"type": "bool",
|
||||
"default_value": "true"
|
||||
},
|
||||
{
|
||||
"name": "disable_sescmd_history",
|
||||
"type": "bool",
|
||||
"default_value": "true"
|
||||
},
|
||||
{
|
||||
"name": "max_sescmd_history",
|
||||
"type": "count",
|
||||
"default_value": "0"
|
||||
},
|
||||
{
|
||||
"name": "strict_multi_stmt",
|
||||
"type": "bool",
|
||||
"default_value": "true"
|
||||
},
|
||||
{
|
||||
"name": "master_accept_reads",
|
||||
"name": "log_match",
|
||||
"type": "bool",
|
||||
"default_value": "false"
|
||||
},
|
||||
{
|
||||
"name": "connection_keepalive",
|
||||
"type": "count",
|
||||
"default_value": "0"
|
||||
"name": "log_no_match",
|
||||
"type": "bool",
|
||||
"default_value": "false"
|
||||
},
|
||||
{
|
||||
"name": "action",
|
||||
"type": "enum",
|
||||
"default_value": "block",
|
||||
"enum_values": [
|
||||
"allow",
|
||||
"block",
|
||||
"ignore"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"links": {
|
||||
"self": "http://localhost:8989/v1/modules/readwritesplit"
|
||||
"self": "http://localhost:8989/v1/modules/dbfwfilter"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -673,7 +673,8 @@ static MXS_ROUTER* createInstance(SERVICE* service, char** options)
|
||||
* the pointer. */
|
||||
|
||||
/* Register a custom command */
|
||||
if (!modulecmd_register_command("rrrouter", "test_command", custom_cmd_example,
|
||||
if (!modulecmd_register_command("rrrouter", "test_command",
|
||||
MODULECMD_TYPE_ACTIVE, custom_cmd_example,
|
||||
2, custom_cmd_args))
|
||||
{
|
||||
MXS_ERROR("Module command registration failed.");
|
||||
|
@ -108,6 +108,7 @@ extern const char CN_LOG_THROTTLING[];
|
||||
extern const char CN_MAXSCALE[];
|
||||
extern const char CN_MAX_CONNECTIONS[];
|
||||
extern const char CN_MAX_RETRY_INTERVAL[];
|
||||
extern const char CN_METHOD[];
|
||||
extern const char CN_MODULE[];
|
||||
extern const char CN_MODULES[];
|
||||
extern const char CN_MODULE_COMMAND[];
|
||||
|
@ -65,6 +65,13 @@ typedef struct
|
||||
This should always be the first argument
|
||||
if the function requires an output DCB. */
|
||||
|
||||
/** What type of an action does the command perform? */
|
||||
enum modulecmd_type
|
||||
{
|
||||
MODULECMD_TYPE_PASSIVE, /**< Command only displays data */
|
||||
MODULECMD_TYPE_ACTIVE /**< Command can modify data */
|
||||
};
|
||||
|
||||
/**
|
||||
* Options for arguments, bits 9 through 32
|
||||
*/
|
||||
@ -123,6 +130,7 @@ typedef struct modulecmd
|
||||
{
|
||||
char *identifier; /**< Unique identifier */
|
||||
char *domain; /**< Command domain */
|
||||
enum modulecmd_type type; /**< Command type, either active or passive */
|
||||
MODULECMDFN func; /**< The registered function */
|
||||
int arg_count_min; /**< Minimum number of arguments */
|
||||
int arg_count_max; /**< Maximum number of arguments */
|
||||
@ -130,6 +138,9 @@ typedef struct modulecmd
|
||||
struct modulecmd *next; /**< Next command */
|
||||
} MODULECMD;
|
||||
|
||||
/** Check if the module command can modify the data/state of the module */
|
||||
#define MODULECMD_MODIFIES_DATA(t) (t->type == MODULECMD_TYPE_ACTIVE)
|
||||
|
||||
/**
|
||||
* @brief Register a new command
|
||||
*
|
||||
@ -143,7 +154,8 @@ typedef struct modulecmd
|
||||
* @return True if the module was successfully registered, false on error
|
||||
*/
|
||||
bool modulecmd_register_command(const char *domain, const char *identifier,
|
||||
MODULECMDFN entry_point, int argc, modulecmd_arg_type_t *argv);
|
||||
enum modulecmd_type type, MODULECMDFN entry_point,
|
||||
int argc, modulecmd_arg_type_t *argv);
|
||||
|
||||
/**
|
||||
* @brief Find a registered command
|
||||
@ -196,6 +208,15 @@ void modulecmd_arg_free(MODULECMD_ARG *arg);
|
||||
*/
|
||||
bool modulecmd_arg_is_present(const MODULECMD_ARG *arg, int idx);
|
||||
|
||||
/**
|
||||
* @brief Check if module command requires an output DCB
|
||||
*
|
||||
* @param cmd Command to check
|
||||
*
|
||||
* @return True if module requires a DCB for printing output
|
||||
*/
|
||||
bool modulecmd_requires_output_dcb(const MODULECMD* cmd);
|
||||
|
||||
/**
|
||||
* @brief Call a registered command
|
||||
*
|
||||
|
@ -92,6 +92,7 @@ const char CN_LOG_THROTTLING[] = "log_throttling";
|
||||
const char CN_MAXSCALE[] = "maxscale";
|
||||
const char CN_MAX_CONNECTIONS[] = "max_connections";
|
||||
const char CN_MAX_RETRY_INTERVAL[] = "max_retry_interval";
|
||||
const char CN_METHOD[] = "method";
|
||||
const char CN_MODULE[] = "module";
|
||||
const char CN_MODULES[] = "modules";
|
||||
const char CN_MODULE_COMMAND[] = "module_command";
|
||||
|
@ -417,6 +417,12 @@ struct cb_param
|
||||
|
||||
bool modulecmd_cb(const MODULECMD *cmd, void *data)
|
||||
{
|
||||
if (modulecmd_requires_output_dcb(cmd))
|
||||
{
|
||||
/** Module requires an output DCB, don't print it */
|
||||
return true;
|
||||
}
|
||||
|
||||
cb_param* d = static_cast<cb_param*>(data);
|
||||
|
||||
json_t* obj = json_object();
|
||||
@ -424,6 +430,8 @@ bool modulecmd_cb(const MODULECMD *cmd, void *data)
|
||||
json_object_set_new(obj, CN_TYPE, json_string(CN_MODULE_COMMAND));
|
||||
|
||||
json_t* attr = json_object();
|
||||
const char* method = MODULECMD_MODIFIES_DATA(cmd) ? "POST" : "GET";
|
||||
json_object_set_new(attr, CN_METHOD, json_string(method));
|
||||
json_object_set_new(attr, CN_ARG_MIN, json_integer(cmd->arg_count_min));
|
||||
json_object_set_new(attr, CN_ARG_MAX, json_integer(cmd->arg_count_max));
|
||||
|
||||
|
@ -43,6 +43,34 @@ static int value_iterator(void *cls,
|
||||
|
||||
return MHD_YES;
|
||||
}
|
||||
static int value_sum_iterator(void *cls,
|
||||
enum MHD_ValueKind kind,
|
||||
const char *key,
|
||||
const char *value)
|
||||
{
|
||||
size_t& count = *(size_t*)cls;
|
||||
count++;
|
||||
return MHD_YES;
|
||||
}
|
||||
|
||||
static int value_copy_iterator(void *cls,
|
||||
enum MHD_ValueKind kind,
|
||||
const char *key,
|
||||
const char *value)
|
||||
{
|
||||
std::string k = key;
|
||||
if (value)
|
||||
{
|
||||
k += "=";
|
||||
k += value;
|
||||
}
|
||||
|
||||
char**& dest = *(char***) cls;
|
||||
*dest = MXS_STRDUP_A(k.c_str());
|
||||
dest++;
|
||||
|
||||
return MHD_YES;
|
||||
}
|
||||
|
||||
class HttpRequest
|
||||
{
|
||||
@ -106,6 +134,34 @@ public:
|
||||
return p.second;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get request option count
|
||||
*
|
||||
* @return Number of options in the request
|
||||
*/
|
||||
size_t get_option_count() const
|
||||
{
|
||||
size_t rval = 0;
|
||||
MHD_get_connection_values(m_connection, MHD_GET_ARGUMENT_KIND,
|
||||
value_sum_iterator, &rval);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy options to an array
|
||||
*
|
||||
* The @c dest parameter must be able to hold at least get_option_count()
|
||||
* pointers. The values stored need to be freed by the caller.
|
||||
*
|
||||
* @param dest Destination where options are copied
|
||||
*/
|
||||
void copy_options(char** dest) const
|
||||
{
|
||||
MHD_get_connection_values(m_connection, MHD_GET_ARGUMENT_KIND,
|
||||
value_copy_iterator, &dest);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return request body
|
||||
*
|
||||
@ -131,7 +187,7 @@ public:
|
||||
*
|
||||
* @return The complete request URI
|
||||
*/
|
||||
const std::string& get_uri() const
|
||||
std::string get_uri() const
|
||||
{
|
||||
return m_resource;
|
||||
}
|
||||
@ -143,11 +199,39 @@ public:
|
||||
*
|
||||
* @return The request URI part or empty string if no part was found
|
||||
*/
|
||||
const std::string uri_part(uint32_t idx) const
|
||||
std::string uri_part(uint32_t idx) const
|
||||
{
|
||||
return m_resource_parts.size() > idx ? m_resource_parts[idx] : "";
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return a segment of the URI
|
||||
*
|
||||
* Combines a range of parts into a segment of the URI. Each part is
|
||||
* separated by a forward slash.
|
||||
*
|
||||
* @param start Start of range
|
||||
* @param end End of range, not inclusive
|
||||
*
|
||||
* @return The URI segment that matches this range
|
||||
*/
|
||||
std::string uri_segment(uint32_t start, uint32_t end) const
|
||||
{
|
||||
std::string rval;
|
||||
|
||||
for (uint32_t i = start; i < end && i < m_resource_parts.size(); i++)
|
||||
{
|
||||
if (i > start)
|
||||
{
|
||||
rval += "/";
|
||||
}
|
||||
|
||||
rval += m_resource_parts[i];
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return how many parts are in the URI
|
||||
*
|
||||
@ -158,12 +242,12 @@ public:
|
||||
return m_resource_parts.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the last part of the URI
|
||||
*
|
||||
* @return The last URI part
|
||||
*/
|
||||
const std::string last_uri_part() const
|
||||
/**
|
||||
* @brief Return the last part of the URI
|
||||
*
|
||||
* @return The last URI part
|
||||
*/
|
||||
std::string last_uri_part() const
|
||||
{
|
||||
return m_resource_parts.size() > 0 ? m_resource_parts[m_resource_parts.size() - 1] : "";
|
||||
}
|
||||
|
@ -64,6 +64,7 @@ private:
|
||||
|
||||
ResourceCallback m_cb; /**< Resource handler callback */
|
||||
std::deque<std::string> m_path; /**< Path components */
|
||||
bool m_is_glob; /**< Does this path glob? */
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -137,8 +137,8 @@ static MODULECMD_DOMAIN* get_or_create_domain(const char *domain)
|
||||
}
|
||||
|
||||
static MODULECMD* command_create(const char *identifier, const char *domain,
|
||||
MODULECMDFN entry_point, int argc,
|
||||
modulecmd_arg_type_t* argv)
|
||||
enum modulecmd_type type, MODULECMDFN entry_point,
|
||||
int argc, modulecmd_arg_type_t* argv)
|
||||
{
|
||||
ss_dassert((argc && argv) || (argc == 0 && argv == NULL));
|
||||
MODULECMD *rval = (MODULECMD*)MXS_MALLOC(sizeof(*rval));
|
||||
@ -166,6 +166,7 @@ static MODULECMD* command_create(const char *identifier, const char *domain,
|
||||
types[0].description = "";
|
||||
}
|
||||
|
||||
rval->type = type;
|
||||
rval->func = entry_point;
|
||||
rval->identifier = id;
|
||||
rval->domain = dm;
|
||||
@ -413,7 +414,8 @@ static void free_argument(struct arg_node *arg)
|
||||
*/
|
||||
|
||||
bool modulecmd_register_command(const char *domain, const char *identifier,
|
||||
MODULECMDFN entry_point, int argc, modulecmd_arg_type_t *argv)
|
||||
enum modulecmd_type type, MODULECMDFN entry_point,
|
||||
int argc, modulecmd_arg_type_t *argv)
|
||||
{
|
||||
reset_error();
|
||||
bool rval = false;
|
||||
@ -430,7 +432,7 @@ bool modulecmd_register_command(const char *domain, const char *identifier,
|
||||
}
|
||||
else
|
||||
{
|
||||
MODULECMD *cmd = command_create(identifier, domain, entry_point, argc, argv);
|
||||
MODULECMD *cmd = command_create(identifier, domain, type, entry_point, argc, argv);
|
||||
|
||||
if (cmd)
|
||||
{
|
||||
@ -687,3 +689,17 @@ bool modulecmd_arg_is_present(const MODULECMD_ARG *arg, int idx)
|
||||
return arg->argc > idx &&
|
||||
MODULECMD_GET_TYPE(&arg->argv[idx].type) != MODULECMD_ARG_NONE;
|
||||
}
|
||||
|
||||
bool modulecmd_requires_output_dcb(const MODULECMD* cmd)
|
||||
{
|
||||
for (int i = 0; i < cmd->arg_count_max; i++)
|
||||
{
|
||||
if (cmd->arg_types[i].type == MODULECMD_ARG_OUTPUT)
|
||||
{
|
||||
/** We can't call this as it requries a DCB for output so don't show it */
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <maxscale/housekeeper.h>
|
||||
#include <maxscale/http.hh>
|
||||
#include <maxscale/adminusers.h>
|
||||
#include <maxscale/modulecmd.h>
|
||||
|
||||
#include "maxscale/httprequest.hh"
|
||||
#include "maxscale/httpresponse.hh"
|
||||
@ -103,7 +104,8 @@ private:
|
||||
};
|
||||
|
||||
Resource::Resource(ResourceCallback cb, int components, ...) :
|
||||
m_cb(cb)
|
||||
m_cb(cb),
|
||||
m_is_glob(false)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, components);
|
||||
@ -112,6 +114,10 @@ Resource::Resource(ResourceCallback cb, int components, ...) :
|
||||
{
|
||||
string part = va_arg(args, const char*);
|
||||
m_path.push_back(part);
|
||||
if (part == "?")
|
||||
{
|
||||
m_is_glob = true;
|
||||
}
|
||||
}
|
||||
va_end(args);
|
||||
}
|
||||
@ -124,11 +130,12 @@ bool Resource::match(const HttpRequest& request) const
|
||||
{
|
||||
bool rval = false;
|
||||
|
||||
if (request.uri_part_count() == m_path.size())
|
||||
if (request.uri_part_count() == m_path.size() || m_is_glob)
|
||||
{
|
||||
rval = true;
|
||||
size_t parts = MXS_MIN(request.uri_part_count(), m_path.size());
|
||||
|
||||
for (size_t i = 0; i < request.uri_part_count(); i++)
|
||||
for (size_t i = 0; i < parts; i++)
|
||||
{
|
||||
if (m_path[i] != request.uri_part(i) &&
|
||||
!matching_variable_path(m_path[i], request.uri_part(i)))
|
||||
@ -185,6 +192,11 @@ bool Resource::matching_variable_path(const string& path, const string& target)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (path == "?")
|
||||
{
|
||||
/** Wildcard match */
|
||||
rval = true;
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
@ -550,6 +562,43 @@ HttpResponse cb_delete_user(const HttpRequest& request)
|
||||
return HttpResponse(MHD_HTTP_FORBIDDEN, runtime_get_json_error());
|
||||
}
|
||||
|
||||
HttpResponse cb_modulecmd(const HttpRequest& request)
|
||||
{
|
||||
std::string module = request.uri_part(2);
|
||||
std::string identifier = request.uri_segment(3, request.uri_part_count());
|
||||
std::string verb = request.get_verb();
|
||||
|
||||
const MODULECMD* cmd = modulecmd_find_command(module.c_str(), identifier.c_str());
|
||||
|
||||
if (cmd && !modulecmd_requires_output_dcb(cmd))
|
||||
{
|
||||
if ((!MODULECMD_MODIFIES_DATA(cmd) && verb == MHD_HTTP_METHOD_GET) ||
|
||||
(MODULECMD_MODIFIES_DATA(cmd) && verb == MHD_HTTP_METHOD_POST))
|
||||
{
|
||||
int n_opts = (int)request.get_option_count();
|
||||
char* opts[n_opts];
|
||||
request.copy_options(opts);
|
||||
|
||||
MODULECMD_ARG* args = modulecmd_arg_parse(cmd, n_opts, (const void**)opts);
|
||||
bool rval = false;
|
||||
|
||||
if (args)
|
||||
{
|
||||
rval = modulecmd_call_command(cmd, args);
|
||||
}
|
||||
|
||||
for (int i = 0; i < n_opts; i++)
|
||||
{
|
||||
MXS_FREE(opts[i]);
|
||||
}
|
||||
|
||||
return HttpResponse(rval ? MHD_HTTP_OK : MHD_HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
return HttpResponse(MHD_HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
HttpResponse cb_send_ok(const HttpRequest& request)
|
||||
{
|
||||
return HttpResponse(MHD_HTTP_OK);
|
||||
@ -563,6 +612,18 @@ public:
|
||||
typedef std::shared_ptr<Resource> SResource;
|
||||
typedef list<SResource> ResourceList;
|
||||
|
||||
/**
|
||||
* Create REST API resources
|
||||
*
|
||||
* Each resource represents either a collection of resources, an individual
|
||||
* resource, a sub-resource of a resource or an "action" endpoint which
|
||||
* executes an action.
|
||||
*
|
||||
* The resources are defined by the Resource class. Each resource maps to a
|
||||
* HTTP method and one or more paths. The path components can contain either
|
||||
* an explicit string, a colon-prefixed object type or a question mark for
|
||||
* a path component that matches everything.
|
||||
*/
|
||||
RootResource()
|
||||
{
|
||||
// Special resources required by OPTION etc.
|
||||
@ -594,6 +655,9 @@ public:
|
||||
m_get.push_back(SResource(new Resource(cb_all_modules, 2, "maxscale", "modules")));
|
||||
m_get.push_back(SResource(new Resource(cb_module, 3, "maxscale", "modules", ":module")));
|
||||
|
||||
/** For all read-only module commands */
|
||||
m_get.push_back(SResource(new Resource(cb_modulecmd, 4, "maxscale", "modules", ":module", "?")));
|
||||
|
||||
m_get.push_back(SResource(new Resource(cb_all_users, 1, "users")));
|
||||
m_get.push_back(SResource(new Resource(cb_all_inet_users, 2, "users", "inet")));
|
||||
m_get.push_back(SResource(new Resource(cb_all_unix_users, 2, "users", "unix")));
|
||||
@ -609,6 +673,9 @@ public:
|
||||
m_post.push_back(SResource(new Resource(cb_create_user, 2, "users", "inet")));
|
||||
m_post.push_back(SResource(new Resource(cb_create_user, 2, "users", "unix")));
|
||||
|
||||
/** For all module commands that modify state/data */
|
||||
m_post.push_back(SResource(new Resource(cb_modulecmd, 4, "maxscale", "modules", ":module", "?")));
|
||||
|
||||
/** Update resources */
|
||||
m_put.push_back(SResource(new Resource(cb_alter_server, 2, "servers", ":server")));
|
||||
m_put.push_back(SResource(new Resource(cb_alter_monitor, 2, "monitors", ":monitor")));
|
||||
|
@ -66,10 +66,10 @@ int test_arguments()
|
||||
TEST(modulecmd_find_command(ns, id) == NULL, "The registered command should not yet be found");
|
||||
TEST(strlen(modulecmd_get_error()), "Error message should not be empty");
|
||||
|
||||
TEST(modulecmd_register_command(ns, id, test_fn, 2, args1),
|
||||
TEST(modulecmd_register_command(ns, id, MODULECMD_TYPE_ACTIVE, test_fn, 2, args1),
|
||||
"Registering a command should succeed");
|
||||
|
||||
TEST(!modulecmd_register_command(ns, id, test_fn, 2, args1),
|
||||
TEST(!modulecmd_register_command(ns, id, MODULECMD_TYPE_ACTIVE, test_fn, 2, args1),
|
||||
"Registering the command a second time should fail");
|
||||
TEST(strlen(modulecmd_get_error()), "Error message should not be empty");
|
||||
|
||||
@ -162,7 +162,7 @@ int test_optional_arguments()
|
||||
{MODULECMD_ARG_BOOLEAN | MODULECMD_ARG_OPTIONAL, ""}
|
||||
};
|
||||
|
||||
TEST(modulecmd_register_command(ns, id, test_fn2, 2, args1),
|
||||
TEST(modulecmd_register_command(ns, id, MODULECMD_TYPE_ACTIVE, test_fn2, 2, args1),
|
||||
"Registering a command should succeed");
|
||||
|
||||
const MODULECMD *cmd = modulecmd_find_command(ns, id);
|
||||
@ -234,7 +234,7 @@ int test_module_errors()
|
||||
const char *ns = "test_module_errors";
|
||||
const char *id = "test_module_errors";
|
||||
|
||||
TEST(modulecmd_register_command(ns, id, test_fn3, 0, NULL),
|
||||
TEST(modulecmd_register_command(ns, id, MODULECMD_TYPE_ACTIVE, test_fn3, 0, NULL),
|
||||
"Registering a command should succeed");
|
||||
|
||||
const MODULECMD *cmd = modulecmd_find_command(ns, id);
|
||||
@ -266,7 +266,7 @@ int test_map()
|
||||
{
|
||||
char id[200];
|
||||
sprintf(id, "test_map%d", i + 1);
|
||||
TEST(modulecmd_register_command(map_dom, id, test_fn_map, 0, NULL),
|
||||
TEST(modulecmd_register_command(map_dom, id, MODULECMD_TYPE_ACTIVE, test_fn_map, 0, NULL),
|
||||
"Registering a command should succeed");
|
||||
}
|
||||
|
||||
@ -332,7 +332,8 @@ int test_pointers()
|
||||
{MODULECMD_ARG_DCB, ""}
|
||||
};
|
||||
|
||||
TEST(modulecmd_register_command(ns, id, ptrfn, 1, args), "Registering a command should succeed");
|
||||
TEST(modulecmd_register_command(ns, id, MODULECMD_TYPE_ACTIVE, ptrfn, 1, args),
|
||||
"Registering a command should succeed");
|
||||
TEST(strlen(modulecmd_get_error()) == 0, "Error message should be empty");
|
||||
|
||||
const MODULECMD *cmd = modulecmd_find_command(ns, id);
|
||||
@ -366,7 +367,8 @@ int test_domain_matching()
|
||||
{MODULECMD_ARG_MONITOR | MODULECMD_ARG_NAME_MATCHES_DOMAIN, ""}
|
||||
};
|
||||
|
||||
TEST(modulecmd_register_command(ns, id, monfn, 1, args), "Registering a command should succeed");
|
||||
TEST(modulecmd_register_command(ns, id, MODULECMD_TYPE_ACTIVE, monfn, 1, args),
|
||||
"Registering a command should succeed");
|
||||
TEST(strlen(modulecmd_get_error()) == 0, "Error message should be empty");
|
||||
|
||||
const MODULECMD *cmd = modulecmd_find_command(ns, id);
|
||||
|
@ -154,7 +154,7 @@ MXS_MODULE* MXS_CREATE_MODULE()
|
||||
{ MODULECMD_ARG_STRING, "Password of the user"}
|
||||
};
|
||||
|
||||
modulecmd_register_command("cdc", "add_user", cdc_add_new_user, 3, args);
|
||||
modulecmd_register_command("cdc", "add_user", MODULECMD_TYPE_ACTIVE, cdc_add_new_user, 3, args);
|
||||
|
||||
static MXS_AUTHENTICATOR MyObject =
|
||||
{
|
||||
|
4
server/modules/filter/cache/cachefilter.cc
vendored
4
server/modules/filter/cache/cachefilter.cc
vendored
@ -147,8 +147,8 @@ extern "C" MXS_MODULE* MXS_CREATE_MODULE()
|
||||
{ MODULECMD_ARG_FILTER | MODULECMD_ARG_NAME_MATCHES_DOMAIN, "Cache name" }
|
||||
};
|
||||
|
||||
modulecmd_register_command(MXS_MODULE_NAME, "show", cache_command_show,
|
||||
MXS_ARRAY_NELEMS(show_argv), show_argv);
|
||||
modulecmd_register_command(MXS_MODULE_NAME, "show", MODULECMD_TYPE_PASSIVE,
|
||||
cache_command_show, MXS_ARRAY_NELEMS(show_argv), show_argv);
|
||||
|
||||
MXS_NOTICE("Initialized cache module %s.\n", VERSION_STRING);
|
||||
|
||||
|
@ -826,7 +826,8 @@ MXS_MODULE* MXS_CREATE_MODULE()
|
||||
{MODULECMD_ARG_STRING | MODULECMD_ARG_OPTIONAL, "Path to rule file"}
|
||||
};
|
||||
|
||||
modulecmd_register_command(MXS_MODULE_NAME, "rules/reload", dbfw_reload_rules, 2, args_rules_reload);
|
||||
modulecmd_register_command(MXS_MODULE_NAME, "rules/reload", MODULECMD_TYPE_ACTIVE,
|
||||
dbfw_reload_rules, 2, args_rules_reload);
|
||||
|
||||
modulecmd_arg_type_t args_rules_show[] =
|
||||
{
|
||||
@ -834,7 +835,8 @@ MXS_MODULE* MXS_CREATE_MODULE()
|
||||
{MODULECMD_ARG_FILTER | MODULECMD_ARG_NAME_MATCHES_DOMAIN, "Filter to inspect"}
|
||||
};
|
||||
|
||||
modulecmd_register_command(MXS_MODULE_NAME, "rules", dbfw_show_rules, 2, args_rules_show);
|
||||
modulecmd_register_command(MXS_MODULE_NAME, "rules", MODULECMD_TYPE_PASSIVE,
|
||||
dbfw_show_rules, 2, args_rules_show);
|
||||
|
||||
static MXS_FILTER_OBJECT MyObject =
|
||||
{
|
||||
|
@ -64,7 +64,8 @@ extern "C" MXS_MODULE* MXS_CREATE_MODULE()
|
||||
{ MODULECMD_ARG_FILTER | MODULECMD_ARG_NAME_MATCHES_DOMAIN, "Masking name" }
|
||||
};
|
||||
|
||||
modulecmd_register_command(MXS_MODULE_NAME, "reload", masking_command_reload,
|
||||
modulecmd_register_command(MXS_MODULE_NAME, "reload",
|
||||
MODULECMD_TYPE_ACTIVE, masking_command_reload,
|
||||
MXS_ARRAY_NELEMS(reload_argv), reload_argv);
|
||||
|
||||
MXS_NOTICE("Masking module %s initialized.", VERSION_STRING);
|
||||
|
@ -148,7 +148,7 @@ MXS_MODULE* MXS_CREATE_MODULE()
|
||||
{ MODULECMD_ARG_SERVICE | MODULECMD_ARG_NAME_MATCHES_DOMAIN, "The avrorouter service" },
|
||||
{ MODULECMD_ARG_STRING, "Action, whether to 'start' or 'stop' the conversion process" }
|
||||
};
|
||||
modulecmd_register_command(MXS_MODULE_NAME, "convert", avro_handle_convert, 2, args);
|
||||
modulecmd_register_command(MXS_MODULE_NAME, "convert", MODULECMD_TYPE_ACTIVE, avro_handle_convert, 2, args);
|
||||
|
||||
static MXS_ROUTER_OBJECT MyObject =
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user