MXS-1929: Allow service creation at runtime
Services can now be created at runtime. The command to create services is exposed in the REST API.
This commit is contained in:
parent
5a40064826
commit
037cedf70e
@ -76,6 +76,7 @@ MXS_BEGIN_DECLS
|
||||
#define MXS_JSON_PTR_PARAM_SSL_VERIFY_PEER_CERT MXS_JSON_PTR_PARAMETERS "/ssl_verify_peer_certificate"
|
||||
|
||||
/** Non-parameter JSON pointers */
|
||||
#define MXS_JSON_PTR_ROUTER "/data/attributes/router"
|
||||
#define MXS_JSON_PTR_MODULE "/data/attributes/module"
|
||||
#define MXS_JSON_PTR_PASSWORD "/data/attributes/password"
|
||||
#define MXS_JSON_PTR_ACCOUNT "/data/attributes/account"
|
||||
|
@ -1078,6 +1078,53 @@ bool runtime_create_filter(const char *name, const char *module, MXS_CONFIG_PARA
|
||||
return rval;
|
||||
}
|
||||
|
||||
static bool runtime_create_service(const char *name, const char *router, MXS_CONFIG_PARAMETER* params)
|
||||
{
|
||||
mxs::SpinLockGuard guard(crt_lock);
|
||||
bool rval = false;
|
||||
|
||||
if (service_find(name) == NULL)
|
||||
{
|
||||
SERVICE* service = NULL;
|
||||
CONFIG_CONTEXT ctx{(char*)""};
|
||||
ctx.parameters = load_defaults(router, MODULE_FILTER, CN_FILTER);
|
||||
|
||||
if (ctx.parameters)
|
||||
{
|
||||
for (MXS_CONFIG_PARAMETER* p = params; p; p = p->next)
|
||||
{
|
||||
config_replace_param(&ctx, p->name, p->value);
|
||||
}
|
||||
|
||||
if ((service = service_alloc(name, router, ctx.parameters)) == NULL)
|
||||
{
|
||||
runtime_error("Could not create service '%s' with module '%s'", name, router);
|
||||
}
|
||||
|
||||
config_parameter_free(ctx.parameters);
|
||||
}
|
||||
|
||||
if (service)
|
||||
{
|
||||
if (service_serialize(service))
|
||||
{
|
||||
MXS_NOTICE("Created service '%s'", name);
|
||||
rval = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
runtime_error("Failed to serialize service '%s'", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
runtime_error("Can't create service '%s', it already exists", name);
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
bool runtime_destroy_service(SERVICE* service)
|
||||
{
|
||||
bool rval = false;
|
||||
@ -1815,6 +1862,28 @@ MXS_FILTER_DEF* runtime_create_filter_from_json(json_t* json)
|
||||
return rval;
|
||||
}
|
||||
|
||||
SERVICE* runtime_create_service_from_json(json_t* json)
|
||||
{
|
||||
SERVICE* rval = NULL;
|
||||
|
||||
if (validate_object_json(json, {MXS_JSON_PTR_ROUTER}, {service_to_filter, object_to_server}))
|
||||
{
|
||||
const char* name = json_string_value(mxs_json_pointer(json, MXS_JSON_PTR_ID));
|
||||
const char* router = json_string_value(mxs_json_pointer(json, MXS_JSON_PTR_ROUTER));
|
||||
MXS_CONFIG_PARAMETER* params = extract_parameters_from_json(json);
|
||||
|
||||
if (runtime_create_service(name, router, params))
|
||||
{
|
||||
rval = service_find(name);
|
||||
ss_dassert(rval);
|
||||
}
|
||||
|
||||
config_parameter_free(params);
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
bool object_to_server_relations(const char* target, json_t* old_json, json_t* new_json)
|
||||
{
|
||||
if (mxs_json_pointer(new_json, MXS_JSON_PTR_RELATIONSHIPS) == NULL)
|
||||
|
@ -275,6 +275,15 @@ MXS_MONITOR* runtime_create_monitor_from_json(json_t* json);
|
||||
*/
|
||||
MXS_FILTER_DEF* runtime_create_filter_from_json(json_t* json);
|
||||
|
||||
/**
|
||||
* @brief Create a new service from JSON
|
||||
*
|
||||
* @param json JSON defining the service
|
||||
*
|
||||
* @return Created service or NULL on error
|
||||
*/
|
||||
SERVICE* runtime_create_service_from_json(json_t* json);
|
||||
|
||||
/**
|
||||
* @brief Alter a monitor using JSON
|
||||
*
|
||||
|
@ -337,6 +337,18 @@ HttpResponse cb_create_filter(const HttpRequest& request)
|
||||
return HttpResponse(MHD_HTTP_FORBIDDEN, runtime_get_json_error());
|
||||
}
|
||||
|
||||
HttpResponse cb_create_service(const HttpRequest& request)
|
||||
{
|
||||
ss_dassert(request.get_json());
|
||||
|
||||
if (runtime_create_service_from_json(request.get_json()))
|
||||
{
|
||||
return HttpResponse(MHD_HTTP_NO_CONTENT);
|
||||
}
|
||||
|
||||
return HttpResponse(MHD_HTTP_FORBIDDEN, runtime_get_json_error());
|
||||
}
|
||||
|
||||
HttpResponse cb_create_service_listener(const HttpRequest& request)
|
||||
{
|
||||
SERVICE* service = service_find(request.uri_part(1).c_str());
|
||||
@ -885,6 +897,7 @@ public:
|
||||
m_post.push_back(SResource(new Resource(cb_create_server, 1, "servers")));
|
||||
m_post.push_back(SResource(new Resource(cb_create_monitor, 1, "monitors")));
|
||||
m_post.push_back(SResource(new Resource(cb_create_filter, 1, "filters")));
|
||||
m_post.push_back(SResource(new Resource(cb_create_service, 1, "services")));
|
||||
m_post.push_back(SResource(new Resource(cb_create_service_listener, 3,
|
||||
"services", ":service", "listeners")));
|
||||
m_post.push_back(SResource(new Resource(cb_create_user, 2, "users", "inet")));
|
||||
|
Loading…
x
Reference in New Issue
Block a user